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
| Part | Description |
|---|---|
Radio.Group | Wrapper that manages value state. Renders a vertical flex column by default. |
Radio.Item | Convenience compound: label + radio + indicator in one element. |
Radio.Root | Individual radio button. Renders a circular control. |
Radio.Indicator | The 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
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.