ThemeToggle
interactiveLight/dark theme toggle. Writes data-theme on<html>, persists to localStorage. Pair with themeInitScript in the head to prevent flash of wrong theme.
Preview
Click to toggle. Persists to localStorage.
Usage
import { ThemeToggle, themeInitScript } from 'PRIVATE_BETA_PACKAGE_COORDINATE_REDACTED';
// In your <head> (prevents FOUC)
<script>{themeInitScript}</script>
// In your header/nav
<ThemeToggle />Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | -- | Additional CSS classes |
Exports
| Export | Type | Description |
|---|---|---|
ThemeToggle | Component | The toggle button component |
themeInitScript | string | Inline script to set data-theme before first paint (no FOUC) |
Accessibility
- ARIA:
aria-pressedreflects dark mode state.aria-labelannounces the action ("Switch to light/dark theme"). - Keyboard: Focusable button. Activates on Enter/Space.
- Icons: Sun/moon SVGs are
aria-hidden="true"(the label carries the meaning). - Focus: Visible
:focus-visiblering. - Motion: Transition honors
prefers-reduced-motion.
How it works
No FOUC: The
themeInitScript runs synchronously in the head, reading localStorage and setting data-theme before the first paint. The component then reads the DOM attribute on mount to sync its internal state.Do / Don't
Do
Always pair the component with themeInitScript in the head. Place it in a consistent, discoverable location (header).
Don't
Don't render multiple ThemeToggle instances -- they share localStorage and may conflict.