Radio Buttons

Mobile Support: Full
Jump to Props

Allows users to make a single selection from a list of options.

Import

import { RadioButtons } from "@vitality-ds/components";

Usage

Radio buttons are a type of selectable input that allow users to communicate exactly one item from a list of options. If more than one item can be selected, use a Checkbox instead. A radio button will always appear as part of a group of radio buttons with mutually exclusive options. For example morning, afternoon, evening or night. As such, when one item is selected, all other items are de-selected. Radio buttons are best used when there are 5 or less options, if your use case needs more than 5 options, a Select would be a better choice.

Building a form? Check out the FormField component.

<RadioButtons
  onChange={(newValue) => console.log(newValue)}
  name="timeOfDay"
  options={[
    { label: "Morning", id: "morning", value: "morning" },
    { label: "Afternoon", id: "afternoon", value: "afternoon" },
    { label: "Evening", id: "evening", value: "evening" },
    { label: "Night", id: "night", value: "night" },
  ]}
/>

Data structure

To pass the list of options to RadioButtons, structure the data as an array of objects. Each object represents an individual radio button and needs a label, id and value.

const options = [
  {
    label: "Label that user reads",
    id: "uniqueIdentifier",
    value: "valueOfThisOption",
  },
];

Label

The label is what the user reads and can click on, so it should represent the value of the options in a readable way, utilising correct grammar.

Aim For
  • Labels that use correct sentence casing
  • Short, concise labels
  • Labels that accurately represent the data value of the option
Avoid
  • Incorrect Capitlisation of Random Words
  • Unnecessarily long titles that are difficult to read

ID

The id is a uniquely identifying string that pairs the individual radio button's label to its input. No two options would have the same id.

Value

RadioButtons are designed to function as a controlled component. While using it as a controlled component is not strictly required, it is necessary if you need to manage the selected value programmatically—such as setting a default value or updating the selection in response to external changes. Without this, the component's state cannot be dynamically manipulated.

The value should be a string matching a value provided in the options array.

() => {
  const [value, setValue] = React.useState("morning");

  const options = [
    { label: "Morning", id: "morning2", value: "morning" },
    { label: "Afternoon", id: "afternoon2", value: "afternoon" },
    { label: "Evening", id: "evening2", value: "evening", disabled: true },
    { label: "Night", id: "night2", value: "night", disabled: true },
  ];

  return (
    <RadioButtons
      onChange={(newValue) => setValue(newValue)}
      value={value}
      name="timeOfDay"
      options={options}
    />
  );
};

Disable an option

We can disable an option by assigning disabled: true. The user cannot engage with a disabled option.

() => {
  const options = [
    { label: "Morning", id: "morning2", value: "morning" },
    { label: "Afternoon", id: "afternoon2", value: "afternoon" },
    { label: "Evening", id: "evening2", value: "evening", disabled: true },
    { label: "Night", id: "night2", value: "night", disabled: true },
  ];

  return (
    <RadioButtons
      onChange={(newValue) => console.log(newValue)}
      name="timeOfDay"
      options={options}
    />
  );
};

Handling change events

The onChange prop is the function that handles change events on radio buttons, which is when any of the items is selected. It's only called when the value changes (not when an already selected item is clicked again) as radio buttons cannot be de-selected. onChange returns the string value of the option that was selected.

() => {
  const [formData, setFormData] = React.useState({});

  return (
    <Stack>
      <RadioButtons
        onChange={(newValue) =>
          setFormData({ ...formData, timeOfDay: newValue })
        }
        name="timeOfDay"
        options={[
          { label: "Morning", id: "morning3", value: "morning" },
          {
            label: "Afternoon",
            id: "afternoon3",
            value: "afternoon",
          },
          { label: "Evening", id: "evening3", value: "evening" },
          { label: "Night", id: "night3", value: "night" },
        ]}
      />
      <Typography>
        {formData.timeOfDay && `You have selected ${formData.timeOfDay}`}
      </Typography>
    </Stack>
  );
};

Radio buttons layout

There may be times where the list should be horizontally displayed, for example the interface is lacking in vertical space. In this case the direction prop can be set to horizontal. The default value of vertical is the preferred design pattern for radio buttons because the labels are easier to read and interact with, and the group is more consistently displayed, so be mindful to only switch directions when really necessary.

<Stack direction="horizontal" spacing="xxl" justify="between" align="center">
  <RadioButtons
    onChange={(newValue) => console.log(newValue)}
    direction="vertical" // default value that does not need to be passed
    name="timeOfDay"
    options={[
      { label: "Morning", id: "morning5", value: "morning" },
      { label: "Afternoon", id: "afternoon5", value: "afternoon" },
      { label: "Evening", id: "evening5", value: "evening" },
      { label: "Night", id: "night5", value: "night" },
    ]}
  />
  <RadioButtons
    onChange={(newValue) => console.log(newValue)}
    direction="horizontal"
    name="timeOfDay"
    options={[
      { label: "Morning", id: "morning6", value: "morning" },
      { label: "Afternoon", id: "afternoon6", value: "afternoon" },
      { label: "Evening", id: "evening6", value: "evening" },
      { label: "Night", id: "night6", value: "night" },
    ]}
  />
</Stack>

Name

The name prop should semantically reflect what the group of radio buttons are referring to. When used within a form, the name is submitted as part of a name/value pair with the selected item's value.

Select an option and click submit to observe how this data is handled in the url in a traditional form manner. For example if "Evening" is selected, the url would be appended with time_of_day=evening.

<form method="GET" action="">
  <RadioButtons
    onChange={(newValue) => console.log(newValue)}
    name="timeOfDay"
    options={[
      { label: "Morning", id: "morning7", value: "morning" },
      { label: "Afternoon", id: "afternoon7", value: "afternoon" },
      { label: "Evening", id: "evening7", value: "evening" },
      { label: "Night", id: "night7", value: "night" },
    ]}
  />
  <br />
  <Button appearance="primary" type="submit">
    Submit
  </Button>
</form>

Ref

Refs can be forwarded to retrieve the HTML element of an individial radio button. They can be passed to both the parent element housing all buttons, or at the individual button level as part of the options object. In this case it will return the div that houses the individual button and its corresponding label so you have access to the 'entire' button. To access only the radio input or label, call .children on the ref.

() => {
  const radioButtonsRef = React.createRef();
  const morningRef = React.createRef();

  React.useEffect(() => {
    console.log("Radio buttons:", radioButtonsRef.current);
    console.log("Morning button:", morningRef.current);
    console.log("Morning button's children:", morningRef.current.children);
  }, [morningRef]);

  return (
    <RadioButtons
      ref={radioButtonsRef}
      onChange={() => {}}
      name="timeOfDay"
      options={[
        { label: "Morning", id: "morning8", value: "morning", ref: morningRef },
        {
          label: "Afternoon",
          id: "afternoon8",
          value: "afternoon",
        },
        { label: "Evening", id: "evening8", value: "evening" },
        { label: "Night", id: "night8", value: "night" },
      ]}
    />
  );
};

Figma Library

Figma.logo

Props

Radio Buttons

direction

Description

Determine whether the radio list stacks vertically or horizontally.

Type

"horizontal" | "vertical"

Default Value

vertical

name

Description

The name of the group of radio buttons. Submitted with its owning form as part of a name/value pair.

Type

string

onChangeRequired

Description

The callback function to handle change events, i.e. the event triggered when a user clicks on a radio item to change the value.

Type

(newValue: string) => void

optionsRequired

Description

An array of objects that determine the individual radio buttons. See Radio Button Props for a full list of valid properties.

Type

RadioButton[]

value

Description

Determines which value will be pre-populated with existing data on form load.

Type

string

Radio Button

disabled

Description

Determines whether this item can be used. If disabled: true the option will still appear in the radio list but be greyed out and not selectable.

Type

boolean

Default Value

false

idRequired

Description

Used to distinguish this radio item from other radio items in the group. Does not change label or value. Must be unique.

Type

string

labelRequired

Description

The radio item label and text that displays next to the radio button.

Type

string

valueRequired

Description

The data value of the radio item.

Type

string

© 2025