You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2026/03/19 19:00:48 UTC

(superset) branch master updated: fix(theme): ensure colorLink follows colorPrimary when not explicitly set (#38517)

This is an automated email from the ASF dual-hosted git repository.

jli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 65f13f773e5 fix(theme): ensure colorLink follows colorPrimary when not explicitly set (#38517)
65f13f773e5 is described below

commit 65f13f773e51ebc46aeab50d6f6cb35defc5fdb5
Author: Levis Mbote <11...@users.noreply.github.com>
AuthorDate: Thu Mar 19 22:00:41 2026 +0300

    fix(theme): ensure colorLink follows colorPrimary when not explicitly set (#38517)
---
 .../superset-core/src/theme/Theme.test.tsx         | 70 ++++++++++++++++++++++
 .../packages/superset-core/src/theme/Theme.tsx     | 15 +++++
 2 files changed, 85 insertions(+)

diff --git a/superset-frontend/packages/superset-core/src/theme/Theme.test.tsx b/superset-frontend/packages/superset-core/src/theme/Theme.test.tsx
index 873cf94ec5f..01d18e7483e 100644
--- a/superset-frontend/packages/superset-core/src/theme/Theme.test.tsx
+++ b/superset-frontend/packages/superset-core/src/theme/Theme.test.tsx
@@ -839,3 +839,73 @@ test('Theme includes both echartsOptionsOverrides and echartsOptionsOverridesByC
     },
   });
 });
+
+test('colorLink derives from colorPrimary when merging with base theme', () => {
+  const baseTheme: AnyThemeConfig = {
+    token: {
+      colorPrimary: '#2893B3',
+      colorLink: '#2893B3',
+      colorInfo: '#66bcfe',
+    },
+  };
+
+  const userTheme: AnyThemeConfig = {
+    token: {
+      colorPrimary: '#f759ab',
+    },
+  };
+
+  const theme = Theme.fromConfig(userTheme, baseTheme);
+
+  expect(theme.theme.colorPrimary).toBe('#f759ab');
+  expect(theme.theme.colorLink).toBe('#f759ab');
+  expect(theme.theme.colorInfo).toBe('#66bcfe');
+});
+
+test('colorLink is not overridden when user explicitly sets it', () => {
+  const baseTheme: AnyThemeConfig = {
+    token: {
+      colorPrimary: '#2893B3',
+      colorLink: '#2893B3',
+    },
+  };
+
+  const userTheme: AnyThemeConfig = {
+    token: {
+      colorPrimary: '#f759ab',
+      colorLink: '#ff0000',
+    },
+  };
+
+  const theme = Theme.fromConfig(userTheme, baseTheme);
+
+  expect(theme.theme.colorPrimary).toBe('#f759ab');
+  expect(theme.theme.colorLink).toBe('#ff0000');
+});
+
+test('colorLink derives from colorPrimary in setConfig when not explicitly set', () => {
+  const theme = Theme.fromConfig();
+
+  theme.setConfig({
+    token: {
+      colorPrimary: '#f759ab',
+    },
+  });
+
+  expect(theme.theme.colorPrimary).toBe('#f759ab');
+  expect(theme.theme.colorLink).toBe('#f759ab');
+});
+
+test('colorLink is preserved in setConfig when explicitly set', () => {
+  const theme = Theme.fromConfig();
+
+  theme.setConfig({
+    token: {
+      colorPrimary: '#f759ab',
+      colorLink: '#ff0000',
+    },
+  });
+
+  expect(theme.theme.colorPrimary).toBe('#f759ab');
+  expect(theme.theme.colorLink).toBe('#ff0000');
+});
diff --git a/superset-frontend/packages/superset-core/src/theme/Theme.tsx b/superset-frontend/packages/superset-core/src/theme/Theme.tsx
index 7a890982eaa..138a0ace9b6 100644
--- a/superset-frontend/packages/superset-core/src/theme/Theme.tsx
+++ b/superset-frontend/packages/superset-core/src/theme/Theme.tsx
@@ -66,6 +66,17 @@ export class Theme {
       mergedConfig = mergeWith({}, baseTheme, config, (objValue, srcValue) =>
         Array.isArray(srcValue) ? srcValue : undefined,
       );
+
+      // In Ant Design v5, colorLink derives from colorInfo, not colorPrimary.
+      // Currently we expectlinks to follow the brand/primary color. When the user
+      // overrides colorPrimary without explicitly setting colorLink, update the
+      // merged colorLink so links match the new primary palette.
+      if (config.token?.colorPrimary && !config.token?.colorLink) {
+        const mToken = mergedConfig?.token;
+        if (mToken) {
+          mToken.colorLink = mToken.colorPrimary;
+        }
+      }
     } else if (baseTheme && !config) {
       mergedConfig = baseTheme;
     }
@@ -98,6 +109,10 @@ export class Theme {
   setConfig(config: AnyThemeConfig): void {
     const antdConfig = normalizeThemeConfig(config);
 
+    if (antdConfig.token?.colorPrimary && !antdConfig.token?.colorLink) {
+      antdConfig.token.colorLink = antdConfig.token.colorPrimary;
+    }
+
     // First phase: Let Ant Design compute the tokens
     const tokens = Theme.getFilteredAntdTheme(antdConfig);