"use client"; import { useEffect, useState } from "react"; import { MoonStars, Sun } from "@phosphor-icons/react/ssr"; const STORAGE_KEY = "pulsenode-theme"; export function ThemeToggle() { const [theme, setTheme] = useState<"dark" | "light" | null>(null); useEffect(() => { // One-time read of browser-only state (DOM attribute set by the anti-FOUC // inline script, or the OS color-scheme preference) to resolve the theme // React couldn't know during SSR. Not a case of syncing to external state // that changes over time, so a single setState here is the right call. const attr = document.documentElement.dataset.theme; if (attr === "light" || attr === "dark") { // eslint-disable-next-line react-hooks/set-state-in-effect setTheme(attr); return; } const prefersLight = window.matchMedia("(prefers-color-scheme: light)").matches; setTheme(prefersLight ? "light" : "dark"); }, []); function toggle() { const next = theme === "light" ? "dark" : "light"; setTheme(next); document.documentElement.dataset.theme = next; try { localStorage.setItem(STORAGE_KEY, next); } catch { // private browsing or storage disabled; toggle still works for this session } } if (theme === null) { return
; } return ( ); }