import { useDevice } from "@/contexts/device-context"; import { Sun, Moon, Monitor } from "lucide-react"; import { motion } from "motion/react"; import type React from "react"; import { cn } from "@/lib/utils"; type ThemeMode = "light" | "dark" | "system"; // PC端:三状态轮换按钮 export function ThemeModeCycleButton(props: React.ButtonHTMLAttributes & { mode: ThemeMode; setMode: (m: ThemeMode) => void }) { const { mode, setMode, className, style, onClick, ...rest } = props; const nextMode = (mode: ThemeMode): ThemeMode => { if (mode === "light") return "dark"; if (mode === "dark") return "system"; return "light"; }; const icon = mode === "light" ? : mode === "dark" ? : ; const label = mode.charAt(0).toUpperCase() + mode.slice(1); const baseCls = "flex items-center gap-2 px-2 py-2 rounded-full bg-muted hover:bg-accent border border-input text-sm font-medium transition-all"; const mergedClassName = cn(baseCls, className); return ( ); } // 移动端:横向按钮组 export function ThemeModeSegmented(props: React.HTMLAttributes & { mode: ThemeMode; setMode: (m: ThemeMode) => void }) { const { mode, setMode, className, style, ...rest } = props; const modes: { value: ThemeMode; icon: React.ReactNode; label: string }[] = [ { value: "light", icon: , label: "Light" }, { value: "system", icon: , label: "System" }, { value: "dark", icon: , label: "Dark" }, ]; const activeIndex = modes.findIndex((m) => m.value === mode); const baseCls = "relative inline-flex bg-muted rounded-full p-1 gap-1 overflow-hidden"; return (
{/* 滑动高亮块 */} {modes.map((m) => ( ))}
); } // 总组件:根据设备类型渲染 export function ThemeModeToggle(props: React.HTMLAttributes & { showSegmented?: boolean }) { const { mode, setMode } = useDevice(); const Comp: React.ElementType = props.showSegmented ? ThemeModeSegmented : ThemeModeCycleButton; const { className, style } = props; return ; }