Skip to content

Commit b0b65dd

Browse files
committed
🤖 fix: stabilize storybook theme by forcing context state
1 parent 0a4415b commit b0b65dd

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

.storybook/preview.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
1-
import React, { useEffect } from "react";
1+
import React from "react";
22
import type { Preview } from "@storybook/react-vite";
33
import {
44
ThemeProvider,
5-
useTheme,
65
type ThemeMode,
76
} from "../src/browser/contexts/ThemeContext";
87
import "../src/browser/styles/globals.css";
98

10-
const ThemeStorySync: React.FC<{ mode: ThemeMode }> = ({ mode }) => {
11-
const { theme, setTheme } = useTheme();
12-
13-
useEffect(() => {
14-
if (theme !== mode) {
15-
setTheme(mode);
16-
}
17-
}, [mode, setTheme, theme]);
18-
19-
return null;
20-
};
21-
229
const preview: Preview = {
2310
globalTypes: {
2411
theme: {
@@ -39,8 +26,7 @@ const preview: Preview = {
3926
(Story, context) => {
4027
const mode = (context.globals.theme ?? "dark") as ThemeMode;
4128
return (
42-
<ThemeProvider>
43-
<ThemeStorySync mode={mode} />
29+
<ThemeProvider forcedTheme={mode}>
4430
<Story />
4531
</ThemeProvider>
4632
);

src/browser/contexts/ThemeContext.tsx

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

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

59+
const theme = props.forcedTheme ?? persistedTheme;
60+
5961
useLayoutEffect(() => {
6062
applyThemeToDocument(theme);
6163
}, [theme]);
6264

65+
const setTheme = useCallback(
66+
(value: React.SetStateAction<ThemeMode>) => {
67+
if (props.forcedTheme) return;
68+
setPersistedTheme(value);
69+
},
70+
[props.forcedTheme, setPersistedTheme]
71+
);
72+
6373
const toggleTheme = useCallback(() => {
64-
setTheme((current) => (current === "dark" ? "light" : "dark"));
65-
}, [setTheme]);
74+
if (props.forcedTheme) return;
75+
setPersistedTheme((current) => (current === "dark" ? "light" : "dark"));
76+
}, [props.forcedTheme, setPersistedTheme]);
6677

6778
const value = useMemo<ThemeContextValue>(
6879
() => ({

0 commit comments

Comments
 (0)