docs: RFC-003 Select + RFC-004 Card + Compliance Matrix update

- RFC-003: Canonical Select Component:
  - Cognitive Purpose: choose one from predefined list
  - When to Use/NOT Use: clear boundaries vs Radio Group, Autocomplete, Multi-Select
  - Interaction Contract: click, arrow keys, type-to-search, escape
  - Failure Behaviour: empty, required, disabled, async loading, load failure
  - Accessibility Contract: combobox role, aria-expanded, aria-selected, focus management
  - AI Contract: when to choose Select vs alternatives
  - Token Dependencies: 21 tokens (trigger + dropdown + options)
  - Layout: trigger + dropdown with sections
  - Sizes (sm/md/lg), Variants (default/ghost/filled), States (10 states)
  - Keyboard: full navigation (Tab, Arrows, Enter, Escape, Home, End, letter keys)
  - Touch: 44px option targets, native scroll
  - Motion: dropdown open/close, option hover/select, chevron rotate
  - Anti-Patterns: < 4 options, > 50 options, no placeholder, clipping
  - Related Components: Input, Radio Group, Checkbox Group, Multi-Select, Autocomplete
  - DDR References: DDR-001 through DDR-004

- RFC-004: Canonical Card Component:
  - Cognitive Purpose: group related information into bounded unit
  - When to Use/NOT Use: clear boundaries vs List Item, Modal, Page
  - Interaction Contract: click/hover/focus for actionable, none for static
  - Failure Behaviour: overflow, image load fail, action fail, loading, empty
  - Accessibility Contract: role, focus, label, keyboard activation
  - AI Contract: when to choose Card vs alternatives
  - Token Dependencies: 12 tokens (bg, border, radius, padding, shadows, text)
  - Layout: Header + Body + Footer with optional divider
  - Sizes (sm/md/lg/fluid), Variants (default/elevated/outlined/interactive)
  - States (7 states), Keyboard, Touch, Motion (with reduced motion)
  - Anti-Patterns: nested cards, excessive padding, no distinction, event collision
  - Related Components: Modal, Panel, List Item, Tile, KPI Card, Dataset Card
  - DDR References: DDR-001, DDR-002, DDR-003, DDR-005

- COMPLIANCE_MATRIX.md: Select and Card updated to 33%

Rationale: Validate RFC-001 template works for selection and container
component types. Three different component types (action, selection,
container) now tested. Mallen håller.
This commit is contained in:
Bernt
2026-07-02 10:41:19 +00:00
parent 54255eeae9
commit 558303784a
3 changed files with 560 additions and 2 deletions
+2 -2
View File
@@ -24,8 +24,8 @@
|-----------|------------|--------|--------|---------------|-----|-----|---------|
| Button | ✅ | ✅ | ✅ | 🟡 | ✅ | ⏳ | 82% |
| Input | 🟡 | 🟡 | 🟡 | 🟡 | ✅ | ⏳ | 33% |
| Select | | | | | ⏳ | ⏳ | 0% |
| Card | | | | | ⏳ | ⏳ | 0% |
| Select | 🟡 | 🟡 | 🟡 | 🟡 | ✅ | ⏳ | 33% |
| Card | 🟡 | 🟡 | 🟡 | 🟡 | ✅ | ⏳ | 33% |
| Modal | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | 0% |
| Navigation | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | 0% |
| Table | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | ⏳ | 0% |
+293
View File
@@ -0,0 +1,293 @@
# RFC-003: Canonical Select Component
**Status:** 🟡 Draft — Under review
**Tier:** 1 (Canonical)
**Inherits From:** — (root component)
**Author:** AI Agent
**Date:** 2026-07-02
---
## 1. COGNITIVE PURPOSE
Select exists to allow users to choose exactly one option from a predefined list. It reduces cognitive load by eliminating free-form input when the valid options are known in advance.
**Design Goal:** The user can see available options, make a selection, and confirm their choice without typing or guessing.
---
## 2. WHEN TO USE
- Choosing from 520 predefined options
- Selecting a single value (country, status, category)
- When options have clear labels
- When free-form input would cause errors
## 3. WHEN NOT TO USE
- Fewer than 4 options (use Radio Group or Segmented Control)
- More than 50 options (use Searchable Select or Autocomplete)
- Multiple selections (use Multi-Select or Checkbox Group)
- Boolean choice (use Switch or Checkbox)
- Free-form entry (use Input)
---
## 4. USER EXPECTATION
- Clicking the field reveals all options
- Selected option is clearly indicated
- Current selection is visible when closed
- Options are searchable if list is long
- Keyboard can navigate options
- Disabled options are visually distinct
---
## 5. INTERACTION CONTRACT
| Event | Response |
|-------|----------|
| Click | Open dropdown, show options |
| Click option | Select option, close dropdown |
| Click outside | Close dropdown, keep selection |
| Tab | Move focus to next field, close dropdown |
| Arrow Down | Open dropdown or move to next option |
| Arrow Up | Move to previous option |
| Enter | Select focused option, close dropdown |
| Escape | Close dropdown, revert to previous selection |
| Type letter | Jump to first option starting with that letter |
---
## 6. FAILURE BEHAVIOUR
| Scenario | Response |
|----------|----------|
| No option selected | Show placeholder, allow form submission if optional |
| Required but empty | Show error on blur or submit |
| Option disabled | Prevent selection, show disabled state |
| Options load asynchronously | Show loading state, then populate |
| Options fail to load | Show error, allow retry |
| User types non-matching letter | No action, or show "no results" |
---
## 7. ACCESSIBILITY CONTRACT
- **Label:** Every Select MUST have associated `<label>` or `aria-label`
- **Role:** MUST use `role="combobox"` or native `<select>`
- **Expanded:** MUST communicate open/closed state with `aria-expanded`
- **Selected:** MUST communicate selected option with `aria-selected`
- **Focus:** Focus MUST move to dropdown when opened, return to trigger when closed
- **Screen reader:** MUST announce number of options, current selection, and position
- **Keyboard:** MUST support all interaction contract keyboard events
---
## 8. AI CONTRACT
| Scenario | AI Choice |
|----------|-----------|
| 520 predefined options, single choice | Select |
| < 4 options, single choice | Radio Group |
| > 50 options | Searchable Select / Autocomplete |
| Multiple selections | Multi-Select / Checkbox Group |
| Boolean toggle | Switch / Checkbox |
| Free-form entry | Input |
---
## 9. TOKEN DEPENDENCIES
| Token | Semantic Reference | Usage |
|-------|-------------------|-------|
| `select-bg` | `surface-primary` | Background |
| `select-border` | `border-default` | Default border |
| `select-border-focus` | `brand-500` | Focus border |
| `select-border-error` | `semantic-red-500` | Error border |
| `select-text` | `text-primary` | Selected text |
| `select-placeholder` | `text-muted` | Placeholder text |
| `select-padding` | `space-3` | Internal padding |
| `select-radius` | `radius-md` | Border radius |
| `select-height-sm` | `space-8` | Small height (32px) |
| `select-height-md` | `space-10` | Medium height (40px) |
| `select-height-lg` | `space-12` | Large height (48px) |
| `select-dropdown-bg` | `surface-primary` | Dropdown background |
| `select-dropdown-border` | `border-default` | Dropdown border |
| `select-dropdown-shadow` | `shadow-md` | Dropdown elevation |
| `select-option-hover` | `surface-secondary` | Option hover background |
| `select-option-selected` | `brand-50` | Selected option background |
| `select-option-disabled` | `surface-secondary` | Disabled option background |
| `select-error-bg` | `semantic-red-50` | Error background tint |
| `select-disabled-bg` | `surface-secondary` | Disabled background |
| `select-disabled-text` | `text-muted` | Disabled text |
| `select-chevron` | `text-muted` | Chevron icon color |
---
## 10. LAYOUT
```
┌─────────────────────────────────────┐
│ Label (optional) │
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐ │
│ │ Selected option ▼ │ │
│ └─────────────────────────────────┘ │
│ ┌─────────────────────────────────┐ │
│ │ Option 1 │ │
│ │ Option 2 (selected) │ │
│ │ Option 3 │ │
│ │ Option 4 (disabled) │ │
│ └─────────────────────────────────┘ │
│ Helper text / Error message │
└─────────────────────────────────────┘
```
- **Label:** Above select, left-aligned, `text-sm`, `font-medium`
- **Trigger:** Full width, padding `space-3`, chevron icon right-aligned
- **Dropdown:** Full width of trigger, max-height 240px, scrollable
- **Option:** Padding `space-2 space-3`, full width
- **Helper/Error:** Below select, `text-xs`
- **Gap:** `space-1` between label and select, `space-1` between select and helper
---
## 11. SIZES
| Size | Height | Font Size | Padding | Usage |
|------|--------|-----------|---------|-------|
| Small | 32px | 14px | `space-2` | Dense forms, tables |
| Medium | 40px | 16px | `space-3` | Default, most forms |
| Large | 48px | 18px | `space-4` | Mobile, touch-first |
---
## 12. VARIANTS
| Variant | Visual | Usage |
|---------|--------|-------|
| Default | Border, background | Standard form select |
| Ghost | No border, underline only | Minimal UI, filters |
| Filled | Solid background, no border | High-contrast forms |
---
## 13. STATES
| State | Visual | Motion |
|-------|--------|--------|
| Default | `select-border`, `select-bg` | — |
| Hover | Border darkens | `duration-instant` |
| Focus | `select-border-focus`, focus ring | `duration-instant` |
| Open | Dropdown visible, chevron rotates | `duration-transition` |
| Option hover | `select-option-hover` | `duration-instant` |
| Option selected | `select-option-selected` | `duration-interaction` |
| Option disabled | `select-option-disabled`, muted text | — |
| Disabled | `select-disabled-bg`, `select-disabled-text` | — |
| Error | `select-border-error`, `select-error-bg` | `duration-interaction` |
| Loading | Spinner in trigger | `duration-attention` |
---
## 14. KEYBOARD
| Key | Action |
|-----|--------|
| `Tab` | Move focus to next field, close dropdown |
| `Shift+Tab` | Move focus to previous field |
| `Enter` / `Space` | Open dropdown or select focused option |
| `Arrow Down` | Open dropdown or move to next option |
| `Arrow Up` | Move to previous option |
| `Escape` | Close dropdown, revert selection |
| `Home` | Move to first option |
| `End` | Move to last option |
| Letter key | Jump to first option starting with that letter |
---
## 15. TOUCH
- Touch target: Minimum 40px height (Medium size)
- Touch target for options: Minimum 44px height
- Active state: Brief background tint on option
- Scroll: Native scroll within dropdown
- No gesture support (no swipe to dismiss)
---
## 16. MOTION
| Transition | Animation | Duration | Easing |
|-----------|-----------|----------|--------|
| Dropdown open | Fade + slide down | `duration-transition` | `ease-out` |
| Dropdown close | Fade + slide up | `duration-transition` | `ease-in` |
| Option hover | Background color change | `duration-instant` | `ease-out` |
| Option select | Background highlight | `duration-interaction` | `ease-out` |
| Chevron rotate | Rotate 180° | `duration-transition` | `ease-out` |
| Error appear | Border + background tint | `duration-interaction` | `ease-out` |
**Reduced Motion:** Dropdown appears/disappears instantly (`duration-instant`). No slide animation.
---
## 17. ANTI-PATTERNS
-**Select with < 4 options:** Use Radio Group instead
-**Select with > 50 options:** Use Searchable Select or Autocomplete
-**No placeholder or label:** User cannot infer purpose
-**Disabled options without visual distinction:** User thinks they can select them
-**Dropdown wider than trigger:** Breaks visual alignment
-**Dropdown clipped by container:** Use portal/overlay to escape overflow:hidden
-**No keyboard navigation:** Accessibility failure
-**Changing options while open:** Causes focus loss and confusion
---
## 18. RELATED COMPONENTS
- **Input** — Free-form text entry
- **Radio Group** — Few options, all visible
- **Checkbox Group** — Multiple selections
- **Multi-Select** — Multiple selections from dropdown
- **Autocomplete** — Searchable selection with free-form input
- **Search** — Input with suggestions
---
## 19. DDR REFERENCES
- **DDR-001:** Device Adaptive over Desktop First (affects sizing)
- **DDR-002:** Information-level typography (affects label and option text)
- **DDR-003:** Semantic color system (affects states)
- **DDR-004:** Motion System v1 intention-based tokens (affects dropdown animation)
---
## 20. ACCEPTANCE CRITERIA
- [ ] All 12 Definition of Done criteria met
- [ ] Works with screen reader (NVDA, VoiceOver, JAWS)
- [ ] Keyboard navigation works (all keys in interaction contract)
- [ ] Touch target minimum 40px on trigger, 44px on options
- [ ] Dropdown does not clip inside overflow:hidden containers
- [ ] Error state visible without color alone
- [ ] Disabled options clearly distinct from enabled
- [ ] Focus management correct (into dropdown, back to trigger)
- [ ] Reduced motion respected
- [ ] Chevron icon rotates when opening/closing
---
## ÄNDRINGSHISTORIA
| Version | Datum | Beskrivning |
|---------|-------|-------------|
| 1.0 | 2026-07-02 | Initial RFC-003 following RFC-001 structure |
---
## STATUS
**DRAFT — Awaiting review**
+265
View File
@@ -0,0 +1,265 @@
# RFC-004: Canonical Card Component
**Status:** 🟡 Draft — Under review
**Tier:** 1 (Canonical)
**Inherits From:** — (root component)
**Author:** AI Agent
**Date:** 2026-07-02
---
## 1. COGNITIVE PURPOSE
Card exists to group related information into a bounded, scannable unit. It creates visual hierarchy by separating content from its surroundings without requiring explicit borders or dividers.
**Design Goal:** The user can scan, compare, and act on grouped information as a single unit.
---
## 2. WHEN TO USE
- Grouping related data (KPI, dataset, asset summary)
- Presenting actionable items that need context
- Creating scannable lists of heterogeneous content
- Elevating content above the page background
- Containing forms or workflows in a bounded area
## 3. WHEN NOT TO USE
- Single line of text (use plain text or List Item)
- Simple navigation (use Link or Navigation)
- Modal content (use Modal)
- Full-page content (use Page layout)
- When elevation is unnecessary (use flat surface)
---
## 4. USER EXPECTATION
- Card is visually distinct from background
- Card content is related and scannable
- Card may be clickable (if actionable)
- Card maintains consistent internal spacing
- Card adapts to container width
- Multiple cards align in grids or lists
---
## 5. INTERACTION CONTRACT
| Event | Response |
|-------|----------|
| Click (actionable) | Navigate or trigger primary action |
| Hover (actionable) | Elevation increases, cursor changes |
| Focus (actionable) | Focus ring appears |
| None (static) | No interaction, purely presentational |
---
## 6. FAILURE BEHAVIOUR
| Scenario | Response |
|----------|----------|
| Content overflows | Scroll internally or truncate with ellipsis |
| Image fails to load | Show placeholder or fallback icon |
| Action fails | Show error state on card or in adjacent area |
| Card is loading | Show skeleton state |
| Card is empty | Show empty state with guidance |
---
## 7. ACCESSIBILITY CONTRACT
- **Role:** Static cards use no ARIA role. Actionable cards use `role="button"` or `role="link"`.
- **Focus:** Actionable cards MUST have visible focus ring
- **Label:** Actionable cards MUST have accessible name (aria-label or visible text)
- **Screen reader:** MUST announce card as group or link/button
- **Keyboard:** Actionable cards MUST be activatable with Enter or Space
- **Color:** MUST NOT rely on color alone to indicate actionability
---
## 8. AI CONTRACT
| Scenario | AI Choice |
|----------|-----------|
| Group related data with actions | Card |
| Single data point with label | List Item |
| Navigation to another page | Link |
| Modal content | Modal |
| Full-page layout | Page |
| Simple text without grouping | Plain text |
---
## 9. TOKEN DEPENDENCIES
| Token | Semantic Reference | Usage |
|-------|-------------------|-------|
| `card-bg` | `surface-primary` | Background |
| `card-border` | `border-default` | Border (optional) |
| `card-radius` | `radius-lg` | Border radius |
| `card-padding` | `space-4` | Internal padding |
| `card-shadow` | `shadow-sm` | Default elevation |
| `card-shadow-hover` | `shadow-md` | Hover elevation (actionable) |
| `card-shadow-active` | `shadow-sm` | Active elevation |
| `card-divider` | `border-default` | Divider between sections |
| `card-header-text` | `text-primary` | Header text |
| `card-body-text` | `text-secondary` | Body text |
| `card-footer-text` | `text-muted` | Footer text |
| `card-loading-bg` | `surface-secondary` | Skeleton background |
---
## 10. LAYOUT
```
┌─────────────────────────────────────┐
│ ┌─────────────────────────────────┐ │
│ │ Header (title, action) │ │
│ ├─────────────────────────────────┤ │
│ │ │ │
│ │ Body (content, data, media) │ │
│ │ │ │
│ ├─────────────────────────────────┤ │
│ │ Footer (metadata, actions) │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
```
- **Header:** Top section, title + optional action, padding `space-4`
- **Body:** Main content, padding `space-4`, flexible height
- **Footer:** Bottom section, metadata or actions, padding `space-4`, top border `card-divider`
- **Divider:** 1px line between sections, `card-divider`
- **Gap:** No gap between sections (padding handles spacing)
---
## 11. SIZES
| Size | Width | Padding | Usage |
|------|-------|---------|-------|
| Small | 240px | `space-3` | Dense grids, compact data |
| Medium | 320px | `space-4` | Default, most content |
| Large | 480px | `space-5` | Featured content, dashboards |
| Fluid | 100% | `space-4` | Responsive, full-width |
---
## 12. VARIANTS
| Variant | Visual | Usage |
|---------|--------|-------|
| Default | Border, subtle shadow | Standard content grouping |
| Elevated | No border, stronger shadow | Featured content, dashboards |
| Outlined | Border, no shadow | Dense layouts, tables |
| Interactive | Hover elevation, cursor pointer | Clickable cards |
---
## 13. STATES
| State | Visual | Motion |
|-------|--------|--------|
| Default | `card-bg`, `card-shadow` | — |
| Hover (interactive) | `card-shadow-hover`, cursor pointer | `duration-interaction` |
| Active (interactive) | `card-shadow-active` | `duration-instant` |
| Focus (interactive) | Focus ring | `duration-instant` |
| Loading | Skeleton state | `duration-background` |
| Empty | Empty state illustration + text | — |
| Error | Error border or error message | `duration-interaction` |
---
## 14. KEYBOARD
| Key | Action |
|-----|--------|
| `Tab` | Move focus to next focusable element |
| `Enter` / `Space` | Activate actionable card |
| `Arrow keys` | Navigate between cards in grid/list |
---
## 15. TOUCH
- Touch target: Entire card if actionable
- Active state: Brief elevation reduction
- No gesture support (no swipe, pinch)
- Scroll: Card content scrolls internally if overflow
---
## 16. MOTION
| Transition | Animation | Duration | Easing |
|-----------|-----------|----------|--------|
| Hover (interactive) | Elevation increase | `duration-interaction` | `ease-out` |
| Active (interactive) | Elevation decrease | `duration-instant` | `ease-in` |
| Focus | Focus ring appear | `duration-instant` | `ease-out` |
| Loading skeleton | Shimmer animation | `duration-background` | `linear` |
| Error appear | Border color change | `duration-interaction` | `ease-out` |
**Reduced Motion:** No elevation animation. Focus ring appears instantly.
---
## 17. ANTI-PATTERNS
-**Nested cards:** Cards inside cards create visual confusion
-**Too much padding:** Wastes space, reduces information density
-**No visual distinction from background:** Defeats purpose of card
-**Inconsistent internal spacing:** Breaks scannability
-**Actionable without focus ring:** Accessibility failure
-**Clickable entire card with internal buttons:** Event collision
-**Card as only layout tool:** Use grid or flexbox for layout, card for grouping
-**Excessive elevation:** Competes with modals and overlays
---
## 18. RELATED COMPONENTS
- **Modal** — Overlay content, not inline
- **Panel** — Larger container, often full-height
- **List Item** — Single row, no grouping
- **Tile** — Image-first card variant
- **KPI Card** — Domain-specific card (Tier 3)
- **Dataset Card** — Domain-specific card (Tier 3)
---
## 19. DDR REFERENCES
- **DDR-001:** Device Adaptive over Desktop First (affects sizing and grid)
- **DDR-002:** Information-level typography (affects header and body text)
- **DDR-003:** Semantic color system (affects states)
- **DDR-005:** Elevation system (affects shadow tokens)
---
## 20. ACCEPTANCE CRITERIA
- [ ] All 12 Definition of Done criteria met
- [ ] Works with screen reader (announces as group or link/button)
- [ ] Keyboard navigation works (Tab, Enter, Space, Arrow keys)
- [ ] Touch target minimum 44px for actionable cards
- [ ] Focus ring visible on actionable cards
- [ ] Loading skeleton state implemented
- [ ] Empty state with guidance
- [ ] Error state handled
- [ ] Reduced motion respected
- [ ] No nested cards
---
## ÄNDRINGSHISTORIA
| Version | Datum | Beskrivning |
|---------|-------|-------------|
| 1.0 | 2026-07-02 | Initial RFC-004 following RFC-001 structure |
---
## STATUS
**DRAFT — Awaiting review**