Sun
Paper / black
The choice stays. The grid does not move.
Switches between light and dark schemes. The icon changes and the choice persists locally.
Paper / black
The choice stays. The grid does not move.
Three ways in. They share one source, so the pixels match whichever you pick.
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { ThemeToggle } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/theme-toggle.
npx @noorddev/vlak-cli add theme-toggle
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
npx shadcn add https://vlak.dev/r/theme-toggle.json
The same registry item, installed by shadcn's CLI.
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
import { ThemeToggle } from "@noorddev/vlak-react";
<ThemeToggle storageKey="vlak-theme" onThemeChange={(dark) => track(dark)} />One filled family mark on a 24px square, about 18–20px of drawn ink. Moon on paper, sun on black. The button sets data-theme="dark" on <html> and persists the choice. Apps pin it top-right; catalog and previews use the inline modifier. The name states the action ("Switch to dark scheme"), so it changes with the state.
| Prop | Type | Default | Description |
|---|---|---|---|
storageKey | string | "vlak-theme" | localStorage key the choice persists under. |
onThemeChange | (dark: boolean) => void |
Also accepts Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onChange">.
| Keys | Does |
|---|---|
| Tab | Moves focus to the button |
| Enter, Space | Switches the scheme |
<button type="button" class="rs-theme-toggle rs-theme-toggle-inline" aria-label="Switch to dark scheme"><svg class="rs-icon rs-theme-moon" aria-hidden="true" viewBox="0 0 16 16" width="24" height="24" fill="currentColor" stroke="none"><path d="M13.5 8.5 A5.5 5.5 0 1 1 7.5 2.5 A4.5 4.5 0 0 0 13.5 8.5 Z"/></svg></button>