import React, { createContext, useContext, useEffect, useState } from 'react'; import { ThemeMode } from 'shared/types'; type ThemeProviderProps = { children: React.ReactNode; initialTheme?: ThemeMode; }; type ThemeProviderState = { theme: ThemeMode; setTheme: (theme: ThemeMode) => void; }; const initialState: ThemeProviderState = { theme: ThemeMode.SYSTEM, setTheme: () => null, }; const ThemeProviderContext = createContext(initialState); export function ThemeProvider({ children, initialTheme = ThemeMode.SYSTEM, ...props }: ThemeProviderProps) { const [theme, setThemeState] = useState(initialTheme); // Update theme when initialTheme changes useEffect(() => { setThemeState(initialTheme); }, [initialTheme]); useEffect(() => { const root = window.document.documentElement; root.classList.remove('light', 'dark'); if (theme === ThemeMode.SYSTEM) { const systemTheme = window.matchMedia('(prefers-color-scheme: dark)') .matches ? 'dark' : 'light'; root.classList.add(systemTheme); return; } root.classList.add(theme.toLowerCase()); }, [theme]); const setTheme = (newTheme: ThemeMode) => { setThemeState(newTheme); }; const value = { theme, setTheme, }; return ( {children} ); } export const useTheme = () => { const context = useContext(ThemeProviderContext); if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider'); return context; };