SPB Git
982 B · 21 lines tsx
1"use client";2import { useEffect, useState } from "react";3import { Moon, Sun, Monitor } from "lucide-react";4type Mode = "light" | "dark" | "system";5export function ThemeToggle() {6  const [mode, setMode] = useState<Mode>("system");7  useEffect(() => { setMode((localStorage.getItem("theme") as Mode) || "system"); }, []);8  const apply = (m: Mode) => {9    setMode(m); localStorage.setItem("theme", m);10    const dark = m === "dark" || (m === "system" && matchMedia("(prefers-color-scheme: dark)").matches);11    document.documentElement.classList.toggle("dark", dark);12  };13  const next: Record<Mode, Mode> = { system: "light", light: "dark", dark: "system" };14  const Icon = mode === "dark" ? Moon : mode === "light" ? Sun : Monitor;15  return (16    <button type="button" onClick={() => apply(next[mode])} className="btn-ghost h-9 w-9 !p-0" aria-label={`Theme: ${mode}. Switch theme`} title={`Theme: ${mode}`}>17      <Icon className="h-4 w-4" aria-hidden />18    </button>19  );20}21
Files · 19c0ff748ee94e0979c734f5fb3afeefc11ee9e1
Menu

Theme