haixunMaster/components/theme-toggle.tsx

56 lines
1.6 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "@/components/theme-provider";
import type { ThemeMode } from "@/lib/theme";
import { cn } from "@/lib/utils";
interface ThemeToggleProps {
className?: string;
compact?: boolean;
}
export function ThemeToggle({ className, compact }: ThemeToggleProps) {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
return (
<div
className={cn(
"inline-flex rounded-lg border border-border bg-muted p-0.5",
className
)}
role="group"
aria-label="外觀模式"
>
{(["light", "dark"] as ThemeMode[]).map((mode) => {
const active = mounted && theme === mode;
const label = mode === "light" ? "淺色" : "深色";
const Icon = mode === "light" ? Sun : Moon;
return (
<button
key={mode}
type="button"
onClick={() => setTheme(mode)}
className={cn(
"inline-flex items-center justify-center gap-1.5 rounded-md text-[12px] font-medium transition-colors",
compact ? "h-8 px-2.5" : "h-9 px-3.5",
active
? "bg-card text-foreground shadow-sm"
: "text-muted-foreground hover:text-foreground"
)}
aria-pressed={active}
>
<Icon className="h-3.5 w-3.5" />
{!compact && label}
</button>
);
})}
</div>
);
}