Skip to content

Switch

Switch allows users to toggle a boolean selection.
Figma logo
  • SwitchGroup is a field element that wraps one or more instances of Switch with label, helper, and validation text.
Switch
  • Switch reflects a boolean state (enabled/disabled, on/off)
  • Switch has a more approachable UI that users may associate with an immediate response
Checkbox
  • A single Checkbox should be used when agreeing/acknowledging/accepting terms/policies, etc.
  • Typically associated with a form that must be submitted for changes to be saved/reflected
  • Checkbox is used when multiple items can be selected
  • Only used to change settings, not as a trigger
    • Use Button if you need to perform an action
Radio
  • Use Radio if you need to toggle between two non-binary options (e.g. CSV/PDF, %/$)
  • Typically associated with a form that must be submitted for changes to be saved/reflected
  • Radio is used when the options are mutually exclusive
  • Only used to change settings, not as a trigger
    • Use Button if you need to perform an action
  • A SwitchGroup can be used with one or more instances of Switch.
  • This example does not use SwitchGroup and instead implements validation manually.
  • This method can be quite laborious, so we generally recommend using SwitchGroup.

Disabled states should be used with caution.

It may sometimes be necessary to hide labels, but label text must still be made available for screen readers. This example uses visuallyHidden to visually hide the label.

React props
NameTypeDefaultDescription
children  RequiredReactNodeIndividual inputs related to the group.
disabled  booleanIf true, the elements in this group will be disabled.
helperText  ReactNodeAdditional descriptive information for the input.
invalid  booleanfalseIf true, the input will be shown in an invalid state.
label  RequiredReactNodeLabel for the associated input.
name  RequiredstringName of the input. Submitted with the form as part of a name/value pair.
optionalText  stringText used to indicate that a field is not required.
validationText  ReactNodeValidation message associated with the input.

The following testing snippet(s) offer suggestions for testing the component using React Testing Library with occasional help from Jest.

// BASIC TESTS
render(
<SwitchGroup
name="notifications"
label="Enable notifications?"
optionalText="(optional)"
helperText="How much would you like to hear from us?"
>
<Switch label="Alerts" value="alerts">
Alerts are like really really important things that we only tell you about when the world is
ending.
</Switch>
<Switch label="Newsletter" value="newsletter">
This is pretty much just everything else.
</Switch>
</SwitchGroup>,
);
const group = screen.getByRole('group', {
name: 'Enable notifications?', // Group label
});
// Group descriptions
expect(group).toHaveAccessibleDescription(expect.stringContaining('(optional)'));
expect(group).toHaveAccessibleDescription(
expect.stringContaining('How much would you like to hear from us?'),
);
const alertsSwitch = screen.getByLabelText('Alerts');
// Alternatively:
// const alertsSwitch = screen.getByRole('switch', {
// name: 'Alerts',
// });
// Switch description
expect(alertsSwitch).not.toBeChecked();
expect(alertsSwitch).toHaveAccessibleDescription(
'Alerts are like really really important things that we only tell you about when the world is ending.',
);
const newsletterSwitch = screen.getByLabelText('Newsletter');
// Switch description
expect(newsletterSwitch).not.toBeChecked();
expect(newsletterSwitch).toHaveAccessibleDescription('This is pretty much just everything else.');
// Checking
userEvent.click(alertsSwitch);
expect(alertsSwitch).toBeChecked();
// TESTING VALIDATION
render(
<SwitchGroup
name="notifications"
label="Enable notifications?"
invalid
validationText="At least one selection is required"
>
<Switch label="Alerts" value="alerts" />
<Switch label="Newsletter" value="newsletter" />
</SwitchGroup>,
);
const group = screen.getByRole('group', {
name: 'Enable notifications?', // Group label
});
expect(group).toHaveAccessibleDescription(
expect.stringContaining('At least one selection is required'),
);