@arbor-education/design-system.components 0.9.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.
- package/.claude/agent-memory/blanche-designspert/MEMORY.md +64 -0
- package/.claude/agent-memory/blanche-designspert/token-review-patterns.md +29 -0
- package/.claude/agent-memory/dorothy-fact-checker/MEMORY.md +129 -0
- package/.claude/agent-memory/rose-storybookspert/MEMORY.md +29 -0
- package/.claude/agent-memory/rose-storybookspert/patterns.md +132 -0
- package/.claude/agent-memory/sophia-componentspert/MEMORY.md +14 -0
- package/.claude/agent-memory/sophia-componentspert/components.md +367 -0
- package/.claude/agents/blanche-designspert.md +150 -0
- package/.claude/agents/dorothy-fact-checker.md +145 -0
- package/.claude/agents/rose-storybookspert.md +148 -0
- package/.claude/agents/sophia-componentspert.md +133 -0
- package/.claude/component-library.md +1107 -0
- package/.claude/design-assessment-daily-attendance-2026-04-10.md +566 -0
- package/.claude/figma-assessment-7154-58899.md +404 -0
- package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-11086-97537.md +392 -0
- package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-551-41974.md +474 -0
- package/.claude/figma-assessment-UKQfcxnT4rlHHNuiumt4o1-551-43094.md +462 -0
- package/.claude/figma-assessment-fcFK4CGzkz2fVyY3koX8ZE-7154-59061.md +440 -0
- package/.claude/migration-report-custom-report-writer-2026-02-19.md +591 -0
- package/.claude/skills/analyze-design/README.md +295 -0
- package/.claude/skills/analyze-design/SKILL.md +741 -0
- package/.claude/skills/create-page/README.md +246 -0
- package/.claude/skills/create-page/SKILL.md +634 -0
- package/.claude/skills/create-page/design-analysis-template.md +333 -0
- package/.claude/skills/create-page/page-template.scss +118 -0
- package/.claude/skills/create-page/page-template.tsx +230 -0
- package/.claude/skills/map-legacy/README.md +87 -0
- package/.claude/skills/map-legacy/SKILL.md +465 -0
- package/.claude/skills/migrate-page/README.md +125 -0
- package/.claude/skills/migrate-page/SKILL.md +374 -0
- package/.github/CODEOWNERS +1 -0
- package/.github/pull_request_template.md +39 -0
- package/.github/workflows/release.yml +1 -1
- package/CHANGELOG.md +16 -0
- package/CLAUDE.md +31 -0
- package/CONTRIBUTING.md +191 -0
- package/README.md +110 -20
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +2 -2
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.js +2 -1
- package/dist/components/combobox/Combobox.js.map +1 -1
- package/dist/components/combobox/Combobox.test.js +98 -61
- package/dist/components/combobox/Combobox.test.js.map +1 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts +3 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts.map +1 -1
- package/dist/components/combobox/useComboboxPopoverBehavior.js +7 -6
- package/dist/components/combobox/useComboboxPopoverBehavior.js.map +1 -1
- package/dist/components/combobox/useComboboxState.d.ts.map +1 -1
- package/dist/components/combobox/useComboboxState.js +4 -1
- package/dist/components/combobox/useComboboxState.js.map +1 -1
- package/dist/components/datePicker/DatePicker.d.ts +4 -1
- package/dist/components/datePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.js +77 -37
- package/dist/components/datePicker/DatePicker.js.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.d.ts +28 -3
- package/dist/components/datePicker/DatePicker.stories.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.js +62 -9
- package/dist/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/components/datePicker/DatePicker.test.js +133 -66
- package/dist/components/datePicker/DatePicker.test.js.map +1 -1
- package/dist/components/datePicker/DatePickerCalendarHeader.d.ts +8 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.d.ts.map +1 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.js +36 -0
- package/dist/components/datePicker/DatePickerCalendarHeader.js.map +1 -0
- package/dist/components/datePicker/dateInputUtils.d.ts +25 -0
- package/dist/components/datePicker/dateInputUtils.d.ts.map +1 -0
- package/dist/components/datePicker/dateInputUtils.js +60 -0
- package/dist/components/datePicker/dateInputUtils.js.map +1 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.d.ts +2 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.d.ts.map +1 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.js +4 -0
- package/dist/components/datePicker/datePickerTestUtils.test-helpers.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.d.ts +22 -0
- package/dist/components/dateTimePicker/DateTimePicker.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.js +132 -0
- package/dist/components/dateTimePicker/DateTimePicker.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts +77 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.js +163 -0
- package/dist/components/dateTimePicker/DateTimePicker.stories.js.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.d.ts +2 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.d.ts.map +1 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.js +235 -0
- package/dist/components/dateTimePicker/DateTimePicker.test.js.map +1 -0
- package/dist/components/formField/FormField.test.d.ts.map +1 -1
- package/dist/components/formField/FormField.test.js +5 -5
- package/dist/components/formField/FormField.test.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts +1 -0
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.d.ts.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js +7 -3
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.test.js +12 -0
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.test.js.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.d.ts +4 -1
- package/dist/components/formField/inputs/text/TextInput.d.ts.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.js +5 -4
- package/dist/components/formField/inputs/text/TextInput.js.map +1 -1
- package/dist/components/formField/inputs/text/TextInput.stories.d.ts +4 -1
- package/dist/components/formField/inputs/text/TextInput.stories.d.ts.map +1 -1
- package/dist/components/table/DSDefaultColDef.js +2 -2
- package/dist/components/table/DSDefaultColDef.js.map +1 -1
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +4 -0
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts +2 -0
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +132 -3
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/Table.test.js +106 -5
- package/dist/components/table/Table.test.js.map +1 -1
- package/dist/components/table/cellRenderers/BooleanCellRenderer.d.ts +3 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.js +15 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.js.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.d.ts +2 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.js +31 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.test.js.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts +3 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +12 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts +2 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js +65 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js.map +1 -0
- package/dist/index.css +259 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.tsx +2 -1
- package/src/components/combobox/Combobox.test.tsx +104 -61
- package/src/components/combobox/Combobox.tsx +3 -1
- package/src/components/combobox/useComboboxPopoverBehavior.ts +10 -5
- package/src/components/combobox/useComboboxState.ts +4 -1
- package/src/components/datePicker/DatePicker.stories.tsx +67 -9
- package/src/components/datePicker/DatePicker.test.tsx +157 -72
- package/src/components/datePicker/DatePicker.tsx +163 -69
- package/src/components/datePicker/DatePickerCalendarHeader.tsx +82 -0
- package/src/components/datePicker/date-field-hint.scss +152 -0
- package/src/components/datePicker/dateInputUtils.ts +117 -0
- package/src/components/datePicker/datePicker.scss +53 -29
- package/src/components/datePicker/datePickerTestUtils.test-helpers.ts +6 -0
- package/src/components/dateTimePicker/DateTimePicker.stories.tsx +202 -0
- package/src/components/dateTimePicker/DateTimePicker.test.tsx +295 -0
- package/src/components/dateTimePicker/DateTimePicker.tsx +293 -0
- package/src/components/dateTimePicker/dateTimePicker.scss +17 -0
- package/src/components/formField/FormField.test.tsx +5 -5
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.test.tsx +28 -0
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.tsx +8 -2
- package/src/components/formField/inputs/text/TextInput.tsx +6 -3
- package/src/components/table/DSDefaultColDef.ts +2 -2
- package/src/components/table/Table.stories.tsx +147 -3
- package/src/components/table/Table.test.tsx +131 -5
- package/src/components/table/Table.tsx +4 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.test.tsx +37 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.tsx +34 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.test.tsx +74 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +28 -0
- package/src/components/table/cellRenderers/booleanCellRenderer.scss +7 -0
- package/src/components/table/table.scss +1 -1
- package/src/index.scss +2 -0
- package/src/index.ts +4 -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 💪🏍️✨🐺
|
package/.github/CODEOWNERS
CHANGED
|
@@ -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. -->
|
|
@@ -99,7 +99,7 @@ jobs:
|
|
|
99
99
|
gh release create "${version}" \
|
|
100
100
|
--repo "arbor-education/design-system.components" \
|
|
101
101
|
--title "${version}" \
|
|
102
|
-
--notes "$
|
|
102
|
+
--notes "$changelog" \
|
|
103
103
|
"./release/design-system.components.tgz"
|
|
104
104
|
|
|
105
105
|
- name: Send Slack Success Message
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
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
|
+
|
|
9
|
+
## 0.10.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#157](https://github.com/arbor-education/design-system.components/pull/157) [`f8a5137`](https://github.com/arbor-education/design-system.components/commit/f8a5137f17b758a6a062fa8c96511fc1e93e6618) Thanks [@danielpeplow](https://github.com/danielpeplow)! - **DatePicker / DateTimePicker** — The date side of `DatePicker` is a normal `date` field now, so you don’t get that odd native “time” bit when you only care about the day. If you set a custom placeholder while the field is still empty, we treat it like a hint: we open the calendar and skip free typing so the fake placeholder and the browser UI don’t fight. Same idea for `DateTimePicker` when you’re in native mode.
|
|
14
|
+
|
|
15
|
+
**Combobox** — If you’re on the button-style dropdown with search inside the panel, filtering down to nothing no longer nukes the whole popover—you can keep typing or clear and try again. Choosing one value (e.g. a time from the list) closes the dropdown even when that combobox lives inside another popover.
|
|
16
|
+
|
|
17
|
+
- [#150](https://github.com/arbor-education/design-system.components/pull/150) [`7f49140`](https://github.com/arbor-education/design-system.components/commit/7f491402c72a29fc29f2ae1907f5487a71d5db70) Thanks [@angusmglfraser](https://github.com/angusmglfraser)! - MIS-69124 ✨ boolean cell renderer for tables
|
|
18
|
+
|
|
3
19
|
## 0.9.0
|
|
4
20
|
|
|
5
21
|
### 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
|
package/CONTRIBUTING.md
ADDED
|
@@ -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`
|