Components / Inputs
RadioCards
Selectable option cards with a sliding selection ring, price and description slots, and radio keyboard behavior.
Install
npx shadcn@latest add https://irisui.dev/r/radio-cards.jsonimport { RadioCards } from "@/components/iris/radio-cards/radio-cards";Preview
RadioCards
Selectable option cards with a sliding selection ring, description and price slots, and radio-group keyboard behaviour.
When to use
- Choosing one plan, workspace, verification method or setup path where each option needs a line of explanation or a price.
- Disabling an option while still explaining why (
disabledReason). - Not for short, label-only choices; use
RadioGrouporSegmentedControl. - Not for selecting several options; use
CheckboxorChipGroup.
Usage
import { RadioCards } from "@/components/iris/radio-cards/radio-cards";
h(RadioCards, {
"aria-label": "Workspace",
name: "workspace",
layout: "list",
defaultValue: "hot-desk",
options: [
{ value: "hot-desk", label: "Hot desk", description: "Any free desk, booked by the day", meta: "€10/day" },
{
value: "dedicated",
label: "Dedicated desk",
description: "Your own desk, booked by the month",
meta: "€145/month",
},
{ value: "meeting", label: "Meeting room", meta: "€25/hour", disabled: true, disabledReason: "Fully booked today" },
],
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
options |
RadioCardOption[] |
required | { value, label, description?, meta?, icon?, disabled?, disabledReason? }. |
value / defaultValue |
string | null |
– / null |
Controlled or initial selection. |
onValueChange |
(value: string) => void |
– | Fires when a new card is selected. |
layout |
"grid" | "list" |
"grid" |
Grid uses responsive columns (meta under the text); list stacks rows (meta at the end). |
minColumnWidth |
number |
180 |
Narrowest grid column before a column drops. |
name |
string |
– | Renders a hidden input with the selected value. |
required |
boolean |
– | Marks the group and hidden input required. |
disabled |
boolean |
false |
Disables all cards. |
...div props |
HTMLAttributes<HTMLDivElement> |
– | Passed to the radiogroup (aria-label, className, ref). |
Notes
- Give the group a name with
aria-labeloraria-labelledby. - Keyboard: a single tab stop on the selected (or first enabled) card; arrows move and select, wrapping and reversing in RTL; Home/End; Enter or Space selects.
- Each card is a
radiolabelled by its label and described by its description ordisabledReason. Selection shows as a ring and a filled dot, not colour alone. - Reduced motion makes the ring and dot jump to their final state.
- The ring and dot use the theme's
control-onandcontrol-glyph; cards usesurface,hover,lineandline-strong.