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.json
import { RadioCards } from "@/components/iris/radio-cards/radio-cards";
Registry item radio-cardsBrings in foundationRegistry JSON

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 RadioGroup or SegmentedControl.
  • Not for selecting several options; use Checkbox or ChipGroup.

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-label or aria-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 radio labelled by its label and described by its description or disabledReason. 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-on and control-glyph; cards use surface, hover, line and line-strong.