Component
Theme Toggle
Sun/moon icon button that switches the site between light and dark mode. Reads and writes the html.dark class, persists the preference to localStorage, and renders a stable placeholder before mount to avoid hydration mismatch.
How it works
StepWhat happens
On mountReads document.documentElement.classList — the FOUC-prevention script in layout.tsx has already applied the correct class from localStorage.
Before mountRenders a Moon icon with pointer-events disabled — stable size prevents layout shift.
On clickToggles .dark on <html>, updates local state, persists "theme" key to localStorage.
Global overrideAll data-theme="dark|light" section overrides are scoped under :not(.dark) — the global toggle always wins.
Appearance
Light mode
Dark mode
32×32px circular hit target. Icon is 15px at 1.5 stroke weight. Foreground color is text-foreground/50 at rest,text-foreground on hover.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | Optional class names merged into the button element via cn(). |
Usage
tsx
import { ThemeToggle } from '@true-north/ui'
// In SiteNav — already wired, no action needed
<ThemeToggle />
// With custom positioning
<ThemeToggle className="ml-auto" />ThemeToggle is already included in SiteNav — you do not need to add it separately unless building a custom nav.