Add Input, Checkbox, Radio, and Switch form components with semantic token layer
Build four form primitives from Figma references with brand-aligned creative decisions: restrained press states (scale-95 instead of highlight splashes), clean iconless Switch, and consistent error states with inline warning icons. Introduce form-control semantic tokens (--color-control-*) in tokens.css so all form components share a single source for borders, checked states, focus rings, labels, and errors. Retrofit Input to use these tokens instead of direct palette references. Update CLAUDE.md and ARCHITECTURE.md with token layer documentation, token discipline rule (no palette references in components), and component tier decision criteria. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,8 +26,17 @@ Components (use Tailwind utilities or var() references)
|
||||
Storybook (visual verification)
|
||||
```
|
||||
|
||||
### Token Layers
|
||||
Tokens are structured in three layers:
|
||||
|
||||
1. **Palette** — raw colour values (`--color-blue-01`, `--color-grey-03`). Not used directly in components.
|
||||
2. **Semantic** — purpose-based aliases (`--color-primary`, `--color-error`, `--color-text`). General UI usage.
|
||||
3. **Form control** — shared interactive-state tokens for all form components (`--color-control-border`, `--color-control-checked`, `--color-control-label`, etc.). Ensures consistent styling across Input, Checkbox, Radio, Switch, Select, and future form primitives.
|
||||
|
||||
### Token Categories
|
||||
- **Colours**: `--color-*` (bg, surface, border, text, primary, success, warning, error)
|
||||
- **Palette colours**: `--color-{palette}-{shade}` (e.g., `--color-blue-01`, `--color-grey-03`)
|
||||
- **Semantic colours**: `--color-{purpose}` (e.g., `--color-primary`, `--color-error`, `--color-text`)
|
||||
- **Form control colours**: `--color-control-{role}` (e.g., `--color-control-border`, `--color-control-checked`)
|
||||
- **Radii**: `--radius-*` (sm, default, lg, full)
|
||||
- **Shadows**: `--shadow-*` (default, md)
|
||||
|
||||
@@ -40,7 +49,8 @@ Declaring `--color-primary: #2563eb` inside `@theme` in `tokens.css` automatical
|
||||
|
||||
### `src/components/ui/` — Primitives
|
||||
Atomic, reusable building blocks. Each is self-contained with no domain logic.
|
||||
- Button, Input, Textarea, Select
|
||||
- Button, Input, Checkbox, Radio/RadioGroup, Switch
|
||||
- Textarea, Select
|
||||
- Card, Badge, Tag
|
||||
- Dialog, Tooltip, Popover
|
||||
|
||||
@@ -55,6 +65,17 @@ Page-level structural components.
|
||||
- AppShell (header + sidebar + content area)
|
||||
- PageHeader
|
||||
|
||||
### Which Tier Does a Component Belong To?
|
||||
|
||||
| Question | If yes → |
|
||||
|---|---|
|
||||
| Does it wrap a single native element or a single interaction pattern (button, input, toggle)? | **ui/** (primitive) |
|
||||
| Does it compose 2+ primitives into a reusable unit (e.g., a search bar = Input + Button)? | **composite/** |
|
||||
| Does it carry domain-specific naming or logic (e.g., ThemeCard, ParticipantRow)? | **composite/** |
|
||||
| Does it define a page-level region or shell (header, sidebar, content area)? | **layout/** |
|
||||
|
||||
When in doubt: start in `ui/`. Promote to `composite/` when a component begins importing other `ui/` components. If the `composite/` directory grows beyond ~15 components, consider splitting it into `molecules/` (generic compositions) and `organisms/` (domain-aware compositions).
|
||||
|
||||
---
|
||||
|
||||
## 4. Styling Approach
|
||||
@@ -62,6 +83,7 @@ Page-level structural components.
|
||||
- **Primary**: Tailwind utility classes
|
||||
- **Conditional classes**: `cn()` from `@/lib/utils` (clsx + tailwind-merge)
|
||||
- **Token values**: Always from `src/tokens/tokens.css`, never hardcoded
|
||||
- **Token discipline**: Components reference semantic or form-control tokens, not palette tokens. If the needed semantic token doesn't exist, add it to `tokens.css` before using a raw palette value.
|
||||
- **No CSS modules, no styled-components, no inline styles** (except truly dynamic values)
|
||||
- **Class ordering**: Enforced by `prettier-plugin-tailwindcss`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user