Application
Theme Toggle
A light and dark switch, a useTheme hook, and a no-flash theme script.
Installation
Copy the source with the CLI to own and edit it, or import it from the npm package.
npx aback-ui@latest add theme-toggleWrites components/ui/theme-toggle.tsx and the components it builds on. First time in this project? Run npx aback-ui@latest init first, as the installation guide shows.
Usage
Import the parts you need from the installed file. The Code tab above has a complete, working example.
import { ThemeScript, ThemeToggle, useTheme } from "@/components/ui/theme-toggle";API reference
Props and composition points for Theme Toggle. Native element props pass through.
| Prop | Type | Default | Description |
|---|---|---|---|
ThemeToggle storageKey | string | "theme" | The localStorage key that remembers the choice. |
ThemeToggle toDarkLabel / toLightLabel | string | "Switch to dark theme" / "Switch to light theme" | The accessible name in each state. Localize both. |
ThemeToggle variant / size | Button variant / size | "ghost" / "icon" | Any Button variant and size. |
useTheme(storageKey?) | () => { theme, resolvedTheme, setTheme } | None | theme is "light", "dark", or "system"; resolvedTheme is what is on screen. Every hook and toggle stays in sync, across tabs too. |
ThemeScript storageKey / nonce | string / string | None | Render in head to apply the stored theme before paint. Pass a CSP nonce if your policy requires one. |
Dependencies: @tabler/icons-react, plus the shared @/lib/utils helper.
Accessibility
Semantics, keyboard behavior, and the decisions that keep the component operable.
- The toggle is a button whose name says what it will do, such as Switch to dark theme.
- The icon follows the dark class through CSS, so it is correct before hydration, and the name updates after.
- A system preference is respected until the visitor chooses, and system changes apply live.
- Blocked storage does not break the toggle; the theme still changes for the current page.
Keyboard
| Key | Action |
|---|---|
| EnterorSpace | Switch between light and dark. |
The contract matches the Aback theme CSS: a dark class on html. Add suppressHydrationWarning to the html element, because ThemeScript changes its class before React hydrates.
Used in production
The Aback products whose interfaces shaped this component.