Skip to content

Switch

An on/off setting that applies immediately. The thumb carries a tick or a cross.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Switch

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Show the code

Default, code

<Switch>Two-factor authentication</Switch>

On

Show the code

On, code

<Switch defaultSelected>Two-factor authentication</Switch>

With description

Show the code

With description, code

<Switch
  description="A summary every Monday morning."
  labelPosition="start"
  className="max-w-md"
>
  Weekly digest
</Switch>

Disabled

Show the code

Disabled, code

<Switch isDisabled defaultSelected>Two-factor authentication</Switch>

Mobile size

Show the code

Mobile size, code

<Switch size="lg" defaultSelected>Two-factor authentication</Switch>

Loading

Show the code

Loading, code

<Switch isLoading defaultSelected>Sync contacts</Switch>

Label hidden

Show the code

Label hidden, code

<Switch hideLabel defaultSelected>Weekly summary</Switch>

Invalid

Show the code

Invalid, code

<Switch
  isInvalid
  errorMessage="Could not turn on sync. Check your connection and try again."
  className="max-w-md"
>
  Sync contacts
</Switch>

Tokens

The 31 design tokens Switch reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 31 tokens
Tokens Switch reads
TokenValue nowCSS variable
color.bg.muted…--sd-color-bg-muted
color.border.subtle…--sd-color-border-subtle
color.text.default…--sd-color-text-default
color.text.disabled…--sd-color-text-disabled
field.error…--sd-field-error
field.error-icon…--sd-field-error-icon
field.hint…--sd-field-hint
input.border-invalid…--sd-input-border-invalid
motion.duration.fast…--sd-motion-duration-fast
motion.easing.standard…--sd-motion-easing-standard
radius.full…--sd-radius-full
size.control.md…--sd-size-control-md
size.icon.lg…--sd-size-icon-lg
size.icon.sm…--sd-size-icon-sm
spacing.gap.md…--sd-spacing-gap-md
spacing.gap.xs…--sd-spacing-gap-xs
switch.border…--sd-switch-border
switch.border-width…--sd-switch-border-width
switch.glyph-off…--sd-switch-glyph-off
switch.glyph-on…--sd-switch-glyph-on
switch.radius…--sd-switch-radius
switch.thumb-off…--sd-switch-thumb-off
switch.thumb-on…--sd-switch-thumb-on
switch.thumb-size…--sd-switch-thumb-size
switch.track-height…--sd-switch-track-height
switch.track-off…--sd-switch-track-off
switch.track-off-pressed…--sd-switch-track-off-pressed
switch.track-on…--sd-switch-track-on
switch.track-on-pressed…--sd-switch-track-on-pressed
switch.track-width…--sd-switch-track-width
target.min…--sd-target-min

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { Switch } from "@superduperui/react"

Props

Switch also takes the props of the React Aria component it’s built on.

Switch props
PropTypeWhat it does
childrenrequiredReactNodeVisible label (required).
descriptionstringOptional second line.
labelPosition'start' | 'end'Default 'end'Put the label before the track (settings rows) or after it (default).
size'default' | 'lg'Default 'default'default; lg (mobile): a 25% larger track and thumb. Both sit in a 44px row (2.5.5).
isLoadingbooleanDefault falseSaving the change: the thumb shows a spinner, aria-busy is set and presses are ignored until it ends.
isInvalidbooleanDefault falseThe setting could not be applied (for example a failed save): shows errorMessage with an icon.
errorMessagestringWhy the setting is invalid; linked to the switch by aria-describedby.
hideLabelbooleanDefault falseKeep the label (and description) as the accessible name but hide them visually, so the track hugs: for setting rows and grids where a visible title already names the switch. The hit area stays 44px; an error stays visible.

When to use it

Use it for

  • Settings that take effect at once (notifications, two-factor)

Use something else for

  • Choices submitted with a form: use Checkbox

Accessibility

Screen readers announce "Two-factor authentication, switch, off".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6, 2.3.3.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Apply the change immediately and confirm it if it is significant

This release’s test results

Test results for Switch in this release
axe-core (WCAG A, AA, AAA and best practice)180 runs across every story, theme, density and width: 0 violations
Rendered text contrast115 text runs: 0 below 7:1, lowest 8.43:1
Target size34 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)36 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 3 of 3, Firefox 3 of 3, WebKit 3 of 3

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

Switch keyboard steps
KeyWhat happens
TabTab reaches the switch (off)
SpaceSpace turns it on
SpaceSpace turns it off

In Figma

The Figma component is Switch, with Checked (False, True); State (Default, Hover, Pressed, Focus, Disabled); Label position (End, Start); Size (Default, Mobile); Label visibility (Visible, Hidden); Width (Fit, Full). The Figma library isn’t published yet.

Figma to code: Checked (False, True = defaultSelected); State (Default, Hover, Pressed, Focus, Disabled = isDisabled); Label position → labelPosition (End = "end", Start = "start"); Label → children; Description → description when Show description; Size → size (Default = "default", Mobile = "lg"); Invalid → isInvalid; Error → errorMessage when Invalid; Loading → isLoading; Label visibility → hideLabel (Visible = false, Hidden = true); Width (Fit, Full; preview only).