@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,333 @@
|
|
|
1
|
+
# Figma Page Design Analysis Template
|
|
2
|
+
|
|
3
|
+
AROOOOO HUNNI!! 🐺 Use this template to analyze the BOMBASS Figma PAGE design and map it to EXISTING components! xxx
|
|
4
|
+
|
|
5
|
+
## 1. Design Overview
|
|
6
|
+
|
|
7
|
+
**Figma URL**: [Paste URL here]
|
|
8
|
+
**File Key**: [Extract from URL]
|
|
9
|
+
**Node ID**: [Extract from URL]
|
|
10
|
+
**Page Name**: [What should we call this page?]
|
|
11
|
+
|
|
12
|
+
## 2. Page Structure
|
|
13
|
+
|
|
14
|
+
### Layout Type
|
|
15
|
+
- [ ] Single column
|
|
16
|
+
- [ ] Multi-column grid (2 cols, 3 cols, etc.)
|
|
17
|
+
- [ ] Sidebar layout
|
|
18
|
+
- [ ] Header + Content + Footer
|
|
19
|
+
- [ ] Dashboard grid
|
|
20
|
+
- [ ] Other: _____________
|
|
21
|
+
|
|
22
|
+
### Page Sections
|
|
23
|
+
|
|
24
|
+
List all major sections in the page:
|
|
25
|
+
|
|
26
|
+
1. **Section**: Header
|
|
27
|
+
- **Content**: Logo, navigation links, user menu
|
|
28
|
+
- **Layout**: Horizontal flex, space-between
|
|
29
|
+
|
|
30
|
+
2. **Section**: Main Content
|
|
31
|
+
- **Content**: Form fields, data table, cards, etc.
|
|
32
|
+
- **Layout**: Grid, flex, or other
|
|
33
|
+
|
|
34
|
+
3. **Section**: Footer
|
|
35
|
+
- **Content**: Links, copyright
|
|
36
|
+
- **Layout**: Centered or flex
|
|
37
|
+
|
|
38
|
+
## 3. Element → Component Mapping
|
|
39
|
+
|
|
40
|
+
Map each Figma element to an EXISTING Arbor component:
|
|
41
|
+
|
|
42
|
+
| Figma Element | Element Type | Arbor Component | Props Needed | Notes |
|
|
43
|
+
|---------------|--------------|-----------------|--------------|-------|
|
|
44
|
+
| "Submit" button | Button | `Button` | `variant="primary"` | Primary CTA |
|
|
45
|
+
| Email field | Text input | `FormField` + `TextInput` | `label="Email", required` | Validation needed |
|
|
46
|
+
| User table | Data grid | `Table` | `data={}, columns={}` | Check Table props |
|
|
47
|
+
| Status badge | Pill/tag | `Pill` | `variant="success"` | Different colors |
|
|
48
|
+
| Help icon | Tooltip | `Tooltip` | `content="Help text"` | Info popover |
|
|
49
|
+
| Filter panel | Form section | `FormField` + various inputs | Multiple fields | Left sidebar |
|
|
50
|
+
|
|
51
|
+
**CRITICAL**: Only use components that EXIST in `src/components/`! Don't invent new ones!
|
|
52
|
+
|
|
53
|
+
## 4. Available Components Reference
|
|
54
|
+
|
|
55
|
+
Before mapping, check what's available by reading `src/index.ts` (the public API):
|
|
56
|
+
|
|
57
|
+
**How to discover components**:
|
|
58
|
+
1. Read `src/index.ts` to see all exported components
|
|
59
|
+
2. Note the import paths for each component
|
|
60
|
+
3. Read individual component files for detailed props
|
|
61
|
+
|
|
62
|
+
**Available components checklist**:
|
|
63
|
+
|
|
64
|
+
### Forms & Inputs
|
|
65
|
+
- [ ] `Button` - Available variants: ___________
|
|
66
|
+
- [ ] `FormField` - Wrapper for inputs
|
|
67
|
+
- [ ] `TextInput` - Text input fields
|
|
68
|
+
- [ ] `NumberInput` - Number input fields
|
|
69
|
+
- [ ] `RadioGroup` - Radio buttons
|
|
70
|
+
- [ ] `Checkbox` - Checkboxes
|
|
71
|
+
- [ ] Other input types: ___________
|
|
72
|
+
|
|
73
|
+
### Data Display
|
|
74
|
+
- [ ] `Table` - AG Grid wrapper
|
|
75
|
+
- [ ] `Pill` - Tags/badges
|
|
76
|
+
- [ ] Other: ___________
|
|
77
|
+
|
|
78
|
+
### Overlays & Floating
|
|
79
|
+
- [ ] `Modal` - Dialog modals
|
|
80
|
+
- [ ] `Slideover` - Side panels
|
|
81
|
+
- [ ] `Tooltip` - Info tooltips
|
|
82
|
+
- [ ] Other: ___________
|
|
83
|
+
|
|
84
|
+
### Other Components
|
|
85
|
+
- [ ] List any other available components: ___________
|
|
86
|
+
|
|
87
|
+
## 5. Component Props Investigation
|
|
88
|
+
|
|
89
|
+
For each component you'll use, note the important props:
|
|
90
|
+
|
|
91
|
+
### Button
|
|
92
|
+
```typescript
|
|
93
|
+
// Props found in src/components/button/Button.tsx:
|
|
94
|
+
- variant?: 'primary' | 'secondary' | '...'
|
|
95
|
+
- size?: 'small' | 'medium' | 'large'
|
|
96
|
+
- disabled?: boolean
|
|
97
|
+
- onClick?: () => void
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### FormField + TextInput
|
|
101
|
+
```typescript
|
|
102
|
+
// FormField props:
|
|
103
|
+
- label: string
|
|
104
|
+
- required?: boolean
|
|
105
|
+
- error?: string
|
|
106
|
+
|
|
107
|
+
// TextInput props:
|
|
108
|
+
- value: string
|
|
109
|
+
- onChange: (e) => void
|
|
110
|
+
- type?: 'text' | 'email' | 'password'
|
|
111
|
+
- placeholder?: string
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### [Add other components you'll use]
|
|
115
|
+
```typescript
|
|
116
|
+
// Component props:
|
|
117
|
+
- ...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 6. Design Tokens Mapping
|
|
121
|
+
|
|
122
|
+
Map Figma design tokens to `src/tokens.scss`:
|
|
123
|
+
|
|
124
|
+
### Colors Used
|
|
125
|
+
| Figma Color/Variable | Token Variable | Where Used |
|
|
126
|
+
|----------------------|----------------|------------|
|
|
127
|
+
| Primary Blue #1A73E8 | `$color-primary-500` | Buttons, links |
|
|
128
|
+
| Background Gray #F8F9FA | `$color-background-secondary` | Page background |
|
|
129
|
+
| Text Dark #202124 | `$color-text-primary` | Main text |
|
|
130
|
+
| Border Light #DADCE0 | `$color-border-primary` | Dividers |
|
|
131
|
+
|
|
132
|
+
### Spacing Used
|
|
133
|
+
| Figma Spacing | Token | Where Used |
|
|
134
|
+
|---------------|-------|------------|
|
|
135
|
+
| 8px | `$space-2` | Small gaps |
|
|
136
|
+
| 16px | `$space-4` | Standard padding |
|
|
137
|
+
| 24px | `$space-6` | Section spacing |
|
|
138
|
+
| 32px | `$space-8` | Large gaps |
|
|
139
|
+
|
|
140
|
+
### Typography Used
|
|
141
|
+
| Figma Text Style | Token Prefix | CSS Properties |
|
|
142
|
+
|------------------|--------------|----------------|
|
|
143
|
+
| Page Title | `$text-heading-1-*` | 32px, bold |
|
|
144
|
+
| Section Header | `$text-heading-2-*` | 24px, semibold |
|
|
145
|
+
| Body | `$text-body-*` | 16px, regular |
|
|
146
|
+
| Small text | `$text-small-*` | 14px, regular |
|
|
147
|
+
|
|
148
|
+
### Other Tokens
|
|
149
|
+
| Figma Style | Token | Value |
|
|
150
|
+
|-------------|-------|-------|
|
|
151
|
+
| Card border radius | `$border-radius-medium` | 8px |
|
|
152
|
+
| Button border radius | `$border-radius-small` | 4px |
|
|
153
|
+
|
|
154
|
+
## 7. Page Component Hierarchy
|
|
155
|
+
|
|
156
|
+
Sketch the component tree:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
PageName
|
|
160
|
+
├── <div className="page-name">
|
|
161
|
+
│ ├── <header className="page-name__header">
|
|
162
|
+
│ │ ├── <h1>Page Title</h1>
|
|
163
|
+
│ │ └── <Button variant="primary">Action</Button>
|
|
164
|
+
│ ├── <main className="page-name__content">
|
|
165
|
+
│ │ ├── <section className="page-name__filters">
|
|
166
|
+
│ │ │ └── <FormField><TextInput /></FormField>
|
|
167
|
+
│ │ └── <section className="page-name__data">
|
|
168
|
+
│ │ └── <Table data={...} columns={...} />
|
|
169
|
+
│ └── <footer className="page-name__footer">
|
|
170
|
+
│ ├── <Button variant="secondary">Cancel</Button>
|
|
171
|
+
│ └── <Button variant="primary">Save</Button>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## 8. Interactive Behaviors
|
|
175
|
+
|
|
176
|
+
Document any interactive elements:
|
|
177
|
+
|
|
178
|
+
| Element | User Action | Expected Behavior | State Needed |
|
|
179
|
+
|---------|-------------|-------------------|--------------|
|
|
180
|
+
| Submit button | Click | Validate and submit form | Form data state |
|
|
181
|
+
| Search input | Type | Filter table data | Search query state |
|
|
182
|
+
| Delete button | Click | Show confirmation modal | Modal open state |
|
|
183
|
+
| ... | ... | ... | ... |
|
|
184
|
+
|
|
185
|
+
## 9. State Management
|
|
186
|
+
|
|
187
|
+
What React state does the page need?
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Page state:
|
|
191
|
+
const [formData, setFormData] = useState<FormData>({});
|
|
192
|
+
const [tableData, setTableData] = useState<Row[]>([]);
|
|
193
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
194
|
+
const [error, setError] = useState<string | null>(null);
|
|
195
|
+
const [filters, setFilters] = useState<Filters>({});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 10. Responsive Design
|
|
199
|
+
|
|
200
|
+
How should the page adapt?
|
|
201
|
+
|
|
202
|
+
### Desktop (> 1024px)
|
|
203
|
+
- Grid layout with sidebar
|
|
204
|
+
- Full table visible
|
|
205
|
+
- All filters expanded
|
|
206
|
+
|
|
207
|
+
### Tablet (768px - 1024px)
|
|
208
|
+
- Stacked layout
|
|
209
|
+
- Table horizontal scroll
|
|
210
|
+
- Collapsible filters
|
|
211
|
+
|
|
212
|
+
### Mobile (< 768px)
|
|
213
|
+
- Single column
|
|
214
|
+
- Simplified table or cards
|
|
215
|
+
- Filter drawer/modal
|
|
216
|
+
|
|
217
|
+
### Breakpoints Needed
|
|
218
|
+
```scss
|
|
219
|
+
@media (max-width: 768px) {
|
|
220
|
+
// Mobile styles
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@media (min-width: 769px) and (max-width: 1024px) {
|
|
224
|
+
// Tablet styles
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 11. Accessibility Checklist
|
|
229
|
+
|
|
230
|
+
- [ ] Semantic HTML (`header`, `main`, `section`, `nav`, `footer`)
|
|
231
|
+
- [ ] ARIA labels for interactive elements
|
|
232
|
+
- [ ] `aria-required` on required form fields
|
|
233
|
+
- [ ] `aria-invalid` and error messages for validation
|
|
234
|
+
- [ ] Keyboard navigation works (Tab, Enter, Escape)
|
|
235
|
+
- [ ] Focus indicators visible
|
|
236
|
+
- [ ] Color contrast meets WCAG AA (4.5:1 for text)
|
|
237
|
+
- [ ] Screen reader friendly (test with VoiceOver/NVDA)
|
|
238
|
+
- [ ] Form labels associated with inputs
|
|
239
|
+
|
|
240
|
+
## 12. Code Connect Mappings
|
|
241
|
+
|
|
242
|
+
List any existing Code Connect mappings from Figma MCP:
|
|
243
|
+
|
|
244
|
+
| Figma Node ID | Component Name | File Path | Props |
|
|
245
|
+
|---------------|----------------|-----------|-------|
|
|
246
|
+
| 123:456 | Button | `src/components/button/Button.tsx` | `variant`, `size` |
|
|
247
|
+
| 789:012 | TextInput | `src/components/formField/inputs/TextInput.tsx` | `value`, `onChange` |
|
|
248
|
+
|
|
249
|
+
**Use these mappings!** They tell you exactly what components to use!
|
|
250
|
+
|
|
251
|
+
## 13. Implementation Plan
|
|
252
|
+
|
|
253
|
+
### Files to Create
|
|
254
|
+
|
|
255
|
+
1. **Page Component**: `app/src/pages/pageName/PageName.tsx`
|
|
256
|
+
- Imports existing components
|
|
257
|
+
- Composes them into layout
|
|
258
|
+
- Manages state
|
|
259
|
+
|
|
260
|
+
2. **Page Styles**: `app/src/pages/pageName/pageName.scss`
|
|
261
|
+
- Uses design tokens
|
|
262
|
+
- Layout styles (grid/flex)
|
|
263
|
+
- Responsive breakpoints
|
|
264
|
+
|
|
265
|
+
3. **Tests**: `app/src/pages/pageName/PageName.test.tsx`
|
|
266
|
+
- Renders correctly
|
|
267
|
+
- Interactive elements work
|
|
268
|
+
- Handles errors
|
|
269
|
+
|
|
270
|
+
4. **Story** (optional): `app/src/pages/pageName/PageName.stories.tsx`
|
|
271
|
+
- Default state
|
|
272
|
+
- With data
|
|
273
|
+
- Error state
|
|
274
|
+
|
|
275
|
+
### Imports Needed
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
// Existing components to import:
|
|
279
|
+
import { Button } from 'Components/button/Button';
|
|
280
|
+
import { FormField } from 'Components/formField/FormField';
|
|
281
|
+
import { TextInput } from 'Components/formField/inputs/TextInput';
|
|
282
|
+
import { Table } from 'Components/table/Table';
|
|
283
|
+
// ... add all components you'll use
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### NO New Components
|
|
287
|
+
|
|
288
|
+
- ❌ Do NOT create new reusable components
|
|
289
|
+
- ✅ DO use existing components
|
|
290
|
+
- ✅ DO create custom layout divs with classes
|
|
291
|
+
- ✅ DO compose existing components
|
|
292
|
+
|
|
293
|
+
### Integration
|
|
294
|
+
|
|
295
|
+
- ❌ Do NOT add to `src/index.ts` (pages aren't library exports!)
|
|
296
|
+
- ✅ DO add to app routing
|
|
297
|
+
- ✅ DO import in app pages directory
|
|
298
|
+
- ✅ DO create tests
|
|
299
|
+
|
|
300
|
+
## 14. Special Considerations
|
|
301
|
+
|
|
302
|
+
### Third-party Integrations
|
|
303
|
+
- APIs to call? ___________
|
|
304
|
+
- External services? ___________
|
|
305
|
+
|
|
306
|
+
### Performance
|
|
307
|
+
- Large data sets (virtualization needed)?
|
|
308
|
+
- Heavy computations (memoization)?
|
|
309
|
+
- Image optimization?
|
|
310
|
+
|
|
311
|
+
### Browser Support
|
|
312
|
+
- Modern browsers only?
|
|
313
|
+
- Legacy IE support needed? (hopefully not!)
|
|
314
|
+
|
|
315
|
+
### Error Handling
|
|
316
|
+
- What can go wrong?
|
|
317
|
+
- How to show errors to user?
|
|
318
|
+
- Recovery actions?
|
|
319
|
+
|
|
320
|
+
## 15. Quality Checks
|
|
321
|
+
|
|
322
|
+
Before calling it done:
|
|
323
|
+
|
|
324
|
+
- [ ] `yarn check-types` passes
|
|
325
|
+
- [ ] `yarn style-lint` passes
|
|
326
|
+
- [ ] `yarn test` passes (100%!)
|
|
327
|
+
- [ ] Manually tested in Storybook
|
|
328
|
+
- [ ] Manually tested in app
|
|
329
|
+
- [ ] Responsive breakpoints work
|
|
330
|
+
- [ ] Accessibility checked
|
|
331
|
+
- [ ] Matches Figma design
|
|
332
|
+
|
|
333
|
+
MOST EXCELLENT! LET'S COMPOSE THIS BODACIOUS PAGE, HUNNI!! xxx 🐺💪🏍️✨
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// Page-specific styles
|
|
2
|
+
// NOTE: Pages don't use the ds- prefix (that's for library components)
|
|
3
|
+
// Use a descriptive page name instead
|
|
4
|
+
|
|
5
|
+
.page-name {
|
|
6
|
+
// Page container
|
|
7
|
+
max-width: 1200px;
|
|
8
|
+
margin: 0 auto;
|
|
9
|
+
padding: $space-8;
|
|
10
|
+
background-color: $color-background-primary;
|
|
11
|
+
min-height: 100vh;
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
|
|
15
|
+
// Header section
|
|
16
|
+
&__header {
|
|
17
|
+
margin-bottom: $space-6;
|
|
18
|
+
padding-bottom: $space-4;
|
|
19
|
+
border-bottom: 1px solid $color-border-primary;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&__title {
|
|
23
|
+
font-size: $text-heading-1-size;
|
|
24
|
+
font-weight: $text-heading-1-weight;
|
|
25
|
+
line-height: $text-heading-1-line-height;
|
|
26
|
+
color: $color-text-primary;
|
|
27
|
+
margin: 0 0 $space-2;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&__subtitle {
|
|
31
|
+
font-size: $text-body-size;
|
|
32
|
+
color: $color-text-secondary;
|
|
33
|
+
margin: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Main content
|
|
37
|
+
&__content {
|
|
38
|
+
flex: 1;
|
|
39
|
+
display: grid;
|
|
40
|
+
grid-template-columns: 1fr 2fr; // Adjust based on your layout
|
|
41
|
+
gap: $space-6;
|
|
42
|
+
margin-bottom: $space-6;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&__section-title {
|
|
46
|
+
font-size: $text-heading-2-size;
|
|
47
|
+
font-weight: $text-heading-2-weight;
|
|
48
|
+
color: $color-text-primary;
|
|
49
|
+
margin: 0 0 $space-4;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Form section
|
|
53
|
+
&__form {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
gap: $space-4;
|
|
57
|
+
padding: $space-4;
|
|
58
|
+
background-color: $color-background-secondary;
|
|
59
|
+
border-radius: $border-radius-medium;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Data section
|
|
63
|
+
&__data {
|
|
64
|
+
padding: $space-4;
|
|
65
|
+
background-color: $color-background-secondary;
|
|
66
|
+
border-radius: $border-radius-medium;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Footer section
|
|
70
|
+
&__footer {
|
|
71
|
+
display: flex;
|
|
72
|
+
justify-content: flex-end;
|
|
73
|
+
align-items: center;
|
|
74
|
+
gap: $space-3;
|
|
75
|
+
padding-top: $space-4;
|
|
76
|
+
border-top: 1px solid $color-border-primary;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Responsive breakpoints
|
|
80
|
+
@media (width <= 1024px) {
|
|
81
|
+
padding: $space-6;
|
|
82
|
+
|
|
83
|
+
&__content {
|
|
84
|
+
grid-template-columns: 1fr;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@media (width <= 768px) {
|
|
89
|
+
padding: $space-4;
|
|
90
|
+
|
|
91
|
+
&__header {
|
|
92
|
+
margin-bottom: $space-4;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&__title {
|
|
96
|
+
font-size: $text-heading-2-size;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&__content {
|
|
100
|
+
gap: $space-4;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&__form,
|
|
104
|
+
&__data {
|
|
105
|
+
padding: $space-3;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&__footer {
|
|
109
|
+
flex-direction: column-reverse;
|
|
110
|
+
gap: $space-2;
|
|
111
|
+
|
|
112
|
+
// Make buttons full width on mobile
|
|
113
|
+
> button {
|
|
114
|
+
width: 100%;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import classnames from 'classnames';
|
|
3
|
+
|
|
4
|
+
// Import EXISTING design system components
|
|
5
|
+
// These are the ACTUAL Arbor components - adjust based on your needs!
|
|
6
|
+
import { Button } from 'Components/button/Button';
|
|
7
|
+
import { Heading } from 'Components/heading/Heading';
|
|
8
|
+
import { Section } from 'Components/section/Section';
|
|
9
|
+
import { FormField } from 'Components/formField/FormField';
|
|
10
|
+
import { Table } from 'Components/table/Table';
|
|
11
|
+
// Import more as needed: Card, Pill, Icon, Separator, Modal, etc.
|
|
12
|
+
|
|
13
|
+
// Import page-specific styles
|
|
14
|
+
import './pageName.scss';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props for the PAGE_NAME page
|
|
18
|
+
*/
|
|
19
|
+
export interface PAGE_NAMEProps {
|
|
20
|
+
/**
|
|
21
|
+
* Optional className for the page container
|
|
22
|
+
*/
|
|
23
|
+
className?: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Initial data (if needed)
|
|
27
|
+
*/
|
|
28
|
+
initialData?: unknown;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Callback functions (if needed)
|
|
32
|
+
*/
|
|
33
|
+
onSubmit?: (data: unknown) => void;
|
|
34
|
+
onCancel?: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* PAGE_NAME Page
|
|
39
|
+
*
|
|
40
|
+
* A bodacious page generated from Figma designs! AROOOOO! 🐺
|
|
41
|
+
* This page COMPOSES existing Arbor design system components
|
|
42
|
+
* to match the Figma layout.
|
|
43
|
+
*
|
|
44
|
+
* Components used:
|
|
45
|
+
* - Heading (for all headings - not raw h1/h2!)
|
|
46
|
+
* - Section (for sections - not raw <section>!)
|
|
47
|
+
* - Button (for actions)
|
|
48
|
+
* - FormField (self-contained field with label + input)
|
|
49
|
+
* - Table (for data display)
|
|
50
|
+
* - Card (for card layouts)
|
|
51
|
+
*/
|
|
52
|
+
export const PAGE_NAME: React.FC<PAGE_NAMEProps> = ({
|
|
53
|
+
className,
|
|
54
|
+
initialData,
|
|
55
|
+
onSubmit,
|
|
56
|
+
onCancel,
|
|
57
|
+
}) => {
|
|
58
|
+
// State management for the page
|
|
59
|
+
const [formData, setFormData] = useState({
|
|
60
|
+
field1: '',
|
|
61
|
+
field2: '',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
65
|
+
const [error, setError] = useState<string | null>(null);
|
|
66
|
+
|
|
67
|
+
// Event handlers
|
|
68
|
+
const handleSubmit = () => {
|
|
69
|
+
setIsLoading(true);
|
|
70
|
+
setError(null);
|
|
71
|
+
|
|
72
|
+
// Validate and submit
|
|
73
|
+
try {
|
|
74
|
+
onSubmit?.(formData);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
setError('Something went wrong!');
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
setIsLoading(false);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const handleCancel = () => {
|
|
85
|
+
onCancel?.();
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const handleFieldChange = (field: string, value: string) => {
|
|
89
|
+
setFormData(prev => ({
|
|
90
|
+
...prev,
|
|
91
|
+
[field]: value,
|
|
92
|
+
}));
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div className={classnames('page-name', className)}>
|
|
97
|
+
{/* Header Section - Use Heading component, not raw h1! */}
|
|
98
|
+
<header className="page-name__header">
|
|
99
|
+
<Heading level={1}>Page Title</Heading>
|
|
100
|
+
<p className="page-name__subtitle">
|
|
101
|
+
Describe what this page does
|
|
102
|
+
</p>
|
|
103
|
+
</header>
|
|
104
|
+
|
|
105
|
+
{/* Main Content */}
|
|
106
|
+
<main className="page-name__content">
|
|
107
|
+
{/* Form Section - Use Section component! */}
|
|
108
|
+
<Section
|
|
109
|
+
title="Form Section"
|
|
110
|
+
headingLevel={2}
|
|
111
|
+
>
|
|
112
|
+
{/* FormField is self-contained - includes label AND input */}
|
|
113
|
+
<FormField
|
|
114
|
+
label="Field 1"
|
|
115
|
+
id="field1"
|
|
116
|
+
inputType="text"
|
|
117
|
+
errorText={error ?? undefined}
|
|
118
|
+
inputProps={{
|
|
119
|
+
value: formData.field1,
|
|
120
|
+
onChange: e => handleFieldChange('field1', e.target.value),
|
|
121
|
+
placeholder: 'Enter field 1',
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
<FormField
|
|
126
|
+
label="Field 2"
|
|
127
|
+
id="field2"
|
|
128
|
+
inputType="text"
|
|
129
|
+
inputProps={{
|
|
130
|
+
value: formData.field2,
|
|
131
|
+
onChange: e => handleFieldChange('field2', e.target.value),
|
|
132
|
+
placeholder: 'Enter field 2',
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
</Section>
|
|
136
|
+
|
|
137
|
+
{/* Data Section - Use Section component! */}
|
|
138
|
+
<Section
|
|
139
|
+
title="Data Section"
|
|
140
|
+
headingLevel={2}
|
|
141
|
+
>
|
|
142
|
+
<Table
|
|
143
|
+
data={initialData || []}
|
|
144
|
+
columns={[
|
|
145
|
+
{ field: 'id', headerName: 'ID' },
|
|
146
|
+
{ field: 'name', headerName: 'Name' },
|
|
147
|
+
]}
|
|
148
|
+
/>
|
|
149
|
+
</Section>
|
|
150
|
+
|
|
151
|
+
{/* -------------------------------------------------------
|
|
152
|
+
⚠️ MISSING COMPONENT PLACEHOLDER EXAMPLE
|
|
153
|
+
Component: ProgressTracker
|
|
154
|
+
Reason: No matching Arbor component exists for this Figma element.
|
|
155
|
+
Figma element: "Progress Bar / States" (layer in Figma design)
|
|
156
|
+
TODO: Replace this placeholder once the ProgressTracker component
|
|
157
|
+
is built in the design system.
|
|
158
|
+
------------------------------------------------------- */}
|
|
159
|
+
<Section
|
|
160
|
+
title="Progress"
|
|
161
|
+
headingLevel={2}
|
|
162
|
+
>
|
|
163
|
+
<svg
|
|
164
|
+
role="img"
|
|
165
|
+
aria-label="ProgressTracker placeholder - component not yet available in design system"
|
|
166
|
+
width="100%"
|
|
167
|
+
height="80"
|
|
168
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
169
|
+
>
|
|
170
|
+
<rect width="100%" height="100%" fill="#f5f5f5" rx="4" />
|
|
171
|
+
<rect
|
|
172
|
+
x="2"
|
|
173
|
+
y="2"
|
|
174
|
+
width="calc(100% - 4px)"
|
|
175
|
+
height="76"
|
|
176
|
+
fill="none"
|
|
177
|
+
stroke="#cccccc"
|
|
178
|
+
strokeWidth="2"
|
|
179
|
+
strokeDasharray="8 4"
|
|
180
|
+
rx="3"
|
|
181
|
+
/>
|
|
182
|
+
<text
|
|
183
|
+
x="50%"
|
|
184
|
+
y="42%"
|
|
185
|
+
textAnchor="middle"
|
|
186
|
+
dominantBaseline="middle"
|
|
187
|
+
fill="#888888"
|
|
188
|
+
fontSize="13"
|
|
189
|
+
fontWeight="600"
|
|
190
|
+
fontFamily="sans-serif"
|
|
191
|
+
>
|
|
192
|
+
ProgressTracker
|
|
193
|
+
</text>
|
|
194
|
+
<text
|
|
195
|
+
x="50%"
|
|
196
|
+
y="65%"
|
|
197
|
+
textAnchor="middle"
|
|
198
|
+
dominantBaseline="middle"
|
|
199
|
+
fill="#aaaaaa"
|
|
200
|
+
fontSize="11"
|
|
201
|
+
fontFamily="sans-serif"
|
|
202
|
+
>
|
|
203
|
+
Component not yet available in design system
|
|
204
|
+
</text>
|
|
205
|
+
</svg>
|
|
206
|
+
</Section>
|
|
207
|
+
</main>
|
|
208
|
+
|
|
209
|
+
{/* Footer Section with Actions */}
|
|
210
|
+
<footer className="page-name__footer">
|
|
211
|
+
<Button
|
|
212
|
+
variant="secondary"
|
|
213
|
+
onClick={handleCancel}
|
|
214
|
+
disabled={isLoading}
|
|
215
|
+
>
|
|
216
|
+
Cancel
|
|
217
|
+
</Button>
|
|
218
|
+
<Button
|
|
219
|
+
variant="primary"
|
|
220
|
+
onClick={handleSubmit}
|
|
221
|
+
disabled={isLoading}
|
|
222
|
+
>
|
|
223
|
+
{isLoading ? 'Submitting...' : 'Submit'}
|
|
224
|
+
</Button>
|
|
225
|
+
</footer>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export default PAGE_NAME;
|