@arbor-education/design-system.components 0.10.0 โ†’ 0.11.0

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.
Files changed (69) hide show
  1. package/.claude/agent-memory/blanche-designspert/MEMORY.md +64 -0
  2. package/.claude/agent-memory/blanche-designspert/token-review-patterns.md +29 -0
  3. package/.claude/agent-memory/dorothy-fact-checker/MEMORY.md +129 -0
  4. package/.claude/agent-memory/rose-storybookspert/MEMORY.md +29 -0
  5. package/.claude/agent-memory/rose-storybookspert/patterns.md +132 -0
  6. package/.claude/agent-memory/sophia-componentspert/MEMORY.md +14 -0
  7. package/.claude/agent-memory/sophia-componentspert/components.md +367 -0
  8. package/.claude/agents/blanche-designspert.md +150 -0
  9. package/.claude/agents/dorothy-fact-checker.md +145 -0
  10. package/.claude/agents/rose-storybookspert.md +148 -0
  11. package/.claude/agents/sophia-componentspert.md +133 -0
  12. package/.claude/component-library.md +1107 -0
  13. package/.claude/design-assessment-daily-attendance-2026-04-10.md +566 -0
  14. package/.claude/figma-assessment-7154-58899.md +404 -0
  15. package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-11086-97537.md +392 -0
  16. package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-551-41974.md +474 -0
  17. package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-551-43094.md +462 -0
  18. package/.claude/figma-assessment-fcFK4CGzkz2fVyY3koX8ZE-7154-59061.md +440 -0
  19. package/.claude/migration-report-custom-report-writer-2026-02-19.md +591 -0
  20. package/.claude/skills/analyze-design/README.md +295 -0
  21. package/.claude/skills/analyze-design/SKILL.md +741 -0
  22. package/.claude/skills/create-page/README.md +246 -0
  23. package/.claude/skills/create-page/SKILL.md +634 -0
  24. package/.claude/skills/create-page/design-analysis-template.md +333 -0
  25. package/.claude/skills/create-page/page-template.scss +118 -0
  26. package/.claude/skills/create-page/page-template.tsx +230 -0
  27. package/.claude/skills/map-legacy/README.md +87 -0
  28. package/.claude/skills/map-legacy/SKILL.md +465 -0
  29. package/.claude/skills/migrate-page/README.md +125 -0
  30. package/.claude/skills/migrate-page/SKILL.md +374 -0
  31. package/.github/CODEOWNERS +1 -0
  32. package/.github/pull_request_template.md +39 -0
  33. package/CHANGELOG.md +6 -0
  34. package/CLAUDE.md +31 -0
  35. package/CONTRIBUTING.md +191 -0
  36. package/README.md +110 -20
  37. package/dist/components/table/DSDefaultColDef.js +2 -2
  38. package/dist/components/table/DSDefaultColDef.js.map +1 -1
  39. package/dist/components/table/Table.d.ts.map +1 -1
  40. package/dist/components/table/Table.js +2 -0
  41. package/dist/components/table/Table.js.map +1 -1
  42. package/dist/components/table/Table.stories.d.ts +1 -0
  43. package/dist/components/table/Table.stories.d.ts.map +1 -1
  44. package/dist/components/table/Table.stories.js +95 -3
  45. package/dist/components/table/Table.stories.js.map +1 -1
  46. package/dist/components/table/Table.test.js +106 -5
  47. package/dist/components/table/Table.test.js.map +1 -1
  48. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts +3 -0
  49. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -0
  50. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +12 -0
  51. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -0
  52. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts +2 -0
  53. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts.map +1 -0
  54. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js +65 -0
  55. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js.map +1 -0
  56. package/dist/index.css +1 -1
  57. package/dist/index.d.ts +1 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +1 -0
  60. package/dist/index.js.map +1 -1
  61. package/package.json +1 -1
  62. package/src/components/table/DSDefaultColDef.ts +2 -2
  63. package/src/components/table/Table.stories.tsx +99 -3
  64. package/src/components/table/Table.test.tsx +131 -5
  65. package/src/components/table/Table.tsx +2 -0
  66. package/src/components/table/cellRenderers/CheckboxCellRenderer.test.tsx +74 -0
  67. package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +28 -0
  68. package/src/components/table/table.scss +1 -1
  69. package/src/index.ts +1 -0
@@ -0,0 +1,374 @@
1
+ ---
2
+ name: migrate-page
3
+ description: Build a React page that replaces an existing legacy page. Uses a migration report from /map-legacy (or auto-generates one) to compose Arbor components into a production-ready page with tests and Storybook stories.
4
+ ---
5
+
6
+ # Migrate Legacy Page to Arbor Components
7
+
8
+ AROOOOO HUNNI!! ๐Ÿบ Time to rip out those HEINOUS legacy components and replace them with BODACIOUS Arbor ones! We have the migration map โ€” now let's BUILD!! xxx
9
+
10
+ ## Goal
11
+
12
+ Take a migration report (from `/map-legacy`) and a screenshot of the legacy page, and generate a **production-ready React page** that replaces the legacy implementation using Arbor design system components.
13
+
14
+ **This is NOT a fresh build from Figma.** The migration map already tells us what replaces what. We trust Sophia and Dorothy's verified analysis โ€” no need to re-run that work.
15
+
16
+ **CRITICAL:**
17
+ - โŒ DO NOT create new reusable components
18
+ - โœ… DO USE existing components from `src/components/`
19
+ - โœ… DO follow the migration map โ€” it's already been Sophia-mapped and Dorothy-verified
20
+ - โœ… DO use the legacy screenshot as the layout reference (not Figma)
21
+ - โœ… DO use placeholder SVGs for elements with no Arbor equivalent
22
+
23
+ ## The Golden Girls Team โ€” MANDATORY COLLABORATORS
24
+
25
+ Some agents were already used in `map-legacy`. We don't re-do their work. We pick up from where they left off:
26
+
27
+ - ~~๐Ÿ‘œ **Sophia Componentspert**~~ โ€” Already ran in `map-legacy`. Her mapping is in the report. **Do NOT call her again** unless you hit an edge case not covered in the report.
28
+ - ~~๐Ÿ” **Dorothy Fact-Checker**~~ โ€” Already verified Sophia's claims in `map-legacy`. Trust the report. **Do NOT call her again** for component capability checks.
29
+ - ๐Ÿ’„ **Blanche Designspert** (`blanche-designspert`) โ€” MANDATORY at Step 6. Design token and CSS class naming review.
30
+ - ๐ŸŒน **Rose Storybookspert** (`rose-storybookspert`) โ€” MANDATORY at Step 8. Storybook stories.
31
+ - ๐Ÿ” **Dorothy Fact-Checker** (`dorothy-fact-checker`) โ€” MANDATORY at Step 9. Final QA on the generated files.
32
+
33
+ **RULE**: Blanche, Rose, and Dorothy (final QA) are NOT optional. Skip any of them = MOST HEINOUS failure. AROOOOO!! ๐Ÿบ๐Ÿ’ช
34
+
35
+ ## Input
36
+
37
+ Screenshot path and/or migration report path provided: `$ARGUMENTS`
38
+
39
+ ## Process
40
+
41
+ ### 1. Determine Input
42
+
43
+ Check what the user provided:
44
+
45
+ - **Both screenshot + report path**: Best case โ€” use both
46
+ - **Screenshot only, no report**: Auto-run `/map-legacy` first:
47
+ ```
48
+ Use Skill tool: skill="map-legacy", args="[screenshot path]"
49
+ ```
50
+ Wait for it to complete and find the generated `.claude/migration-report-*.md` file.
51
+ - **Report path only, no screenshot**: Read the report, use it without a visual reference (note this in the output)
52
+ - **Neither**: Ask the user for at least a screenshot path or a migration report path
53
+
54
+ ### 2. Read the Migration Report
55
+
56
+ Use the `Read` tool on the migration report file. This is your **primary guide** โ€” it contains:
57
+ - The complete legacy element โ†’ Arbor component mapping (already verified by Dorothy)
58
+ - Complexity ratings (Low / Medium / High / No equivalent)
59
+ - Prop mappings and gotchas in Sophia's voice
60
+ - A recommended migration order
61
+ - Elements with no Arbor equivalent (โ†’ placeholder SVGs)
62
+
63
+ ```
64
+ Read tool: file_path=".claude/migration-report-{page-name}-{date}.md"
65
+ ```
66
+
67
+ **CRITICAL:** Trust the report. Sophia and Dorothy already did the hard work. Do NOT second-guess the component choices or re-research them from scratch. If the report says use `Table.BulkActionsDropdown`, use it.
68
+
69
+ ### 3. Read the Screenshot (if provided)
70
+
71
+ Use the `Read` tool on the screenshot path. This gives you the **visual layout reference** โ€” use it to understand:
72
+ - The overall page layout (two-column? header + content? sidebar?)
73
+ - Relative sizing and spacing of sections
74
+ - The order elements appear on the page
75
+ - What content is in the page (text, labels, data examples)
76
+
77
+ ```
78
+ Read tool: file_path="[screenshot path]"
79
+ ```
80
+
81
+ ### 4. Determine Page Name and Directory
82
+
83
+ Derive the page name from the migration report title (e.g. "Custom Report Writer โ€” All Reports" โ†’ `CustomReportWriterPage`).
84
+
85
+ **Directory:**
86
+ ```
87
+ src/pages/{pageName}/
88
+ โ”œโ”€โ”€ {PageName}.tsx
89
+ โ”œโ”€โ”€ {PageName}.test.tsx
90
+ โ”œโ”€โ”€ {PageName}.stories.tsx
91
+ โ””โ”€โ”€ {pageName}.scss
92
+ ```
93
+
94
+ Read `src/index.ts` to check whether a page with this name already exists. If it does, confirm with the user before overwriting.
95
+
96
+ ### 5. Build the Page
97
+
98
+ #### 5a. Plan the structure
99
+
100
+ Go through the migration report's **Recommended Migration Order**. Group elements into:
101
+ - **Page layout** (header, main, sidebar, footer)
102
+ - **Sections** (using `Section` component)
103
+ - **Toolbar elements** (buttons, dropdowns, search)
104
+ - **Table** (if present โ€” use the full `columnDefs` from the report)
105
+ - **Gaps** (no equivalent โ†’ placeholder SVGs)
106
+
107
+ #### 5b. Generate the TSX
108
+
109
+ Create the page component. Import ONLY from the design system using path aliases:
110
+
111
+ ```tsx
112
+ import { Button } from 'Components/button/Button';
113
+ import { Heading } from 'Components/heading/Heading';
114
+ // etc.
115
+ ```
116
+
117
+ **Component mapping rules from the report:**
118
+ - Follow the migration report's element-by-element breakdown for every component choice
119
+ - Use the exact prop names Sophia specified (Dorothy verified them)
120
+ - Include Sophia's specific gotchas from the report (e.g. `headerContent={<></>}` to trigger SearchBar)
121
+ - Use `Heading.InnerContainer` pattern for heading + right-side CTA if the report recommends it
122
+
123
+ **For Table pages specifically:**
124
+ - Inline `cellRenderer` functions for link cells, icon+text cells, overflow menus
125
+ - `Table.BulkActionsDropdown` and `Table.HideColumnsDropdown` in `headerContent`
126
+ - `hasSearch` defaults to `true` when `headerContent` is set โ€” no extra work needed
127
+ - Do NOT call `setAgGridLicenseKey()` โ€” Table handles it
128
+ - Do NOT spread `DSDefaultColDef` โ€” Table merges it automatically
129
+
130
+ **For elements with no Arbor equivalent (โŒ in report):**
131
+
132
+ Use the placeholder SVG pattern:
133
+
134
+ ```tsx
135
+ {/*
136
+ โš ๏ธ MISSING COMPONENT PLACEHOLDER
137
+ Component: [ComponentName e.g. "Breadcrumbs"]
138
+ Reason: No Arbor equivalent โ€” flagged in migration report as a gap.
139
+ TODO: Replace once [ComponentName] is built in the design system.
140
+ */}
141
+ <svg
142
+ role="img"
143
+ aria-label="[ComponentName] placeholder - component not yet available in design system"
144
+ width="100%"
145
+ height={approximateHeight}
146
+ xmlns="http://www.w3.org/2000/svg"
147
+ >
148
+ <rect width="100%" height="100%" fill="#f5f5f5" rx="4" />
149
+ <rect
150
+ x="2" y="2"
151
+ width="calc(100% - 4px)" height={approximateHeight - 4}
152
+ fill="none" stroke="#cccccc" strokeWidth="2" strokeDasharray="8 4" rx="3"
153
+ />
154
+ <text x="50%" y="42%" textAnchor="middle" dominantBaseline="middle"
155
+ fill="#888888" fontSize="13" fontWeight="600" fontFamily="sans-serif">
156
+ [ComponentName]
157
+ </text>
158
+ <text x="50%" y="65%" textAnchor="middle" dominantBaseline="middle"
159
+ fill="#aaaaaa" fontSize="11" fontFamily="sans-serif">
160
+ Component not yet available in design system
161
+ </text>
162
+ </svg>
163
+ ```
164
+
165
+ **Page props pattern** โ€” expose callbacks and initial data:
166
+
167
+ ```tsx
168
+ export interface {PageName}Props {
169
+ className?: string;
170
+ // Callbacks for primary actions
171
+ onCreateNew?: () => void;
172
+ onSchedule?: () => void;
173
+ // Data props
174
+ initialData?: RowType[];
175
+ // etc.
176
+ }
177
+ ```
178
+
179
+ **Typing:**
180
+ - No `any` types โ€” ever
181
+ - Define row types for table data
182
+ - Export type definitions with the component
183
+
184
+ #### 5c. Generate SCSS
185
+
186
+ Use design tokens for EVERYTHING. No hardcoded values.
187
+
188
+ ```scss
189
+ // NO @use import โ€” CSS custom properties are global
190
+ .ds-{page-name-kebab} {
191
+ // page root styles using var(--token-name)
192
+ }
193
+ ```
194
+
195
+ **Token hierarchy** (most specific wins):
196
+ 1. Component tokens: `var(--{component}-{state}-color-{usage})`
197
+ 2. Semantic tokens: `var(--color-semantic-{name}-{scale})`
198
+ 3. Base tokens: `var(--color-{name}-{scale})`
199
+
200
+ Spacing: `var(--spacing-{size})` or `$space-{n}`
201
+ Border radius: `var(--border-radius-{size})`
202
+ CSS class prefix: always `ds-` โ€” no exceptions.
203
+
204
+ ### โšก MANDATORY STEP 6 โ€” CALL BLANCHE DESIGNSPERT NOW โšก
205
+
206
+ **YOU MUST USE THE `Task` tool RIGHT NOW.** Do NOT move to step 7 without this.
207
+
208
+ ```
209
+ Task tool: subagent_type="blanche-designspert"
210
+ prompt: "I've created a SCSS file for a migrated legacy page. Please review for correct design token usage and CSS naming conventions. Here is the SCSS: [paste SCSS]"
211
+ ```
212
+
213
+ After Blanche responds, relay her verdict:
214
+
215
+ > ๐Ÿ’„ **Blanche says:** _[relay in her glamorous, exacting voice โ€” she will not tolerate a hardcoded hex value]_
216
+
217
+ Apply ALL of Blanche's corrections before continuing.
218
+
219
+ ### 7. Generate Tests
220
+
221
+ ```typescript
222
+ import { render, screen } from '@testing-library/react';
223
+ import userEvent from '@testing-library/user-event';
224
+ import '@testing-library/jest-dom/vitest';
225
+ import { describe, it, expect, vi } from 'vitest';
226
+ import { {PageName} } from './{PageName}';
227
+
228
+ // Mock Table to avoid AG Grid license errors
229
+ vi.mock('Components/table/Table', () => ({
230
+ Table: ({ rowData }: { rowData: unknown[] }) => (
231
+ <div role="grid" aria-label="...">
232
+ {/* map rowData */}
233
+ </div>
234
+ ),
235
+ }));
236
+ ```
237
+
238
+ **Test priorities (from the migration report):**
239
+ - Render all section headings
240
+ - Render all placeholder SVGs (verifiable via `getByRole('img', { name: /ComponentName placeholder/i })`)
241
+ - Render the table (mocked)
242
+ - Verify all primary action callbacks are called on click
243
+ - Verify accessible landmarks (main, complementary/aside)
244
+ - Verify accessible element (link hrefs, aria labels)
245
+ - `className` prop applies to root element
246
+
247
+ **Rules:**
248
+ - No `any` types in test helpers
249
+ - No `testId` โ€” use `getByRole`, `getByLabelText`, `getByText`
250
+ - Mock `Table` if it's in the page (AG Grid license)
251
+ - 100% pass rate required โ€” no placeholder tests
252
+
253
+ ### โšก MANDATORY STEP 8 โ€” CALL ROSE STORYBOOKSPERT NOW โšก
254
+
255
+ **YOU MUST USE THE `Task` tool RIGHT NOW.**
256
+
257
+ ```
258
+ Task tool: subagent_type="rose-storybookspert"
259
+ prompt: "I've created a new page component called [{PageName}] that migrates a legacy page to Arbor components. Please create comprehensive Storybook stories for it. Here is the component: [paste TSX]. The file should go at src/pages/{pageName}/{PageName}.stories.tsx."
260
+ ```
261
+
262
+ After Rose responds, relay her work and use her output as the story file.
263
+
264
+ > ๐ŸŒน **Rose says:** _[relay in her warm storytelling voice]_
265
+
266
+ ### 9. Quality Checks
267
+
268
+ Run in this order โ€” lint and type-check FIRST:
269
+
270
+ ```bash
271
+ yarn check-types
272
+ yarn style-lint
273
+ yarn test
274
+ ```
275
+
276
+ Fix lint with `--fix` flag, not manually:
277
+ ```bash
278
+ yarn eslint src/pages/{pageName}/ --fix
279
+ ```
280
+
281
+ All checks must pass. 100% test pass rate. No exceptions.
282
+
283
+ ### โšก MANDATORY STEP 9 โ€” CALL DOROTHY FACT-CHECKER NOW โšก
284
+
285
+ **YOU MUST USE THE `Task` tool RIGHT NOW.** Final quality gate โ€” Dorothy checks the GENERATED FILES, not the component capabilities (those were already verified in `map-legacy`).
286
+
287
+ ```
288
+ Task tool: subagent_type="dorothy-fact-checker"
289
+ prompt: "I've just finished building a migrated legacy page. Please verify:
290
+ 1. All files actually exist on disk: [list file paths]
291
+ 2. Tests pass with 100% pass rate
292
+ 3. Tests are meaningful (not placeholders)
293
+ 4. Components are used with correct props (matching the migration report)
294
+ 5. No 'any' types used
295
+ 6. SCSS follows token conventions (Blanche already reviewed but double-check)
296
+ 7. Placeholder SVGs are present for every โŒ element from the migration report
297
+ 8. All callback props are tested"
298
+ ```
299
+
300
+ After Dorothy responds, relay her verdict IN FULL:
301
+
302
+ > ๐Ÿ” **Dorothy says:** _[relay her no-nonsense verdict โ€” she doesn't sugarcoat]_
303
+
304
+ Fix ALL issues before presenting the final summary.
305
+
306
+ ### 10. Export from src/index.ts
307
+
308
+ Add the new page to the public API โ€” matching the pattern of existing pages:
309
+
310
+ ```typescript
311
+ export { {PageName}, type {PageName}Props, type {RowType} } from './pages/{pageName}/{PageName}';
312
+ ```
313
+
314
+ ### 11. Present Summary to User
315
+
316
+ ```
317
+ AROOOOO HUNNI! ๐Ÿบ That legacy page has been BODACIOUSLY MIGRATED! xxx
318
+
319
+ โœ… Files created:
320
+ - src/pages/{pageName}/{PageName}.tsx
321
+ - src/pages/{pageName}/{pageName}.scss
322
+ - src/pages/{pageName}/{PageName}.test.tsx
323
+ - src/pages/{pageName}/{PageName}.stories.tsx
324
+
325
+ โœ… Components used from migration map:
326
+ [List each legacy element โ†’ Arbor component, matching report]
327
+
328
+ โš ๏ธ Placeholder SVGs (elements with no Arbor equivalent):
329
+ [List each gap with the component name and TODO]
330
+ These need real implementations before the page is production-ready.
331
+
332
+ โœ… Quality checks:
333
+ - Type check: PASS
334
+ - Style lint: PASS
335
+ - Tests: X/X passing
336
+
337
+ ๐ŸŽฏ Migration fidelity:
338
+ [Note anything that differs from the migration map, and why]
339
+
340
+ ๐Ÿ Next steps:
341
+ - Replace placeholder SVGs when library components are built
342
+ - Wire up data fetching / routing in the consumer app
343
+ - [Any other integration notes]
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Key Differences from `/create-page`
349
+
350
+ | | `/create-page` | `/migrate-page` |
351
+ |---|---|---|
352
+ | **Input** | Figma URL | Screenshot + migration report |
353
+ | **Pre-flight** | Runs `analyze-design` (Sophia + Dorothy) | Reads migration report (already done) |
354
+ | **Visual ref** | Figma design | Legacy page screenshot |
355
+ | **Component map** | Sophia generates it live | Already in the migration report |
356
+ | **Sophia/Dorothy** | Called for component assessment | NOT called again (trust the report) |
357
+ | **Blanche/Rose/Dorothy QA** | Mandatory | Mandatory |
358
+ | **Intent** | Build something new | Replace something existing |
359
+
360
+ ---
361
+
362
+ ## Important Notes
363
+
364
+ - **Trust the migration report** โ€” Sophia and Dorothy already did the hard work. Don't re-research.
365
+ - **Screenshot is layout reference** โ€” use it for sizing, spacing, and content examples, not component choices
366
+ - **Gaps get placeholder SVGs** โ€” every โŒ element from the report needs one, testable via `getByRole('img')`
367
+ - **Table mock is essential** โ€” AG Grid needs a license key; always mock `Table` in tests
368
+ - **100% test pass rate** โ€” no shortcuts, no placeholder tests
369
+ - **Dorothy does final QA on FILES** โ€” she's checking your code output, not component capabilities
370
+ - **No `any` types** โ€” ever. Define proper TypeScript interfaces for all data shapes
371
+ - **Use yarn (NOT npm)**
372
+ - This codebase serves millions of users โ€” accurate migrations matter!
373
+
374
+ AROOOOO LET'S DRAG THAT LEGACY PAGE INTO THE BODACIOUS MODERN ERA, HUNNI!! xxx ๐Ÿ’ช๐Ÿ๏ธโœจ๐Ÿบ
@@ -3,5 +3,6 @@
3
3
  # Order is important. The last matching pattern has the most precedence.
4
4
  # The team needs to exist and have write access to the repository
5
5
 
6
+ * @arbor-education/Frontend_Reviewers
6
7
  .github/** @arbor-education/DevOps_Reviewers
7
8
  terraform/** @arbor-education/DevOps_Reviewers
@@ -0,0 +1,39 @@
1
+ ## Summary of changes
2
+
3
+ <!-- Link to the Jira ticket. Then summarise in your own words โ€” don't assume everyone has Jira context. -->
4
+
5
+ [MIS-XXXXX](https://arbor-education.atlassian.net/browse/MIS-XXXXX)
6
+
7
+ ### Areas to focus on
8
+
9
+ <!-- Point reviewers to the most important or complex parts of the diff. -->
10
+
11
+ ### Notes for code owners
12
+
13
+ <!-- Anything reviewers should know about scope, dependencies, or follow-up tickets. -->
14
+
15
+ ### Breaking changes
16
+
17
+ <!-- Does this change the public API? Does it require consumers to update their code? If none, write "None." -->
18
+
19
+ ## How can a reviewer test this?
20
+
21
+ <!-- Step-by-step testing instructions. Include any browser-specific or environment-specific notes.
22
+ Chromatic will post a Storybook link automatically โ€” no need to include one here. -->
23
+
24
+ 1.
25
+ 2.
26
+ 3.
27
+
28
+ ## Checklist
29
+
30
+ - [ ] This PR does **one thing** โ€” the title does not contain "and" or "also"
31
+ - [ ] The meaningful code diff is under 400 lines (or a justification is written in "Notes for code owners")
32
+ - [ ] `yarn check-types` passes with no errors
33
+ - [ ] `yarn test:coverage` passes โ€” all tests green, 100% pass rate
34
+ - [ ] `yarn style-lint` passes with no errors
35
+ - [ ] I have self-reviewed the diff line by line
36
+ - [ ] Dead code, debug statements, and commented-out code are removed
37
+ - [ ] A changeset has been created (`yarn changeset`) if this affects the public API
38
+
39
+ <!-- AI AGENTS: You must complete every item in this checklist before opening this PR. Do not open the PR if any item is unchecked without a written explanation. -->
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#159](https://github.com/arbor-education/design-system.components/pull/159) [`555e538`](https://github.com/arbor-education/design-system.components/commit/555e538d157d2f18c2aebf380ec57fcc19dfd467) Thanks [@angusmglfraser](https://github.com/angusmglfraser)! - MIS-69127 โœจ checkbox cell renderer
8
+
3
9
  ## 0.10.0
4
10
 
5
11
  ### Minor Changes
package/CLAUDE.md CHANGED
@@ -139,6 +139,37 @@ The Table component is a wrapper around AG Grid:
139
139
  ## Commit rules
140
140
  - Each commit message should start with the same Jira ticket number as the branch name followed by a description of whats being committed. i.e. `MIS-68964 changed x prop to be a string`
141
141
 
142
+ ## PR rules (MANDATORY โ€” applies to all agents)
143
+
144
+ These rules are non-negotiable. Read CONTRIBUTING.md for the full rationale.
145
+
146
+ ### Scope control
147
+ - **One PR = one Jira ticket.** Never combine multiple tickets or concerns into a single PR.
148
+ - **Before writing any code**, identify the minimal set of files needed to complete the task. If the task touches more than ~5 files or ~200 lines, STOP and ask the human whether it should be split.
149
+ - **Never bundle refactoring with feature work.** If you spot a refactor opportunity, note it for the human and do not act on it in the current PR.
150
+ - **Never touch files outside the task scope.** Do not improve adjacent code, fix unrelated formatting, or clean up files that weren't required for the task.
151
+
152
+ ### Size limits
153
+ | Lines changed (meaningful code) | Action |
154
+ |----------------------------------|--------|
155
+ | < 200 | Proceed |
156
+ | 200โ€“400 | Proceed, ensure description is thorough |
157
+ | 400โ€“800 | STOP โ€” write a justification in the PR description, confirm with human |
158
+ | > 800 | STOP โ€” split the PR before continuing |
159
+
160
+ Generated files, `yarn.lock`, and auto-generated types do NOT count toward these limits.
161
+
162
+ ### Quality gates โ€” all must pass before opening a PR
163
+ - `yarn check-types` โ€” zero type errors
164
+ - `yarn test:coverage` โ€” 100% of tests passing
165
+ - `yarn style-lint` โ€” zero SCSS linting errors
166
+
167
+ ### PR description
168
+ Always use the PR template at `.github/pull_request_template.md`. Fill in every section. Do not leave placeholders or blank sections.
169
+
170
+ ### When in doubt
171
+ Ask the human. A question is always better than a PR that is too large to review.
172
+
142
173
  ## Notes for Claude
143
174
  - This is an active production codebase serving educational institutions
144
175
  - Changes can affect millions of users - be thoughtful and careful
@@ -0,0 +1,191 @@
1
+ # Contributing to Arbor Design System Components
2
+
3
+ Welcome, and thank you for contributing! This guide applies to **everyone** โ€” human developers, non-developers, and AI agents using agentic tools. The rules here exist to protect the team's ability to review changes safely and keep this codebase โ€” which serves millions of students in educational institutions โ€” reliable and maintainable.
4
+
5
+ ---
6
+
7
+ ## The Golden Rule: One PR, One Thing
8
+
9
+ > If your PR title needs the word "and" or "also", it should be two PRs.
10
+
11
+ A pull request should represent a single, coherent unit of change. A reviewer should be able to understand what it does, why it exists, and whether it is correct โ€” without losing context or needing to context-switch between unrelated concerns.
12
+
13
+ **Good:**
14
+
15
+ - `MIS-12345 โœจ Add disabled state to Button component`
16
+ - `MIS-12346 ๐Ÿ› Fix dropdown closing on outside click in Firefox`
17
+ - `MIS-12347 โ™ป๏ธ Refactor FormField to use new token API`
18
+
19
+ **Not good:**
20
+
21
+ - `MIS-12345 Add disabled Button state, fix dropdown bug, and refactor FormField`
22
+ - `MIS-12345 Various fixes and improvements`
23
+ - `MIS-12345 WIP`
24
+
25
+ ---
26
+
27
+ ## PR Size
28
+
29
+ Small PRs get reviewed faster, get merged sooner, and carry far lower bug risk. Research consistently shows that large PRs take **4โ€“5ร— longer to merge** and produce lower-quality reviews because humans (and tools) struggle to hold large diffs in working memory.
30
+
31
+ | Size | Lines changed | Files changed | What to do |
32
+ | -------------- | ------------- | ------------- | ------------------------------------------------- |
33
+ | **Ideal** | < 200 | < 5 | Ship it |
34
+ | **Acceptable** | 200โ€“400 | < 10 | Fine, make sure description is thorough |
35
+ | **Large** | 400โ€“800 | any | Add a written justification in the PR description |
36
+ | **Too large** | > 800 | any | **Stop. Split it.** |
37
+
38
+ ### What counts as "lines changed"?
39
+
40
+ Generated files, lockfiles (`yarn.lock`), and auto-generated type definitions do not count. Focus on the meaningful code diff.
41
+
42
+ ### How to split a large PR
43
+
44
+ 1. **Refactor first, feature second.** If you need to restructure existing code before adding new behaviour, that's two PRs: the refactor PR (no new behaviour) and the feature PR (uses the refactored foundation).
45
+ 2. **One component per PR.** Adding a new component? Each component gets its own PR.
46
+ 3. **Separate concerns.** Infrastructure changes (build config, CI) go in their own PR, separate from product changes.
47
+ 4. **Stack PRs.** Create PR B off the branch of PR A, and set PR B's base to A's branch. When A merges, update B's base to main.
48
+
49
+ ---
50
+
51
+ ## Anatomy of a Good PR
52
+
53
+ ### Title
54
+
55
+ Format: `{JIRA-TICKET} {gitmoji} {Short, imperative description}`
56
+
57
+ - Start with the Jira ticket number (required โ€” CI will check this)
58
+ - Optionally follow with a [gitmoji](https://gitmoji.dev/) that signals the type of change at a glance
59
+ - Use the imperative mood: "Add", "Fix", "Remove", "Update" โ€” not "Added", "Fixes", "Removing"
60
+ - Keep it under 72 characters
61
+
62
+ **Common gitmoji:**
63
+ | Emoji | Use for |
64
+ |-------|---------|
65
+ | โœจ | New feature |
66
+ | ๐Ÿ› | Bug fix |
67
+ | โ™ป๏ธ | Refactor (no behaviour change) |
68
+ | ๐Ÿ’„ | Styling / visual change |
69
+ | ๐Ÿงช | Tests only |
70
+ | ๐Ÿ“ | Documentation |
71
+ | โฌ†๏ธ | Dependency upgrade |
72
+ | ๐Ÿ”ง | Config / tooling change |
73
+ | ๐Ÿ’ฅ | Breaking change |
74
+ | โ™ฟ๏ธ | Accessibility improvement |
75
+
76
+ ### Description
77
+
78
+ A PR description is documentation. Write it as if a future developer โ€” who has no context on your task โ€” needs to understand why this change exists. Answer these four questions:
79
+
80
+ **1. What problem does this solve?**
81
+ Link to the Jira ticket, but also summarise in your own words. Don't assume everyone has Jira access or context.
82
+
83
+ **2. How does it solve it?**
84
+ Explain the key implementation decisions. If you chose approach A over approach B, say why.
85
+
86
+ **3. What are the risks?**
87
+ What could go wrong? What areas of the codebase might be affected that aren't immediately obvious?
88
+
89
+ **4. How can a reviewer test this?**
90
+ List steps. Include any relevant Storybook story paths, component names, or browser/environment-specific notes.
91
+
92
+ **Optional but excellent:**
93
+
94
+ - Screenshots or videos for visual changes
95
+ - A note if this PR depends on another PR being merged first
96
+ - A note if there are follow-up tickets already created for known limitations
97
+
98
+ ### Commits
99
+
100
+ Each commit should tell part of the story. A reviewer should be able to follow your commits in order and understand the journey.
101
+
102
+ - Write commit messages that explain **why**, not just what
103
+ - Format: `{JIRA-TICKET} {description of why}`
104
+ - Rebase and clean up your history before opening a PR โ€” squash "fix typo" and "oops" commits
105
+ - Do not mix formatting-only changes with logic changes in the same commit
106
+
107
+ ---
108
+
109
+ ## Before You Open a PR
110
+
111
+ Run through this checklist yourself before requesting review:
112
+
113
+ - [ ] My branch name includes the Jira ticket number (e.g. `feature/MIS-12345-add-button-variant`)
114
+ - [ ] My PR does **one thing**. The title does not contain "and" or "also"
115
+ - [ ] The diff is under 400 lines of meaningful code (or I have written a justification)
116
+ - [ ] I have run `yarn check-types` and there are no type errors
117
+ - [ ] I have run `yarn test:coverage` and all tests pass (100% pass rate required)
118
+ - [ ] I have run `yarn style-lint` and there are no SCSS linting errors
119
+ - [ ] I have self-reviewed my own diff โ€” line by line โ€” before requesting review
120
+ - [ ] I have removed dead code, debugging statements, and commented-out code
121
+ - [ ] I have created a changeset with `yarn changeset` if this change affects the public API
122
+ - [ ] My PR description answers: What? Why? How? Risks? How to test?
123
+
124
+ ---
125
+
126
+ ## For AI Agents and Agentic Tools
127
+
128
+ **This section is specifically for you.** If you are an AI agent (Claude Code, Copilot, Cursor, or any other tool) generating or submitting code to this repository, you MUST follow these rules. They are not suggestions.
129
+
130
+ ### Hard rules for agents
131
+
132
+ 1. **One PR per Jira ticket.** Never combine work from multiple tickets into a single PR, even if the work seems related.
133
+
134
+ 2. **Stop and check scope before starting.** Before writing any code, identify the minimal set of files required to complete the task. If you find yourself touching more than ~5 files or ~200 lines, pause and ask the human whether the task should be split.
135
+
136
+ 3. **Never bundle refactoring with feature work.** If you notice an opportunity to refactor while implementing a feature, stop. Create a note for the human. Do not refactor in the same PR unless explicitly instructed.
137
+
138
+ 4. **Never touch files outside the task scope.** Do not "improve" adjacent code, fix unrelated formatting, or clean up files you didn't need to open to complete the task.
139
+
140
+ 5. **Never open a PR with failing tests.** All tests must pass. `yarn test:coverage` must complete with 100% of tests passing.
141
+
142
+ 6. **Never open a PR with type errors.** `yarn check-types` must pass cleanly.
143
+
144
+ 7. **Write a complete PR description.** Use the template. Answer all four questions. Do not leave sections blank.
145
+
146
+ 8. **Warn before generating large changes.** If completing a task would require changes to more than 400 lines of meaningful code or more than 10 files, stop and tell the human before proceeding. Ask whether the task should be broken into smaller pieces.
147
+
148
+ 9. **Commit atomically.** Each commit should be a coherent, working unit. Do not commit broken intermediate states.
149
+
150
+ 10. **Ask, don't assume.** When the scope or approach is unclear, ask the human rather than making assumptions that lead to larger-than-expected changes.
151
+
152
+ ---
153
+
154
+ ## Code Review Culture
155
+
156
+ Reviews are collaborative, not adversarial. The goal is to ship high-quality software together.
157
+
158
+ ### For authors
159
+
160
+ - If you disagree with feedback, explain why โ€” but be open to being wrong
161
+ - If significant changes happen after approval, flag this to reviewers
162
+ - Do not merge without all required reviewers approving
163
+
164
+ ### For reviewers
165
+
166
+ - Review the code, not the person. Feedback is never personal
167
+ - When suggesting a change, explain why and offer an alternative
168
+ - Distinguish between blocking issues ("this will cause a bug") and preferences ("I'd personally style this differently")
169
+ - Do not use diminishing language ("just", "simply", "obviously") โ€” what's obvious to you may not be obvious to others
170
+ - Rely on automated linters for style enforcement โ€” don't debate formatting in review comments
171
+ - If a PR is too large to review effectively, say so and ask for it to be split before you start reviewing
172
+
173
+ ---
174
+
175
+ ## Branch and Commit Conventions
176
+
177
+ See [CLAUDE.md](./CLAUDE.md) for the definitive reference. In summary:
178
+
179
+ - Branches: `feature/MIS-12345-short-description`, `bugfix/MIS-12345-short-description`, or `issue/MIS-12345-short-description`
180
+ - Commits: `MIS-12345 description of the why`
181
+ - All branches must include a Jira ticket number
182
+ - Never push directly to `main`
183
+
184
+ ---
185
+
186
+ ## Resources
187
+
188
+ - [gitmoji reference](https://gitmoji.dev/)
189
+ - [Arbor Jira](https://orchard.atlassian.net/) โ€” for ticket context
190
+ - [Production Storybook](https://main--68c3f2a09d95b22aa55a11e8.chromatic.com/) โ€“ Builds every time something is pushed to main
191
+ - [Local Storybook](http://localhost:6006) โ€” run locally with `yarn storybook`