"use client"; import Image from "next/image"; import { useEffect, useState } from "react"; import { getInitialLocale, getLocaleMessages, type Locale } from "@/lib/i18n"; type ThemePreference = "light" | "system" | "dark"; type ResolvedTheme = "light" | "dark"; function getInitialThemePreference(): ThemePreference { if (typeof window === "undefined") return "system"; const savedTheme = window.localStorage.getItem("kr-theme"); return savedTheme === "light" || savedTheme === "system" || savedTheme === "dark" ? savedTheme : "system"; } function resolveTheme(preference: ThemePreference): ResolvedTheme { if (preference !== "system") return preference; return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; } function applyTheme(preference: ThemePreference) { const theme = resolveTheme(preference); document.documentElement.dataset.theme = theme; document.documentElement.style.colorScheme = theme; window.localStorage.setItem("kr-theme", preference); } export function ThemeToggle() { const [themePreference, setThemePreference] = useState("system"); const [locale, setLocale] = useState("zh-CN"); useEffect(() => { const syncTheme = () => { const preference = getInitialThemePreference(); setThemePreference(preference); applyTheme(preference); }; const syncLocale = () => setLocale(getInitialLocale()); const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const syncSystemTheme = () => { if (getInitialThemePreference() === "system") applyTheme("system"); }; syncTheme(); syncLocale(); window.addEventListener("kr-locale-change", syncLocale); window.addEventListener("storage", syncTheme); mediaQuery.addEventListener("change", syncSystemTheme); return () => { window.removeEventListener("kr-locale-change", syncLocale); window.removeEventListener("storage", syncTheme); mediaQuery.removeEventListener("change", syncSystemTheme); }; }, []); const messages = getLocaleMessages(locale); const options: { theme: ThemePreference; label: string; icon: string }[] = [ { theme: "dark", label: messages.common.useDarkTheme, icon: "/icon/theme/light.svg" }, { theme: "light", label: messages.common.useLightTheme, icon: "/icon/theme/system.svg" }, { theme: "system", label: messages.common.useSystemTheme, icon: "/icon/theme/dark.svg" }, ]; return (
{options.map((option) => ( ))}
); }