Radio
A control for choosing exactly one option from a set.
Installation
bash
npx @smicolon/cli add radioRun init once per project before adding components. See Installation.
Preview
Variants
The layout variant wraps the control and its text in a bordered card, so the whole card becomes the target. Use it when the options carry a description; use the default when they are single words in a tight list.
Sizes
States
Hover and focus are real CSS states rather than props — hover an option, or tab to it, to see them. Selection is carried by the dot alone; the card chrome does not change.
Accessibility
- Renders a native
<input type="radio">, so arrow-key navigation and form submission work without extra code. - Options sharing a
nameform one group, and only one can be selected. descriptionis linked witharia-describedby; the control graphic is hidden from assistive technology.- Without a
labelordescription, pass anaria-label. - Direction is inherited from
dir, never a prop, so the control can never disagree with the page.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "layout" | "default" | A plain control or a bordered card. |
size | "sm" | "md" | "lg" | "md" | Control size. |
checked | boolean | — | Selected state, with onChange. |
disabled | boolean | false | Disables the option and dims it. |
label | string | — | Label text. |
description | string | — | Secondary line below the label. |
name | string | — | Groups radios into one set. |
value | string | — | Value submitted with the form. |
onChange | (event) => void | — | Called when the option is picked. |
className | string | — | Extra classes for the component. |
Usage
tsx
import { Radio } from "@/components/ui/radio"
// A group — options share a name
<Radio name="plan" value="standard" label="Standard" />
<Radio name="plan" value="express" label="Express" />
// With a description
<Radio
name="plan"
value="courier"
label="Same-day courier"
description="Arrives before 6pm"
/>
// Bordered card layout
<Radio variant="layout" name="plan" value="express" label="Express" />
// Controlled
<Radio
name="plan"
value="express"
label="Express"
checked={plan === "express"}
onChange={(e) => setPlan(e.target.value)}
/>Selected: standard