Headless / Selection

Switch

Switch is a binary on/off control. It is a <input type="checkbox"> with role="switch" — the same form semantics as a checkbox, announced as a switch.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A forwardRef wrapper over <input type="checkbox" role="switch">. Mechanically it is a checkbox — it submits, resets, and toggles like one. The role="switch" changes only what assistive technology says: "switch, on" rather than "checkbox, checked", which matches the mental model of a setting that is immediately in effect.

Install

example.tsx
yarn add @usemotif/headless
example.tsx
import { Switch } from '@usemotif/headless';

API

Switch

stable
const Switch: ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLInputElement>>
invalidboolean

Marks the switch invalid — sets `aria-invalid`.

…InputHTMLAttributesOmit<InputHTMLAttributes, "type">

Every standard input attribute except `type`. `checked`, `defaultChecked`, `onChange`, `name`, `disabled`, and the rest pass through.

Switch or Checkbox

Both are checkbox inputs; the choice is about meaning. A switch takes effect immediately — flipping it changes something now, like a settings toggle. A checkbox records a choice that is committed later, typically on a form submit. If the change needs a "Save" button, it is a checkbox; if it acts the instant it is flipped, it is a switch.

Accessibility

role="switch" tells a screen reader to announce the on/off state. Switch still needs an accessible name — wrap it in a <label> or pair it with a Label.

A switch should act on toggle, not on a later submit. If the surrounding UI has a Save button that the toggle waits for, the control is mislabelled — that is checkbox behaviour, and a screen-reader user will expect the switch to have already taken effect.

Examples

A settings toggle:

example.tsx
<label>
<Switch
  checked={settings.notifications}
  onChange={(e) => updateSetting('notifications', e.target.checked)}
/>
Email notifications
</label>