Skip to content
Protocore Design Systemv1.6.9

/// Inputs

Switch

Boxy 36×20 toggle for an instant on/off setting; ink track when on, canvas thumb.

import { Switch } from "@protocore/pds";
View as Markdown

Basics

Pass a label and the track wires its own id to the caption. Use defaultChecked for the uncontrolled starting state.

Controlled

Drive checked from state and read onCheckedChange to react immediately — a switch takes effect the moment it flips, with no separate save step.

Edge traffic is flowing normally.

States

Off, on, and both disabled variants. Disabled tracks are muted and drop out of the tab order.

When to use it

Use a Switch for a binary setting that applies immediately — enable maintenance mode, turn on a webhook, require 2FA. If the value is only committed later as part of a form submit, a Checkbox communicates 'pending' more honestly. For choosing among 2–4 mutually-exclusive modes, use SegmentedControl; for one-of-many in a list, use RadioGroup.

Usage

Do

  • Use a switch only when the change takes effect on toggle, with no confirm step.
  • Label the switch with the thing it turns on, phrased positively ('Require 2FA').
  • Apply and persist the new value as soon as `onCheckedChange` fires.
  • Show the resulting state nearby when the effect isn't visually obvious.

Don't

  • Don't use a switch for a value that's only saved on form submit — use Checkbox.
  • Don't pair a switch with an Apply/Save button; that contradicts its semantics.
  • Don't use switches for mutually-exclusive options — use RadioGroup or SegmentedControl.
  • Don't write ambiguous labels like 'Notifications' with no on/off polarity.

Accessibility

KeysAction
TabMove focus to the switch.
Space / EnterToggle between on and off.
  • Built on Radix Switch: exposes `role="switch"` with `aria-checked`.
  • The label is a real `<label htmlFor>` — clicking the text flips the track.
  • Disabled switches expose `aria-disabled` and are removed from the tab order.

Mobile (React Native)

Preview. @protocore/pds-mobile ships the React Native sibling of Switch. It mirrors the web API where React Native allows; the package is a preview with no device-level QA yet, so pin it and expect small changes.

Import it from the mobile package (not @protocore/pds), inside a <PdsProvider> — there is no stylesheet, so style (a ViewStyle) replaces className and every value comes from the theme:

import { Switch } from "@protocore/pds-mobile";

Parity with web. A custom Pressable toggle (Radix does not exist in RN).

  • Per the spec the track fills ink (not accent) when on.
  • Controllable via checked / defaultChecked / onCheckedChange; sets accessibilityRole="switch".
<Switch label="Enable alerts" checked={on} onCheckedChange={setOn} />

Switch props

PropTypeDefaultDescription
asChildboolean
classNamestring
labelReactNodeText rendered beside the track (sans 14). Omit for a standalone control.
styleCSSProperties

Related

  • CheckboxBoxy 16px checkbox with checked, unchecked, and indeterminate states and an optional label.
  • RadioGroupOne-of-many selection with sharp square markers; the active option carries the accent fill.
  • FieldForm-field wrapper: a caption label, the control, and hint or error messaging with ARIA wired for you.
  • SegmentedControlCompact single-select toggle — a bordered row of mono uppercase segments where the active one inverts to a solid fill.