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

maximebeauchemin 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 05994319b7 feat(theming): improving theme docs and configuration 
(#33851)
05994319b7 is described below

commit 05994319b72d96facf065a4299b2ad9b79a25ab9
Author: Maxime Beauchemin <maximebeauche...@gmail.com>
AuthorDate: Sun Jun 22 15:39:00 2025 -0700

    feat(theming): improving theme docs and configuration (#33851)
---
 docs/docs/configuration/theming.mdx                | 53 ++++++++++++++++++++++
 .../src/components/ThemeEditor/index.tsx           |  1 -
 .../packages/superset-ui-core/src/theme/types.ts   |  5 +-
 superset-frontend/src/constants.ts                 |  2 +-
 superset-frontend/src/features/home/RightMenu.tsx  |  1 -
 superset-frontend/src/preamble.ts                  | 12 +----
 superset-frontend/src/types/bootstrapTypes.ts      |  2 +-
 .../src/views/RootContextProviders.tsx             |  4 ++
 superset/config.py                                 | 29 ++++++++----
 superset/views/base.py                             |  2 +-
 10 files changed, 84 insertions(+), 27 deletions(-)

diff --git a/docs/docs/configuration/theming.mdx 
b/docs/docs/configuration/theming.mdx
new file mode 100644
index 0000000000..7983b07d17
--- /dev/null
+++ b/docs/docs/configuration/theming.mdx
@@ -0,0 +1,53 @@
+---
+title: Theming
+hide_title: true
+sidebar_position: 12
+version: 1
+---
+# Theming Superset
+
+:::note
+apache-superset>=6.0
+:::
+
+Superset now rides on **Ant Design v5’s token-based theming**.
+Every Antd token works, plus a handful of Superset-specific ones for charts 
and dashboard chrome.
+
+## 1 — Create a theme
+
+1. Open the official [Ant Design Theme Editor](https://ant.design/theme-editor)
+2. Design your palette, typography, and component overrides.
+3. Open the `CONFIG` modal and paste the JSON.
+
+You can also extend with Superset-specific tokens (documented in the default 
theme object) before you import.
+
+## 2 — Apply it instance-wide
+
+```python
+# superset_config.py
+THEME = {
+    # Paste your JSON theme definition here
+}
+```
+
+Restart Superset to apply changes
+
+## 3 — Tweak live in the app (beta)
+
+Set the feature flag in your `superset_config`
+```python
+DEFAULT_FEATURE_FLAGS: dict[str, bool] = {
+    {{ ... }}
+    THEME_ALLOW_THEME_EDITOR_BETA = True,
+}
+```
+
+- Enables a JSON editor panel inside Superset as a new icon in the navbar
+- Intended for testing/design and rapid in-context iteration
+- End-user theme switching & preferences coming later
+
+## 4 — Potential Next Steps
+
+- CRUD UI for managing multiple themes
+- Per-dashboard & per-workspace theme assignment
+- User-selectable theme preferences
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/ThemeEditor/index.tsx
 
b/superset-frontend/packages/superset-ui-core/src/components/ThemeEditor/index.tsx
index 1a87688275..93dc0e9b53 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/ThemeEditor/index.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/ThemeEditor/index.tsx
@@ -67,7 +67,6 @@ const ThemeEditor: React.FC<ThemeEditorProps> = ({
   const handleSave = (): void => {
     try {
       const parsedTheme = JSON.parse(jsonMetadata);
-      console.log('Parsed theme:', parsedTheme);
       setTheme?.(parsedTheme);
       setIsModalOpen(false);
     } catch (error) {
diff --git a/superset-frontend/packages/superset-ui-core/src/theme/types.ts 
b/superset-frontend/packages/superset-ui-core/src/theme/types.ts
index bd38d69985..10e75029bf 100644
--- a/superset-frontend/packages/superset-ui-core/src/theme/types.ts
+++ b/superset-frontend/packages/superset-ui-core/src/theme/types.ts
@@ -108,9 +108,6 @@ export interface LegacySupersetTheme {
 }
 
 export interface SupersetSpecificTokens {
-  // Brand-related
-  brandIconMaxWidth: number;
-
   // Font-related
   fontSizeXS: string;
   fontSizeXXL: string;
@@ -118,6 +115,8 @@ export interface SupersetSpecificTokens {
   fontWeightLight: string;
   fontWeightStrong: number;
 
+  // Brand-related
+  brandIconMaxWidth: number;
   brandLogoAlt: string;
   brandLogoUrl: string;
   brandLogoMargin: string;
diff --git a/superset-frontend/src/constants.ts 
b/superset-frontend/src/constants.ts
index 0900265d1e..093dde8ec2 100644
--- a/superset-frontend/src/constants.ts
+++ b/superset-frontend/src/constants.ts
@@ -141,7 +141,7 @@ export const DEFAULT_COMMON_BOOTSTRAP_DATA: 
CommonBootstrapData = {
   },
   extra_categorical_color_schemes: [],
   extra_sequential_color_schemes: [],
-  theme_overrides: {},
+  theme: {},
   menu_data: {
     menu: [],
     brand: {
diff --git a/superset-frontend/src/features/home/RightMenu.tsx 
b/superset-frontend/src/features/home/RightMenu.tsx
index 9ea78f2f80..c3029b34e0 100644
--- a/superset-frontend/src/features/home/RightMenu.tsx
+++ b/superset-frontend/src/features/home/RightMenu.tsx
@@ -373,7 +373,6 @@ const RightMenu = ({
   };
 
   const theme = useTheme();
-
   return (
     <StyledDiv align={align}>
       {canDatabase && (
diff --git a/superset-frontend/src/preamble.ts 
b/superset-frontend/src/preamble.ts
index 1feca31546..d0ea972fb4 100644
--- a/superset-frontend/src/preamble.ts
+++ b/superset-frontend/src/preamble.ts
@@ -20,13 +20,7 @@ import { setConfig as setHotLoaderConfig } from 
'react-hot-loader';
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
 import dayjs from 'dayjs';
 // eslint-disable-next-line no-restricted-imports
-import {
-  configure,
-  makeApi,
-  initFeatureFlags,
-  // eslint-disable-next-line no-restricted-imports
-  themeObject, // TODO: DO not import theme directly
-} from '@superset-ui/core';
+import { configure, makeApi, initFeatureFlags } from '@superset-ui/core';
 import setupClient from './setup/setupClient';
 import setupColors from './setup/setupColors';
 import setupFormatters from './setup/setupFormatters';
@@ -68,10 +62,6 @@ setupFormatters(
 
 setupDashboardComponents();
 
-if (Object.keys(bootstrapData?.common?.theme_overrides || {}).length > 0) {
-  themeObject.setConfig(bootstrapData.common.theme_overrides);
-}
-
 const getMe = makeApi<void, User>({
   method: 'GET',
   endpoint: '/api/v1/me/',
diff --git a/superset-frontend/src/types/bootstrapTypes.ts 
b/superset-frontend/src/types/bootstrapTypes.ts
index 1e943fcdbe..9f20b586d0 100644
--- a/superset-frontend/src/types/bootstrapTypes.ts
+++ b/superset-frontend/src/types/bootstrapTypes.ts
@@ -153,7 +153,7 @@ export interface CommonBootstrapData {
   language_pack: LanguagePack;
   extra_categorical_color_schemes: ColorSchemeConfig[];
   extra_sequential_color_schemes: SequentialSchemeConfig[];
-  theme_overrides: JsonObject;
+  theme: JsonObject;
   menu_data: MenuData;
   d3_format: Partial<FormatLocaleDefinition>;
   d3_time_format: Partial<TimeLocaleDefinition>;
diff --git a/superset-frontend/src/views/RootContextProviders.tsx 
b/superset-frontend/src/views/RootContextProviders.tsx
index 53ae497267..d27b271c44 100644
--- a/superset-frontend/src/views/RootContextProviders.tsx
+++ b/superset-frontend/src/views/RootContextProviders.tsx
@@ -32,6 +32,10 @@ import { store } from './store';
 import '../preamble';
 
 const { common } = getBootstrapData();
+
+if (Object.keys(common?.theme || {}).length > 0) {
+  themeObject.setConfig(common.theme);
+}
 const themeController = new ThemeController({ themeObject });
 
 const extensionsRegistry = getExtensionsRegistry();
diff --git a/superset/config.py b/superset/config.py
index 3df32995bc..c526d01bc2 100644
--- a/superset/config.py
+++ b/superset/config.py
@@ -551,7 +551,8 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = {
     "PLAYWRIGHT_REPORTS_AND_THUMBNAILS": False,
     # Set to True to enable experimental chart plugins
     "CHART_PLUGINS_EXPERIMENTAL": False,
-    # Regardless of database configuration settings, force SQLLAB to run async 
using Celery  # noqa: E501
+    # Regardless of database configuration settings, force SQLLAB to run async
+    # using Celery
     "SQLLAB_FORCE_RUN_ASYNC": False,
     # Set to True to to enable factory resent CLI command
     "ENABLE_FACTORY_RESET_COMMAND": False,
@@ -559,11 +560,17 @@ DEFAULT_FEATURE_FLAGS: dict[str, bool] = {
     # If on, you'll want to add "https://avatars.slack-edge.com"; to the list 
of allowed
     # domains in your TALISMAN_CONFIG
     "SLACK_ENABLE_AVATARS": False,
-    # Adds a switch to the navbar to enable/disable the dark theme
-    # This is used for development to expose what is dynamic (css-in-js) vs
-    # what is managed by `.less` files.
-    "DARK_THEME_SWITCH": False,
-    # Allow users to optionally specify date formats in email subjects, which 
will be parsed if enabled. # noqa: E501
+    # Adds a switch to the navbar to easily switch between light and dark 
themes.
+    # This is intended to use for development, visual review, and 
theming-debugging
+    # purposes.
+    "THEME_ENABLE_DARK_THEME_SWITCH": False,
+    # Adds a theme editor as a modal dialog in the navbar. Allows people to 
type in JSON
+    # and see the changes applied to the current theme.
+    # This is intended to use for theme creation, visual review and 
theming-debugging
+    # purposes.
+    "THEME_ALLOW_THEME_EDITOR_BETA": False,
+    # Allow users to optionally specify date formats in email subjects, which 
will
+    # be parsed if enabled
     "DATE_FORMAT_IN_EMAIL_SUBJECT": False,
     # Allow metrics and columns to be grouped into (potentially nested) 
folders in the
     # chart builder
@@ -662,11 +669,17 @@ COMMON_BOOTSTRAP_OVERRIDES_FUNC: Callable[  # noqa: E731
 # This is merely a default
 EXTRA_CATEGORICAL_COLOR_SCHEMES: list[dict[str, Any]] = []
 
-# THEME_OVERRIDES is used for adding custom theme to superset, it follows the 
ant design
+# THEME is used for setting a custom theme to Superset, it follows the ant 
design
 # theme structure
 # You can use the AntDesign theme editor to generate a theme structure
 # https://ant.design/theme-editor
-THEME_OVERRIDES: dict[str, Any] = {}
+# To expose a JSON theme editor modal that can be triggered from the navbar
+# set the `ENABLE_THEME_EDITOR` feature flag to True.
+#
+# To set up the dark theme:
+# THEME = {"algorithm": "dark"}
+
+THEME: dict[str, Any] = {}
 
 # EXTRA_SEQUENTIAL_COLOR_SCHEMES is used for adding custom sequential color 
schemes
 # EXTRA_SEQUENTIAL_COLOR_SCHEMES =  [
diff --git a/superset/views/base.py b/superset/views/base.py
index 2b7dd076fa..8d31561775 100644
--- a/superset/views/base.py
+++ b/superset/views/base.py
@@ -371,7 +371,7 @@ def cached_common_bootstrap_data(  # pylint: 
disable=unused-argument
         "feature_flags": get_feature_flags(),
         "extra_sequential_color_schemes": 
conf["EXTRA_SEQUENTIAL_COLOR_SCHEMES"],
         "extra_categorical_color_schemes": 
conf["EXTRA_CATEGORICAL_COLOR_SCHEMES"],
-        "theme_overrides": conf["THEME_OVERRIDES"],
+        "theme": conf["THEME"],
         "menu_data": menu_data(g.user),
     }
     
bootstrap_data.update(conf["COMMON_BOOTSTRAP_OVERRIDES_FUNC"](bootstrap_data))

Reply via email to