SelectionCard
A tappable option card for choice grids, with a title, description, optional check control, and selected state.
Implementation previewEvery example. In one place.
Explore every named example, including states, compositions, and theme variants.
Example source
packages/design-system/src/components/cards/SelectionCard/SelectionCard.stories.tsxExport PlaygroundImplementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.
Stories + source JSON ↗Local specification source status: preview. Implementation preview pending sign-off.
A tappable option card for choice grids, with a title, description, optional check control, and selected state.
Implementation API 1 entry point · source-derived preview
Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.
import { SelectionCard } from '@cloakedinc/design-system';SelectionCardSelectionCardProps
packages/design-system/src/components/cards/SelectionCard/SelectionCard.tsx:53
| Prop | Type | Presence | Notes |
|---|---|---|---|
title | string | undefined | Optional | Leading line of the built-in content. Ignored when `children` is given. |
description | string | undefined | Optional | Secondary line under `title`, in the muted color. Ignored when `children` is given. |
children | React.ReactNode | Optional | |
className | string | undefined | Optional | |
style | React.CSSProperties | undefined | Optional | |
variant | "default" | undefined | Optional | The only treatment today; it applies the card's 80px minimum height.Source default: 'default' |
gridSpan | SelectionCardGridSpan | undefined | Optional | Column behavior inside a parent grid: one column, or `full` to span the row.Source default: 'auto' |
control | SelectionCardControl | undefined | Optional | Trailing indicator. Defaults to a checkbox; `none` hides it while the card stays tappable. |
surface | SelectionCardSurface | undefined | Optional | Card fill. Defaults to the standard surface; `muted` fills with the divider color.Source default: 'default' |
selected | boolean | undefined | Optional | Drives the brand border, the checkbox glyph, and `aria-pressed` together.Source default: false |
disabled | boolean | undefined | Optional | Blocks presses and greys the whole card, indicator included.Source default: false |
onSelect | (() => void) | undefined | Optional | Tap handler. Without it no click handler is attached and the card is inert. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for selection. Defaults to `true` (`selection`).Source default: true |
ariaLabel | string | undefined | Optional | Accessible label when visible copy is custom or absent. |
testId | string | undefined | Optional | `data-testid` on the card `<button>`, which is the whole tap target. |
Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.
Overview
A tappable card for choice grids. control encodes the selection model. The card is stateless —
drive selected from parent state and toggle it inside onSelect. For short text-only options, use
RadioGroup instead.
Use when
control picks the affordance, which in turn signals how many options a user may choose.
Both values are live in the questionnaire, chosen per question type (single → none, multi →
checkbox). surface="muted" and the variant prop (only default today) exist for future styles
but are not yet used in app code.
Selected state
Selection adds the brand border and, for checkbox, fills the check circle.
Usage by variant
| Choice | Use when | Avoid when |
|---|---|---|
Control: checkbox | Multi-select lists — the check circle signals "pick any." The default when control is omitted. | Single-select groups, where a check circle wrongly implies multiple picks are allowed. |
Control: none | Single-select groups — the highlighted brand border alone marks the one pick, no check circle. | Multi-select, where users need a persistent per-option checkbox to track several selections. |
Component specification
$schema
../../../specs/component-spec.schema.jsonParts
- Id
- root
- Label
- Root
- Description
- Pressable card carrying the surface, selected border, and layout.
- Required
- true
- Id
- content
- Label
- Content
- Description
- Title and description column.
- Id
- indicator
- Label
- Indicator
- Description
- Optional selection check control.
Allowed Design Choices
- Variants
- Default
- Label
- Default
- Description
- The single card layout; kept open for future option styles.
- Sizes
- Surfaces
- Default
- Label
- Default
- Description
- Raised surface background.
- Muted
- Label
- Muted
- Description
- Divider-toned background for lower-emphasis groups.
- Controls
- Checkbox
- Label
- Checkbox
- Description
- Shows a check circle for multi-select lists.
- None
- Label
- None
- Description
- Hides the check so the highlight border alone marks the pick.
- Grid Spans
- Auto
- Label
- Auto
- Description
- Occupies one cell of a parent grid.
- Full
- Label
- Full
- Description
- Spans every column of a parent grid.
Variants
- Id
- default
- Label
- Default
- Description
- Standard selectable option card.
- Platforms
- ios
- android
- web
Sizes
None specifiedMeasurements
- Id
- row-min-height
- Label
- Minimum height
- Kind
- exact
- Token
- --cds-size-80
- Value
- 80
- Unit
- px
- Applies To
- root
- Id
- content-inset
- Label
- Content inset
- Kind
- exact
- Token
- --cds-space-20
- Value
- 20
- Unit
- px
- Applies To
- root
- Id
- content-gap
- Label
- Content and control gap
- Kind
- exact
- Token
- --cds-space-16
- Value
- 16
- Unit
- px
- Applies To
- root
- Id
- corner-radius
- Label
- Corner radius
- Kind
- exact
- Token
- --cds-radius-md
- Value
- 16
- Unit
- px
- Applies To
- root
- Id
- selection-border
- Label
- Selection border width
- Kind
- exact
- Token
- --cds-border-width-emphasis
- Value
- 2
- Unit
- px
- Applies To
- root
Layout
- Alignment
- Content column and optional control sit centered on the card's vertical center.
- Flow
- A pressable row: flexible content followed by the optional selection control.
- Notes
- Use RadioGroup when the options are short text-only rows rather than titled cards.
Typography And Color
- Typography
- Label
- Title
- Description
- Uses the body ramp.
- Token
- --cds-type-body-size
- Label
- Description
- Description
- Uses the body-small ramp.
- Token
- --cds-type-body-small-size
- Colors
- Label
- Surface
- Description
- Default cards use the raised surface.
- Token
- --cds-bg-surface
- Label
- Muted surface
- Description
- Muted cards use the divider color.
- Token
- --cds-divider
- Label
- Selected border
- Description
- Selection uses the brand border.
- Token
- --cds-brand
States
- Id
- default
- Label
- Default
- Description
- Unselected card with a transparent border.
- Id
- selected
- Label
- Selected
- Description
- Brand border plus a filled check control.
- Id
- disabled
- Label
- Disabled
- Description
- Blocks taps and dims via the disabled opacity.
Behavior
- Label
- Stateless
- Description
- Drive selected from parent state and toggle it inside onSelect.
- Label
- Control mode
- Description
- Use checkbox for multi-select and none for single-select groups.
Accessibility
- Label
- Pressed state
- Description
- The card is a button exposing aria-pressed for its selected state.
- Label
- Accessible name
- Description
- Provide ariaLabel when the visible copy is custom or absent.
Content Adaptation
- Label
- Custom children
- Description
- Custom children replace the default title/description block.
- Label
- Grid span
- Description
- gridSpan=full breaks the card out to the full grid width.
Motion Haptics
- Motion
- Label
- Border transition
- Description
- The selection border eases in on state change.
- Haptics
- Label
- Selection haptic
- Description
- Selecting an enabled card requests the selection haptic.