bui-themer: extract mui theme and then unmount theme provider
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -74,12 +74,22 @@ export function UnifiedThemeProvider(
|
||||
const themeName = 'backstage';
|
||||
|
||||
useEffect(() => {
|
||||
const oldMode = document.body.getAttribute('data-theme-mode');
|
||||
const oldName = document.body.getAttribute('data-theme-name');
|
||||
document.body.setAttribute('data-theme-mode', themeMode);
|
||||
document.body.setAttribute('data-theme-name', themeName);
|
||||
|
||||
return () => {
|
||||
document.body.removeAttribute('data-theme-mode');
|
||||
document.body.removeAttribute('data-theme-name');
|
||||
if (oldMode) {
|
||||
document.body.setAttribute('data-theme-mode', oldMode);
|
||||
} else {
|
||||
document.body.removeAttribute('data-theme-mode');
|
||||
}
|
||||
if (oldName) {
|
||||
document.body.setAttribute('data-theme-name', oldName);
|
||||
} else {
|
||||
document.body.removeAttribute('data-theme-name');
|
||||
}
|
||||
};
|
||||
}, [themeMode, themeName]);
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
import { useMemo, useState, useCallback, useEffect } from 'react';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { AppTheme, useApi } from '@backstage/core-plugin-api';
|
||||
import { appThemeApiRef } from '@backstage/core-plugin-api';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { Theme, useTheme } from '@mui/material/styles';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -33,13 +33,6 @@ import {
|
||||
ConvertMuiToBuiThemeOptions,
|
||||
} from './convertMuiToBuiTheme';
|
||||
|
||||
interface ThemePreviewProps {
|
||||
themeId: string;
|
||||
themeTitle: string;
|
||||
variant: 'light' | 'dark';
|
||||
Provider: React.ComponentType<{ children: React.ReactNode }>;
|
||||
}
|
||||
|
||||
// Memoization cache for generated CSS
|
||||
const cssCache = new Map<string, string>();
|
||||
|
||||
@@ -47,13 +40,18 @@ interface ThemeContentProps {
|
||||
themeId: string;
|
||||
themeTitle: string;
|
||||
variant: 'light' | 'dark';
|
||||
muiTheme: Theme;
|
||||
}
|
||||
|
||||
function ThemeContent({ themeId, themeTitle, variant }: ThemeContentProps) {
|
||||
function ThemeContent({
|
||||
themeId,
|
||||
themeTitle,
|
||||
variant,
|
||||
muiTheme,
|
||||
}: ThemeContentProps) {
|
||||
const [generatedCss, setGeneratedCss] = useState<string>('');
|
||||
const [isPreviewMode, setIsPreviewMode] = useState(false);
|
||||
const [includeThemeId, setIncludeThemeId] = useState(false);
|
||||
const muiTheme = useTheme();
|
||||
|
||||
const css = useMemo(() => {
|
||||
// Create cache key based on theme properties and options
|
||||
@@ -243,23 +241,29 @@ function ThemeContent({ themeId, themeTitle, variant }: ThemeContentProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function ThemePreview({
|
||||
themeId,
|
||||
themeTitle,
|
||||
variant,
|
||||
Provider,
|
||||
}: ThemePreviewProps) {
|
||||
function MuiThemeExtractor(props: {
|
||||
appTheme: AppTheme;
|
||||
children: (theme: Theme) => JSX.Element;
|
||||
}): JSX.Element {
|
||||
const { appTheme, children } = props;
|
||||
const [theme, setTheme] = useState<Theme | null>(null);
|
||||
const { Provider } = appTheme;
|
||||
if (theme) {
|
||||
return children(theme);
|
||||
}
|
||||
|
||||
return (
|
||||
<Provider>
|
||||
<ThemeContent
|
||||
themeId={themeId}
|
||||
themeTitle={themeTitle}
|
||||
variant={variant}
|
||||
/>
|
||||
<MuiThemeExtractorInner setTheme={setTheme} />
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function MuiThemeExtractorInner(props: { setTheme: (theme: Theme) => void }) {
|
||||
props.setTheme(useTheme());
|
||||
return null;
|
||||
}
|
||||
|
||||
export function BuiThemerPage() {
|
||||
const appThemeApi = useApi(appThemeApiRef);
|
||||
const installedThemes = appThemeApi.getInstalledThemes();
|
||||
@@ -287,13 +291,17 @@ export function BuiThemerPage() {
|
||||
) : (
|
||||
<Flex direction="column" gap="4">
|
||||
{installedThemes.map(theme => (
|
||||
<ThemePreview
|
||||
key={theme.id}
|
||||
themeId={theme.id}
|
||||
themeTitle={theme.title}
|
||||
variant={theme.variant}
|
||||
Provider={theme.Provider}
|
||||
/>
|
||||
<MuiThemeExtractor key={theme.id} appTheme={theme}>
|
||||
{muiTheme => (
|
||||
<ThemeContent
|
||||
key={theme.id}
|
||||
themeId={theme.id}
|
||||
themeTitle={theme.title}
|
||||
variant={theme.variant}
|
||||
muiTheme={muiTheme}
|
||||
/>
|
||||
)}
|
||||
</MuiThemeExtractor>
|
||||
))}
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user