Skip to contentSkip to navigationSkip to topbar
Paste assistant Assistant
Figma
Star

Radio Group

Version 13.1.1GithubStorybook

A Radio Group is a form element that lets users select a single choice from a list of at least two options.

Component preview theme
const NetworkRadioGroup = () => {
return (
<RadioGroup
name="uncontrolled-radio-group"
legend="Choose Network Access Profile"
helpText="Network Access Profile specifies what networks your SIM's would connect to and how you will be billed."
>
<Radio
id={useUID()}
value="lowest"
name="uncontrolled-radio-group"
>
Select lowest priced networks globally
</Radio>
<Radio
id={useUID()}
value="existing"
name="uncontrolled-radio-group"
>
Select existing network access profile
</Radio>
<Radio
id={useUID()}
value="new"
name="uncontrolled-radio-group"
defaultChecked
>
Create new network access profile
</Radio>
</RadioGroup>
);
};
render(
<NetworkRadioGroup />
)

Guidelines

Guidelines page anchor

A radio group is used for selecting a single choice from a list of at least two options. The user can only select one radio option at a time.

About Radio Group

About Radio Group page anchor

Radio groups are used when a user must make a single choice from two or more options. The user can only choose one radio selection at a time.

Radio groups should:

  • Include at least two or more options.
  • Allow users to select only one option.
  • Include at most 6 options. If there's a chance the Radio might later expand to include more than 6 options, use a Select instead.
  • List options in an order that is contextual.

Best practices

Best practices page anchor
  • Avoid nesting radio buttons within other radio buttons.
  • If an option is strongly recommended, add "(Recommended)" to the label. Be sure to add it to the label, not the help text.
  • Use the same name attribute on all radio buttons in the group. This ensures that if there is more than one group in the form, each one stays associated with its own group
  • If a radio group is “Optional”, users won't be able to unselect a selected radio. If you need to give users a way to unselect, consider adding a clear button or using another type of form field.
  • A radio group must have a visible label that is in close proximity to the control.
  • HTML radio groups don't natively support the required attribute. If a radio must be checked, display a required indicator.
  • Display error messages in an inline error below the radio group that clearly describes the error.
  • Radio groups act as a single tab stop. When focused on a radio, use the arrow keys to navigate to the other radios.

Controlled vs. uncontrolled RadioGroup

Controlled vs. uncontrolled RadioGroup page anchor

The radio and radio group components can either be controlled, meaning there is an external state that determines if it is checked, or uncontrolled, meaning the component manages its own state.

To make an uncontrolled radio group, do not pass the value or onChange props. To check the radio by default, use the defaultChecked prop.

Component preview theme
const NetworkRadioGroup = () => {
return (
<RadioGroup
name="uncontrolled-radio-group"
legend="Choose Network Access Profile"
helpText="Network Access Profile specifies what networks your SIM's would connect to and how you will be billed."
>
<Radio
id={useUID()}
value="lowest"
name="uncontrolled-radio-group"
>
Select lowest priced networks globally
</Radio>
<Radio
id={useUID()}
value="existing"
name="uncontrolled-radio-group"
>
Select existing network access profile
</Radio>
<Radio
id={useUID()}
value="new"
name="uncontrolled-radio-group"
defaultChecked
>
Create new network access profile
</Radio>
</RadioGroup>
);
};
render(
<NetworkRadioGroup />
)

To make a controlled radio group, pass the value and onChange props.

Component preview theme
const NetworkRadioGroup = () => {
const [value, setValue] = React.useState('lowest');
return (
<RadioGroup
name="controlled-radio-group"
legend="Choose Network Access Profile"
helpText="Network Access Profile specifies what networks your SIM's would connect to and how you will be billed."
value={value}
onChange={newValue => {
setValue(newValue);
}}
>
<Radio
id={useUID()}
value="lowest"
name="controlled-radio-group"
>
Select lowest priced networks globally
</Radio>
<Radio
id={useUID()}
value="existing"
name="controlled-radio-group"
>
Select existing network access profile
</Radio>
<Radio
id={useUID()}
value="new"
name="controlled-radio-group"
>
Create new network access profile
</Radio>
</RadioGroup>
);
};
render(
<NetworkRadioGroup />
)

Vertically-stacked Radio Group

Vertically-stacked Radio Group page anchor

The vertically-stacked Radio Group is the easiest for users to scan, in particular if labels are more than 3 words. Use the vertical stack if the list wraps to two lines.

Component preview theme
const CampaignRadioGroup = () => {
const [value, setValue] = React.useState();
return (
<RadioGroup
name="campaign"
value={value}
legend="When should your campaign run?"
helpText="We recommend at least two weeks."
onChange={newValue => {
setValue(newValue);
}}
>
<Radio
id="ongoing"
value="ongoing"
name="campaign"
>
Run my ads as ongoing
</Radio>
<Radio
id="enddate"
value="enddate"
name="campaign"
>
Set a start and end date
</Radio>
</RadioGroup>
);
};
render(
<CampaignRadioGroup />
)

By default, the Radio Group component doesn't apply a pre-selected value.

Apply a pre-selected value only if:

  • The default value is a safe, secure, and reversible option, and you're willing to collect biased data. Defaulting to a value biases or alters the experience so that your data may be skewed.
  • The user doesn't need to make an explicit choice for safety, security, or legal reasons.

For additional guidance on whether to use a default selection, check out this article from the Nielsen Norman Group(link takes you to an external page).

If you do apply a pre-selected value, make the first option the default option.

Component preview theme
const AccountRadioGroup = () => {
const [value, setValue] = React.useState('accountSid');
return (
<RadioGroup
name="account"
value={value}
legend="How should we identify your account?"
onChange={newValue => {
setValue(newValue);
}}
>
<Radio
id="accountSid"
value="accountSid"
name="account"
>
Account SID
</Radio>
<Radio
id="messageSid"
value="messageSid"
name="account"
>
Message SID
</Radio>
</RadioGroup>
);
};
render(
<AccountRadioGroup />
)

Use the helpText prop, rather than the Help Text component, to provide information that helps users understand the radio options. Avoid using help text to tell users how to use the component (for example, "Select an option.").

Help text appears after the group label but before the first radio option.

Component preview theme
const NetworkRadioGroup = () => {
const [value, setValue] = React.useState('lowest');
return (
<RadioGroup
name="network"
value={value}
legend="Choose Network Access Profile"
helpText="Network Access Profile specifies what networks your SIM's would connect to and how you will be billed."
onChange={newValue => {
setValue(newValue);
}}
>
<Radio
id="lowest"
value="lowest"
name="network"
>
Select lowest priced networks globally
</Radio>
<Radio
id="existing"
value="existing"
name="network"
>
Select existing network access profile
</Radio>
<Radio
id="new"
value="new"
name="network"
>
Create new network access profile
</Radio>
</RadioGroup>
);
};
render(
<NetworkRadioGroup />
)

Use the required dot to denote a required field. The required dot appears before the fieldset legend.

Component preview theme
const SslRadioGroup = () => {
const [value, setValue] = React.useState('on');
return (
<RadioGroup
name="ssl"
value={value}
legend="SSL Certificate Validation"
helpText="Determines if certificate validation is performed on all Twilio originated requests."
onChange={newValue => {
setValue(newValue);
}}
required
>
<Radio
id="on"
value="on"
name="ssl"
>
Validation on
</Radio>
<Radio
id="off"
value="off"
name="ssl"
>
Validation off
</Radio>
</RadioGroup>
);
};
render(
<SslRadioGroup />
)

Use horizontal alignment sparingly, as the options are harder to scan. Use labels that are 3 words or less, or less than 20 characters.

Place options next to each other with appropriate spacing. Avoid letting options run onto two lines.

Component preview theme
const PaymentMethodRadioGroup = () => {
const [value, setValue] = React.useState('credit');
return (
<RadioGroup
name="payment"
value={value}
legend="Select payment method"
onChange={newValue => {
setValue(newValue);
}}
orientation="horizontal"
>
<Radio
id="credit"
value="credit"
name="payment"
>
Credit Card
</Radio>
<Radio
id="paypal"
value="paypal"
name="payment"
>
PayPal
</Radio>
</RadioGroup>
);
};
render(
<PaymentMethodRadioGroup />
)

To internationalize a radio group, pass different text as children to the radios. The only exception to this is the required dot in the legend of a required radio group. To change the required dot's text, use the i18nRequiredLabel prop.

Component preview theme
const PaymentMethodRadioGroup = () => {
const [value, setValue] = React.useState('credit');
return (
<RadioGroup
name="payment"
value={value}
legend="Choisissez votre mode de paiement"
onChange={newValue => {
setValue(newValue);
}}
required
i18nRequiredLabel="(requis)"
>
<Radio
id="credit"
value="credit"
name="payment"
>
Carte de crédit
</Radio>
<Radio
id="paypal"
value="paypal"
name="payment"
>
PayPal
</Radio>
</RadioGroup>
);
};
render(
<PaymentMethodRadioGroup />
)
Component preview theme
<>
<Radio id="option" value="option" name="option" disabled>
Option 1
</Radio>
</>
Component preview theme
<>
<Radio id="option" value="option" name="option" checked disabled>
Option 2
</Radio>
</>
Component preview theme
const DisabledRadio = () => {
const [value, setValue] = React.useState('disabled_automation');
return (
<RadioGroup
name="disabled_exit"
value={value}
legend="Exit Criteria"
onChange={newValue => {
setValue(newValue);
}}
disabled
>
<Radio
id="disabled_automation"
value="disabled_automation"
name="disabled_exit"
>
Contact have received all emails in the automation.
</Radio>
<Radio
id="disabled_entry"
value="disabled_entry"
name="disabled_exit"
>
Contacts no longer meet entry criteria
</Radio>
</RadioGroup>
);
};
render(
<DisabledRadio />
)

If the selected items don't pass the group validation requirements, use Help Text to show an inline error message below the group.

For required field errors, consider the following formats depending on the use case:

SituationRecommended phrasing
When the option being selected is not a nounSelect an option.
When the option to be selected is a nounSelect a [noun in group label].

For additional guidance on how to compose error messages, refer to the error state pattern.

Component preview theme
const CriteriaRadioGroup = () => {
const [value, setValue] = React.useState();
return (
<RadioGroup
name="exit"
value={value}
legend="Exit Criteria"
errorText="Select an exit criteria."
onChange={newValue => {
setValue(newValue);
}}
>
<Radio
id="automation"
value="automation"
name="exit"
>
Contact have received all emails in the automation.
</Radio>
<Radio
id="entry"
value="entry"
name="exit"
>
Contacts no longer meet entry criteria
</Radio>
</RadioGroup>
);
};
render(
<CriteriaRadioGroup />
)
Component preview theme
<>
<Radio id="criteria" value="criteria" name="criteria" checked hasError>
Contacts no longer meet entry criteria
</Radio>
</>

Start all options with a capital letter.

Avoid using periods with radio option text, even if it's a sentence.

If using Help Text for radio options, include it for each option.

Validate the group on form submission. Don't validate each item in the group, treat validation on the group as a whole.