Foundations
Theme Controls
The UI for Orbit's theme runtime — six brand presets and a light/dark toggle. Changes apply to <html> instantly, persist to localStorage, and every component re-themes through the shared CSS tokens.
npx shadcn@latest add @orbit/theme-controlsDefault
This is live — it drives the whole docs site.
Presets only
Runtime API
ThemeControls is a thin UI over the OrbitTheme store (registry/theme). Use the useTheme() hook in components, or the store directly outside React.
| Prop | Type | Default | Description |
|---|---|---|---|
| useTheme() | hook | — | Subscribes to { preset, mode } and exposes setPreset, setMode, toggleMode, presets. |
| OrbitTheme.get() | () => ThemeState | — | Current { preset, mode }. |
| OrbitTheme.set() | (Partial<ThemeState>) => void | — | Set either or both; persists and emits an 'orbit-theme' CustomEvent. |
| OrbitTheme.onChange() | (fn) => unsubscribe | — | Subscribe outside React. |
| <ThemeScript /> | component | — | Inline script for <head> that applies the saved theme before first paint. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| showMode | boolean | true | Show the light/dark segmented control. |
| className | string | — | Extends or overrides the card chrome (e.g. borderless inside a top bar). |
Keyboard & accessibility
Every control is a real button reachable with Tab. Each preset swatch carries its preset name as an aria-label and reflects selection with aria-pressed (the check glyph is decorative); the light/dark segmented control likewise exposes aria-pressed on each option. Enter and Space activate the focused control, changes apply to <html> instantly and persist, and the hover/selection transitions collapse under prefers-reduced-motion.