Record the move from a fork-based downstream model to versioned npm-package consumption (GitHub Packages, @richiesnitch/ads3-design-system). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
183 lines
11 KiB
Markdown
183 lines
11 KiB
Markdown
# ARCHITECTURE.md — ADS 3.0 Design System
|
||
|
||
This is the living architecture document for the ADS 3.0 design system. All structural decisions are recorded here. Update this document when the architecture evolves — never let the codebase and this document drift apart.
|
||
|
||
---
|
||
|
||
## 1. Overview
|
||
|
||
ADS 3.0 Design System is a React component library implementing the ADS 3.0 (Adaptive Design System) design language. It provides tokens, primitives, and composite components as a shared foundation. Application-specific screens and domain logic belong in **consuming applications**, not in this repo.
|
||
|
||
### Distribution
|
||
|
||
ADS is distributed as a **versioned npm package** consumed by downstream apps — not by forking this repo. (The earlier fork-based model has been superseded.)
|
||
|
||
- Published to **GitHub Packages** as `@richiesnitch/ads3-design-system` from `Richiesnitch/ads3-design-system`; a publish-on-tag GitHub Action runs `build:lib` and `npm publish`.
|
||
- Built via `npm run build:lib` (`vite.lib.config.ts`): bundles `src/index.ts` to ESM with React/react-dom externalised and internal `@/` imports resolved at build time; emits type declarations and copies `tokens.css` / `typography.css` into `dist/`.
|
||
- Consumers import components from the package entry, `@richiesnitch/ads3-design-system/tokens` + `/typography` for the design-token CSS, and point Tailwind's `@source` at the built bundle to generate utilities. No `@/` alias or sibling-folder clone required.
|
||
|
||
---
|
||
|
||
## 2. Token Pipeline
|
||
|
||
```
|
||
Figma (design tool)
|
||
↓ Figma MCP / get_variable_defs
|
||
src/tokens/tokens.css (@theme block)
|
||
↓ Tailwind CSS v4 reads @theme
|
||
↓ Generates utility classes + CSS custom properties
|
||
Components (use Tailwind utilities or var() references)
|
||
↓ Rendered in
|
||
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.
|
||
4. **Button** — dedicated tokens for the Button component's intent system (`--color-button-default`, `--color-button-danger`, `--color-button-neutral`, `--color-button-subtle-bg`, `--color-button-subtle-text`).
|
||
5. **Badge** — status colour tokens for the Badge component's variant system (`--color-badge-info`, `--color-badge-success`, `--color-badge-error`, `--color-badge-warning`, `--color-badge-neutral`, `--color-badge-text`).
|
||
6. **Chip** — tokens for the Chip component's border/fill states (`--color-chip-border`, `--color-chip-text`, `--color-chip-bg`, `--color-chip-selected-bg`, `--color-chip-selected-text`).
|
||
7. **Tag** — colour tokens for the Tag component's 11-colour system (`--color-tag-navy`, `--color-tag-blue`, `--color-tag-green`, `--color-tag-red`, `--color-tag-orange`, `--color-tag-grey`, `--color-tag-teal`, `--color-tag-brown`, `--color-tag-purple`, `--color-tag-fuchsia`, `--color-tag-yellow`, plus `-light` variants for each).
|
||
8. **Alert** — background, border, and icon colour tokens for 5 alert variants (`--color-alert-{variant}-bg`, `--color-alert-{variant}-border`, `--color-alert-{variant}-icon` for info, warning, error, success, neutral).
|
||
9. **Switch** — dedicated on-state tokens (`--color-switch-on`, `--color-switch-on-hover`) using success green per ADS 3.0.
|
||
10. **Avatar** — background and text colour tokens (`--color-avatar`, `--color-avatar-text`).
|
||
11. **TopBar** — background colour token (`--color-topbar`).
|
||
12. **SideNav** — navigation-specific tokens (`--color-nav-bg`, `--color-nav-text`, `--color-nav-icon`, `--color-nav-active`, `--color-nav-divider`).
|
||
|
||
### Token Categories
|
||
- **Palette colours**: `--color-{palette}-{shade}` — 10 families (blue, red, orange, green, teal, brown, purple, fuchsia, yellow, grey) × 4 shades each
|
||
- **Semantic colours**: `--color-{purpose}` (e.g., `--color-primary` = navy, `--color-info` = bright blue, `--color-error`, `--color-text`)
|
||
- **Form control colours**: `--color-control-{role}` (e.g., `--color-control-border`, `--color-control-checked`)
|
||
- **Button colours**: `--color-button-{intent}` (e.g., `--color-button-default`, `--color-button-danger`)
|
||
- **Badge colours**: `--color-badge-{variant}` (e.g., `--color-badge-info`, `--color-badge-error`)
|
||
- **Chip colours**: `--color-chip-{role}` (e.g., `--color-chip-border`, `--color-chip-selected-bg`)
|
||
- **Tag colours**: `--color-tag-{color}` and `--color-tag-{color}-light` (e.g., `--color-tag-blue`, `--color-tag-blue-light`)
|
||
- **Radii**: `--radius-*` (sm, default, lg, full)
|
||
- **Shadows**: `--shadow-*` (default, md)
|
||
|
||
### How Tailwind v4 @theme Works
|
||
Declaring `--color-primary: #2563eb` inside `@theme` in `tokens.css` automatically generates utilities like `bg-primary`, `text-primary`, `border-primary`. No JavaScript config file needed — the CSS file is the config.
|
||
|
||
---
|
||
|
||
## 3. Component Taxonomy
|
||
|
||
### `src/components/atoms/` — Atoms
|
||
Single-purpose, atomic building blocks. Each wraps a single native element or interaction pattern with no domain logic.
|
||
- Button, IconButton
|
||
- Input, Textarea, Select, Autocomplete
|
||
- Checkbox, Radio/RadioGroup, Switch
|
||
- Slider, RangeSlider
|
||
- FileInput
|
||
- Badge, Tag, Chip
|
||
- Tabs (TabList, Tab, TabPanel)
|
||
- List (ListItem, ListSubheader, ListDivider)
|
||
- Avatar, Tooltip
|
||
|
||
### `src/components/molecules/` — Molecules
|
||
Small compositions of atoms into reusable units. May combine icons, text, buttons, or other atoms.
|
||
- Alert, Accordion, Card, Dialog, Popover
|
||
- DataTable
|
||
|
||
### `src/components/organisms/` — Organisms
|
||
Larger compositions that carry domain semantics or define page-level regions. Built from atoms and molecules.
|
||
- TopBar, SideNav, PageHeader
|
||
- *(planned)* DatePicker
|
||
|
||
### `src/components/templates/` — Templates
|
||
Page-level layout components that define the shell and content structure. Templates accept typed slot props (ReactNode) for their sections, making them composable by AI agents and developers. They do not own content — they define where content goes.
|
||
- **AppShell** — TopBar + SideNav + scrollable content area. All pages render inside this.
|
||
- **DashboardPage** — PageHeader + stat cards row + responsive 2-column content grid
|
||
- **ListPage** — PageHeader + stat cards + list header with actions + scrollable item list
|
||
- **FormPage** — PageHeader + optional action bar + optional vertical stepper + constrained-width form content
|
||
- **DetailPage** — PageHeader + optional action bar (e.g. tabs) + single-column constrained content for viewing records/profiles/documents
|
||
- **CenteredPage** — TopBar (optional) + horizontally/vertically centered content, no sidebar. For login, error, onboarding flows
|
||
|
||
Templates have Storybook stories tagged `['autodocs', 'template']` that show realistic "recipe" compositions — full pages built from real components with sample data. These serve as reference implementations for AI coding agents.
|
||
|
||
### 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)? | **atoms/** |
|
||
| Does it compose 2+ atoms into a reusable unit (e.g., Alert = icon + text + close button)? | **molecules/** |
|
||
| Does it carry domain-specific naming or logic (e.g., ThemeCard, ParticipantRow)? | **organisms/** |
|
||
| Does it define a page-level region or shell (header, sidebar, content area)? | **organisms/** |
|
||
| Does it define the layout structure of a full page (slot-based, no owned content)? | **templates/** |
|
||
|
||
When in doubt: start in `atoms/`. Promote to `molecules/` when a component begins importing other atoms.
|
||
|
||
---
|
||
|
||
## 4. Styling Approach
|
||
|
||
- **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 domain-specific tokens (form-control, button), not palette tokens. If the needed 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`
|
||
|
||
---
|
||
|
||
## 5. Storybook Conventions
|
||
|
||
- Every component has a co-located `.stories.tsx` file
|
||
- All stories use `tags: ['autodocs']` for auto-generated docs
|
||
- Stories cover: default state, all variants, edge cases, disabled/error states
|
||
- A11y addon runs on all stories — violations should be addressed
|
||
- MCP addon enabled at `localhost:6006/mcp` for AI-assisted development
|
||
|
||
---
|
||
|
||
## 6. Project Structure
|
||
|
||
```
|
||
src/
|
||
├── components/
|
||
│ ├── atoms/ # Single-purpose elements
|
||
│ ├── molecules/ # Small compositions of atoms
|
||
│ ├── organisms/ # Domain-aware / page-level components
|
||
│ └── templates/ # Page-level layout components (slot-based)
|
||
├── tokens/
|
||
│ └── tokens.css # Design tokens (@theme block)
|
||
├── styles/
|
||
│ └── global.css # Tailwind imports + base styles
|
||
├── lib/
|
||
│ └── utils.ts # cn() utility
|
||
├── hooks/ # Custom React hooks
|
||
├── App.tsx # Root component
|
||
└── main.tsx # Vite entry point
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Design Tool Integration
|
||
|
||
### Figma
|
||
- Project file: https://www.figma.com/design/mrabO6AtxN3ektGiTk0I9c/ResearchInsights (file key: `mrabO6AtxN3ektGiTk0I9c`)
|
||
- MCP server: Official Figma Remote MCP at `https://mcp.figma.com/mcp` (HTTP transport, OAuth auth)
|
||
- Key tools: `get_design_context`, `get_variable_defs`, `get_screenshot`, `search_design_system`, `use_figma`
|
||
- Design tokens extracted via `get_variable_defs` → mapped to `@theme` values in `tokens.css`
|
||
|
||
### Code Connect
|
||
- Links Figma components to their React implementations
|
||
- Once linked, `get_design_context` returns actual component code instead of generic markup
|
||
- Mapped as we build each component via `add_code_connect_map` (label: "React")
|
||
|
||
### Storybook MCP
|
||
- Available at `localhost:6006/mcp` when Storybook dev server is running
|
||
- Provides: component listing, documentation retrieval, story generation, a11y testing
|
||
- `@storybook/addon-designs` embeds Figma frames in the story panel for side-by-side comparison
|
||
- `@storybook/addon-mcp` serves the MCP endpoint
|
||
|
||
### claude2figma Skills
|
||
- 4 skills in `.claude/skills/` that enforce design system compliance when writing to Figma
|
||
- **figma-preflight**: Validates MCP connection, audits libraries, builds a Token Map of all styles/variables
|
||
- **component-rules**: Library-first lookup, Auto Layout conventions, semantic node naming
|
||
- **figma-style-binding**: All visual values must bind to Figma Styles or Variables, never hardcoded; includes post-write QA
|
||
- **reference-interpreter**: Converts screenshots/references into structured Design Briefs mapped to design tokens
|