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 2025/11/17 18:30:09 UTC
(superset) branch master updated: feat(embedded): add setThemeMode API for dynamic theme switching (#36125)
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 282f4e5de2 feat(embedded): add setThemeMode API for dynamic theme switching (#36125)
282f4e5de2 is described below
commit 282f4e5de2be345e5e9c7c5d439981fb53286dee
Author: Gabriel Torres Ruiz <ga...@gmail.com>
AuthorDate: Mon Nov 17 14:30:02 2025 -0400
feat(embedded): add setThemeMode API for dynamic theme switching (#36125)
---
superset-embedded-sdk/src/index.ts | 18 +++++++++++++++-
superset-frontend/src/embedded/index.tsx | 35 +++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts
index c04873924a..b9405393c5 100644
--- a/superset-embedded-sdk/src/index.ts
+++ b/superset-embedded-sdk/src/index.ts
@@ -81,6 +81,8 @@ export type ObserveDataMaskCallbackFn = (
nativeFiltersChanged: boolean;
},
) => void;
+export type ThemeMode = 'default' | 'dark' | 'system';
+
export type EmbeddedDashboard = {
getScrollSize: () => Promise<Size>;
unmount: () => void;
@@ -92,6 +94,7 @@ export type EmbeddedDashboard = {
getDataMask: () => Promise<Record<string, any>>;
getChartStates: () => Promise<Record<string, any>>;
setThemeConfig: (themeConfig: Record<string, any>) => void;
+ setThemeMode: (mode: ThemeMode) => void;
};
/**
@@ -265,6 +268,18 @@ export async function embedDashboard({
}
};
+ const setThemeMode = (mode: ThemeMode): void => {
+ try {
+ ourPort.emit('setThemeMode', { mode });
+ log(`Theme mode set to: ${mode}`);
+ } catch (error) {
+ log(
+ 'Error sending theme mode. Ensure the iframe side implements the "setThemeMode" method.',
+ );
+ throw error;
+ }
+ };
+
return {
getScrollSize,
unmount,
@@ -273,6 +288,7 @@ export async function embedDashboard({
observeDataMask,
getDataMask,
getChartStates,
- setThemeConfig
+ setThemeConfig,
+ setThemeMode,
};
}
diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx
index 794cca051d..560aed5d0b 100644
--- a/superset-frontend/src/embedded/index.tsx
+++ b/superset-frontend/src/embedded/index.tsx
@@ -22,7 +22,7 @@ import { lazy, Suspense } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { makeApi, t, logging } from '@superset-ui/core';
-import { type SupersetThemeConfig } from '@apache-superset/core/ui';
+import { type SupersetThemeConfig, ThemeMode } from '@apache-superset/core/ui';
import Switchboard from '@superset-ui/switchboard';
import getBootstrapData, { applicationRoot } from 'src/utils/getBootstrapData';
import setupClient from 'src/setup/setupClient';
@@ -264,6 +264,39 @@ window.addEventListener('message', function embeddedPageInitializer(event) {
},
);
+ Switchboard.defineMethod(
+ 'setThemeMode',
+ (payload: { mode: 'default' | 'dark' | 'system' }) => {
+ const { mode } = payload;
+ log('Received setThemeMode request:', mode);
+
+ try {
+ const themeController = getThemeController();
+
+ const themeModeMap: Record<string, ThemeMode> = {
+ default: ThemeMode.DEFAULT,
+ dark: ThemeMode.DARK,
+ system: ThemeMode.SYSTEM,
+ };
+
+ const themeMode = themeModeMap[mode];
+ if (!themeMode) {
+ throw new Error(`Invalid theme mode: ${mode}`);
+ }
+
+ themeController.setThemeMode(themeMode);
+ return { success: true, message: `Theme mode set to ${mode}` };
+ } catch (error) {
+ logging.debug('Theme mode not changed:', error.message);
+ return {
+ success: false,
+ message: `Theme locked to current mode`,
+ silent: true,
+ };
+ }
+ },
+ );
+
Switchboard.start();
}
});