"use client"; import React, { createContext, useContext, useEffect, useState } from "react"; type Theme = "light" | "dark" | "auto"; interface ThemeContextType { theme: Theme; setTheme: (theme: Theme) => void; isDark: boolean; } const ThemeContext = createContext(undefined); export function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setTheme] = useState("light"); const [isDark, setIsDark] = useState(false); useEffect(() => { // 从 localStorage 获取保存的主题 const savedTheme = localStorage.getItem("theme") as Theme; if (savedTheme && ["light", "dark", "auto"].includes(savedTheme)) { setTheme(savedTheme); } }, []); useEffect(() => { // 保存主题到 localStorage localStorage.setItem("theme", theme); // 应用主题 const root = document.documentElement; const body = document.body; if (theme === "auto") { // 跟随系统主题 const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleChange = (e: MediaQueryListEvent) => { setIsDark(e.matches); if (e.matches) { root.classList.add("dark"); body.classList.add("dark"); } else { root.classList.remove("dark"); body.classList.remove("dark"); } }; setIsDark(mediaQuery.matches); if (mediaQuery.matches) { root.classList.add("dark"); body.classList.add("dark"); } else { root.classList.remove("dark"); body.classList.remove("dark"); } mediaQuery.addEventListener("change", handleChange); return () => mediaQuery.removeEventListener("change", handleChange); } else { // 手动设置主题 setIsDark(theme === "dark"); if (theme === "dark") { root.classList.add("dark"); body.classList.add("dark"); } else { root.classList.remove("dark"); body.classList.remove("dark"); } } }, [theme]); const value = { theme, setTheme, isDark, }; return ( {children} ); } export function useTheme() { const context = useContext(ThemeContext); if (context === undefined) { throw new Error("useTheme must be used within a ThemeProvider"); } return context; }