diff --git a/superset-frontend/packages/superset-core/src/theme/types.ts b/superset-frontend/packages/superset-core/src/theme/types.ts index 697cb8cb727..fccbfd41d36 100644 --- a/superset-frontend/packages/superset-core/src/theme/types.ts +++ b/superset-frontend/packages/superset-core/src/theme/types.ts @@ -110,6 +110,26 @@ export interface ColorVariants { } export interface SupersetSpecificTokens { + // Label variant tokens — Published/Draft (dashboard status) + labelPublishedColor?: string; + labelPublishedBg?: string; + labelPublishedBorderColor?: string; + labelPublishedIconColor?: string; + labelDraftColor?: string; + labelDraftBg?: string; + labelDraftBorderColor?: string; + labelDraftIconColor?: string; + + // Label variant tokens — Dataset type (Physical/Virtual) + labelDatasetPhysicalColor?: string; + labelDatasetPhysicalBg?: string; + labelDatasetPhysicalBorderColor?: string; + labelDatasetPhysicalIconColor?: string; + labelDatasetVirtualColor?: string; + labelDatasetVirtualBg?: string; + labelDatasetVirtualBorderColor?: string; + labelDatasetVirtualIconColor?: string; + // Font-related fontSizeXS: string; fontSizeXXL: string; diff --git a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.test.tsx new file mode 100644 index 00000000000..091d794dcba --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.test.tsx @@ -0,0 +1,128 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { supersetTheme } from '@apache-superset/core/theme'; +import { DatasetTypeLabel } from './DatasetTypeLabel'; +import { renderWithTheme } from './testUtils'; + +test('renders "Physical" text for physical dataset', () => { + renderWithTheme(); + expect(screen.getByText('Physical')).toBeInTheDocument(); +}); + +test('renders "Virtual" text for virtual dataset', () => { + renderWithTheme(); + expect(screen.getByText('Virtual')).toBeInTheDocument(); +}); + +test('uses default primary color for physical label', () => { + renderWithTheme(); + const tag = screen + .getByText('Physical') + .closest('[data-test="dataset-type-label"]'); + expect(tag).toHaveStyle({ color: supersetTheme.colorPrimaryText }); +}); + +test('uses default color for virtual label', () => { + renderWithTheme(); + const tag = screen + .getByText('Virtual') + .closest('[data-test="dataset-type-label"]'); + expect(tag).toHaveStyle({ color: supersetTheme.colorPrimary }); +}); + +test('applies custom labelDatasetPhysical tokens when set', () => { + renderWithTheme(, { + labelDatasetPhysicalColor: '#111111', + labelDatasetPhysicalBg: '#222222', + labelDatasetPhysicalBorderColor: '#333333', + }); + const tag = screen + .getByText('Physical') + .closest('[data-test="dataset-type-label"]'); + expect(tag).toHaveStyle({ + color: '#111111', + backgroundColor: '#222222', + borderColor: '#333333', + }); +}); + +test('applies custom labelDatasetVirtual tokens when set', () => { + renderWithTheme(, { + labelDatasetVirtualColor: '#444444', + labelDatasetVirtualBg: '#555555', + labelDatasetVirtualBorderColor: '#666666', + }); + const tag = screen + .getByText('Virtual') + .closest('[data-test="dataset-type-label"]'); + expect(tag).toHaveStyle({ + color: '#444444', + backgroundColor: '#555555', + borderColor: '#666666', + }); +}); + +test('applies custom labelDatasetPhysicalIconColor to icon', () => { + const { container } = renderWithTheme( + , + { labelDatasetPhysicalIconColor: '#aabbcc' }, + ); + const svg = container.querySelector('[role="img"]'); + expect(svg).toHaveStyle({ color: '#aabbcc' }); +}); + +test('applies custom labelDatasetVirtualIconColor to icon', () => { + const { container } = renderWithTheme( + , + { labelDatasetVirtualIconColor: '#ddeeff' }, + ); + const svg = container.querySelector('[role="img"]'); + expect(svg).toHaveStyle({ color: '#ddeeff' }); +}); + +test('uses default colorPrimary for physical dataset icon', () => { + const { container } = renderWithTheme( + , + ); + const svg = container.querySelector('[role="img"]'); + expect(svg).toHaveStyle({ color: supersetTheme.colorPrimary }); +}); + +test('virtual dataset icon has no explicit icon color by default', () => { + const { container } = renderWithTheme( + , + ); + const svg = container.querySelector('[role="img"]') as HTMLElement; + expect(svg.style.color).toBe(''); +}); + +test('partial token override uses custom bg with default color fallback', () => { + renderWithTheme(, { + labelDatasetPhysicalBg: '#ff0000', + }); + const tag = screen + .getByText('Physical') + .closest('[data-test="dataset-type-label"]'); + expect(tag).toHaveStyle({ + backgroundColor: '#ff0000', + color: supersetTheme.colorPrimaryText, + }); +}); diff --git a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx index 48784d937a3..cab54c35e8a 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/Label/reusable/DatasetTypeLabel.tsx @@ -32,28 +32,41 @@ export const DatasetTypeLabel: React.FC = ({ datasetType, }) => { const theme = useTheme(); - const label: string = - datasetType === 'physical' ? t('Physical') : t('Virtual'); - const icon = - datasetType === 'physical' ? ( - - ) : ( - - ); - const labelType = datasetType === 'physical' ? 'primary' : 'default'; + const isPhysical = datasetType === 'physical'; + const label: string = isPhysical ? t('Physical') : t('Virtual'); + const labelType = isPhysical ? 'primary' : 'default'; + + const color = isPhysical + ? (theme.labelDatasetPhysicalColor ?? theme.colorPrimaryText) + : (theme.labelDatasetVirtualColor ?? theme.colorPrimary); + const bg = isPhysical + ? theme.labelDatasetPhysicalBg + : theme.labelDatasetVirtualBg; + const borderColor = isPhysical + ? theme.labelDatasetPhysicalBorderColor + : theme.labelDatasetVirtualBorderColor; + const iconColor = isPhysical + ? (theme.labelDatasetPhysicalIconColor ?? theme.colorPrimary) + : theme.labelDatasetVirtualIconColor; + + const icon = isPhysical ? ( + + ) : ( + + ); return (