"use client"; /** * `ThemeSwitch` — single-button replacement for Fumadocs's two-icon split. * * Renders a compact icon button that displays the current resolved theme and * swaps between `light` and `dark` on click. The site itself defaults to the * user's system preference via RootProvider's `defaultTheme: "system"`; once * clicked, this button stores the opposite explicit theme through next-themes. * * Why not Fumadocs's built-in `ThemeSwitch`? * - The `light-dark` mode renders two `` buttons side-by-side with a * 1px border-left between them, which looks more like a tab pair than a * toggle. Removing the divider on its own still leaves two icons; we * want a single switch instead. * * Hydration: `next-themes` only resolves the theme client-side, so the first * render is unavoidably indeterminate. We render the light-mode current icon * until `mounted` flips to true; the first-paint script in layout.tsx already * applies the correct html class before this button hydrates. */ import * as React from "react"; import { useTheme } from "next-themes"; import { MoonStar, SunMedium } from "lucide-react"; import { cn } from "@/lib/cn"; export function ThemeSwitch({ className }: { className?: string }) { const { resolvedTheme, setTheme } = useTheme(); const [mounted, setMounted] = React.useState(false); React.useEffect(() => { setMounted(true); }, []); const isDark = mounted && resolvedTheme === "dark"; const nextTheme = isDark ? "light" : "dark"; const label = isDark ? "Switch to light theme" : "Switch to dark theme"; const Icon = isDark ? MoonStar : SunMedium; return ( ); }