# Token-Styled Select — Design **Date:** 2026-06-08 **Status:** Approved (brainstorming) — ready for implementation planning. **Issue:** #51. ## Context Four raw ``, so existing tests using `userEvent.selectOptions` / `HTMLSelectElement` must be rewritten to click interaction. ### Decisions (from brainstorming) 1. **All four selects → `ui/Select`** (uniform token styling + focus ring; lowest risk). 2. New `ui/select.tsx` wraps Base UI Select; **validated by running** (novel primitive). 3. Tests rewritten to Base UI Select interaction (open trigger → click item). ## Components ### `web/src/components/ui/select.tsx` (new) Wrap Base UI Select in the `ui/*` style (`data-slot`, `cn`, no semicolons), mirroring `ui/combobox.tsx`/`ui/menu.tsx`. Exports (names final after validate-by-running): - `Select` — `SelectPrimitive.Root` (generic value; `value`/`onValueChange`/`defaultValue`/`disabled`/`name`). - `SelectTrigger` — `SelectPrimitive.Trigger` styled to **match Input**: `h-8 w-full rounded-lg border border-input bg-transparent px-2.5 py-1 text-sm inline-flex items-center justify-between transition-colors outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive dark:bg-input/30` + a trailing chevron (`SelectPrimitive.Icon` with a lucide `ChevronDown`, `aria-hidden`) and a `SelectValue` (`SelectPrimitive.Value`) showing the chosen item (with `placeholder`). - `SelectContent` — `SelectPrimitive.Portal` + `SelectPrimitive.Positioner` (`sideOffset`, `z-50`) + `SelectPrimitive.Popup` styled as a card (`min-w-[var(--anchor-width)]` if supported, else `min-w-32`; `rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-none` + open/close animation data-attrs). - `SelectItem` — `SelectPrimitive.Item` row (`flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground`) + a `SelectPrimitive.ItemIndicator` (lucide `Check`) and `SelectPrimitive.ItemText`. - Token classes only (no raw palette). The exact part tree + props (`SelectValue` placeholder, positioner anchoring, item `value`) **must be confirmed by running the story** (Base UI Select is novel here), as combobox/menu/toast were. **Accessibility:** `SelectTrigger` accepts `id` so the existing `