MCPcopy
hub / github.com/codeaashu/claude-code / ThemeProvider

Function ThemeProvider

web/lib/theme.tsx:16–68  ·  view source on GitHub ↗
({
  children,
  defaultTheme = 'dark',
  storageKey = 'ui-theme',
}: {
  children: React.ReactNode
  defaultTheme?: Theme
  storageKey?: string
})

Source from the content-addressed store, hash-verified

14const ThemeContext = createContext<ThemeContextValue | null>(null)
15
16export function ThemeProvider({
17 children,
18 defaultTheme = 'dark',
19 storageKey = 'ui-theme',
20}: {
21 children: React.ReactNode
22 defaultTheme?: Theme
23 storageKey?: string
24}) {
25 const [theme, setThemeState] = useState<Theme>(defaultTheme)
26 const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>('dark')
27
28 useEffect(() => {
29 const stored = localStorage.getItem(storageKey) as Theme | null
30 if (stored && ['dark', 'light', 'system'].includes(stored)) {
31 setThemeState(stored)
32 }
33 }, [storageKey])
34
35 useEffect(() => {
36 const root = document.documentElement
37
38 const apply = (resolved: ResolvedTheme) => {
39 setResolvedTheme(resolved)
40 if (resolved === 'light') {
41 root.classList.add('light')
42 } else {
43 root.classList.remove('light')
44 }
45 }
46
47 if (theme === 'system') {
48 const mq = window.matchMedia('(prefers-color-scheme: light)')
49 apply(mq.matches ? 'light' : 'dark')
50 const handler = (e: MediaQueryListEvent) => apply(e.matches ? 'light' : 'dark')
51 mq.addEventListener('change', handler)
52 return () => mq.removeEventListener('change', handler)
53 } else {
54 apply(theme)
55 }
56 }, [theme])
57
58 const setTheme = (t: Theme) => {
59 setThemeState(t)
60 localStorage.setItem(storageKey, t)
61 }
62
63 return (
64 <ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>
65 {children}
66 </ThemeContext.Provider>
67 )
68}
69
70export function useTheme(): ThemeContextValue {
71 const ctx = useContext(ThemeContext)

Callers

nothing calls this directly

Calls 1

applyFunction · 0.70

Tested by

no test coverage detected