Skip to content

Radio Group

Choose one option from a visible list or a set of cards.

import { RadioGroup, RadioGroupItem } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use Radio Group when people need to choose one option and see the full list. Use a Select for longer lists, Checkboxes for choices that can combine, or a Toggle Group for view settings.

Each RadioGroupItem sits in its own Field with a FieldLabel. Name the group with a FieldSet and FieldLegend, or with aria-label on the RadioGroup.

import { Field, FieldLabel, FieldLegend, FieldSet, RadioGroup, RadioGroupItem } from '@youj/react'

export function Density() {
  return (
    <FieldSet>
      <FieldLegend variant="label">Density</FieldLegend>
      <RadioGroup defaultValue="comfortable" name="density">
        <Field orientation="horizontal">
          <RadioGroupItem value="comfortable" />
          <FieldLabel>Comfortable</FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <RadioGroupItem value="compact" />
          <FieldLabel>Compact</FieldLabel>
        </Field>
      </RadioGroup>
    </FieldSet>
  )
}

defaultValue makes it uncontrolled. Pass value and onValueChange to own the choice, and name to submit it with a form.

Reference

PropsThe group takes Base UI's value, defaultValue, onValueChange, name,…

Props

RadioGroup adds no props of its own. They pass through to RadioGroupPrimitive.Props.

RadioGroupItem

RadioGroupItem adds no props of its own. They pass through to RadioPrimitive.Root.Props.

The group takes Base UI's value, defaultValue, onValueChange, name, disabled, readOnly and required. Each item takes a value, plus its own disabled.

MotionDot in, dot out, ring fill… · reduced motion

Motion

Motion tokens
MomentTokens
Dot inthe chosen dot grows from zero
duration.fastease.enter

140ms · cubic-bezier(0.16, 1, 0.3, 1)

140mscubic-bezier(0.16, 1, 0.3, 1)
Dot outthe previous dot shrinks away at the same time
duration.fastease.exit

140ms · cubic-bezier(0.4, 0, 1, 1)

140mscubic-bezier(0.4, 0, 1, 1)
Ring fillbackground and border color
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)
Pressthe ring squeezes to 90%
duration.instantease.standard

80ms · cubic-bezier(0.2, 0, 0, 1)

80mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

The dot appears and disappears without scaling, and the ring doesn't squeeze on press.

The dot is a CSS transition, so a choice that changes mid-way picks up from the dot's current scale.

Reduced motion

The dot switches on and off without growing, and the press doesn't squeeze. The chosen option still shows the filled ring and the dot, so the choice reads the same.

AccessibilityKeyboard, ARIA, focus

Accessibility

  • The group is one tab stop. Tab lands on the chosen option, the arrow keys move the choice and wrap at the ends, and Space selects the focused option.
  • The group is a radiogroup, named by its FieldLegend or aria-label. Each item is a radio, named by its FieldLabel.
  • required on the group or its Field makes a choice mandatory before the form submits.
  • Each 16px radio has a 24px hit area, and 40px on touch screens.