feat(embedded): add setThemeMode API for dynamic theme switching (#36125)

This commit is contained in:
Gabriel Torres Ruiz
2025-11-17 14:30:02 -04:00
committed by GitHub
parent 9bff64824b
commit 282f4e5de2
2 changed files with 51 additions and 2 deletions

View File

@@ -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,
};
}

View File

@@ -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();
}
});