Switch ported
A tactile toggle for settings that take effect immediately.
A toggle for a single on/off preference, with a spring-glide thumb, tactile press-stretch, and integrated accessible label.
Loading demo…
Guidance
When to use
- Settings that take effect as soon as they are flipped, such as notifications or feature toggles.
- Settings lists where each row represents one distinct on/off preference.
When not to use
- Use Checkbox when the choice waits for a form submit button.
- Use Segmented Control for choosing between multiple named options.
- Use Theme Switch for light and dark appearance toggling.
pnpm dlx shadcn-svelte@latest add @arcui/switchUsage
<script lang="ts">
import Switch from '$lib/components/switch/switch.svelte';
let enabled = $state(true);
</script>
<Switch bind:checked={enabled} label="Email notifications" />Variants & Examples
Default (Controlled)
Two-way binding with Svelte 5 $bindable() rune.
<Switch bind:checked={val} label="Push notifications" />Disabled State
Interaction is disabled and visual opacity is dimmed.
<Switch checked={false} label="Location services" disabled />Uncontrolled with Default
Seeds initial state once via defaultChecked without external binding.
<Switch defaultChecked={true} label="Auto-update apps" />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled state. Use bind:checked for two-way reactivity. |
defaultChecked | boolean | false | Initial state when uncontrolled. |
onCheckedChange | (checked: boolean) => void | — | Callback fired on every toggle transition. |
label | string | — | Visible label text; automatically acts as aria-label. |
disabled | boolean | false | Disables interaction and dims control contrast. |
required | boolean | false | Marks the input field as required in forms. |
name | string | — | Form input field name; renders a hidden input for form submissions. |
value | string | 'on' | Form value submitted when the switch is checked. |
ref | HTMLElement | null | — | Bindable ref to the underlying Bits UI root button element. |
Keyboard Interactions
| Key | Action |
|---|---|
Space | Toggles the switch. Holding Space stretches the thumb until release. |
Enter | Toggles the switch. |
Tab | Moves focus to or away from the switch control. |
Accessibility
- Bits UI renders a semantic <button> with role="switch" and aria-checked.
- The label prop automatically connects as the accessible label; icon-only variants require an explicit aria-label.
- Focus states display a high-contrast focus ring conforming to WCAG 2.1 AA.
Motion
Phase 1 still-state: the thumb rests at its static terminal coordinate (translateX 0 vs 18px). Phase 2 wires the dynamic spring glide and press-stretch (scaleX) via @humanspeak/svelte-motion; the prefers-reduced-motion path is instant CSS state and already fully functional.
Notes for AI
- Use for preferences that take effect immediately upon toggle. Use Checkbox when choices require a submit button.
- Always prefer bind:checked with Svelte 5 runes for reactive state synchronization.
- Pass the name prop whenever the switch is part of a native HTML form or SvelteKit form action.
Source of truth: registry/components/switch/switch.tsx