If you are building a SPFx extension and try to use theme colors, you probably already noticed that when debugging, the getTheme().palette
will always return default, blue, palette (when deployed, the result is correct).
This results in rather hilarious and questionable design:
const stackStyles: Partial<IStackStyles> = {
root: {
borderColor: theme.palette.themePrimary,
backgroundColor: theme.palette.themeLight,
...
},
}
The trick is to get the theme from the window.__themeState__.theme
as mentioned in here (scroll down to find Note section).
However... I never trust objects or methods whose names start with _
and since getTheme()
works just fine in production, I also see no reason for this workaround to be used permanently.
The solution
I'm defining all the component styles in a separate file, ComponentStyles.ts
. In here, I access the __themeState__
only if debugging
ComponentStyles.ts
let siteTheme: ITheme = null;
if (process.env.NODE_ENV !== 'production') {
siteTheme = createTheme({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
palette: (window as any).__themeState__.theme
});
}
//if siteTheme is undefined, use the default theme
const theme = siteTheme ?? getTheme();
const stackStyles: Partial<IStackStyles> = {
root: {
borderColor: theme.palette.themePrimary,
backgroundColor: theme.palette.themeLight,
...
},
}
export { stackStyles };
The solution components will only import the required styles, and the colors are correct in both, workbench and production environments.
DatePickerMenu.tsx
import { stackStyles } from "../../common/ComponentStyles";
const DatePickerMenu: React.FunctionComponent<IDatePickerMenuProps> = (props) => {
...
return (
<Stack
horizontal={true}
styles={stackStyles}
>
</Stack>
);
};
}
Much better, isn't it? Now I can style my components seeing the correct result.
And at the same time I don't have to remember to remove the __themeState__
before releasing the solution.
Top comments (0)