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 ships in @diffgazer/add on npm: pnpm add -D @diffgazer/add puts it on pnpm exec, and npx @diffgazer/add runs it without the install.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS from the installed package.

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
checkedboolean—Controlled checked state.
defaultCheckedbooleanfalseInitial checked state for uncontrolled usage.
onChange(checked: boolean) => void—Called when the boolean checked state changes.
valuestring"on"Hidden native input value used for form submission.
namestring—Hidden native input name used for form submission.
formstring—ID 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.
labelReactNode—Visible label rendered beside the track. Wires aria-labelledby and makes the whole row a tap target.
descriptionReactNode—Visible description under the label, wired with aria-describedby.
size"sm" | "md""md"Switch size token.
aria-labelstring—Accessible name for the switch when no visible label labels it.
aria-labelledbystring—ID reference for visible text that labels the switch.
aria-describedbystring—ID 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.