"use client"; import { useSyncExternalStore } from "react"; type Theme = "light" | "dark"; const STORAGE_KEY = "theme-preference"; const THEME_CHANGE_EVENT = "theme-preference-change"; function getSystemTheme(): Theme { return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; } function applyTheme(theme: Theme) { document.documentElement.dataset.theme = theme; try { window.localStorage.setItem(STORAGE_KEY, theme); } catch { } window.dispatchEvent(new Event(THEME_CHANGE_EVENT)); } function getCurrentTheme(): Theme { if (typeof window === "undefined") return "light"; const currentTheme = document.documentElement.dataset.theme; if (currentTheme === "light" || currentTheme === "dark") { return currentTheme; } return getSystemTheme(); } function subscribeToTheme(callback: () => void) { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleSystemThemeChange = () => { try { if (!window.localStorage.getItem(STORAGE_KEY)) { document.documentElement.dataset.theme = getSystemTheme(); } } catch { document.documentElement.dataset.theme = getSystemTheme(); } callback(); }; mediaQuery.addEventListener("change", handleSystemThemeChange); window.addEventListener("storage", callback); window.addEventListener(THEME_CHANGE_EVENT, callback); return () => { mediaQuery.removeEventListener("change", handleSystemThemeChange); window.removeEventListener("storage", callback); window.removeEventListener(THEME_CHANGE_EVENT, callback); }; } export function ThemeToggle() { const theme = useSyncExternalStore(subscribeToTheme, getCurrentTheme, () => "light"); const toggleTheme = () => { const nextTheme = getCurrentTheme() === "dark" ? "light" : "dark"; applyTheme(nextTheme); }; return ( ); }