Radio Group
A set of mutually exclusive radio options. Built on Radix UI RadioGroup with roving focus and arrow-key navigation.
Vertical
Horizontal
With descriptions
$12 / month · cancel anytime.
$120 / year · save two months.
With disabled option
Installation
pnpm dlx @hex-core/cli add radio-groupCard-style tiles
Wrap each option in a Label so the entire card becomes the click target. Canonical plan-tier or upgrade picker.
<RadioGroup defaultValue="pro" className="grid gap-3 sm:grid-cols-3">
<Label
htmlFor="plan-starter"
className="flex cursor-pointer flex-col gap-1 rounded-lg border border-input p-4 shadow-sm transition-colors hover:border-ring/50 has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:bg-accent/40"
>
<div className="flex items-center justify-between">
<span className="text-sm font-semibold">Starter</span>
<RadioGroupItem value="starter" id="plan-starter" />
</div>
<span className="text-xs text-muted-foreground">For solo developers exploring the platform.</span>
<span className="mt-1 text-sm font-medium">$0/mo</span>
</Label>
<Label
htmlFor="plan-pro"
className="flex cursor-pointer flex-col gap-1 rounded-lg border border-input p-4 shadow-sm transition-colors hover:border-ring/50 has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:bg-accent/40"
>
<div className="flex items-center justify-between">
<span className="text-sm font-semibold">Pro</span>
<RadioGroupItem value="pro" id="plan-pro" />
</div>
<span className="text-xs text-muted-foreground">For small teams shipping production apps.</span>
<span className="mt-1 text-sm font-medium">$29/mo</span>
</Label>
<Label
htmlFor="plan-enterprise"
className="flex cursor-pointer flex-col gap-1 rounded-lg border border-input p-4 shadow-sm transition-colors hover:border-ring/50 has-[[data-state=checked]]:border-primary has-[[data-state=checked]]:bg-accent/40"
>
<div className="flex items-center justify-between">
<span className="text-sm font-semibold">Enterprise</span>
<RadioGroupItem value="enterprise" id="plan-enterprise" />
</div>
<span className="text-xs text-muted-foreground">SSO, audit logs, and a dedicated support channel.</span>
<span className="mt-1 text-sm font-medium">Contact sales</span>
</Label>
</RadioGroup>With descriptions inline
Notification frequency picker — each option pairs a primary label with a secondary description for context.
<RadioGroup defaultValue="mentions" className="grid gap-4">
<div className="flex items-start gap-3">
<RadioGroupItem value="all" id="freq-all" className="mt-1" />
<div className="grid gap-0.5">
<Label htmlFor="freq-all" className="font-medium">All activity</Label>
<p className="text-sm text-muted-foreground">Email me whenever anything happens in this workspace.</p>
</div>
</div>
<div className="flex items-start gap-3">
<RadioGroupItem value="mentions" id="freq-mentions" className="mt-1" />
<div className="grid gap-0.5">
<Label htmlFor="freq-mentions" className="font-medium">Mentions only</Label>
<p className="text-sm text-muted-foreground">Email me only when I am @-mentioned or assigned.</p>
</div>
</div>
<div className="flex items-start gap-3">
<RadioGroupItem value="none" id="freq-none" className="mt-1" />
<div className="grid gap-0.5">
<Label htmlFor="freq-none" className="font-medium">Nothing</Label>
<p className="text-sm text-muted-foreground">Stay quiet. I will check the workspace manually.</p>
</div>
</div>
</RadioGroup>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selected value |
defaultValue | string | — | Default selected value for uncontrolled usage |
onValueChange | function | — | Callback on value change: (value: string) => void |
disabled | boolean | false | Disable all items |
name | string | — | Form field name (for native form submission) |
orientation | "horizontal" | "vertical" | vertical | Layout direction |
AI Guidance
When to use
Use for mutually exclusive choices from a short list (2-5 options) where all options should be visible. Pair each RadioGroupItem with a Label.
When not to use
Don't use for many options (use Select). Don't use for boolean toggles (use Switch or Checkbox). Don't use for multi-select.
Common mistakes
- Missing Label for each RadioGroupItem
- Using for more than 5 options (use Select)
- Using htmlFor id mismatch between Label and RadioGroupItem
Accessibility
Radix implements the WAI-ARIA radio group pattern. Arrow keys move focus+selection. Radix handles aria-checked, role='radiogroup', role='radio'.
Token budget: 400
Verified against @hex-core/components@1.12.0