@arbor-education/design-system.components 0.10.0 → 0.11.1

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 (119) 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 +14 -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 +5 -29
  40. package/dist/components/table/Table.d.ts.map +1 -1
  41. package/dist/components/table/Table.js +12 -22
  42. package/dist/components/table/Table.js.map +1 -1
  43. package/dist/components/table/Table.stories.d.ts +4 -0
  44. package/dist/components/table/Table.stories.d.ts.map +1 -1
  45. package/dist/components/table/Table.stories.js +163 -28
  46. package/dist/components/table/Table.stories.js.map +1 -1
  47. package/dist/components/table/Table.test.js +109 -8
  48. package/dist/components/table/Table.test.js.map +1 -1
  49. package/dist/components/table/TableSettingsContext.d.ts +13 -0
  50. package/dist/components/table/TableSettingsContext.d.ts.map +1 -0
  51. package/dist/components/table/TableSettingsContext.js +15 -0
  52. package/dist/components/table/TableSettingsContext.js.map +1 -0
  53. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts +3 -0
  54. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -0
  55. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +12 -0
  56. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -0
  57. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts +2 -0
  58. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.d.ts.map +1 -0
  59. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js +65 -0
  60. package/dist/components/table/cellRenderers/CheckboxCellRenderer.test.js.map +1 -0
  61. package/dist/components/table/tableConsts.d.ts +7 -0
  62. package/dist/components/table/tableConsts.d.ts.map +1 -0
  63. package/dist/components/table/tableConsts.js +8 -0
  64. package/dist/components/table/tableConsts.js.map +1 -0
  65. package/dist/components/table/{BulkActionsDropdown.d.ts → tableControls/BulkActionsDropdown.d.ts} +1 -1
  66. package/dist/components/table/tableControls/BulkActionsDropdown.d.ts.map +1 -0
  67. package/dist/components/table/{BulkActionsDropdown.js → tableControls/BulkActionsDropdown.js} +3 -3
  68. package/dist/components/table/tableControls/BulkActionsDropdown.js.map +1 -0
  69. package/dist/components/table/{HideColumnsDropdown.d.ts → tableControls/HideColumnsDropdown.d.ts} +1 -2
  70. package/dist/components/table/tableControls/HideColumnsDropdown.d.ts.map +1 -0
  71. package/dist/components/table/{HideColumnsDropdown.js → tableControls/HideColumnsDropdown.js} +2 -2
  72. package/dist/components/table/tableControls/HideColumnsDropdown.js.map +1 -0
  73. package/dist/components/table/tableControls/TableControls.d.ts +23 -0
  74. package/dist/components/table/tableControls/TableControls.d.ts.map +1 -0
  75. package/dist/components/table/tableControls/TableControls.js +21 -0
  76. package/dist/components/table/tableControls/TableControls.js.map +1 -0
  77. package/dist/components/table/tableControls/TableControls.test.d.ts +2 -0
  78. package/dist/components/table/tableControls/TableControls.test.d.ts.map +1 -0
  79. package/dist/components/table/tableControls/TableControls.test.js +124 -0
  80. package/dist/components/table/tableControls/TableControls.test.js.map +1 -0
  81. package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -0
  82. package/dist/components/table/{TableSettingsDropdown.js → tableControls/TableSettingsDropdown.js} +7 -6
  83. package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -0
  84. package/dist/components/table/useTableSettings.d.ts +1 -1
  85. package/dist/components/table/useTableSettings.d.ts.map +1 -1
  86. package/dist/components/table/useTableSettings.js +1 -1
  87. package/dist/components/table/useTableSettings.js.map +1 -1
  88. package/dist/index.css +19 -1
  89. package/dist/index.css.map +1 -1
  90. package/dist/index.d.ts +1 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +1 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/utils/setAgGridLicenseKey.js +1 -1
  95. package/package.json +1 -1
  96. package/src/components/table/DSDefaultColDef.ts +2 -2
  97. package/src/components/table/Table.stories.tsx +202 -35
  98. package/src/components/table/Table.test.tsx +134 -8
  99. package/src/components/table/Table.tsx +12 -22
  100. package/src/components/table/TableSettingsContext.ts +15 -0
  101. package/src/components/table/cellRenderers/CheckboxCellRenderer.test.tsx +74 -0
  102. package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +28 -0
  103. package/src/components/table/table.scss +23 -1
  104. package/src/components/table/tableConsts.ts +6 -0
  105. package/src/components/table/{BulkActionsDropdown.tsx → tableControls/BulkActionsDropdown.tsx} +2 -2
  106. package/src/components/table/{HideColumnsDropdown.tsx → tableControls/HideColumnsDropdown.tsx} +2 -2
  107. package/src/components/table/tableControls/TableControls.test.tsx +150 -0
  108. package/src/components/table/tableControls/TableControls.tsx +143 -0
  109. package/src/components/table/{TableSettingsDropdown.tsx → tableControls/TableSettingsDropdown.tsx} +2 -1
  110. package/src/components/table/useTableSettings.ts +1 -1
  111. package/src/index.ts +1 -0
  112. package/src/utils/setAgGridLicenseKey.ts +1 -1
  113. package/dist/components/table/BulkActionsDropdown.d.ts.map +0 -1
  114. package/dist/components/table/BulkActionsDropdown.js.map +0 -1
  115. package/dist/components/table/HideColumnsDropdown.d.ts.map +0 -1
  116. package/dist/components/table/HideColumnsDropdown.js.map +0 -1
  117. package/dist/components/table/TableSettingsDropdown.d.ts.map +0 -1
  118. package/dist/components/table/TableSettingsDropdown.js.map +0 -1
  119. /package/dist/components/table/{TableSettingsDropdown.d.ts → tableControls/TableSettingsDropdown.d.ts} +0 -0
@@ -0,0 +1,462 @@
1
+ # Figma Design Feasibility Assessment
2
+ ## Design: Node 551:43094 — Daily Attendance Page
3
+ **Written by:** Sophia Petrillo, Componentspert, age none-of-your-business
4
+ **Fact-checked by:** Dorothy Zbornak, QA Expert
5
+ **Date**: 2026-04-10
6
+
7
+ ---
8
+
9
+ ## What Is This Thing, Anyway?
10
+
11
+ Picture it: Sicily, 1952. My Aunt Lucia was the attendance secretary at the village school. Every morning she stood at the gate with a ledger, ticking off children as they arrived. Messy, slow, and she always smelled of aniseed.
12
+
13
+ THIS is what Arbor built to replace that. The Daily Attendance page is the command centre for tracking which children are in which registers, which lessons they belong to, and whether their marks have been filled. It's a full-desktop layout — 1366px wide — featuring a top navigation bar, a collapsible left sidebar, breadcrumb navigation, a page heading, a filter info bar, and a very large, very capable AG Grid data table. Nineteen distinct UI elements. Some map beautifully to our library. Some do not exist at all. Pull up a chair.
14
+
15
+ ---
16
+
17
+ ## Design Overview
18
+
19
+ **Daily Attendance | Desktop 1366px** — A full application page layout for school attendance management.
20
+
21
+ ### UI Elements Identified
22
+
23
+ - Top navigation bar (logo, nav links with dropdowns, global search, Ask Arbor AI button, user avatar dropdown, org logo)
24
+ - Left side navigation panel (collapsible sections, active items, favorites star icons, notification badge)
25
+ - Breadcrumbs (Students / Attendance / Registers / Daily Attendance + link icon)
26
+ - Page heading H1 "Daily Attendance" with right-aligned primary action button
27
+ - Filter info bar (colored square indicators + info text summary + secondary Edit button)
28
+ - Table toolbar: Actions dropdown, Undo/Redo buttons, Hide columns dropdown
29
+ - Table toolbar: Icon-only buttons (search, comment/message, download, settings, expand)
30
+ - AG Grid table: checkbox selection column
31
+ - AG Grid table: column definitions (Time, Lesson/Event, Year Group, Event Type, Teacher, Marks)
32
+ - AG Grid table: marks status indicators cell (✓ count / ⏱ count / ✗ count)
33
+ - AG Grid table: "(No Students)" placeholder text
34
+ - Pagination footer (first/prev/page input/next/last + "Showing X of Y results")
35
+ - Expand table button
36
+ - UserDropdown (top right of nav bar)
37
+
38
+ ---
39
+
40
+ ## Section 1: What We Already Have — Use These As-Is, Don't Reinvent Them
41
+
42
+ ### Page Heading + Right-Aligned Action Button (`src/components/heading/Heading.tsx`)
43
+
44
+ Oh, this one is a gift. `Heading` with TWO `Heading.InnerContainer` children is precisely the flex layout pattern that splits a title left and an action button right. This is not improvisation — this is the component doing exactly what it was built for.
45
+
46
+ **Key features:**
47
+ - `level={1}` → renders as `<h1>`
48
+ - `Heading.InnerContainer` → `<span class="ds-heading__inner-container">`, one per side
49
+ - No custom flex/justify CSS needed — `Heading` handles it
50
+
51
+ **Example:**
52
+ ```tsx
53
+ <Heading level={1}>
54
+ <Heading.InnerContainer>Daily Attendance</Heading.InnerContainer>
55
+ <Heading.InnerContainer>
56
+ <Button variant="primary">Button Text</Button>
57
+ </Heading.InnerContainer>
58
+ </Heading>
59
+ ```
60
+
61
+ ---
62
+
63
+ ### Table — Actions Dropdown (`src/components/table/Table.tsx`)
64
+
65
+ `Table.BulkActionsDropdown` was built for exactly this "Actions (0)" pattern. It reads the selected row count from `GridApiContext` internally and renders a `Button variant="dropdown"` with the count automatically.
66
+
67
+ **Key features:**
68
+ - Must be rendered INSIDE the `Table` component tree (uses `GridApiContext`)
69
+ - Receives an `actions` array of `{ displayName, callback }` objects
70
+ - Pass via `headerContent` prop on `Table`
71
+
72
+ **Example:**
73
+ ```tsx
74
+ <Table
75
+ headerContent={
76
+ <Table.BulkActionsDropdown
77
+ actions={[
78
+ { displayName: 'Mark Present', callback: (api) => { /* ... */ } },
79
+ ]}
80
+ />
81
+ }
82
+ />
83
+ ```
84
+
85
+ ---
86
+
87
+ ### Table — Hide Columns Dropdown (`src/components/table/Table.tsx`)
88
+
89
+ `Table.HideColumnsDropdown` is purpose-built. It reads current column state from `GridApiContext` and renders a multi-select dropdown for toggling visibility. Also lives in `headerContent`.
90
+
91
+ **Example:**
92
+ ```tsx
93
+ <Table headerContent={<Table.HideColumnsDropdown />} />
94
+ ```
95
+
96
+ ---
97
+
98
+ ### Table — Pagination Footer (`src/components/table/Table.tsx`)
99
+
100
+ `Table.PaginationPanel` + `Table.RowCountInfo` in `footerContent`. The "Showing X of Y results" text and all pagination controls are covered.
101
+
102
+ **Key features:**
103
+ - `Table.PaginationPanel` → first/prev/page input/next/last controls
104
+ - `Table.RowCountInfo` → "Showing X of Y results" text
105
+ - All use `GridApiContext` — must be inside `Table`'s tree
106
+ - Enable pagination: `pagination={true}` + `paginationPageSize={100}` on `Table`
107
+
108
+ **Example:**
109
+ ```tsx
110
+ <Table
111
+ pagination={true}
112
+ paginationPageSize={100}
113
+ footerContent={
114
+ <>
115
+ <Table.RowCountInfo />
116
+ <Table.PaginationPanel />
117
+ </>
118
+ }
119
+ />
120
+ ```
121
+
122
+ ---
123
+
124
+ ### Table — AG Grid Checkbox Selection
125
+
126
+ Native AG Grid. No custom component needed. Pass `checkboxSelection` and `headerCheckboxSelection` in the first column definition:
127
+
128
+ ```tsx
129
+ const columnDefs = [
130
+ {
131
+ checkboxSelection: true,
132
+ headerCheckboxSelection: true,
133
+ width: 50,
134
+ pinned: 'left',
135
+ },
136
+ { field: 'time', headerName: 'Time' },
137
+ // etc.
138
+ ];
139
+ <Table rowSelection="multiple" columnDefs={columnDefs} />
140
+ ```
141
+
142
+ AG Grid Enterprise handles the indeterminate header state automatically.
143
+
144
+ ---
145
+
146
+ ### Table — Empty State "(No Students)"
147
+
148
+ Native AG Grid via `noRowsOverlayComponent`:
149
+
150
+ ```tsx
151
+ <Table
152
+ noRowsOverlayComponent={() => (
153
+ <span className="ds-daily-attendance__empty">No Students</span>
154
+ )}
155
+ />
156
+ ```
157
+
158
+ ---
159
+
160
+ ### Undo / Redo Toolbar Buttons (`src/components/button/Button.tsx`)
161
+
162
+ `Button variant="secondary" size="S"` with verified icon names. Dorothy confirmed `'undo'` and `'redo'` BOTH exist in the allowed icons set.
163
+
164
+ **Example:**
165
+ ```tsx
166
+ <Button variant="secondary" size="S" iconLeftName="undo" iconLeftScreenReaderText="Undo" />
167
+ <Button variant="secondary" size="S" iconLeftName="redo" iconLeftScreenReaderText="Redo" />
168
+ ```
169
+
170
+ ---
171
+
172
+ ### Icon-Only Toolbar Buttons (`src/components/button/Button.tsx`)
173
+
174
+ `Button` in icon-only mode (auto-applied when `iconLeftName` is set and `children` is absent). Use `variant="tertiary"` for the toolbar ghost style. ALWAYS wrap in `TooltipWrapper` — icon-only buttons without tooltips fail WCAG 2.1 AA.
175
+
176
+ **Dorothy-verified icon names:**
177
+ - Search: `'search'` ✅
178
+ - Download: `'download'` ✅
179
+ - Settings: use `Table.TableSettingsDropdown` instead (see below)
180
+ - Expand: `'expand'` ✅
181
+ - Comment/Message: `'message-square-more'` ✅ — **`'comment'` does NOT exist**
182
+
183
+ **Example:**
184
+ ```tsx
185
+ <TooltipWrapper tooltipContent="Download">
186
+ <Button variant="tertiary" size="S" iconLeftName="download" iconLeftScreenReaderText="Download registers" />
187
+ </TooltipWrapper>
188
+ ```
189
+
190
+ ---
191
+
192
+ ### Table — Settings Button (`src/components/table/Table.tsx`)
193
+
194
+ `Table.TableSettingsDropdown` is the right component — not a raw icon button. It provides the settings icon trigger and the full settings panel (row spacing, borders, cell colours).
195
+
196
+ ```tsx
197
+ <Table.TableSettingsDropdown onTableSettingsChanged={handleSettingsChange} />
198
+ ```
199
+
200
+ ---
201
+
202
+ ### Table — Expand Table Button
203
+
204
+ `Button variant="secondary" size="S"` in the `footerContent` slot:
205
+
206
+ ```tsx
207
+ footerContent={
208
+ <>
209
+ <Table.RowCountInfo />
210
+ <div className="ds-daily-attendance__footer-right">
211
+ <Table.PaginationPanel />
212
+ <Button variant="secondary" size="S">Expand table</Button>
213
+ </div>
214
+ </>
215
+ }
216
+ ```
217
+
218
+ ---
219
+
220
+ ### UserDropdown — Top Right User Menu (`src/components/userDropdown/UserDropdown.tsx`)
221
+
222
+ `UserDropdown` handles the entire top-right user avatar trigger, name, role, linked apps, and sign-out in one component. Use `variant="dark"` for a dark navigation bar.
223
+
224
+ **Example:**
225
+ ```tsx
226
+ <UserDropdown
227
+ variant="dark"
228
+ user={{ name: 'Amee Morris', subtitle: 'Administrator', avatarSrc: '/path/to/avatar.jpg' }}
229
+ onSignOut={handleSignOut}
230
+ logoSrc="/path/to/org-logo.png"
231
+ sections={[
232
+ {
233
+ label: 'Switch product',
234
+ items: [{ label: 'Arbor', href: '...', logo: ArborLogo }],
235
+ },
236
+ ]}
237
+ />
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Section 2: Almost There — Minor Issues or Gotchas
243
+
244
+ ### Filter Info Bar
245
+
246
+ **What exists:** No single `FilterInfoBar` component. `Banner` LOOKS superficially similar but is wrong here — it has rigid semantic styling (info/warning/destructive) and an opinionated layout that doesn't match the filter summary pattern.
247
+
248
+ **What's needed:** A horizontal strip with colored square/circle indicators, a text summary, and a secondary action button.
249
+
250
+ **The fix — compose from primitives:**
251
+ ```tsx
252
+ <div className="ds-daily-attendance__filter-bar">
253
+ <Tag text="AM" color="blue" dotColour="blue" />
254
+ <Tag text="Internal Exclusions" color="orange" dotColour="orange" />
255
+ <span className="ds-daily-attendance__filter-text">
256
+ Select Date Wed, 05 Feb 2025 AM Showing Attendance Registers...
257
+ </span>
258
+ <Button variant="secondary" size="S" iconLeftName="pencil">Edit</Button>
259
+ </div>
260
+ ```
261
+
262
+ Note: `Tag dotColour` produces circles. If the design requires literal squares, that's a bespoke `<span>` with CSS. `'pencil'` is the correct icon name — Dorothy confirmed `'edit'` does NOT exist.
263
+
264
+ **Effort:** Low — composable from primitives.
265
+
266
+ ---
267
+
268
+ ### Marks Status Indicators Cell (`src/components/icon/Icon.tsx`)
269
+
270
+ **What exists:** No registered cell renderer handles the "✓ 24 ⏱ 1 ✗ 3" pattern. `dsInlineTextCellRenderer` is text-only. `dsButtonCellRenderer` renders a single button.
271
+
272
+ **What's needed:** A custom `cellRenderer` component for the Marks column. This is expected AG Grid architecture.
273
+
274
+ **The fix:**
275
+ ```tsx
276
+ const MarksSummaryCellRenderer = ({ value }) => (
277
+ <span className="ds-daily-attendance__marks-summary">
278
+ <Icon name="check" size={16} color="var(--color-success-500)" />
279
+ <span>{value.present}</span>
280
+ <Icon name="clock" size={16} color="var(--color-caution-500)" />
281
+ <span>{value.pending}</span>
282
+ <Icon name="x" size={16} color="var(--color-destructive-500)" />
283
+ <span>{value.absent}</span>
284
+ </span>
285
+ );
286
+
287
+ // in columnDefs:
288
+ { field: 'marks', headerName: 'Marks', cellRenderer: MarksSummaryCellRenderer }
289
+ ```
290
+
291
+ **Not a library gap** — this is correct pluggable AG Grid architecture. **Effort:** Low.
292
+
293
+ ---
294
+
295
+ ### Breadcrumbs
296
+
297
+ **What exists:** No `Breadcrumbs` component. Must be composed from `Button variant="text-link"`, `Separator orientation="vertical"`, and semantic HTML.
298
+
299
+ **The fix:**
300
+ ```tsx
301
+ <nav aria-label="Breadcrumb">
302
+ <ol className="ds-daily-attendance__breadcrumbs">
303
+ <li><Button variant="text-link">Students</Button></li>
304
+ <li aria-hidden="true"><Separator orientation="vertical" decorative={true} /></li>
305
+ <li><Button variant="text-link">Attendance</Button></li>
306
+ <li aria-hidden="true"><Separator orientation="vertical" decorative={true} /></li>
307
+ <li><Button variant="text-link">Registers</Button></li>
308
+ <li aria-hidden="true"><Separator orientation="vertical" decorative={true} /></li>
309
+ <li><span aria-current="page">Daily Attendance</span></li>
310
+ </ol>
311
+ </nav>
312
+ ```
313
+
314
+ **Effort:** Low for this instance. But this pattern appears on every Arbor MIS page — it needs a library component.
315
+
316
+ ---
317
+
318
+ ## Section 3: Build It From Scratch — These Don't Exist Yet
319
+
320
+ ### Top Navigation Bar (Layout Shell)
321
+
322
+ The layout chrome — dark background, logo slot, horizontal nav link row, layout structure — does not exist as a component. The interactive pieces ARE available (`UserDropdown`, `SearchBar`, `Button`, `Icon`) but the container shell is bespoke.
323
+
324
+ **What would need building:** `TopNavigationBar` with logo slot, nav links slot, search slot, right-aligned actions slot. Nav link items are `Button` + `Dropdown` composites.
325
+
326
+ **Effort:** High. Should be a shared library component, not inline page code.
327
+
328
+ ---
329
+
330
+ ### Left Side Navigation Panel
331
+
332
+ No `SideNavigation` or sidebar component exists. The design shows collapsible section groups, individual nav items with active state, favourites (`'favourite-outline'` / `'favourite-filled'` — `'star'` does NOT exist per Dorothy), and notification badges.
333
+
334
+ `Section` is NOT the answer — it's a page-layout card, not a slim sidebar nav item.
335
+
336
+ **What would need building:** `SideNavigation` shell, `SideNavigation.Section` for collapsible groups, `SideNavigation.Item` for individual links.
337
+
338
+ **Effort:** High. Single most impactful missing component for Arbor MIS page fidelity.
339
+
340
+ ---
341
+
342
+ ### Notification Badge
343
+
344
+ The circular count badge overlaying nav items has no library equivalent. `Tag` is rectangular. No `Badge` component exists.
345
+
346
+ **What would need building:** Small circular `Badge` component with count/dot variants and colour options. Absolute overlay or inline positioning.
347
+
348
+ **Effort:** Low. Small, focused, immediately reusable across nav, avatars, icons.
349
+
350
+ ---
351
+
352
+ ## Section 4: Tricky Bits — Pay Attention Here
353
+
354
+ ### 1. `headerContent` Must Be Truthy for Search/Toolbar to Render
355
+
356
+ Dorothy caught a critical gotcha: `TableHeader` only renders when `headerContent` is truthy. Passing `hasSearch={true}` alone does NOTHING if `headerContent` is `null`. You must pass truthy `headerContent` to get any header (including the search bar). If the design uses a custom toolbar, pass `hasSearch={false}` and wire search state yourself.
357
+
358
+ ### 2. `CheckboxInput` is NOT in the Public API
359
+
360
+ Dorothy confirmed `CheckboxInput` and `CheckboxGroup` are NOT exported from `src/index.ts`. Use the Table's native AG Grid `checkboxSelection` for row selection (the correct approach). If standalone checkboxes are needed elsewhere on this page, raise a ticket to export these.
361
+
362
+ ### 3. Tooltip Every Icon-Only Button
363
+
364
+ Every icon-only toolbar button MUST be wrapped in `TooltipWrapper`. WCAG 2.1 AA requirement. Not optional.
365
+
366
+ ### 4. Verify Icon Names Before Committing
367
+
368
+ Dorothy's caught hallucinations:
369
+ - `'comment'` → **DOES NOT EXIST** → use `'message-square-more'`
370
+ - `'star'` → **DOES NOT EXIST** → use `'favourite-outline'` or `'favourite-filled'`
371
+ - `'edit'` → **DOES NOT EXIST** → use `'pencil'`
372
+ - `'ghost'` → **NOT a Button variant** → use `'tertiary'`
373
+
374
+ TypeScript will catch these at compile time, but verify upfront against `src/components/icon/allowedIcons.tsx`.
375
+
376
+ ---
377
+
378
+ ## Section 5: The Verdict
379
+
380
+ Picture it: Sicily, 1967. My cousin Giacomo spent three days building a barn without a blueprint. Half the walls fell down. The other half ended up where the chicken coop was supposed to go. The chickens were confused for months.
381
+
382
+ Don't be Giacomo.
383
+
384
+ ### Is It Buildable With Our Existing Components?
385
+
386
+ **Mostly YES. High confidence for the table. Bespoke work required for navigation chrome.**
387
+
388
+ The data table — the heart of this page — maps almost perfectly to our `Table` component and its sub-components. AG Grid Enterprise handles the heavy lifting. Toolbar, pagination, bulk actions, settings, hide columns are all pre-built. The navigation chrome (top nav, side nav) is genuine bespoke work — but if this page lives inside an existing Arbor app shell that already renders navigation, those concerns are already solved at the host application level.
389
+
390
+ ### Summary Table
391
+
392
+ | Design Element | Library Component | Status |
393
+ |---|---|---|
394
+ | Page H1 + right button | `Heading` + `Heading.InnerContainer` | ✅ Ready |
395
+ | Actions dropdown | `Table.BulkActionsDropdown` | ✅ Ready |
396
+ | Undo/Redo buttons | `Button` with `iconLeftName="undo/redo"` | ✅ Ready |
397
+ | Hide columns | `Table.HideColumnsDropdown` | ✅ Ready |
398
+ | Settings button | `Table.TableSettingsDropdown` | ✅ Ready |
399
+ | Icon toolbar buttons | `Button` icon-only + `TooltipWrapper` | ✅ Ready |
400
+ | Checkbox column | AG Grid native `checkboxSelection` | ✅ Ready |
401
+ | Column definitions | AG Grid `columnDefs` | ✅ Ready |
402
+ | Empty state "(No Students)" | `noRowsOverlayComponent` prop | ✅ Ready |
403
+ | Pagination | `Table.PaginationPanel` + `Table.RowCountInfo` | ✅ Ready |
404
+ | Expand table button | `Button variant="secondary"` | ✅ Ready |
405
+ | UserDropdown | `UserDropdown variant="dark"` | ✅ Ready |
406
+ | Filter info bar | Compose: `Tag` + `Button` + layout | 🔧 Minor work |
407
+ | Marks status cell | Custom `cellRenderer` with `Icon` | 🔧 Minor work |
408
+ | Breadcrumbs | Compose: `Button text-link` + `Separator` + semantic HTML | 🔧 Minor work |
409
+ | Top navigation bar | `UserDropdown`/`SearchBar`/`Button` for parts; chrome is bespoke | 🆕 New component |
410
+ | Side navigation panel | No equivalent exists | 🆕 New component |
411
+ | Notification badge | No `Badge` component exists | 🆕 New component |
412
+
413
+ ### What Actually Needs Work
414
+
415
+ | Item | Where It Lives | Effort |
416
+ |---|---|---|
417
+ | Marks status cell renderer | Page-level component | Low |
418
+ | Breadcrumbs (this instance) | Page-level composition | Low |
419
+ | Filter info bar | Page-level composition | Low |
420
+ | Breadcrumbs (library component) | New library component | Medium |
421
+ | Notification Badge component | New library component | Low |
422
+ | Top Navigation Bar | New library component (or host app) | High |
423
+ | Side Navigation Panel | New library component (or host app) | High |
424
+
425
+ ### Summary Verdict
426
+
427
+ **12 out of 18 elements** can be built directly with current library components. 3 elements need minor composition work (filter bar, breadcrumbs instance, marks cell renderer). 3 require new library components (top nav, side nav, notification badge).
428
+
429
+ **Recommendation:** Highly feasible for the table and content area. The data table is essentially already built. The navigation chrome gaps are structural — either build as shared library components (high value, high effort) or deliver inside the host app's existing nav shell.
430
+
431
+ ---
432
+
433
+ ## Appendix: Files Referenced in This Assessment
434
+
435
+ *Every file Dorothy read to verify claims. This assessment is grounded in actual source code.*
436
+
437
+ - `src/index.ts`
438
+ - `src/components/table/Table.tsx`
439
+ - `src/components/table/TableHeader.tsx`
440
+ - `src/components/table/useTableSettings.ts`
441
+ - `src/components/table/BulkActionsDropdown.tsx`
442
+ - `src/components/table/HideColumnsDropdown.tsx`
443
+ - `src/components/button/Button.tsx`
444
+ - `src/components/heading/Heading.tsx`
445
+ - `src/components/section/Section.tsx`
446
+ - `src/components/banner/Banner.tsx`
447
+ - `src/components/icon/Icon.tsx`
448
+ - `src/components/icon/allowedIcons.tsx`
449
+ - `src/components/dropdown/Dropdown.tsx`
450
+ - `src/components/dropdown/DropdownTrigger.tsx`
451
+ - `src/components/dropdown/DropdownContent.tsx`
452
+ - `src/components/dropdown/items/DropdownItem.tsx`
453
+ - `src/components/dropdown/items/DropdownSelectItem.tsx`
454
+ - `src/components/dropdown/items/DropdownGroup.tsx`
455
+ - `src/components/searchBar/SearchBar.tsx`
456
+ - `src/components/pill/Pill.tsx`
457
+ - `src/components/tag/Tag.tsx`
458
+
459
+ ---
460
+
461
+ *Analysis by Sophia Petrillo, Componentspert 👜, fact-checked by Dorothy Zbornak 🔍*
462
+ *Powered by Claude Code 🐺*