Skip to Content

Radio

Radio buttons built on Base UI’s Radio and RadioGroup primitives. Includes a group wrapper for managing single-selection among multiple options.

Import

import { Radio } from 'chunks-ui'

Basic Usage

<Radio.Group defaultValue="option-a"> <Radio.Item value="option-a">Option A</Radio.Item> <Radio.Item value="option-b">Option B</Radio.Item> <Radio.Item value="option-c">Option C</Radio.Item> </Radio.Group>

Controlled

Radio.Group infers the type of its value from value or defaultValue, so a typed useState setter is an onValueChange:

function ControlledRadio() { const [value, setValue] = useState<'a' | 'b'>('a') return ( <Radio.Group value={value} onValueChange={setValue}> <Radio.Item value="a">Option A</Radio.Item> <Radio.Item value="b">Option B</Radio.Item> </Radio.Group> ) }

Disabled

Disable individual radio buttons or the entire group:

<Radio.Group disabled> <Radio.Item value="a">Disabled option</Radio.Item> </Radio.Group>

A disabled Radio.Root dims and shows a not-allowed cursor on its own too, outside Radio.Item and in a group that isn’t disabled. Inside a disabled Radio.Group or a disabled Radio.Item, the radio is dimmed once with them, not twice. Radio.Item dims its radio and its text together whichever disables the radio: its own disabled, its Radio.Group or a Field.Root around them.

<Radio.Group defaultValue="free" aria-label="Plan"> <Radio.Root value="free" aria-label="Free"> <Radio.Indicator /> </Radio.Root> <Radio.Root value="pro" aria-label="Pro" disabled> <Radio.Indicator /> </Radio.Root> </Radio.Group>

The Radio.Item dim is keyed on the radio’s data-disabled, so an override in className on Radio.Item is spelled with the same variant; a plain opacity-75 loses to it:

<Radio.Item value="pro" disabled className="has-[>[data-disabled]]:opacity-75">Pro</Radio.Item>

That holds for the item’s own disabled. In a disabled Radio.Group, or a group inside a disabled Field.Root, the group carries the dim and the item turns its own off, so override it there on Radio.Group with data-disabled:opacity-75:

<Radio.Group disabled className="data-disabled:opacity-75" aria-label="Plan"> <Radio.Item value="pro">Pro</Radio.Item> </Radio.Group>

Compound Parts

PartDescription
Radio.GroupWrapper that manages value state. Renders a vertical flex column by default.
Radio.ItemConvenience compound: label + radio + indicator in one element.
Radio.RootIndividual radio button. Renders a circular control.
Radio.IndicatorThe inner dot that appears when the radio is selected. Children you pass replace the dot; with a render element and no children, there is no dot, and the element may be a void element such as <img>. Your content scales and fades in and out as the dot does.

Radio.Group Props

All props are forwarded to the underlying Base UI RadioGroup.

Radio.Item Props

NameTypeDefault
classNamestring

Classes for the item’s <label>. A string only: the label has no Base UI state to pass to a function. Style the radio itself with Radio.Root.

childrenReactNode

Label text displayed next to the radio indicator.

All other props are forwarded to the underlying Base UI Radio.Root. className is the exception: it goes on the item’s <label>, and it takes a string only. To style the radio itself, build the item from Radio.Root and Radio.Indicator.

Radio.Root Props

All props are forwarded to the underlying Base UI Radio.Root.

Last updated on