Skip to content
omaris

Selection

Switch

MD3 switch.

import { Switch } from 'omaris'
Learn

Examples

Basic

A switch takes effect immediately. If it needs a Save button, use a checkbox.

<script lang="ts">	import { Switch } from 'omaris';​	let wifi = $state(true);</script>​<Switch label="Wi-Fi" bind:checked={wifi} />

Settings row

labelPosition="start" gives you the settings-row layout for free.

<script lang="ts">	import { Switch } from 'omaris';​	let backup = $state(true);	let beta = $state(false);</script>​<div class="flex w-80 max-w-full flex-col gap-4 px-2">	<Switch		class="w-full justify-between"		labelPosition="start"		label="Automatic backups"		description="Every night at 2 AM"		bind:checked={backup}	/>	<Switch		class="w-full justify-between"		labelPosition="start"		label="Beta features"		description="May break without warning"		bind:checked={beta}	/></div>

Icons and tones

icons puts a tick and a cross in the handle, for a clearer on/off.

<script lang="ts">	import { Switch } from 'omaris';</script>​<Switch label="With icons" icons checked /><Switch label="Success" tone="success" checked /><Switch label="Small" size="sm" checked /><Switch label="Large" size="lg" checked /><Switch label="Disabled" disabled checked />

When to use it

Use it for

  • One setting that takes effect the moment it flips: notifications, dark mode, Wi-Fi. No Save button after it.
  • A settings screen. labelPosition="start" puts the label first and the switch at the trailing edge, like a row in a List.
  • A row that needs a second line. description says what "on" does.
  • A state that must be clear at a glance, like a safety toggle or a row seen in monochrome. Pass icons.

Not for

  • A choice submitted with a form → Checkbox. If a Save button follows it, it is a checkbox.
  • Several items from a set → Checkbox. One switch per table row is too many toggles.
  • One of several → Radio or Segmented Button.
  • A momentary on/off in a toolbar, like mute or bookmark → a toggle Icon Button.
  • Revealing a section of a form → Accordion.

Do

  • Label it with the thing, not the state: "Email notifications", not "Enable" or "On".
  • Apply the change on onchange at once. If it can fail, flip the switch back and say why in a Toast.
  • Keep size="md" in a settings list. sm fits a table cell or a dense card header.
  • Put a destructive setting like "Delete after 30 days" behind a Dialog before it applies.

Don't

  • Disable a switch without saying why. Explain in description.
  • Rely on tone to carry meaning. It only colours the on state; icons makes on and off legible without colour.
  • Add a Save button under a page of switches. Either they apply as they flip, or they are checkboxes.

Quick reference

tone
  • primary (default)
  • secondary
  • tertiary
  • destructive
  • success
  • warning
  • info
size
  • md (default)
  • lg

API

Switch

MD3 switch.

The MD3 details that make it feel alive: the handle is small when off and grows when on, it swells while pressed, an MD3 state layer haloes it on hover/press, and the optional check/cross icon rides inside it.

Everything that moves animates translate and scale only — never justify-content (which doesn't interpolate, so the handle used to jump) and never width/height (which relayout mid-gesture and stutter on touch). Both are compositor properties, so the whole thing stays smooth on a phone. It's still pure CSS off a checkbox input, so keyboard and form behaviour come free.

import { Switch } from 'omaris'

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
track
The track.
handle
The slot the knob travels in. Always the full "on" handle size, so the only thing that changes is translate — no layout, no jump.
state
The MD3 state layer, haloing the knob on hover and press.
knob
The knob itself — the only thing that scales.
input
No description in the source yet.
icon
No description in the source yet.
label
No description in the source yet.
description
No description in the source yet.

Props

tone

Defaults to 'primary'

SwitchTone
primary
secondary
tertiary
destructive
success
warning
info
size

Defaults to 'md'

SwitchSize
md
lg
checked bindable

Defaults to false

boolean

Bindable.

icons

Defaults to false

boolean

Draw a tick (on) and a cross (off) inside the handle.

label
string
description
string
labelPosition

Defaults to 'end'

'start' | 'end'

Put the label before the switch — the settings-row layout.

haptics

Defaults to true

boolean

A haptic tap when it flips. Follows the shared haptics store; false opts this switch out.

sound

Defaults to true

boolean

A sound cue when it flips. Follows the shared sound store; false opts this switch out.

class
string
classes
SwitchClasses

Per-part Tailwind overrides. class still covers the root.

children
Snippet
ref bindable

Defaults to null

HTMLInputElement | null