Skip to content

shadcn.io is an independent project built on shadcn/ui

Horizontal Radio Group for React

Option 1, Option 2 and Option 3 in a single row. Option 1 starts selected, and each label sits beside its radio.

Option 1, Option 2 and Option 3 sit on one line, each with a radio and a label. Option 1 starts selected.

Use a row for a short choice that should not take vertical space. Stack the options, or use a Select, when the labels get long. In React, Base UI does not wrap the row.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Radio Group anatomy: root, label, item control, indicator, item, item text

Usage

<RadioGroup
  className="flex w-fit flex-row flex-wrap gap-4"
  defaultValue="option-1"
>
  <Field className="w-fit" orientation="horizontal">
    <RadioGroupItem id="horizontal-option-1" value="option-1" />
    <FieldLabel htmlFor="horizontal-option-1">Option 1</FieldLabel>
  </Field>
  <Field className="w-fit" orientation="horizontal">
    <RadioGroupItem id="horizontal-option-2" value="option-2" />
    <FieldLabel htmlFor="horizontal-option-2">Option 2</FieldLabel>
  </Field>
  <Field className="w-fit" orientation="horizontal">
    <RadioGroupItem id="horizontal-option-3" value="option-3" />
    <FieldLabel htmlFor="horizontal-option-3">Option 3</FieldLabel>
  </Field>
</RadioGroup>

FAQ

How are the options placed in a row?

RadioGroup takes flex flex-row flex-wrap gap-4, which replaces its default grid. defaultValue is option-1.

How do I start on a different option?

Change defaultValue to option-2 or option-3, matching that item's value.

Why does the label text select the radio?

The text is the item's label, so clicking it checks that item. Each RadioGroupItem has an id, and FieldLabel points at it with htmlFor.

What if the labels get too long for one row?

flex-wrap moves the options that do not fit onto the next line. For more than four options, or long labels, a vertical group reads faster.

How do I control the selected value?

This demo uses defaultValue, so the group stores the choice. Pass value, and onValueChange receives the next string.

Do the arrow keys still move across a horizontal group?

Yes. Tab moves focus to the checked item, and the arrow keys move to the next or previous item and check it, in the order of the row.

API Reference

Radio Group

Sets defaultValue="option-1", id="horizontal-option-1", value="option-1", id="horizontal-option-2", value="option-2" and id="horizontal-option-3". The rest is on the Radio Group page.

Field

Sets orientation="horizontal", htmlFor="horizontal-option-1", htmlFor="horizontal-option-2" and htmlFor="horizontal-option-3". The rest is on the Field page.