Components

Radio Card

A card-style radio button for visually prominent single-selection choices with icon, label, and description support.

Installation

npm install @marmoui/ui
yarn add @marmoui/ui
pnpm add @marmoui/ui
bun add @marmoui/ui

Usage

import { RadioCard, RadioCardItem } from '@marmoui/ui';

Examples

Basic

Plan Selection

Radio cards for selecting a pricing plan

For individuals getting started

For growing businesses

For large organizations

<RadioCard defaultValue="pro" className="max-w-md">
<RadioCardItem value="starter" label="Starter" description="For individuals getting started" />
<RadioCardItem value="pro" label="Pro" description="For growing businesses" />
<RadioCardItem value="enterprise" label="Enterprise" description="For large organizations" />
</RadioCard>

With Indicator

The indicator renders a radio dot inside the card. Control its position with indicatorPlacement ('start', 'end'), or hide it with indicator={null}.

Indicator Placement

Radio indicator at different positions, or hidden

Indicator at end (default)

Billed every month

Billed once a year — save 20%

Indicator at start

Billed every month

Billed once a year — save 20%

No indicator

Billed every month

Billed once a year — save 20%

{/* End (default) */}
<RadioCardItem value="a" label="Option" description="..." />

{/* Start */}
<RadioCardItem indicatorPlacement="start" value="b" label="Option" description="..." />

{/* Hidden */}
<RadioCardItem indicator={null} value="c" label="Option" description="..." />

With Icons

Cards with Icons

Radio cards with leading icons

Up to 1,000 contacts

Up to 10,000 contacts

Unlimited contacts

<RadioCard defaultValue="pro" className="max-w-md">
<RadioCardItem
  value="starter"
  icon={<MdRocketLaunch className="size-5 text-icon" />}
  label="Starter"
  description="Up to 1,000 contacts"
/>
<RadioCardItem
  value="pro"
  icon={<MdSpeed className="size-5 text-icon" />}
  label="Pro"
  description="Up to 10,000 contacts"
/>
<RadioCardItem
  value="enterprise"
  icon={<MdStar className="size-5 text-icon" />}
  label="Enterprise"
  description="Unlimited contacts"
/>
</RadioCard>

Grid Layout

Grid Layout

Cards in a multi-column grid for layout selection

Card-based layout

Detailed list view

Compact grid view

<RadioCard defaultValue="grid" className="grid-cols-3 max-w-2xl">
<RadioCardItem
  value="module"
  icon={<MdViewModule className="size-5 text-icon" />}
  label="Module"
  description="Card-based layout"
/>
<RadioCardItem
  value="list"
  icon={<MdViewList className="size-5 text-icon" />}
  label="List"
  description="Detailed list view"
/>
<RadioCardItem
  value="grid"
  icon={<MdGridView className="size-5 text-icon" />}
  label="Grid"
  description="Compact grid view"
/>
</RadioCard>

With Addon

Cards with Addon

Radio cards with additional metadata

Visa, Mastercard, Amex

Processing fee: 2.9%

Direct ACH payment

No fee

Pay with PayPal balance

Processing fee: 3.4%
<RadioCard defaultValue="card" className="max-w-md">
<RadioCardItem
  value="card"
  icon={<MdCreditCard className="size-5 text-icon" />}
  label="Credit Card"
  description="Visa, Mastercard, Amex"
  addon={<span className="text-xs text-ink-muted">Processing fee: 2.9%</span>}
/>
<RadioCardItem
  value="bank"
  icon={<MdAccountBalance className="size-5 text-icon" />}
  label="Bank Transfer"
  description="Direct ACH payment"
  addon={<span className="text-xs text-ink-muted">No fee</span>}
/>
<RadioCardItem
  value="paypal"
  icon={<MdPayment className="size-5 text-icon" />}
  label="PayPal"
  description="Pay with PayPal balance"
  addon={<span className="text-xs text-ink-muted">Processing fee: 3.4%</span>}
/>
</RadioCard>

Disabled

Disabled State

Disabled radio cards

This option can be selected

This option is not available

<RadioCard defaultValue="active" className="max-w-md">
<RadioCardItem value="active" label="Active Option" description="This option can be selected" />
<RadioCardItem value="disabled" label="Disabled Option" description="This option is not available" disabled />
</RadioCard>

Best Practices

✓

Limit options to 3-5

Keep the number of radio cards manageable. Too many options cause decision fatigue.

✓

Pre-select a recommended option

When appropriate, pre-select the most common or recommended option.

✗

Don't use without descriptions

If options don't need descriptions, use standard RadioGroup instead.

✗

Don't mix with regular radio buttons

Use either card radios or standard radios within the same form section.

Props

PropTypeDefaultDescription
valuestring-Unique value for the radio item
labelReactNode-Card title text
descriptionReactNode-Card description text
iconReactElement-Leading icon element
addonReactNode-Additional content below the description
indicatorReactNode | nullDefault radio dotCustom indicator element, or null to hide
indicatorPlacement'start' | 'end''end'Position of the indicator
disabledbooleanfalseDisable the radio card
classNamestring-Additional className for the card wrapper

RadioCard (Group) Props

PropTypeDefaultDescription
valuestring-Controlled selected value
defaultValuestring-Default selected value (uncontrolled)
onValueChange(value: string) => void-Callback when selection changes
classNamestring-Additional className for the group

Accessibility

  • Only one option can be selected at a time within a group.
  • Arrow keys navigate between options, Space/Enter selects.
  • Selected state is communicated via aria-checked.
  • Uses role="radiogroup" for the container.