Files
boc/docs/design/components/RFC-002-Input.md
T
Bernt 78436cecc2 docs: Foundation Freeze v1.0 + directory reorganization
- FOUNDATIONS-v1.0.md:
  - Freeze contract for Landvex Design System
  - Scope: Motion, AI Principles, Semantic Colors, Grid, Elevation, Typography, RFC Template, Definition of Done
  - Reference components: Button, Input, Select, Card (all ~83%)
  - Invariants: token rules, component rules, accessibility rules, AI rules
  - Change policy: no new foundation concepts without v2.0 RFC
  - Versioning: 1.0.x patches, 1.x.0 new components, 2.0.0 new foundations
  - Compatibility matrix for all foundations and components

- Directory reorganization:
  - docs/design/foundations/ → frozen foundation documents
  - docs/design/components/ → component RFCs
  - docs/design/README.md → navigation and structure

- Foundation documents moved:
  - TOKEN_PHILOSOPHY, SEMANTIC_COLOR_SYSTEM, GRID_ELEVATION
  - AI_DESIGN_PRINCIPLES, COMPONENT_TEMPLATE, RFC_DEFINITION_OF_DONE
  - DESIGN_ANTI_PATTERNS, COMPONENT_DECISION_TREE, GLOSSARY
  - BRAND_PALETTE, RELEASE_DEFINITION, SEMANTIC_COLOR_SYSTEM_REVIEW

- Component RFCs moved:
  - RFC-002-Input, RFC-003-Select, RFC-004-Card

Rationale: Clear separation between foundations (stable platform) and
components (built on top). Foundations v1.0 frozen — components can be
added freely within v1.x, but foundations require v2.0 RFC to change.
This prevents gradual erosion of the design system architecture.
2026-07-02 11:23:10 +00:00

266 lines
8.6 KiB
Markdown

# RFC-002: Canonical Input Component
**Status:** 🟡 Draft — Under review
**Tier:** 1 (Canonical)
**Inherits From:** — (root component)
**Author:** AI Agent
**Date:** 2026-07-02
---
## 1. COGNITIVE PURPOSE
Input exists to capture free-form text or numeric data from the user. It is the primary interface for data entry in forms, filters, and search.
**Design Goal:** The user knows what to enter, where to enter it, and whether the entry is valid — without reading documentation.
---
## 2. WHEN TO USE
- Free-form text entry (name, address, description)
- Numeric entry (quantity, price, coordinates)
- Password entry
- Search queries
- Filter values
## 3. WHEN NOT TO USE
- Selection from predefined options (use Select)
- Boolean toggle (use Switch or Checkbox)
- Date/time selection (use Date Picker)
- File upload (use File Input)
- Rich text (use Rich Text Editor)
---
## 4. USER EXPECTATION
- Input field is identifiable as editable
- Placeholder text hints at expected format
- Focus state indicates where typing will appear
- Validation errors are shown immediately or on blur
- Required fields are marked
- Disabled fields are visually distinct
---
## 5. INTERACTION CONTRACT
| Event | Response |
|-------|----------|
| Click | Focus input, place cursor |
| Type | Character appears at cursor position |
| Tab | Move focus to next field |
| Shift+Tab | Move focus to previous field |
| Blur | Validate (if configured), show error if invalid |
| Enter | Submit form (if single-line), new line (if multi-line) |
| Escape | Clear input (if configured), or cancel |
---
## 6. FAILURE BEHAVIOUR
| Scenario | Response |
|----------|----------|
| Invalid input on blur | Show error message below input, red border |
| Invalid input on submit | Show error, scroll to first error, focus it |
| Network validation fails | Show error, allow retry |
| Input exceeds max length | Prevent further input, show character count |
| Input is required but empty | Show error on blur or submit |
| Input is disabled | Ignore all interactions, show disabled state |
---
## 7. ACCESSIBILITY CONTRACT
- **Label:** Every input MUST have an associated `<label>` or `aria-label`
- **Focus:** Focus ring MUST be visible (WCAG 2.4.7)
- **Error:** Error message MUST be associated with `aria-describedby`
- **Required:** Required state MUST be communicated with `aria-required` or `required` attribute
- **Screen reader:** MUST announce label, current value, and error state
- **Color:** Error state MUST NOT rely on color alone (icon or text required)
---
## 8. AI CONTRACT
| Scenario | AI Choice |
|----------|-----------|
| Free-form text entry | Input |
| Predefined options | Select |
| Boolean toggle | Switch / Checkbox |
| Date/time | Date Picker |
| File upload | File Input |
| Search with suggestions | Search (specialized component) |
---
## 9. TOKEN DEPENDENCIES
| Token | Semantic Reference | Usage |
|-------|-------------------|-------|
| Token | Semantic Alias | Primitive | Usage |
|-------|---------------|-----------|-------|
| `input-bg` | `color.surface.default` | `gray-0` | Background |
| `input-border` | `color.border.default` | `gray-200` | Default border |
| `input-border-focus` | `color.border.focus` | `blue-500` | Focus border |
| `input-border-error` | `color.border.error` | `red-500` | Error border |
| `input-text` | `color.text.primary` | `gray-900` | Input text |
| `input-placeholder` | `color.text.muted` | `gray-400` | Placeholder text |
| `input-padding` | `space-3` | `12px` | Internal padding |
| `input-radius` | `radius-md` | `8px` | Border radius |
| `input-height-sm` | `space-8` | `32px` | Small height |
| `input-height-md` | `space-10` | `40px` | Medium height |
| `input-height-lg` | `space-12` | `48px` | Large height |
| `input-error-bg` | `color.status.danger` (at 5%) | `red-50` | Error background tint |
| `input-disabled-bg` | `color.surface.raised` | `gray-50` | Disabled background |
| `input-disabled-text` | `color.text.muted` | `gray-400` | Disabled text |
---
## 10. LAYOUT
```
┌─────────────────────────────────────┐
│ Label (optional) │
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐ │
│ │ Placeholder text... │ │
│ └─────────────────────────────────┘ │
│ Helper text / Error message │
└─────────────────────────────────────┘
```
- **Label:** Above input, left-aligned, `text-sm`, `font-medium`
- **Input:** Full width of container, padding `space-3`
- **Helper/Error:** Below input, `text-xs`, `color.text.muted` (helper) or `color.status.danger` (error)
- **Gap:** `space-1` between label and input, `space-1` between input 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 input |
| Ghost | No border, underline only | Minimal UI, filters |
| Filled | Solid background, no border | High-contrast forms |
---
## 13. STATES
| State | Visual | Motion |
|-------|--------|--------|
| Default | `input-border`, `input-bg` | — |
| Hover | Border darkens slightly | `duration-instant` |
| Focus | `input-border-focus`, focus ring | `duration-instant` |
| Active | Same as focus | — |
| Disabled | `input-disabled-bg`, `input-disabled-text` | — |
| Error | `input-border-error`, `input-error-bg` | `duration-interaction` |
| Loading | Spinner inside input, disabled | `duration-attention` |
| Valid | Green checkmark icon (optional) | `duration-interaction` |
---
## 14. KEYBOARD
| Key | Action |
|-----|--------|
| `Tab` | Move focus to next field |
| `Shift+Tab` | Move focus to previous field |
| `Enter` | Submit form (single-line) |
| `Escape` | Clear input (if clearable) |
| `Ctrl+A` | Select all text |
| `Ctrl+C/V/X` | Copy/paste/cut |
---
## 15. TOUCH
- Touch target: Minimum 40px height (Medium size)
- Active state: Brief background tint
- No gesture support (no swipe, pinch)
---
## 16. MOTION
| Transition | Animation | Duration | Easing |
|-----------|-----------|----------|--------|
| Focus | Border color change | `duration-instant` | `ease-out` |
| Error appear | Border + background tint | `duration-interaction` | `ease-out` |
| Error disappear | Revert to default | `duration-interaction` | `ease-in` |
| Loading spinner | Rotate | `duration-background` | `linear` |
**Reduced Motion:** All transitions become instant (`duration-instant`).
---
## 17. ANTI-PATTERNS
-**Placeholder as label:** Placeholder disappears on typing, user loses context
-**Validation only on submit:** User should know immediately if input is wrong
-**No visual feedback on focus:** User cannot see where they are typing
-**Error message in color only:** Screen reader users miss it
-**Input without label:** Accessibility failure, unclear purpose
-**Too many variations:** Stick to Default, Ghost, Filled
---
## 18. RELATED COMPONENTS
- **Select** — Predefined options instead of free-form
- **Textarea** — Multi-line text entry
- **Search** — Input with autocomplete and suggestions
- **Form** — Groups inputs with validation logic
- **Label** — Associated text for input
---
## 19. DDR REFERENCES
- **DDR-001:** Device Adaptive over Desktop First (affects input sizing)
- **DDR-002:** Information-level typography (affects label and helper text)
- **DDR-003:** Semantic color system (affects error and disabled states)
---
## 20. ACCEPTANCE CRITERIA
- [ ] All 12 Definition of Done criteria met
- [ ] Works with screen reader (NVDA, VoiceOver, JAWS)
- [ ] Keyboard navigation works (Tab, Shift+Tab, Enter, Escape)
- [ ] Touch target minimum 40px on mobile
- [ ] Error state visible without color alone
- [ ] Placeholder does not replace label
- [ ] Loading state prevents duplicate submission
- [ ] Disabled state clearly distinct from enabled
- [ ] Focus ring visible and logical
- [ ] Reduced motion respected
---
## ÄNDRINGSHISTORIA
| Version | Datum | Beskrivning |
|---------|-------|-------------|
| 1.0 | 2026-07-02 | Initial RFC-002 following RFC-001 structure |
---
## STATUS
**DRAFT — Awaiting review**