Toggle switch for binary on/off settings
Tags: component form toggle
Switch is a toggle control for binary settings, providing an alternative to checkboxes for on/off states.
Import
<script>
import { Switch } from '@classic-homes/theme-svelte';
</script>Basic Usage
<script>
let enabled = $state(false);
</script>
<Switch bind:checked={enabled} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked |
boolean |
false |
Whether the switch is on (bindable) |
disabled |
boolean |
false |
Disables the switch |
required |
boolean |
false |
Marks as required |
name |
string |
- | Name attribute for forms |
value |
string |
- | Value attribute for forms |
id |
string |
- | Element ID for label association |
class |
string |
- | Additional CSS classes |
onchange |
(checked: boolean) => void |
- | Callback when checked state changes |
With Label
Pair switches with descriptive labels:
<script>
import { Switch, Label } from '@classic-homes/theme-svelte';
let darkMode = $state(false);
</script>
<div class="flex items-center gap-3">
<Switch id="dark-mode" bind:checked={darkMode} />
<Label for="dark-mode">Dark mode</Label>
</div>States
On (Checked)
<Switch checked />Off (Unchecked)
<Switch />Disabled
<Switch disabled />
<Switch disabled checked />Controlled Switch
Use onchange for controlled behavior:
<script>
let notifications = $state(false);
function handleChange(newChecked: boolean) {
// Save preference to server
savePreference('notifications', newChecked);
notifications = newChecked;
}
</script>
<Switch checked={notifications} onchange={handleChange} />Switch vs Checkbox
Use Switch when:
- The setting takes effect immediately (no form submission)
- The option is a clear on/off toggle
- You want a more visual, mobile-friendly control
Use Checkbox when:
- The selection is part of a form that will be submitted
- Multiple selections are possible
- The change requires explicit save/submit
Settings Pattern
Common pattern for settings pages:
<script>
import { Switch, Label } from '@classic-homes/theme-svelte';
let settings = $state({
notifications: true,
emailUpdates: false,
autoSave: true,
});
</script>
<div class="space-y-6">
<div class="flex items-center justify-between">
<div>
<Label for="notifications" class="text-base font-medium">Notifications</Label>
<p class="text-sm text-muted-foreground">Receive push notifications</p>
</div>
<Switch id="notifications" bind:checked={settings.notifications} />
</div>
<div class="flex items-center justify-between">
<div>
<Label for="email-updates" class="text-base font-medium">Email Updates</Label>
<p class="text-sm text-muted-foreground">Receive weekly email updates</p>
</div>
<Switch id="email-updates" bind:checked={settings.emailUpdates} />
</div>
<div class="flex items-center justify-between">
<div>
<Label for="auto-save" class="text-base font-medium">Auto-save</Label>
<p class="text-sm text-muted-foreground">Automatically save changes</p>
</div>
<Switch id="auto-save" bind:checked={settings.autoSave} />
</div>
</div>Touch Target
The Switch component includes an expanded touch target that extends beyond the visible switch, ensuring easy tapping on mobile devices.
Accessibility
The Switch component includes:
- Uses Bits UI Switch primitive for proper accessibility
- Keyboard navigation (Space to toggle)
- Expanded touch target for mobile
- Proper ARIA role and state
- Visual focus indicator
- Smooth thumb animation
Keyboard Navigation
Press Space to toggle a focused switch. Tab moves focus between switches.
Examples
Feature Toggle
<script>
let betaFeatures = $state(false);
</script>
<div class="p-4 border rounded-lg">
<div class="flex items-center justify-between">
<div>
<h3 class="font-medium">Beta Features</h3>
<p class="text-sm text-muted-foreground">Enable experimental features</p>
</div>
<Switch bind:checked={betaFeatures} />
</div>
{#if betaFeatures}
<p class="mt-3 text-sm text-warning">Beta features may be unstable.</p>
{/if}
</div>Privacy Controls
<script>
let privacy = $state({
analytics: true,
personalization: false,
thirdParty: false,
});
</script>
<div class="space-y-4">
<h2 class="text-lg font-semibold">Privacy Settings</h2>
<div class="space-y-3">
<div class="flex items-center justify-between">
<Label for="analytics">Analytics cookies</Label>
<Switch id="analytics" bind:checked={privacy.analytics} />
</div>
<div class="flex items-center justify-between">
<Label for="personalization">Personalization</Label>
<Switch id="personalization" bind:checked={privacy.personalization} />
</div>
<div class="flex items-center justify-between">
<Label for="third-party">Third-party cookies</Label>
<Switch id="third-party" bind:checked={privacy.thirdParty} />
</div>
</div>
</div>Inline Switch
<p class="text-sm">
Show completed tasks
<Switch bind:checked={showCompleted} class="ml-2 align-middle" />
</p>Related Components
- Checkbox - Checkbox for form selections
- RadioGroup - Single selection from options
- Label - Label for form inputs