# Radio cards

A React component in [Beamline](https://beamline.io/)'s [Form controls](https://beamline.io/components/forms) category, in the free sample. Live demo: https://beamline.io/components/radio-cards

One choice among rich options as cards with optional media, icon, detail and a figure; one selection ring follows the stable choice.

## Use it for

- Choosing one of a few rich options with a description or price.
- Choosing one of a few image variants or output formats while keeping every option in a stable row.
- The main choice of a form (a goal, a [plan](https://beamline.io/components/plan)) as a field with its label, help and error.

## Not for

- Short plain options ([radio-group](https://beamline.io/components/radio-group)).
- More than about five options ([select](https://beamline.io/components/select)).

## Anatomy

- group visual root
- card (m-control): optional media, head (icon tile, label, detail, radio mark = RadioGroup's m-toggle dot), figure
- figure: closes a grid card under a line-soft seam (body face, tabular digits); inline-end in stacked rows
- one measured selection ring (1.5px accent) that glides

## Variants

- **stacked**: false (side by side), true (rows)
- **layout**: grid (responsive cards), stacked (rows), row (one nonwrapping, horizontally scrollable row)

## States

- chosen (ring + filled mark)
- other
- hover (mark ring strengthens)
- disabled (--pui-opacity-disabled)

## Keyboard

- Tab enters the group
- arrows move and choose
- The selected card keeps its stable value and focus when the caller updates its media or labels.

## Motion

The ring stretches toward the chosen card on both axes and gathers there: the edges on the side it travels lead and the others follow a beat later, critically damped, never overshooting. Reduced motion: it jumps.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `cards` | `{ value, label, media?, detail?, figure?, icon?, disabled? }[]` | — |  |
| `value / defaultValue / onValueChange` | `string` | — |  |
| `stacked / cardWidth` | `boolean / number` | `false / 180` |  |
| `label` | `string` | — |  |
| `name / required / disabled` | `form` | — |  |
| `layout` | `"grid" \| "stacked" \| "row"` | — | Explicit layout wins the existing stacked shorthand. Row preserves source order and uses cardWidth or the inherited card-width token. |
| `classNames` | `RadioCardsClassNames` | — | Visual parts: root, item, media, head, icon, text, label, detail, mark, figure and ring. Styling does not replace radio semantics or indicator measurement. |
| `style` | `CSSProperties` | — | The visual root; inherited --pui-radio-cards-card-width controls responsive sizing unless cardWidth is explicit. |
| `field / hideLabel / description / error` | `boolean / ReactNode` | — | A form field: label above, help or error below, on whenever the label shows; hideLabel for a view switch or quick filter (the label stays the accessible name). name submits with a native form. |

## Dependencies

`@radix-ui/react-radio-group`

## Import

```tsx
import { RadioCards } from "@/components/radio-cards/radio-cards";
```

## Get it

Radio cards is part of Beamline: 190 React components and screens your coding agent (Claude Code, Codex, Cursor or any MCP client) installs into your app through Beamline's MCP server, as a ready-built package or as plain React source you can change. $49 one payment (regular $200), no subscription, a year of updates, one licence for your whole team. Radio cards is in the free sample, which costs nothing. [Get Beamline](https://beamline.io/checkout?pack=complete) · [Connect your agent](https://beamline.io/connect)

## More in Form controls

- [Allocation editor](https://beamline.io/components/allocation-editor): Parts of a fixed whole edited as transfers: an ordered strip whose boundaries drag or step between neighbours and a roster of exact amounts where typing…
- [Billing toggle](https://beamline.io/components/billing-toggle): Monthly or yearly: a segmented control whose yearly note turns into what the choice saves.
- [Calendar](https://beamline.io/components/calendar): Month grids for picking a day or a range: a real grid with arrows by day and week, Page keys by month, closed days, today's dot, and a range span that…
- [Checkbox](https://beamline.io/components/checkbox): A yes/no choice with an optional label and help, including the mixed state for select-all; the check draws itself in.
- [Chip group](https://beamline.io/components/chip-group): Quick filters as chips: a chosen chip fills and grows a check, counts show what each would return, and extra chips fold behind “+N more”.
- [Color Palette](https://beamline.io/components/color-palette): A wheel of preset colours to pick from: twelve hues around the ring, their tints inward, white at the middle; the chosen swatch lifts and carries a check.
- [Colour picker](https://beamline.io/components/color-picker): A swatch that opens a picker: saturation-brightness plane, hue strip, HEX/RGB/HSL/OKLCH value to type or copy, the screen eyedropper where available…
- [Combobox](https://beamline.io/components/combobox): One value from a long list found by typing (time zones, countries, customers): ranked matches with the match emphasised, keywords, optional group…
- [Date picker](https://beamline.io/components/date-picker): One date in a form: a field that opens the month grid under it with focus inside, picks and closes; Today and Clear below, optional clear button.
- [Date range picker](https://beamline.io/components/date-range-picker): A reporting range: presets on one side and two months on the other (one on a phone); the trigger names the preset in use, and the footer counts the days.
- [File drop zone](https://beamline.io/components/file-dropzone): A generous target for files: drop or choose, each checked against type, size and count with the reason when turned away; uploads show progress and can be…
- [Form](https://beamline.io/components/form): Validation wiring for react-hook-form (and zod) on the system's own fields: each field already links its label, help and error, so FormField hands over…
- [Inline edit](https://beamline.io/components/inline-edit): Text that becomes a field in the same place: Enter (or ⌘Enter when multiline) saves, Escape cancels, leaving saves; saving shows progress and a refusal…
- [Input](https://beamline.io/components/input): A single-line text field with its label, help and error wired for assistive tech, three sizes and adornments.
- [Input Dissolve](https://beamline.io/components/input-dissolve): A one-line field whose text breaks into specks and drifts off once it is sent, last letter first; the field is empty and ready again.
- [Label](https://beamline.io/components/label): The text label tied to a form control, with a required marker that screen readers announce.
- [Mention input](https://beamline.io/components/mention-input): A composer where @people and #channels become single tokens with suggestions at the caret; the value keeps the text and where each mention sits.
- [Multi-select](https://beamline.io/components/multi-select): Several values from a known list as removable chips in the field; the list has a search field (for long lists), checkable rows and a count with Clear.
- [Number field](https://beamline.io/components/number-field): A bounded number with − and +: arrows and Page keys step, typing is read in the locale and clamped on leaving, limits can be explained, and the label can…
- [OTP input](https://beamline.io/components/otp-input): A verification code in separate boxes backed by one real field, so paste, SMS autofill and Backspace work; optional groups like 123–456.
- [Password field](https://beamline.io/components/password-field): A password field with a reveal control, and a strength meter when a password is being created.
- [Phone input](https://beamline.io/components/phone-input): A phone number with its country: searchable picker with country and dialling codes, “+44…” switches the country, the number groups as typed, and the…
- [Radio group](https://beamline.io/components/radio-group): One choice from a short visible set, each option with an optional description, vertical or in a row.
- [Rich text editor](https://beamline.io/components/rich-text-editor): A Notion-grade writing surface: slash menu for every block, a formatting toolbar on selection, drag-to-move blocks, nesting, markdown shortcuts, paste…
- [Search field](https://beamline.io/components/search-field): The search entry point: magnifier, clear button, Escape to clear, a shortcut hint and an optional live border beam.
- [Segmented control](https://beamline.io/components/segmented-control): Two to five views or ranges of the same content (1D / 1W / 1M, List / Board): a radio group whose raised thumb slides to the choice.
- [Select](https://beamline.io/components/select): One choice from a short known list, in the same frame as every text field: label, help, error, option groups and details.
- [Shortcut recorder](https://beamline.io/components/shortcut-recorder): Lets people set their own shortcut: press the keys, see them as keycaps; a clash or a browser-kept shortcut asks first. ShortcutCheatsheet lists every…
- [Signature pad](https://beamline.io/components/signature-pad): A pad for a drawn signature whose ink thins with speed; undo, replay, PNG or SVG export, and typing instead for keyboards and screen readers.
- [Slider](https://beamline.io/components/slider): A value or range on a known scale: the thumb grows under the finger and shows its value while dragged or focused; marks, end icons and a value readout.
- [Switch](https://beamline.io/components/switch): A setting that applies at once: a thumb that slides on a spring and stretches under the finger, with an optional label before or after.
- [Tag input](https://beamline.io/components/tag-input): Short free-form values as tags: Enter, comma or Tab adds, a pasted list adds them all, Backspace twice removes the last; duplicates and invalid values…
- [Textarea](https://beamline.io/components/textarea): Multi-line plain text that grows with what is typed up to a limit, with an optional character count.
- [Time picker](https://beamline.io/components/time-picker): A time of day as hour and minute segments, typed or stepped, 12- or 24-hour; the clock opens a list of times at the step.
- [Toggle group](https://beamline.io/components/toggle-group): Pressable toggles where one or several can be on: alignment, bold and italic, view options; bare for toolbars or framed.
