@spark-web/design-system 5.1.3 → 5.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,236 +0,0 @@
1
- # Layer 2 — Surface & Pattern files
2
-
3
- ## What this layer is
4
-
5
- The surface and pattern layer sits between the root and individual component
6
- rules. It has two responsibilities:
7
-
8
- 1. **Surface classifier** — determines _which product_ is being built before any
9
- component is touched.
10
- 2. **Surface rules** — defines interaction behaviour that applies globally
11
- across all components on that surface.
12
-
13
- Together they answer: _"For this surface, what are the rules that override
14
- component defaults?"_
15
-
16
- ---
17
-
18
- ## Where these files live
19
-
20
- ```
21
- docs/patterns/
22
- CLAUDE.md ← surface classifier (always read first)
23
- internal-admin/
24
- CLAUDE.md ← surface rules for internal admin
25
- list-page.md ← feature pattern: list of records
26
- form-page.md ← feature pattern: create / edit (coming soon)
27
- detail-page.md ← feature pattern: record detail (coming soon)
28
- customer-portal/ ← not yet defined
29
- website/ ← not yet defined
30
- ```
31
-
32
- ---
33
-
34
- ## File 1 — The surface classifier (`docs/patterns/CLAUDE.md`)
35
-
36
- ### What it does
37
-
38
- This is the agent's second read (after the root). Its only job is to map signals
39
- from a PRD or feature brief to a named surface, then point the agent at the
40
- correct surface rules file.
41
-
42
- ### What it must contain
43
-
44
- **A signal-to-surface lookup table.** Words or phrases that appear in a PRD,
45
- mapped to the surface they indicate:
46
-
47
- | Signal in PRD | Surface |
48
- | ---------------------------------------------------------------- | --------------- |
49
- | "admin", "internal", "back office", "ops", "manage", "dashboard" | Internal admin |
50
- | "customer", "portal", "my account", "self-service" | Customer portal |
51
- | "website", "marketing", "landing page", "public" | Website |
52
- | "mobile", "app", "iOS", "Android" | Mobile app |
53
-
54
- **A pointer to the surface rules file for each defined surface.** Undefined
55
- surfaces should be flagged explicitly so the agent stops and asks rather than
56
- guessing:
57
-
58
- ```markdown
59
- | Surface | Rules location |
60
- | --------------- | -------------------------------------- |
61
- | Internal admin | docs/patterns/internal-admin/CLAUDE.md |
62
- | Customer portal | Not yet defined — flag to the team |
63
- ```
64
-
65
- **A pointer to feature pattern files** for each surface:
66
-
67
- ```markdown
68
- | Feature type | Pattern file |
69
- | ---------------------------- | ----------------------------------------- |
70
- | List of records with actions | docs/patterns/internal-admin/list-page.md |
71
- | Create or edit a record | docs/patterns/internal-admin/form-page.md |
72
- ```
73
-
74
- **The canonical reading order** — a numbered list reinforcing the full sequence
75
- from root to component. This is intentional redundancy: the more times the agent
76
- sees the reading order, the less likely it is to skip steps.
77
-
78
- ```markdown
79
- 1. docs/patterns/CLAUDE.md ← surface classifier (this file)
80
- 2. docs/patterns/[surface]/CLAUDE.md ← surface rules
81
- 3. docs/patterns/[surface]/[pattern].md ← feature pattern (if exists)
82
- 4. packages/[component]/CLAUDE.md ← component rules
83
- 5. packages/[component]/src/[component].stories.tsx ← usage examples
84
- ```
85
-
86
- ---
87
-
88
- ## File 2 — Surface rules (`docs/patterns/[surface]/CLAUDE.md`)
89
-
90
- ### What it does
91
-
92
- Defines interaction and visual rules that apply across **all** components when
93
- building for this surface. These rules sit above component-level CLAUDE.md
94
- files. When a conflict exists between a surface rule and a component rule, the
95
- surface rule wins.
96
-
97
- ### What it must contain
98
-
99
- Rules that are **cross-component** in nature — things that would otherwise be
100
- decided inconsistently component by component. Examples from the internal admin
101
- surface:
102
-
103
- **Row interaction rules**
104
-
105
- Whether a table row is clickable, and what that implies for hover state.
106
- Connecting row clickability to the data model (does a detail page exist?) rather
107
- than leaving it to the agent to infer:
108
-
109
- ```markdown
110
- ### Clickable rows
111
-
112
- - If the PRD describes a detail page, record view, or drill-down → row is
113
- clickable
114
- - If the PRD describes a read-only display with no destination → row is not
115
- clickable
116
- - If unsure, default to clickable
117
-
118
- ### Hover state
119
-
120
- - Row is clickable → hover state always applied
121
- - Row is not clickable → hover state never applied, no exceptions
122
- ```
123
-
124
- **Overflow menu rules**
125
-
126
- A decision tree for when a row gets an overflow menu vs. an inline button vs.
127
- nothing:
128
-
129
- ```markdown
130
- Does the row have actions? No → no overflow menu, no action column Yes → how
131
- many actions? 1 action + row is NOT clickable → inline button or icon 1 action +
132
- row IS clickable → overflow menu 2+ actions → always overflow menu
133
- ```
134
-
135
- **Badge and pill rules**
136
-
137
- When to use a status badge, and how to map status values to visual tones.
138
- Explicit tone definitions prevent the agent from inventing tones:
139
-
140
- ```markdown
141
- - Positive / active / approved / complete → `positive`
142
- - Warning / approaching limit / expiring → `caution`
143
- - Critical / rejected / failed / overdue → `critical`
144
- - Neutral / inactive / archived / unknown → `neutral`
145
- - Pending / in review / awaiting approval → `pending`
146
- ```
147
-
148
- ### What it must NOT contain
149
-
150
- - Component-specific implementation rules (those live in component CLAUDE.md)
151
- - Rules that only apply to one feature type (those live in pattern files)
152
- - Duplication of anything that already lives in a lower layer
153
-
154
- ---
155
-
156
- ## File 3 — Feature pattern file (`[surface]/[pattern].md`)
157
-
158
- ### What it does
159
-
160
- Describes how to assemble a specific type of page or feature — which components
161
- to use, in what order, with what configuration. It is a recipe, not a reference.
162
-
163
- The agent reads this _after_ the surface rules and _before_ component docs.
164
-
165
- ### What it must contain
166
-
167
- - **Component list** — the exact packages to use for this feature type
168
- - **Assembly order** — the layout structure from outermost to innermost
169
- - **Per-component configuration** — which props to set, what to avoid
170
- - **A validation checklist** — the agent must run this before marking the task
171
- complete
172
-
173
- Example structure for a list page:
174
-
175
- ```markdown
176
- ## Components required
177
-
178
- - @spark-web/header
179
- - @spark-web/table (Table, TableHeaderRow, TableHeaderCell, TableRow, TableCell)
180
- - @spark-web/status-badge (if status column present)
181
- - @spark-web/meatball (if row actions present)
182
- - @spark-web/table (TablePagination, outside Table)
183
-
184
- ## Assembly order
185
-
186
- 1. Header
187
- 2. Table a. TableHeaderRow → TableHeaderCell (one per column) b. TableRow (one
188
- per record) → TableCell
189
- 3. TablePagination (sibling of Table, never inside it)
190
-
191
- ## Validation checklist
192
-
193
- - [ ] Header has a title prop
194
- - [ ] Hover state matches row clickability (see surface rules)
195
- - [ ] Meatball only present when 2+ row actions exist
196
- - [ ] Status cells use StatusBadge — no inline styling
197
- - [ ] TablePagination is outside Table
198
- ```
199
-
200
- ---
201
-
202
- ## How this layer connects to the others
203
-
204
- | Layer | Reads from | Overrides |
205
- | ------------------- | ------------------------------- | ---------------------------------------- |
206
- | Root CLAUDE.md | Nothing — entry point | — |
207
- | Surface classifier | Root (via reading order) | — |
208
- | Surface rules | Surface classifier | Component defaults |
209
- | Feature pattern | Surface rules | Nothing — it assembles, doesn't override |
210
- | Component CLAUDE.md | Feature pattern (per component) | Nothing for this surface |
211
-
212
- ---
213
-
214
- ## How to add a new surface
215
-
216
- 1. Create a folder at `docs/patterns/[surface-name]/`.
217
- 2. Create `CLAUDE.md` inside it with the surface rules (row behaviour, badge
218
- rules, any globally applicable interaction patterns).
219
- 3. Add a row to the signal table in `docs/patterns/CLAUDE.md` pointing to the
220
- new file.
221
- 4. Update the root `CLAUDE.md` if needed to note the new surface.
222
- 5. Create pattern files (list, form, detail, etc.) as features are designed.
223
-
224
- Do not build for a surface until its rules file exists. An undefined surface
225
- means the agent has no contract and will make assumptions.
226
-
227
- ---
228
-
229
- ## What happens if this layer is missing or incomplete
230
-
231
- - The agent applies component defaults regardless of surface context — hover
232
- states, overflow menus, and badge tones become inconsistent across pages.
233
- - Surface-level rules that conflict with component defaults are silently
234
- ignored.
235
- - Two agents working on the same surface independently will produce different
236
- interaction patterns.
@@ -1,271 +0,0 @@
1
- # Layer 3 — Component CLAUDE.md files
2
-
3
- ## What this layer is
4
-
5
- Every component package that an agent is expected to use gets its own
6
- `CLAUDE.md` inside `packages/[component]/`. This file is the agent's contract
7
- for that component: what it does, how its pieces fit together, what tokens to
8
- use, and what it must never do.
9
-
10
- This is the most granular layer. It is read last — only after the surface
11
- classifier, surface rules, and feature pattern have already been read. By the
12
- time the agent reaches this file it already knows _which_ components to use and
13
- _why_. This file tells it _how_.
14
-
15
- ---
16
-
17
- ## Where these files live
18
-
19
- ```
20
- packages/
21
- table/
22
- CLAUDE.md ← component rules for @spark-web/table
23
- src/
24
- Table.tsx
25
- table.stories.tsx
26
- table.test.tsx
27
- status-badge/
28
- CLAUDE.md
29
- meatball/
30
- CLAUDE.md
31
- header/
32
- CLAUDE.md
33
- ...
34
- ```
35
-
36
- One `CLAUDE.md` per package. Not one per sub-component — one per package.
37
-
38
- ---
39
-
40
- ## Anatomy of a component CLAUDE.md
41
-
42
- The sections below are the standard structure. Every component file should
43
- follow this shape. Use `@spark-web/table` as the reference example.
44
-
45
- ---
46
-
47
- ### Section 1 — What this package is
48
-
49
- One short paragraph. Plain language. States the component's purpose and its
50
- compositional structure (sub-components, if any).
51
-
52
- ```markdown
53
- ## What this package is
54
-
55
- A composable table component for displaying tabular data. Five sub-components
56
- used together: Table, TableHeaderRow, TableHeaderCell, TableRow, TableCell.
57
- Optional TablePagination is a separate compositional layer used OUTSIDE Table.
58
- ```
59
-
60
- ---
61
-
62
- ### Section 2 — What this package is NOT
63
-
64
- Equally important. Explicitly rules out common misuses. This prevents the agent
65
- from reaching for this component when a different one is needed, and prevents it
66
- from adding features the component was never designed to have.
67
-
68
- ```markdown
69
- ## What this package is NOT
70
-
71
- - Not a data-grid. No virtual scrolling, column reordering, or column resizing.
72
- - Not a standalone component. TableRow and TableCell are meaningless outside
73
- Table.
74
- - Not responsible for data fetching, sorting, or filtering.
75
- ```
76
-
77
- ---
78
-
79
- ### Section 3 — Component hierarchy
80
-
81
- Shows the parent/child relationship between sub-components. For simple single-
82
- component packages this can be omitted. For composable packages it is essential.
83
-
84
- ```markdown
85
- ## Component hierarchy
86
-
87
- Table ← scroll container, layout owner TableHeaderRow ← always first child of
88
- Table TableHeaderCell ← one per column, owns sort state TableRow (× n) ← one per
89
- data row, owns row state TableCell (× n) ← one per column per row
90
- TableRow[state=loading] ← replaces data rows during fetch, no children
91
-
92
- TablePagination is always OUTSIDE and BELOW Table — never inside it.
93
- ```
94
-
95
- ---
96
-
97
- ### Section 4 — Token usage
98
-
99
- All design token values the component uses, grouped by category. This is the
100
- most mechanical section and must be exhaustive — if a token is omitted the agent
101
- will either guess or use a raw value.
102
-
103
- Every token must reference `useTheme()` from `@spark-web/theme`. Raw hex values,
104
- pixel values, and Tailwind classes are never acceptable.
105
-
106
- ```markdown
107
- ## Token usage
108
-
109
- All values from useTheme() from @spark-web/theme.
110
-
111
- ### Spacing tokens
112
-
113
- Cell padding all sides: theme.spacing.large Header cell padding horizontal:
114
- theme.spacing.large Pagination gap between buttons: theme.spacing.small
115
-
116
- ### Color tokens
117
-
118
- Cell background default: theme.color.background.surface Cell background hover:
119
- theme.color.background.inputPressed Cell text default:
120
- theme.color.foreground.neutral Header cell background:
121
- theme.color.background.surface
122
-
123
- ### Typography
124
-
125
- Use @spark-web/text for all text. Never raw <p> or <span>. Cell content:
126
- <Text tone="neutral"> using Body/Small scale Header cell label:
127
- <Text weight="semibold"> using xSmall scale
128
- ```
129
-
130
- ---
131
-
132
- ### Section 5 — States (if applicable)
133
-
134
- For components with visual states, list every valid state, the prop that
135
- controls it, and the tokens that apply. Be specific about which states interact
136
- (e.g. hover must not apply when state is disabled).
137
-
138
- ```markdown
139
- ## Row states
140
-
141
- state prop on TableRow: 'default' | 'selected' | 'disabled' | 'loading' Hover is
142
- CSS :hover only — not a state prop.
143
-
144
- default: theme.color.background.surface, text theme.color.foreground.neutral
145
- hover: theme.color.background.inputPressed, text theme.color.foreground.neutral
146
- selected: theme.color.background.primarySoft, text
147
- theme.color.foreground.neutral disabled: theme.color.background.inputDisabled,
148
- text theme.color.foreground.disabled, pointer-events none loading:
149
- theme.color.background.surface, renders "Loading" + spinner, ignores children
150
-
151
- Hover must NOT apply when state is disabled or loading.
152
- ```
153
-
154
- ---
155
-
156
- ### Section 6 — Composition rules
157
-
158
- Numbered constraints on how sub-components must be assembled. These prevent
159
- structural errors that would silently render incorrectly or break at runtime.
160
-
161
- ```markdown
162
- ## Composition rules
163
-
164
- 1. Table must always contain exactly one TableHeaderRow as its first child.
165
- 2. TableHeaderRow must contain one TableHeaderCell per column.
166
- 3. TableRow must contain the same number of TableCell children as header
167
- columns.
168
- 4. A loading TableRow ignores all children.
169
- 5. TablePagination is always a sibling of Table, never a child.
170
- ```
171
-
172
- ---
173
-
174
- ### Section 7 — Do NOTs
175
-
176
- A bulleted list of the most common agent mistakes for this component, stated as
177
- explicit prohibitions. These should cover the things an agent would most likely
178
- get wrong if it had only read the component source code without this file.
179
-
180
- ```markdown
181
- ## Do NOTs
182
-
183
- - NEVER raw hex values e.g. #1a2a3a — always use theme color tokens
184
- - NEVER raw pixel values e.g. 16px — always use theme spacing/sizing tokens
185
- - NEVER Tailwind classes — use Emotion CSS-in-JS via useTheme()
186
- - NEVER TableCell state prop — state on TableRow only
187
- - NEVER TablePagination inside Table
188
- - NEVER raw <table> <tr> <th> <td> HTML elements
189
- - NEVER omit forwardRef
190
- - NEVER re-implement the status dot/pill inline — use StatusBadge
191
- ```
192
-
193
- ---
194
-
195
- ## How this layer defers to surface rules
196
-
197
- A component CLAUDE.md defines _default_ behaviour. Surface rules override those
198
- defaults for a specific product context.
199
-
200
- Example: the table component has a hover state. The component CLAUDE.md defines
201
- the token to use for that hover state. The internal admin surface rules define
202
- _when_ hover is applied at all (only on clickable rows). The component file does
203
- not repeat the surface rule — it only documents what the hover state looks like
204
- when it is applied.
205
-
206
- If you find yourself writing a rule in a component CLAUDE.md that says "on admin
207
- pages, do X" — stop. That rule belongs in the surface rules file, not here.
208
-
209
- ---
210
-
211
- ## When to create a component CLAUDE.md
212
-
213
- Create one when any of the following are true:
214
-
215
- - The component has sub-components that must be assembled in a specific order
216
- - The component uses design tokens that an agent would otherwise guess at
217
- - There are common misuses that would be hard to catch from the component's
218
- TypeScript types alone
219
- - The component has states or variants with non-obvious visual behaviour
220
- - The component depends on another package that must always be used alongside it
221
-
222
- Do NOT create one for simple, single-element components with no configuration
223
- surface. If the TypeScript types and stories are sufficient, a CLAUDE.md adds no
224
- value.
225
-
226
- ---
227
-
228
- ## Relationship to Storybook stories
229
-
230
- The component CLAUDE.md defines rules. The `.stories.tsx` file shows correct
231
- usage in real-world context. Both are required reading for the agent — the
232
- CLAUDE.md alone may not cover every prop combination, and stories alone do not
233
- explain why constraints exist.
234
-
235
- The reading order from the root file enforces this:
236
-
237
- ```
238
- 4. packages/[component]/CLAUDE.md ← rules
239
- 5. packages/[component]/src/[component].stories.tsx ← usage examples
240
- ```
241
-
242
- Never reference a story in the CLAUDE.md and say "see stories for examples" as a
243
- substitute for writing out the composition rules. The rules must be explicit in
244
- this file.
245
-
246
- ---
247
-
248
- ## What happens if this layer is missing or incomplete
249
-
250
- - The agent uses raw values (`#1a2a3a`, `16px`) instead of theme tokens,
251
- breaking dark mode support and responsive scaling.
252
- - Sub-components are assembled in the wrong order or at the wrong nesting level
253
- (e.g. `TablePagination` inside `Table`).
254
- - State props are applied to the wrong sub-component.
255
- - The agent re-implements functionality that already exists in a dependency
256
- (e.g. builds a custom status pill instead of using `@spark-web/status-badge`).
257
-
258
- ---
259
-
260
- ## Installed component context
261
-
262
- When `@spark-web/design-system` is installed, component-level CLAUDE.md files
263
- are available at `node_modules/@spark-web/{name}/CLAUDE.md`. Read the relevant
264
- file before working with any of the following components:
265
-
266
- - `node_modules/@spark-web/description-list/CLAUDE.md`
267
- - `node_modules/@spark-web/highlight-card/CLAUDE.md`
268
- - `node_modules/@spark-web/overflow-menu/CLAUDE.md`
269
- - `node_modules/@spark-web/section-card/CLAUDE.md`
270
- - `node_modules/@spark-web/section-header/CLAUDE.md`
271
- - `node_modules/@spark-web/tag/CLAUDE.md`