Theme Toggler
Light/dark switch with a View Transitions reveal. Pro · Animated components › Buttons
Cycles light / dark (/ system) and sweeps the new theme over the page with the View Transitions API — from an edge or as a circle out of the button. Where the API is missing, or under reduced motion, the theme simply switches.
Installation
npx valyro-cli@latest login
npx valyro-cli@latest add theme-toggler
npm install valyro-ui-pro
import 'valyro-ui-pro/styles.css';
import { ThemeToggler } from 'valyro-ui-pro';
Props
| Prop | Type | Default | |
|---|---|---|---|
mode | 'light' | 'dark' | 'system' | The chosen mode. Applying it (ThemeProvider, a class on <html>) is up to the app, in onModeChange. | |
defaultMode | 'light' | 'dark' | 'system' | 'light' | Initial mode when uncontrolled. |
onModeChange | (mode: ThemeTogglerMode) => void | Called inside the view transition, so the new theme is painted into the sweep. | |
modes | ThemeTogglerMode[] | ['light', 'dark'] | Modes the button cycles through, in order (default light, dark). |
direction | 'ltr' | 'rtl' | 'ttb' | 'btt' | 'circle' | 'ltr' | How the new theme sweeps over the page (default ltr). |
onImmediateChange | (mode: ThemeTogglerMode) => void | Called on click with the next mode before the sweep starts (e.g. to save the choice). | |
labels | Partial<ThemeTogglerLabels> | Overrides for the built-in English text; keys left out keep their defaults. | |
round | boolean | Circle instead of the theme's default button radius. | |
variant | 'primary' | 'secondary' | 'ghost' | 'accent' | 'danger' | 'link' | Solid primary/accent/danger fill, outlined secondary, transparent ghost, or unpadded text link. | |
size | 'sm' | 'md' | 'lg' | Control height, padding and text size. | |
loading | boolean | Shows a spinner and blocks activation without changing the button's width: the spinner takes the left icon's place, or covers the label when there is no left icon. The button stays focusable and gets aria-busy. | |
pill | boolean | Fully rounded ends, regardless of theme. | |
hoverScale | number | Scale under a hovering mouse, e.g. 1.05; it springs back with a slight bounce. Off by default (the theme's own hover). Skipped on touch and under reduced motion. | |
tapScale | number | Scale while pressed, e.g. 0.95, instead of the theme's press transform; springs back on release. |
Related components
- Toggle — Toggle button with a springy response
- Flip Button — Two-sided button that flips on a spring
- Liquid Button — Button that fills with “liquid” on hover
- GitHub Stars Button — Repository link with a rolling star count
- Share Button — Button that fans out social icons
- Code Tabs — Code variants in tabs: npm, pnpm, bun, with copy
- Number Wheel — Number on a spinning wheel with neighboring values
- Pin List — Pinnable list: items glide between groups
- Notification Stack — Notification stack that expands into a list
- Todo List — Checklist with a wavy strike-through on done items
- Presence Avatars — Who’s online: avatars rearrange as status changes
- Radial Menu — Ring-shaped context menu on right-click
Previous: Liquid Button · Next: GitHub Stars Button · All Animated components