Switch

Toggles a setting that takes effect immediately.

import { Switch } from "@usefragments/ui";Source

Preview

<StatefulSwitch label="Email notifications" />

Usage

Use when

  • Settings that apply the moment they change
  • Turning a feature on or off in a settings panel
  • The result is visible straight away

Avoid when

  • Choices that only apply on submit (use Checkbox)
  • Several options at once (use a Checkbox group)
  • Yes/no questions in a form (use RadioGroup)
  • More than two states (use Select or RadioGroup)

Implementation notes

  • The label names what is being turned on
  • On always means enabled, never the reverse
  • Apply the change immediately — no save button
  • Add helperText when the label alone is ambiguous
  • Stack related switches together

Installation

pnpm add @usefragments/ui

Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Examples

Checked

Starts on; the track fills with the accent colour.

<StatefulSwitch defaultChecked label="Dark mode" />

With Helper Text

Second line says what the setting actually does.

<StatefulSwitch
  defaultChecked
  label="Auto-save"
  helperText="Automatically save changes as you type"
/>

Disabled and Read-only

Disabled dims once; read-only keeps full ink and refuses the toggle.

<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
  <Switch disabled label="Premium feature (upgrade required)" />
  <Switch readOnly checked label="System managed (read-only)" />
</div>

Settings Panel

Stacked switches sharing one rhythm and helper column.

<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>
  <StatefulSwitch
    defaultChecked
    label="Push notifications"
    helperText="Receive push notifications on your device"
  />

Invalid

A message with an icon under the label; the track keeps its colours.

<StatefulSwitch
  label="Share findings with the team"
  invalid
  errorMessage="Sharing is off on this plan."
/>

API reference

Component props
Prop
Type
Default
Description
aria-describedbystring | undefinedNot set—
aria-labelstring | undefinedNot set—
aria-labelledbystring | undefinedNot set—
checkedboolean | undefinedfalseWhether the switch is in the on state
defaultCheckedboolean | undefinedNot setDefault checked state (uncontrolled)
disabledboolean | undefinedfalseWhether the switch is non-interactive
errorMessageReact.ReactNodeNot setMessage shown with a warning icon under the label while invalid; wired to aria-describedby
formstring | undefinedNot set—
helperTextstring | undefinedNot setHelper text shown below the label (preferred)
idstring | undefinedNot setID for the hidden input
inputRefReact.Ref<HTMLInputElement> | undefinedNot set—
invalidboolean | undefinedfalseThe value fails validation: errorMessage shows under the label with an icon
labelstring | undefinedNot setVisible label beside the track (outside the switch element, tied by aria-labelledby)
namestring | undefinedNot set—
onCheckedChange((checked: boolean) => void) | undefinedNot setCalled with the next state when the user toggles the switch
readOnlyboolean | undefinedfalseThe switch cannot be toggled; an off track takes the band and a dashed edge
requiredboolean | undefinedfalseThe switch must be on before the form submits
uncheckedValuestring | undefinedNot set—
valuestring | undefinedNot set—
classNamestring | undefinedNot setClass on the outer element: the label row, or the track when there is no visible text

Accessibility

  • role="switch" with aria-checked
  • Every switch has a label, visible or aria-label
  • Focus ring stays visible
  • Flipping it is announced
  • InputsiblingInput handles text/number entry; Switch handles boolean state
  • CheckboxalternativeUse Checkbox when change requires form submission

Next steps