Forms

Switch

A toggle switch for boolean values. Supports labels, descriptions, checked/unchecked icons, colors, sizes, and loading states.

Migration
/* Before 2.9.0: the attribute sat on the wrapper */
[aria-label="Airplane mode"] [role="switch"] {
  outline-offset: 4px;
}

/* From 2.9.0: it is on the control. In a test,
   getByRole('switch', { name: 'Airplane mode' }) now finds it */
[role="switch"][aria-label="Airplane mode"] {
  outline-offset: 4px;
}

Playground

Experiment with different props in real-time.

Toggle this feature on or off

Basic Usage

<script lang="ts">
  import { Switch } from 'sv5ui';

  let enabled = $state(false);
</script>

<Switch bind:checked={enabled} />

Label & Description

Add context with label and description props.

Receive alerts when someone mentions you.

Use dark theme across the application.

Help us improve by sending anonymous usage data.

<Switch
  bind:checked={notifications}
  label="Push Notifications"
  description="Receive alerts when someone mentions you."
/>

<Switch
  bind:checked={darkMode}
  label="Dark Mode"
  description="Use dark theme across the application."
/>

<Switch
  bind:checked={analytics}
  label="Usage Analytics"
  description="Help us improve by sending anonymous usage data."
/>

Sizes

5 sizes.

<Switch size="xs" label="Extra Small" bind:checked={xs} />
<Switch size="sm" label="Small" bind:checked={sm} />
<Switch size="md" label="Medium" bind:checked={md} />
<Switch size="lg" label="Large" bind:checked={lg} />
<Switch size="xl" label="Extra Large" bind:checked={xl} />

Colors

8 semantic color schemes.

<Switch color="primary" label="Primary" checked />
<Switch color="secondary" label="Secondary" checked />
<Switch color="tertiary" label="Tertiary" checked />
<Switch color="success" label="Success" checked />
<Switch color="warning" label="Warning" checked />
<Switch color="error" label="Error" checked />
<Switch color="info" label="Info" checked />
<Switch color="surface" label="Surface" checked />

With Icons

Show different icons for checked/unchecked states.

<Switch
  bind:checked={wifi}
  label="Wi-Fi"
  checkedIcon="lucide:wifi"
  uncheckedIcon="lucide:wifi-off"
/>

<Switch
  bind:checked={sound}
  label="Sound"
  checkedIcon="lucide:volume-2"
  uncheckedIcon="lucide:volume-x"
/>

<Switch
  bind:checked={visibility}
  label="Visibility"
  checkedIcon="lucide:eye"
  uncheckedIcon="lucide:eye-off"
/>

Loading

<Switch label="Syncing settings..." loading checked />
<Switch label="Connecting..." loading />

Disabled

<Switch label="Enabled (disabled)" checked disabled />
<Switch label="Disabled (disabled)" disabled />

Accessibility

A switch with a label is named by it. Without one, pass aria-label. It lands on the switch itself, where assistive technology looks for it, along with the other naming and describing attributes: aria-label, aria-labelledby, aria-describedby, aria-invalid, aria-required, aria-errormessage and aria-details. class, style, data-* and aria-hidden stay on the wrapper.

<!-- No visible label: name it yourself -->
<Switch aria-label="Airplane mode" />

onfocus and onblur are attached to the switch as well. Inside a FormField the field label names the switch and its description is announced.

UI Slots

Use the ui prop to override classes on internal elements.

SlotDescription
rootOutermost wrapper
baseSwitch track
containerTrack container
thumbSliding thumb
iconIcon inside thumb
wrapperLabel/description wrapper
labelLabel text
descriptionDescription text

With overridden slot classes

<Switch
  label="Custom Styled"
  description="With overridden slot classes"
  checked
  ui={{
    base: 'bg-success',
    thumb: 'bg-white shadow-lg',
    label: 'font-bold tracking-wide',
    description: 'italic'
  }}
/>

Snippets

SnippetDescription
labelSlotCustom label rendering
descriptionSlotCustom description rendering

Props

PropTypeDefault
checkedbooleanfalse
onCheckedChange(checked) => void-
colorColorType'primary'
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
labelstring-
descriptionstring-
checkedIconstring-
uncheckedIconstring-
loadingbooleanfalse
loadingIconstringicons.loading
disabledbooleanfalse
requiredbooleanfalse
idstring-
namestring-
valuestring-
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-