Radio
Single native radio input. Use Radio Group for accessible keyboard-navigable groups.
Examples
Single radios
Standalone radios sharing a name; the selected value is echoed below.
Size: Medium
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";
const SIZES = ["Small", "Medium", "Large"];
export function RadioSizes() {
const [selected, setSelected] = useState("Medium");
return (
<div className="space-y-3">
<div className="flex flex-col gap-3">
{SIZES.map((size) => (
<div key={size} className="flex items-center gap-2">
<Radio
id={`size-${size}`}
name="size"
value={size}
checked={selected === size}
onValueChange={(value) => setSelected(value)}
/>
<Label htmlFor={`size-${size}`}>{size}</Label>
</div>
))}
</div>
<p className="text-xs text-ui-muted">
Size: <span className="font-medium text-ui-fg">{selected}</span>
</p>
</div>
);
}
Horizontal
Lay standalone radios out in a row.
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";
const OPTIONS = ["Yes", "No", "Maybe"];
export function RadioHorizontal() {
const [value, setValue] = useState("Yes");
return (
<div className="flex flex-wrap items-center justify-center gap-4">
{OPTIONS.map((option) => (
<div key={option} className="flex items-center gap-2">
<Radio
id={`vote-${option}`}
name="vote"
value={option}
checked={value === option}
onValueChange={(next) => setValue(next)}
/>
<Label htmlFor={`vote-${option}`}>{option}</Label>
</div>
))}
</div>
);
}
Disabled option
Disable an individual choice while keeping it visible.
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
import { useState } from "react";
export function RadioDisabled() {
const [value, setValue] = useState("available");
return (
<div className="flex flex-col gap-3">
<div className="flex items-center gap-2">
<Radio
id="ship-available"
name="shipping"
value="available"
checked={value === "available"}
onValueChange={(next) => setValue(next)}
/>
<Label htmlFor="ship-available">Standard — in stock</Label>
</div>
<div className="flex items-center gap-2 opacity-50">
<Radio id="ship-soldout" name="shipping" value="soldout" disabled checked={false} />
<Label htmlFor="ship-soldout">Overnight — sold out</Label>
</div>
</div>
);
}
Usage
The minimal import and composition — see Examples below for styled, real-world variants.
import { Label } from "@codefast/ui/label";
import { Radio } from "@codefast/ui/radio";
export function RadioUsage() {
return (
<div className="flex flex-col gap-3">
<div className="flex items-center gap-2">
<Radio defaultChecked id="plan-starter" name="plan" value="starter" />
<Label htmlFor="plan-starter">Starter</Label>
</div>
<div className="flex items-center gap-2">
<Radio id="plan-pro" name="plan" value="pro" />
<Label htmlFor="plan-pro">Pro</Label>
</div>
</div>
);
}
Anatomy
How the parts nest — every slot the component exposes, in composition order.
Features
- Plain native <input type="radio"> — radios sharing the same name form one exclusive group with zero JS.
- A convenience onValueChange(value) callback fires alongside the native onChange.
- For a managed, keyboard-navigable single-selection widget, use Radio Group instead.
API reference
Props for each part of the component. All native element props are also forwarded.
Radio
A single native radio input. Use Radio Group for managed groups.
checkedbooleanThe controlled selected state (native input prop).
onValueChange(value: string) => voidCalled with this radio’s value when it becomes checked.
namestringRadios sharing a name form one exclusive group.
valuestringThe value submitted when this radio is chosen.
Accessibility
Built to be keyboard-navigable and screen-reader friendly out of the box.
| Key | Function |
|---|---|
| Tab | Moves focus to the radio group. |
| Arrow+Down | Selects the next radio in the group. |
- Give every radio in a set the same name so only one can be selected.
- Pair each radio with a Label via matching id / htmlFor.
- For a managed, keyboard-navigable group, prefer Radio Group.
Guidelines
Conventions that keep usage consistent across an app.
Do
- Use Radio Group for most cases; reach for Radio for bespoke layouts.
- Always provide labels.
Don’t
- Don’t use radios for multi-select.
- Don’t forget the shared name attribute.
Explore further
Ready to integrate?
Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.