Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x | import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
type Theme = 'light' | 'dark';
type ThemeContextValue = {
theme: Theme;
toggleTheme: () => void;
};
const STORAGE_KEY_THEME = 'sem-theme';
const ThemeContext = createContext<ThemeContextValue>({
theme: 'light',
toggleTheme: () => undefined,
});
function getInitialTheme(): Theme {
if (typeof window === 'undefined') {
return 'light';
}
const storedTheme = window.localStorage.getItem(STORAGE_KEY_THEME);
if (storedTheme === 'light' || storedTheme === 'dark') {
return storedTheme;
}
return 'light';
}
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<Theme>(getInitialTheme);
useEffect(() => {
document.documentElement.dataset.theme = theme;
document.documentElement.style.colorScheme = theme;
window.localStorage.setItem(STORAGE_KEY_THEME, theme);
}, [theme]);
const value = useMemo(
() => ({
theme,
toggleTheme: () => setTheme((current) => (current === 'light' ? 'dark' : 'light')),
}),
[theme],
);
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
return useContext(ThemeContext);
}
|