"use client" import * as React from "react" type Theme = "light" | "dark" | "system" const ThemeContext = React.createContext<{ theme: Theme setTheme: (theme: Theme) => void resolvedTheme: "light" | "dark" }>({ theme: "system", setTheme: () => {}, resolvedTheme: "light", }) export function useTheme() { return React.useContext(ThemeContext) } function getSystemTheme(): "light" | "dark" { if (typeof window === "undefined") return "light" return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" } export function ThemeProvider({ children, attribute = "class", defaultTheme = "system", enableSystem = true, }: { children: React.ReactNode attribute?: string defaultTheme?: Theme enableSystem?: boolean disableTransitionOnChange?: boolean }) { const [theme, setThemeState] = React.useState(defaultTheme) const [resolvedTheme, setResolvedTheme] = React.useState<"light" | "dark">("light") const [mounted, setMounted] = React.useState(false) // Read saved theme from localStorage on mount React.useEffect(() => { const saved = localStorage.getItem("theme") as Theme | null if (saved) { setThemeState(saved) } setMounted(true) }, []) // Resolve system theme and apply to document React.useEffect(() => { const resolved = theme === "system" ? getSystemTheme() : theme setResolvedTheme(resolved) const root = document.documentElement root.classList.remove("light", "dark") root.classList.add(resolved) }, [theme]) // Listen for system theme changes React.useEffect(() => { if (!enableSystem) return const mql = window.matchMedia("(prefers-color-scheme: dark)") const handler = () => { if (theme === "system") { const resolved = getSystemTheme() setResolvedTheme(resolved) const root = document.documentElement root.classList.remove("light", "dark") root.classList.add(resolved) } } mql.addEventListener("change", handler) return () => mql.removeEventListener("change", handler) }, [theme, enableSystem]) const setTheme = React.useCallback((newTheme: Theme) => { setThemeState(newTheme) localStorage.setItem("theme", newTheme) }, []) return ( {children} ) }