ComponentsForms & inputs

Switch

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.

Radix Switch components/switch.tsx, components/spinner.tsx, styles/forms.csstheme · material · accent · density · font

Installation

$ pnpm add @vamos-ui/react

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 memberRoleBookable
Elif KayaHead chef
Mert DemirSommelier
Zeynep ÇelikFront of house
Can ÖztürkPastry

Sizes & states

md 36×20, sm 28×16; loading, disabled, read-only and a Field error.

Required by your organisation's policy.

API

Switch

PropTypeDefault
checked
Controlled state.
boolean—
defaultChecked
Initial state (uncontrolled).
booleanfalse
onCheckedChange
Called with the next state.
(checked: boolean) => void—
label
Names the switch; clicking it toggles.
ReactNode—
description
Second line, linked with aria-describedby.
ReactNode—
labelPosition
start = label first, switch at the far end.
"start" | "end""end"
size
28×16 or 36×20 px.
"sm" | "md""md"
loading
Spinner in the thumb, aria-busy, changes locked.
boolean—
invalid
Danger outline + aria-invalid. Set by Field error.
boolean—
readOnly
Focusable but can't be flipped.
boolean—
name / value
Form submission (hidden input).
stringvalue "on"
controlClassName
Classes for the track when label is used.
string—