Skip to content

Switch

Terminal-styled binary toggle switch. Uses role="switch" with checked/defaultChecked/onChange(boolean) pattern and a hidden native checkbox for form submission.

Preview

Installation

$pnpm exec dgadd add ui/switch
[Installs to]src/components/ui/switch[Item]ui/switch

dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.

Usage

tsx
import { Switch } from "@/components/ui/switch";export default function SwitchDefault() {  return (    <Switch      defaultChecked      label="Enable notifications"      description="Delivered when a review finishes."    />  );}

Examples

Sizes and States

Preview

Controlled

Preview

API Reference

Switch

NameTypeDefaultDescription
checkedbooleanControlled checked state.
defaultCheckedbooleanfalseInitial checked state for uncontrolled usage.
onChange(checked: boolean) => voidCalled when the boolean checked state changes.
valuestring"on"Hidden native input value used for form submission.
namestringHidden native input name used for form submission.
formstringID of the form that owns the switch and hidden native input, including when rendered outside that form.
requiredbooleanfalseMarks the hidden native checkbox as required.
disabledbooleanfalseDisables the switch and hidden input.
labelReactNodeVisible label rendered beside the track. Wires aria-labelledby and makes the whole row a tap target.
descriptionReactNodeVisible description under the label, wired with aria-describedby.
size"sm" | "md""md"Switch size token.
aria-labelstringAccessible name for the switch when no visible label labels it.
aria-labelledbystringID reference for visible text that labels the switch.
aria-describedbystringID reference for helper or error text describing the switch.
aria-invalidboolean | 'true' | 'false' | 'grammar' | 'spelling'Invalid state override. Field.Control also forwards its invalid state to this prop.

Data attributes

AttributeApplies toValuesDescription
data-stateSwitch"checked" | "unchecked"Reflects the checked state for track and thumb styling.
data-slotSwitch row"switch-row"Present on the row wrapper rendered when label or description is set.
data-disabledSwitchpresent when disabledMarks the disabled state for styling hooks.

Accessibility

Keyboard Navigation

Switch renders a native button with role=switch, so keyboard activation follows button semantics.

KeyAction
SpaceToggles the checked state when the switch is focused.
EnterToggles the checked state when the switch is focused.

Controlled toggle

Preview

Notes

State Glyph

The thumb renders a binary glyph — "1" when checked, "0" when unchecked — so the on/off state stays readable without relying on track inversion or thumb position. The glyph is aria-hidden; role="switch" plus aria-checked carries the state for assistive technology.

Labelled Row

Pass label (and optionally description) to render the same row grammar Checkbox and Radio use: track on the left, label on the right, one shared gap and one shared 44px coarse-pointer height. The label is wired as the accessible name through aria-labelledby, the description through aria-describedby, and clicking either forwards to the control. An explicit aria-label still wins. With neither prop the render is unchanged, so hand-rolled rows keep working.

Disabled Treatment

A disabled switch dashes its track border and resolves the thumb to the recessed surface with a muted digit — the same disabled grammar Input and Textarea use. It is not an opacity fade: forced-colors mode drops opacity but keeps border-style, so the state stays visible in high-contrast themes.

Form Submission

Switch renders a hidden native checkbox when name or required is set. The value prop controls the form-submission string (default "on"). Pass form to associate both the switch and its form mirror with a remote form.

Source

Install via CLI: pnpm exec dgadd add ui/switch. Keyboard hooks are included as standalone copies. For the full experience, use --integration keys.

Highlighted source loads after this disclosure opens. Browse the source repository.