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 (