diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts index c04873924a4..b9405393c57 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; unmount: () => void; @@ -92,6 +94,7 @@ export type EmbeddedDashboard = { getDataMask: () => Promise>; getChartStates: () => Promise>; setThemeConfig: (themeConfig: Record) => 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 794cca051d0..560aed5d0b6 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 = { + 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(); } });