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 thevisuallyHideLabel prop to visually hide the label.

React props
NameTypeDefaultDescription
children  Required
ReactNode
-Individual inputs related to the group.
disabled  
boolean
-If true, the elements in this group will be disabled.
helperText  
ReactNode
-Additional descriptive information for the input.
invalid  
boolean
falseIf true, the input will be shown in an invalid state.
legend  Required
string
-Label text associated with the group.
name  Required
string
-Name of the input. Submitted with the form as part of a name/value pair.
optional  
boolean
-Used to indicate the field is optional
validationText  
ReactNode
-Validation message associated with the input.
React props
NameTypeDefaultDescription
children  
ReactNode
-Content will be treated as helper text.
component  
ReactNode
-Component override for the <input> element.
label  Required
string
-Label text associated with the input.
value  
string
-The data value of the input.

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

// BASIC TESTS
render(
<SwitchGroup
name="notifications"
legend="Enable notifications?"
helperText="How much would you like to hear from us?"
optional
>
<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"
legend="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'),
);