Spaces:
Sleeping
Sleeping
| "use client"; | |
| import { Moon, Sun } from "lucide-react"; | |
| import { useEffect, useState } from "react"; | |
| type Theme = "light" | "dark"; | |
| const STORAGE_KEY = "chatgpt2api-theme"; | |
| function resolveInitialTheme(): Theme { | |
| if (typeof window === "undefined") { | |
| return "light"; | |
| } | |
| const stored = window.localStorage.getItem(STORAGE_KEY); | |
| if (stored === "light" || stored === "dark") { | |
| return stored; | |
| } | |
| return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; | |
| } | |
| function applyTheme(theme: Theme) { | |
| document.documentElement.classList.toggle("dark", theme === "dark"); | |
| document.documentElement.style.colorScheme = theme; | |
| } | |
| export function ThemeToggle() { | |
| const [theme, setTheme] = useState<Theme>("light"); | |
| const isDark = theme === "dark"; | |
| useEffect(() => { | |
| const nextTheme = resolveInitialTheme(); | |
| setTheme(nextTheme); | |
| applyTheme(nextTheme); | |
| }, []); | |
| const toggleTheme = () => { | |
| const nextTheme: Theme = isDark ? "light" : "dark"; | |
| window.localStorage.setItem(STORAGE_KEY, nextTheme); | |
| setTheme(nextTheme); | |
| applyTheme(nextTheme); | |
| }; | |
| return ( | |
| <button | |
| type="button" | |
| aria-label={isDark ? "切换到浅色模式" : "切换到深色模式"} | |
| title={isDark ? "浅色模式" : "深色模式"} | |
| className="inline-flex size-8 shrink-0 items-center justify-center rounded-full border border-stone-200/80 bg-white/80 text-stone-500 shadow-sm transition hover:border-stone-300 hover:text-stone-900 dark:border-white/10 dark:bg-white/8 dark:text-stone-300 dark:hover:border-white/20 dark:hover:text-white" | |
| onClick={toggleTheme} | |
| > | |
| {isDark ? <Sun className="size-4" /> : <Moon className="size-4" />} | |
| </button> | |
| ); | |
| } | |