Skip to content

Commit dd40c7e

Browse files
committed
🤖 fix(storybook): add forcedTheme prop to respect Chromatic mode variants
Added a `forcedTheme` prop to ThemeProvider that overrides the persisted localStorage theme. This ensures Chromatic's mode variants (dark/light) are correctly applied during visual snapshots. Without this, ThemeProvider would read from localStorage and ignore the mode set by Chromatic, causing all snapshots to appear in the same theme (the persisted one). Changes: - ThemeProvider now accepts optional `forcedTheme` prop - Storybook decorator passes `context.globals.theme` as forcedTheme - When forcedTheme is set, it overrides the persisted theme - When forcedTheme is undefined (local dev), uses normal persistence This restores the original PR intent where Chromatic's dark/light modes produce correctly themed snapshots.
1 parent 54699a4 commit dd40c7e

File tree

2 files changed

+9
-6
lines changed

2 files changed

+9
-6
lines changed

‎.storybook/preview.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const preview: Preview = {
6464
const mode = context.globals.theme as ThemeMode | undefined;
6565
syncStorybookTheme(mode);
6666
return (
67-
<ThemeProvider>
67+
<ThemeProvider forcedTheme={mode}>
6868
<Story />
6969
</ThemeProvider>
7070
);

‎src/browser/contexts/ThemeContext.tsx‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,29 @@ function applyThemeToDocument(theme: ThemeMode) {
5151
}
5252
}
5353

54-
export function ThemeProvider(props: { children: ReactNode }) {
54+
export function ThemeProvider(props: { children: ReactNode; forcedTheme?: ThemeMode }) {
5555
const [theme, setTheme] = usePersistedState<ThemeMode>(UI_THEME_KEY, resolveSystemTheme(), {
5656
listener: true,
5757
});
5858

59+
// Use forcedTheme if provided (e.g., from Storybook), otherwise use persisted theme
60+
const activeTheme = props.forcedTheme ?? theme;
61+
5962
useLayoutEffect(() => {
60-
applyThemeToDocument(theme);
61-
}, [theme]);
63+
applyThemeToDocument(activeTheme);
64+
}, [activeTheme]);
6265

6366
const toggleTheme = useCallback(() => {
6467
setTheme((current) => (current === "dark" ? "light" : "dark"));
6568
}, [setTheme]);
6669

6770
const value = useMemo<ThemeContextValue>(
6871
() => ({
69-
theme,
72+
theme: activeTheme,
7073
setTheme,
7174
toggleTheme,
7275
}),
73-
[setTheme, theme, toggleTheme]
76+
[activeTheme, setTheme, toggleTheme]
7477
);
7578

7679
return <ThemeContext.Provider value={value}>{props.children}</ThemeContext.Provider>;

0 commit comments

Comments
 (0)