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  Required
ReactNode
-The individual Radio elements that are part of the group.
disabled  
boolean
-If true, the elements in this group will be shown in their disabled state.
helperText  
ReactNode
-Additional descriptive information for the radios.
invalid  
boolean
-If true, the radios will be shown in their invalid state.
legend  Required
string
-Label text associated with the group.
name  
string
-Name of the input. Submitted with the form as part of a name/value pair.
optionalText  
string
-Text used to indicate that a field is not required.
validationText  
ReactNode
-Validation message associated with the input.
React props
NameTypeDefaultDescription
component  
ReactNode
-Component override for the input element
label  Required
ReactNode
-Content for the associated label
value  Required
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(
<RadioGroup
name="payment"
legend="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"
legend="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'));