Theme switcher ported
Four smooth ways to move between light and dark appearance.
Four smooth ways to move between light and dark appearance.
Loading demo…
Guidance
When to use
- A single light and dark toggle in an app or marketing top bar.
- Pages that want to run their own view transition from the button's position.
When not to use
- Use user-menu when theme choice, including system, belongs inside an account menu.
- Use theme-switch-rise for quiet product chrome, or theme-switch-eclipse for a dramatic showcase change.
pnpm dlx shadcn-svelte@latest add @arcui/theme-switchUsage
<script lang="ts">
import { ThemeSwitch } from '$lib/components/theme-switch';
let theme = $state<'light' | 'dark'>('light');
</script>
<ThemeSwitch bind:theme variant="reveal" />Variants & Examples
Default
Standard appearance and configuration.
<ThemeSwitch theme="light" variant="reveal" />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
onThemeChange | (next: Theme, variant: ThemeSwitchVariant, trigger: HTMLElement) => void | – | (Required) Called on press with the opposite theme, the variant, and the button, so the page transition can start from it. |
label | string | – | Accessible name. Defaults to \"Switch to dark mode\" or \"Switch to light mode\". |
iconOnly | boolean | 'false' | Hides the \"Switch theme\" text and renders a 38px square button. |
Keyboard Interactions
| Key | Action |
|---|---|
Enter / Space | Toggles the theme. |
Accessibility
- Renders the library Button with aria-pressed set when the theme is dark.
- aria-label defaults to "Switch to dark mode" or "Switch to light mode"; pass label to override.
- The icons are aria-hidden.
Motion
- Sun and moon trade places with a shared rotation, scale, and blur on a snappy spring; the icon also nudges in the direction of the chosen variant. - A theme that arrives during hydration swaps without motion, so a dark page never spins its switch on load. - Reduced motion swaps the icon with an instant fade and removes the nudge; skip the page transition too when reduced.
Notes for AI
- Use for a single light/dark toggle in a top bar. For light, dark, and system inside an account menu use user-menu.
- The component only reports the change. Apply the theme in onThemeChange, typically inside document.startViewTransition, and use trigger's rect as the transition origin.
- variant is passed back to onThemeChange so one handler can run the matching page transition (reveal, eclipse, split, rise).
Source of truth: registry/components/theme-switch/theme-switch.tsx