Skip to content

Radio

Radio and RadioGroup enable a user to select one of multiple options.
Figma logo
  • RadioGroup is a field element that wraps Radios 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 basic RadioGroup implementation using Formik and Yup to require one selection.

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. These examples use visuallyHidden to visually hide the label.

React props
NameTypeDefaultDescription
children  RequiredReactNodeThe individual Radio elements that are part of the group.
disabled  booleanIf true, the elements in this group will be shown in their disabled state.
helperText  ReactNodeAdditional descriptive information for the radios.
invalid  booleanIf true, the radios will be shown in their invalid state.
label  RequiredstringLabel text associated with the input.
name  stringName 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.
React props
NameTypeDefaultDescription
component  ReactNodeComponent override for the input element
label  RequiredReactNodeContent for the associated label
value  RequiredstringThe data value of 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(
<RadioGroup
name="payment"
label="How would you prefer to be paid?"
optionalText="(optional)"
helperText="Don’t worry, you may change this at any time"
>
<Radio value="direct_deposit" label="Direct deposit">
Your money will be securely deposited each pay cycle into your account ending in 5555.
</Radio>
<Radio value="check" label="Check">
An old fashioned paper check will be sent via USPS to 555 Drury Lane, courtesy of the muffin
man.
</Radio>
</RadioGroup>,
);
const group = screen.getByRole('group', {
name: 'How would you prefer to be paid?', // Group label
});
// Group descriptions
expect(group).toHaveAccessibleDescription(expect.stringContaining('(optional)'));
expect(group).toHaveAccessibleDescription(
expect.stringContaining('Don’t worry, you may change this at any time'),
);
const directDepositRadio = screen.getByLabelText('Direct deposit');
// Alternatively:
// const directDepositRadio = screen.getByRole('radio', {
// name: 'Direct deposit',
// });
// Checkbox description
expect(directDepositRadio).not.toBeChecked();
expect(directDepositRadio).toHaveAccessibleDescription(
'Your money will be securely deposited each pay cycle into your account ending in 5555.',
);
const checkRadio = screen.getByLabelText('Check');
// Checkbox description
expect(checkRadio).not.toBeChecked();
expect(checkRadio).toHaveAccessibleDescription(
'An old fashioned paper check will be sent via USPS to 555 Drury Lane, courtesy of the muffin man.',
);
// Checking
userEvent.click(directDepositRadio);
expect(directDepositRadio).toBeChecked();
// TESTING VALIDATION
render(
<RadioGroup
name="payment"
label="How would you prefer to be paid?"
invalid
validationText="Payment type is required"
>
<Radio value="direct_deposit" label="Direct deposit" />
<Radio value="check" label="Check" />
</RadioGroup>,
);
const group = screen.getByRole('group', {
name: 'Enable notifications?', // Group label
});
expect(group).toHaveAccessibleDescription(expect.stringContaining('Payment type is required'));