Switch
An on/off toggle that applies immediately, with an accessible name and optional state labels.
Live demo
Switch is a role="switch" toggle for a setting that takes effect immediately, distinct from a checkbox that stages a value until a form submit. It renders a native <button> track with a sliding thumb, so pointer, Space, and Enter all flip it and the state lives in aria-checked.
An optional leading label and optional on-label/off-label state text make the toggle self-describing, and it is form-associated: give it a name (and optional value) and it contributes to form data only while on. Two sizes: the default md and a compact sm.
When to use
How this component composes with the rest of the set.
Props
14 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Variants
square
Squared track and thumb corners.
vertical
Track stood on its end; down is off, up is on.
reverse
On/off direction flipped (on at the left, or the bottom when vertical).
label-end
Label after the control instead of before it.
Sizes
sm
Compact.
md
Default.
States
on
Toggle is on: the track fills with the chosen tone (accent by default) and the thumb slides to the end.
hover
Pointer over the track: overlay paints the hover tint.
active
Track pressed: overlay paints the press tint.
focus-visible
Keyboard focus: a token-colored ring, plus a transparent outline that becomes real in forced-colors mode.
disabled
Non-interactive: muted track and thumb, overlay suppressed.
Anatomy
The named parts that make up the component, with their selectors.
switch
The row wrapper carrying the size and disabled classes and laying out label, track, and state text.
track
The interactive role="switch" button: the pill the thumb slides within.
thumb
The circular knob: a darkened cast of the track's tone, kept visible on and off.
label
The visible leading label that names the toggle and is referenced as its accessible name.
state
Optional trailing on/off state text; becomes the accessible name when no other label is given.
overlay
The pseudo-element behind the track that paints hover and active state tints.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xoji-default register
(derive(xojiDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--accent-2
--accent-2-fg
--accent-3
--accent-3-fg
--accent-4
--accent-4-fg
--accent-fg
--black
--black-fg
--blue
--blue-fg
--border-normal
--border-thick
--border-thin
--brown
--brown-fg
--cyan
--cyan-fg
--danger
--danger-fg
--duration-base
--duration-fast
--ease-emphasized
--ease-standard
--elevation-1
--fg-0
--fg-2
--fg-disabled
--font-sans
--gray
--gray-fg
--green
--green-fg
--info
--info-fg
--leading-tight
--line-2
--neutral
--neutral-bg
--neutral-fg
--orange
--orange-fg
--pink
--pink-fg
--purple
--purple-fg
--radius-full
--radius-sm
--red
--red-fg
--ring
--space-1
--space-2
--space-4
--space-5
--space-6
--space-7
--state-disabled
--state-hover
--state-press
--success
--success-fg
--text-body
--text-sm
--warn
--warn-fg
--white
--white-fg
--yellow
--yellow-fg
Accessibility
Code
Labels, tones, shapes, and form association
A named toggle, on/off state text, the compact size, a toned switch, the square / vertical / reversed variants, a form-bound switch, and a disabled one.
<xoji-switch label="Wi-Fi" checked></xoji-switch>
<xoji-switch label="Notifications" on-label="On" off-label="Off"></xoji-switch>
<xoji-switch size="sm" label="Compact mode"></xoji-switch>
<xoji-switch label="Alerts" tone="danger" checked></xoji-switch>
<xoji-switch label="Square" shape="square" checked></xoji-switch>
<xoji-switch label="Vertical" orientation="vertical" checked></xoji-switch>
<xoji-switch label="Reversed" reverse checked></xoji-switch>
<xoji-switch label="Label after" label-side="end" checked></xoji-switch>
<xoji-switch label="Sync" name="sync" value="enabled" checked></xoji-switch>
<xoji-switch label="Locked" disabled checked></xoji-switch>
<script lang="ts">
import { Switch } from "@xoji/svelte";
let wifi = $state(true);
let notify = $state(false);
</script>
<Switch label="Wi-Fi" bind:checked={wifi} />
<Switch label="Notifications" onLabel="On" offLabel="Off" bind:checked={notify} />
<Switch size="sm" label="Compact mode" />
<Switch label="Alerts" tone="danger" checked />
<Switch label="Square" shape="square" checked />
<Switch label="Vertical" orientation="vertical" checked />
<Switch label="Reversed" reverse checked />
<Switch label="Label after" labelSide="end" checked />
<Switch label="Sync" name="sync" value="enabled" bind:checked={wifi} />
<Switch label="Locked" disabled checked />
---
import { Switch } from "@xoji/astro";
---
<Switch label="Wi-Fi" checked />
<Switch label="Notifications" onLabel="On" offLabel="Off" />
<Switch size="sm" label="Compact mode" />
<Switch label="Alerts" tone="danger" checked />
<Switch label="Square" shape="square" checked />
<Switch label="Vertical" orientation="vertical" checked />
<Switch label="Reversed" reverse checked />
<Switch label="Label after" labelSide="end" checked />
<Switch label="Sync" name="sync" value="enabled" checked />
<Switch label="Locked" disabled checked />