"use client"; import { CheckIcon, MonitorIcon, MoonIcon, SunIcon } from "lucide-react"; import { Popover as PopoverPrimitive } from "radix-ui"; import { useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; type ThemeMode = "light" | "dark" | "system"; const THEME_STORAGE_KEY = "claw.theme"; const THEME_OPTIONS: Array<{ mode: ThemeMode; label: string; icon: typeof SunIcon; }> = [ { mode: "light", label: "亮色", icon: SunIcon }, { mode: "dark", label: "暗色", icon: MoonIcon }, { mode: "system", label: "跟随系统", icon: MonitorIcon }, ]; export function ClawThemeSwitcher() { const [mode, setMode] = useState("system"); const activeOption = THEME_OPTIONS.find((option) => option.mode === mode) ?? THEME_OPTIONS[2]; const ActiveIcon = activeOption.icon; useEffect(() => { const stored = window.localStorage.getItem(THEME_STORAGE_KEY); const initialMode = isThemeMode(stored) ? stored : "system"; setMode(initialMode); applyTheme(initialMode); const media = window.matchMedia("(prefers-color-scheme: dark)"); const onChange = () => { if (window.localStorage.getItem(THEME_STORAGE_KEY) === "system") { applyTheme("system"); } }; media.addEventListener("change", onChange); return () => media.removeEventListener("change", onChange); }, []); const updateMode = (nextMode: ThemeMode) => { window.localStorage.setItem(THEME_STORAGE_KEY, nextMode); setMode(nextMode); applyTheme(nextMode); }; return ( {THEME_OPTIONS.map((option) => { const Icon = option.icon; return ( ); })} ); } function applyTheme(mode: ThemeMode) { const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; const shouldUseDark = mode === "dark" || (mode === "system" && prefersDark); document.documentElement.classList.toggle("dark", shouldUseDark); } function isThemeMode(value: string | null): value is ThemeMode { return value === "light" || value === "dark" || value === "system"; }