JM Family Design System

Toggle

Toggles turn settings on or off. Use them when the change is immediate, reversible, and clearly understood from the label.

Guidance for adoption

Start here before choosing examples or props. These notes explain where Toggle helps, where another pattern is better, and what should stay true in product work.

When to use

  • Immediate settings
  • Feature on/off controls
  • Preference switches

When not to use

  • Submitting form values later
  • High-risk changes without confirmation
  • Multiple selection

Accessibility expectations

  • Use switch semantics when the control changes a setting.
  • Expose checked state programmatically.
  • Keep visible label close to the control.

Content guidance

  • Write the label as the setting name, such as "Email notifications", not as a command like "Enable notifications".
  • Use helper text to explain what changes when the setting is on or off.
  • Make risky or costly setting changes explicit before users flip the switch.
  • If an async save fails, show clear recovery copy near the setting instead of leaving the state ambiguous.

Implementation notes

  • Drive checked from consumer state; the component has no internal state or defaultChecked mode.
  • Use onClick to update state and pass the next checked value back into the component.
  • For async changes, compose pending, failure, and rollback behavior outside the component.
  • Use Checkbox when a value is collected and submitted later as part of a form.

Import

import { Toggle } from '@/components/ui/Toggle';

Renders a button[role=switch] with label and helper text wired in. Pair with state in the consumer.

States

Toggle states should communicate a setting clearly. Do not animate form layout or move labels; only the thumb position and tokenized colors should change.

Updates will not be sent for this request.

Off

The setting is available and currently disabled.

Updates will be sent for this request.

On

The setting is enabled and should take effect immediately.

Keyboard users can change this setting with Space.

Focused

Focus appears on the active switch without moving the control.

Managed by administrator permissions.

Disabled

The setting cannot be changed in the current state.

Anatomy

Toggles need a label that names the setting, plus programmatic switch semantics that expose whether the setting is on or off.

Inactive vendors appear in search results.
  1. Switch track
  2. Switch thumb
  3. Visible label
  4. Current checked state
  5. Optional helper text
  6. Focus and disabled state

Props

The component accepts every native HTMLButtonElement attribute on top of the design system props below.

PropTypeDefaultDescription
labelReactNodeVisible label describing the setting. Required for accessibility.
helperReactNodeSecondary text below the label. Auto-wired to aria-describedby on the switch.
checkedbooleanfalseCurrent on/off state. Reflected as aria-checked on the switch button.

Usage rules

Use for immediate settings

A toggle should apply a setting right away or clearly indicate that the setting has changed.

Do not use for deferred form choices

If the value is only saved after a form submit, use Checkbox or another form control instead.

Write labels so the on state is clear

Use labels like "Email notifications" or "Show inactive vendors" so users understand what changes when it is on.

Do not hide risk behind a switch

If turning a setting on has cost, security, or destructive impact, add confirmation or use a safer pattern.

Known limitations

What Toggle does not do yet, and what consumers need to compose themselves.

  • Visually controlled only. The component has no internal state and no defaultChecked support, so consumers must wire onClick to flip state and re-pass checked.
  • No error or loading state. Settings that toggle asynchronously cannot show a pending or failed transition through the component.

Agent guidance

Agents should use toggles only for immediate settings. For form values collected with a submit button, agents should choose Checkbox instead.

Generation rules

  • Use toggles for immediate settings, not deferred form choices.
  • Write labels so the on state is unambiguous.
  • Confirm destructive or costly settings before applying them.
  • Drive the checked prop from controlled state and flip it inside the onClick handler. The component has no internal state and no defaultChecked, so an uncontrolled toggle will not change visually.
  • For async settings, optimistically flip checked, then revert and surface an Alert if the save fails. There is no loading or error state on Toggle, so the failure feedback must live outside the component.
  • Use a Checkbox instead when the value is part of a form the user must submit. Toggles imply the change has already taken effect.
  • Label the toggle next to the control with a noun phrase such as "Email notifications", not a verb phrase such as "Enable notifications". The on/off state, not the label, expresses the action.

Baseline example

import { Toggle } from '@/components/ui/Toggle';

<Toggle
  label="Email notifications"
  helper="Updates will be sent for this request."
  checked={true}
  onClick={() => setEnabled((v) => !v)}
/>
If a setting has irreversible consequences, agents should add confirmation or propose a safer flow instead of using a bare toggle.

Decision standard

Toggle means immediate setting. Checkbox means independent form choice. Radio means one answer from a visible set. Select means compact single choice.