Skip to content
Component installs need the registry setup
VegaStack Design

Choice Card

Radio options drawn as cards — icon, title, description — two across from @sm.

Status
stable
Since
0.23.116
Accessibility pattern
radio group; each card labels its radio; arrows move

Last updated

Install

Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Choice Card before installation. Retain the digest printed by this command.

pnpm exec vegastack-design verify choice-card

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/choice-card

Run the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.

The same command installs the registry items it composes: @vegastack/field, @vegastack/radio-group.

Usage

import { ChoiceCard, ChoiceCardGroup } from "@/components/ui/choice-card";

<ChoiceCardGroup aria-label="Access" value={access} onValueChange={setAccess}>
  <ChoiceCard
    value="open"
    icon={<Globe />}
    title="Open"
    description="Everyone can find and join"
  />
  <ChoiceCard
    value="private"
    icon={<Lock />}
    title="Private"
    description="Only members can find and open it"
  />
</ChoiceCardGroup>;

A thin wrapper over the documented Field choice-card pattern (FieldLabel around a horizontal Field with a RadioGroupItem): the look, the hover and the checked tint are Field's and RadioGroup's own. The group lays the cards out two across once its own container is @sm wide, and stacks them below that.

Scope

  • Owns: the card layout and the two-across grid.
  • Does not own: the radio behaviour (RadioGroup) or the card surface (Field).
  • Compose with: SettingsRow (a stacked row), forms.

Anatomy

ChoiceCardGroup — data-slot="choice-card-group" | "choice-card-group-container"
ChoiceCard — data-slot="choice-card" | "choice-card-icon"

Examples

Disabled option

API Reference

PropTypeDefaultDescription
title*React.ReactNode—The option's name.
value*string—The option's value.
classNamestring—Classes for the card.
descriptionReact.ReactNode—One muted line under the title.
disabledbooleanfalseShown but not choosable.
iconReact.ReactNode—A leading icon (a lucide icon), drawn muted at 16px.
idstring—The radio's id; one is generated when omitted.

Data attributes and CSS variables on ChoiceCard

AttributeValues
data-disabled"true"
data-slot"choice-card" | "choice-card-icon"

ChoiceCardGroup takes RadioGroup's props (value, defaultValue, onValueChange, disabled).

Accessibility

  • A radio group: name it with aria-label or aria-labelledby. Each card is its radio's label, so the title and description are the radio's name.
KeyAction
TabInto and out of the group
↑ / ↓Move and choose
ContractStates tested
Behaviourunchecked, checked, disabled, keyboard
Accessibilitylabeled, keyboard, browser-accessibility-test
Visualdefault, hover, focus

Do / Don't

Do
Use choice cards for two to four options that each need a sentence.
Don't
Use them for long lists or one-word options — use RadioGroup, Select or ToggleGroup.

On this page