Inputs/Switch

Switch

A control that allows the user to toggle between on and off.

Themed

When to Use

Use Switch when you need to:

  • Toggle a setting that takes effect immediately (e.g., Wi-Fi, Dark Mode)
  • Control a binary on/off state without requiring form submission
  • Build settings panels with independent toggleable options
  • Represent a real-world physical switch metaphor (enable/disable)

When Not to Use

  • Selections that require a submit action to apply - use Checkbox
  • Choosing between two or more distinct options - use Radio Group
  • Binary pressed/unpressed button state - use Toggle
  • Multi-select lists or forms with batch submission - use Checkbox

Default

A simple switch paired with a label. Always associate a Switch with a Label for accessibility.

Disabled

Disabled switches in both off and on states. Opacity is reduced to indicate non-interactive state.

With Description

Switches with labels and descriptive helper text, ideal for settings panels.

Receive notifications about updates.

Receive emails about new products.

Controlled

Controlled switch with external state management using checked and onCheckedChange.

Form Example

Multiple switches in a settings form layout with a submit action.

Email Preferences

UX & Design Guidelines

Immediate Feedback

Switches should apply their effect immediately without requiring a separate save action. The checked state uses bg-primary to clearly indicate the "on" position, while the unchecked state uses bg-input for a subtle inactive appearance. If the action requires confirmation, consider using a Checkbox with a submit button instead.

Labeling & Description

Always pair a Switch with a visible <Label> that clearly describes what the switch controls. Use positive, affirmative language (e.g., "Enable notifications" rather than "Disable notifications"). For complex settings, add a secondary description below the label using text-muted-foreground.

Layout & Spacing

Place the switch to the right of its label for settings panels using justify-between. For simple inline usage, place the switch to the left with space-x-2. When stacking multiple switches, use gap-4 for clear separation between items.

Color & Contrast

The switch thumb uses bg-background against the track color for clear contrast in both states. In dark mode, the unchecked track uses bg-input/80 and the thumb shifts to bg-foreground for visibility. Disabled states reduce opacity to 50% while maintaining readability.

Accessibility

Keyboard Navigation

  • Tab — Move focus to/from the switch
  • Space — Toggle the switch between on and off
  • Enter is not used — switches respond only to Space per WAI-ARIA spec

Screen Reader Support

  • Uses role="switch" — screen readers announce it as a switch, not a checkbox
  • State is announced as "on" or "off" via aria-checked
  • Always pair with a <Label> using matching id and htmlFor so the label is announced
  • If no visible label, provide aria-label directly on the Switch

Focus Management

Visible focus ring with 3px width using focus-visible:ring-[3px] and focus-visible:ring-ring/50. The border shifts to focus-visible:border-ring when focused. Focus states meet WCAG 2.1 Level AA requirements.

Touch Targets

The switch track is 32px wide and 18px tall. When paired with a <Label>, clicking the label also toggles the switch, effectively enlarging the interactive area to meet minimum touch target recommendations (44x44px).

ARIA Attributes

{/* Always pair with a Label */}
<div className="flex items-center space-x-2">
  <Switch id="wifi" />
  <Label htmlFor="wifi">Wi-Fi</Label>
</div>

{/* Using aria-label when no visible label */}
<Switch aria-label="Enable dark mode" />

{/* With aria-describedby for additional context */}
<div>
  <div className="flex items-center space-x-2">
    <Switch id="analytics" aria-describedby="analytics-desc" />
    <Label htmlFor="analytics">Analytics</Label>
  </div>
  <p id="analytics-desc" className="text-sm text-muted-foreground">
    Allow us to collect anonymous usage data.
  </p>
</div>

API Reference

The Switch component accepts the following props in addition to standard button attributes.

PropTypeDefaultDescription
checkedbooleanThe controlled checked state of the switch.
defaultCheckedbooleanfalseThe default checked state when initially rendered (uncontrolled).
onCheckedChange(checked: boolean) => voidEvent handler called when the checked state changes.
disabledbooleanfalseWhen true, prevents user interaction and applies disabled styles.
requiredbooleanfalseWhen true, indicates the switch must be checked for form submission.
namestringThe name of the switch for form submission.
valuestring"on"The value of the switch for form submission.
classNamestringAdditional CSS classes to apply to the switch.