An on/off setting that applies immediately: maintenance mode, online bookings, active/inactive in a table row. Two sizes, label + description on either side, and a loading state for optimistic saves.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { Switch } from "@vamos-ui/react";
<Switch label="Accept online bookings" description="Guests can reserve from your website." defaultChecked />Switches apply instantly. If a change only takes effect after Save, use a Checkbox instead.
The thumb uses --accent-fg when on, so it stays visible on every accent (graphite in dark mode included). Thumb travel follows --dir for RTL.
Examples
Settings rows
labelPosition="start" puts the label first and the switch at the far end — the settings-page pattern.
Website
kadikoyroasters.com
Optimistic save
Flip immediately, lock with loading (aria-busy, spinner in the thumb), revert on error and announce the result in a live region. Every second save fails here.
In a table row
size="sm" for dense rows; give each switch an aria-label that names the row.
| Staff member | Role | Bookable |
|---|---|---|
| Elif Kaya | Head chef | |
| Mert Demir | Sommelier | |
| Zeynep Çelik | Front of house | |
| Can Öztürk | Pastry |
Sizes & states
md 36×20, sm 28×16; loading, disabled, read-only and a Field error.
Required by your organisation's policy.
API
Switch
| Prop | Type | Default |
|---|---|---|
checkedControlled state. | boolean | — |
defaultCheckedInitial state (uncontrolled). | boolean | false |
onCheckedChangeCalled with the next state. | (checked: boolean) => void | — |
labelNames the switch; clicking it toggles. | ReactNode | — |
descriptionSecond line, linked with aria-describedby. | ReactNode | — |
labelPositionstart = label first, switch at the far end. | "start" | "end" | "end" |
size28×16 or 36×20 px. | "sm" | "md" | "md" |
loadingSpinner in the thumb, aria-busy, changes locked. | boolean | — |
invalidDanger outline + aria-invalid. Set by Field error. | boolean | — |
readOnlyFocusable but can't be flipped. | boolean | — |
name / valueForm submission (hidden input). | string | value "on" |
controlClassNameClasses for the track when label is used. | string | — |