Skip to content

Commit 5c1acee

Browse files
committed
🤖 fix: simplify storybook theme sync
1 parent 507a39f commit 5c1acee

File tree

2 files changed

+22
-57
lines changed

2 files changed

+22
-57
lines changed

.storybook/preview.tsx

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,24 @@ 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";
7+
import { UI_THEME_KEY } from "@/common/constants/storage";
88
import "../src/browser/styles/globals.css";
99

10-
const ThemeToggle = () => {
11-
const { theme, toggleTheme } = useTheme();
12-
return (
13-
<button
14-
onClick={toggleTheme}
15-
style={{
16-
position: "fixed",
17-
bottom: "1rem",
18-
right: "1rem",
19-
zIndex: 9999,
20-
padding: "0.5rem 1rem",
21-
background: theme === "dark" ? "#f5f6f8" : "#1e1e1e",
22-
color: theme === "dark" ? "#1e1e1e" : "#f5f6f8",
23-
border: "1px solid #777",
24-
borderRadius: "4px",
25-
cursor: "pointer",
26-
fontFamily: "system-ui, sans-serif",
27-
fontSize: "12px",
28-
boxShadow: "0 2px 5px rgba(0,0,0,0.2)",
29-
}}
30-
>
31-
{theme === "dark" ? "☀️ Light" : "🌙 Dark"}
32-
</button>
33-
);
10+
const syncStorybookTheme = (mode?: ThemeMode) => {
11+
if (typeof window === "undefined" || !mode) {
12+
return;
13+
}
14+
15+
try {
16+
window.localStorage.setItem(UI_THEME_KEY, JSON.stringify(mode));
17+
const root = document.documentElement;
18+
root.dataset.theme = mode;
19+
root.style.colorScheme = mode;
20+
} catch (error) {
21+
console.warn("Failed to sync Storybook theme:", error);
22+
}
3423
};
3524

3625
const preview: Preview = {
@@ -51,10 +40,10 @@ const preview: Preview = {
5140
decorators: [
5241
(Story, context) => {
5342
const mode = context.globals.theme as ThemeMode | undefined;
43+
syncStorybookTheme(mode);
5444
return (
55-
<ThemeProvider forcedTheme={mode}>
45+
<ThemeProvider>
5646
<Story />
57-
{!mode && <ThemeToggle />}
5847
</ThemeProvider>
5948
);
6049
},

src/browser/contexts/ThemeContext.tsx

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

54-
export function ThemeProvider(props: { children: ReactNode; forcedTheme?: ThemeMode }) {
55-
const parentContext = useContext(ThemeContext);
56-
const [persistedTheme, setPersistedTheme] = usePersistedState<ThemeMode>(
57-
UI_THEME_KEY,
58-
resolveSystemTheme(),
59-
{
60-
listener: true,
61-
}
62-
);
63-
64-
const theme = props.forcedTheme ?? parentContext?.theme ?? persistedTheme;
54+
export function ThemeProvider(props: { children: ReactNode }) {
55+
const [theme, setTheme] = usePersistedState<ThemeMode>(UI_THEME_KEY, resolveSystemTheme(), {
56+
listener: true,
57+
});
6558

6659
useLayoutEffect(() => {
6760
applyThemeToDocument(theme);
6861
}, [theme]);
6962

70-
const setTheme = useCallback(
71-
(value: React.SetStateAction<ThemeMode>) => {
72-
if (props.forcedTheme) return;
73-
if (parentContext) {
74-
parentContext.setTheme(value);
75-
return;
76-
}
77-
setPersistedTheme(value);
78-
},
79-
[props.forcedTheme, parentContext, setPersistedTheme]
80-
);
81-
8263
const toggleTheme = useCallback(() => {
83-
if (props.forcedTheme) return;
84-
if (parentContext) {
85-
parentContext.toggleTheme();
86-
return;
87-
}
88-
setPersistedTheme((current) => (current === "dark" ? "light" : "dark"));
89-
}, [props.forcedTheme, parentContext, setPersistedTheme]);
64+
setTheme((current) => (current === "dark" ? "light" : "dark"));
65+
}, [setTheme]);
9066

9167
const value = useMemo<ThemeContextValue>(
9268
() => ({

0 commit comments

Comments
 (0)