docs / core / radio

Radio

one choice from a visible set of options. use it when every option should be seen at once; a long list wants a select.

intensity · recedesrsc · client

provenance

authored in usva

layer

core / primitives

intensity

recedes · safe anywhere, including dense surfaces

composition

settings forms, plan pickers, anywhere 2 to 5 options fit on screenorientation horizontal for short, label-only optionsnot for more than a handful of options. that is a selectdescriptions on horizontal groups, the indent only works stacked

a11y

radiogroup with aria-orientation · each radio reflects aria-checked and aria-disabled · label and description bind through Fieldjest-axe

dependencies

@base-ui/react · class-variance-authority
live demo · try it out

Good for trying things out.

For growing teams.

Advanced controls and support.

customize
orientationstacked or inline
sizecontrol diameter
descriptionshelper text under each label
disableLastdim and block the last option
usagecopy
import { Radio, RadioGroup } from "@usva-ui/react/primitives/radio";

<RadioGroup name="plan" defaultValue="free">
  <Radio value="free" label="Free" description="Good for trying things out." />
  <Radio value="pro" label="Pro" description="For growing teams." />
  <Radio value="enterprise" label="Enterprise" description="Advanced controls and support." disabled />
</RadioGroup>

RadioGroup

proptypedefaultnotes
valueValuecontrolled selected value.
defaultValueValueinitial selected value when uncontrolled.
onValueChange(value: Value, eventDetails) => voidfires when the selected value changes.
namestringidentifies the group in form submissions.
orientation"horizontal" | "vertical""vertical"layout direction, announced to assistive tech.

Radio

proptypedefaultnotes
valueValuethe value this radio represents.
labelReactNodethe field label, clickable and tied to the control.
descriptionReactNodehelper text below, indented to line up under the label.
disabledbooleanfalsedims to 50% and blocks selection.
size"sm" | "md""md"control size. the hit area extends well past both.

get it

bun add @usva-ui/reactcopy
usagecopy
import { Radio, RadioGroup } from "@usva-ui/react/primitives/radio";

<RadioGroup name="plan" defaultValue="free">
  <Radio value="free" label="Free" description="Good for trying things out." />
  <Radio value="pro" label="Pro" description="For growing teams." />
</RadioGroup>