# Card select
> Generated from card-select.contract.json — do not edit by hand.

Single-select as an icon+label card grid — pick one of N options each shown as its own visual card, with roving radiogroup keyboard navigation. Two layouts: labelled tiles (stretch to fill `columns`) or compact 44px icon-only squares.

Tier: **leaf-lit**. Frameworks: HTML (paste-and-run, no build step) · React · Vue 3.

Surfaces: editor, settings.

## Props
| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `options` | Array<{value,label,icon}> | `[]` | The cards — each an icon name + a label; set as a property or a JSON attribute |
| `value` | string | `—` | The selected option's value (single-select) |
| `columns` | number | `3` | Grid column count — labelled tiles fill each track; iconOnly lays out that many 44px squares |
| `iconOnly` | boolean | `false` | Compact layout — fixed 44px icon squares packed to the start; the label is hidden but kept as title + aria-label |
| `disabled` | boolean | `false` | Non-interactive; grey fill |
| `change` | CustomEvent<{value}> | `—` | Composed event on selection; read e.detail.value |

## Visual standard (measured)
- Card: icon 24 over label; padding 16 12; radius 8; 1px #D4D4D4 border
- Grid: repeat(columns, minmax(0,1fr)) — tiles stretch to fill; columns default 3; 8px gap
- iconOnly: repeat(columns, 44px) — fixed 44px squares packed to the start; label hidden, kept as title + aria-label
- Selected: #6A1EBB border + #F9F5FF tint + #6A1EBB label/icon (persistent node)
- Hover: #D3B4FF border
- Keyboard: roving radiogroup — one tab-stop; Arrow keys move-and-select; Space/Enter select
- Disabled: #F1F1F1 fill, #EBEBEB border, not-allowed

## When to use
- **Card select** — pick one of N options, each carrying a visual (icon/preview) — a chart-type, layout or mode picker
- **Segmented** — 2–4 short text-only options in one row (SETTINGS-38)
- **Select** — a longer or space-constrained set with no per-option visual

Reach for CardSelect only when each option carries a visual. Do not hand-roll a grid of bespoke <button>/<div> tiles with inline <svg> icons and a manual selected state (SETTINGS-51) — the roving radiogroup a11y is the hard part and it lives here.
