@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.
- 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/CHANGELOG.md +14 -0
- package/CLAUDE.md +31 -0
- package/CONTRIBUTING.md +191 -0
- package/README.md +110 -20
- package/dist/components/table/DSDefaultColDef.js +2 -2
- package/dist/components/table/DSDefaultColDef.js.map +1 -1
- package/dist/components/table/Table.d.ts +5 -29
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +12 -22
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts +4 -0
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +163 -28
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/Table.test.js +109 -8
- package/dist/components/table/Table.test.js.map +1 -1
- package/dist/components/table/TableSettingsContext.d.ts +13 -0
- package/dist/components/table/TableSettingsContext.d.ts.map +1 -0
- package/dist/components/table/TableSettingsContext.js +15 -0
- package/dist/components/table/TableSettingsContext.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/components/table/tableConsts.d.ts +7 -0
- package/dist/components/table/tableConsts.d.ts.map +1 -0
- package/dist/components/table/tableConsts.js +8 -0
- package/dist/components/table/tableConsts.js.map +1 -0
- package/dist/components/table/{BulkActionsDropdown.d.ts → tableControls/BulkActionsDropdown.d.ts} +1 -1
- package/dist/components/table/tableControls/BulkActionsDropdown.d.ts.map +1 -0
- package/dist/components/table/{BulkActionsDropdown.js → tableControls/BulkActionsDropdown.js} +3 -3
- package/dist/components/table/tableControls/BulkActionsDropdown.js.map +1 -0
- package/dist/components/table/{HideColumnsDropdown.d.ts → tableControls/HideColumnsDropdown.d.ts} +1 -2
- package/dist/components/table/tableControls/HideColumnsDropdown.d.ts.map +1 -0
- package/dist/components/table/{HideColumnsDropdown.js → tableControls/HideColumnsDropdown.js} +2 -2
- package/dist/components/table/tableControls/HideColumnsDropdown.js.map +1 -0
- package/dist/components/table/tableControls/TableControls.d.ts +23 -0
- package/dist/components/table/tableControls/TableControls.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableControls.js +21 -0
- package/dist/components/table/tableControls/TableControls.js.map +1 -0
- package/dist/components/table/tableControls/TableControls.test.d.ts +2 -0
- package/dist/components/table/tableControls/TableControls.test.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableControls.test.js +124 -0
- package/dist/components/table/tableControls/TableControls.test.js.map +1 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -0
- package/dist/components/table/{TableSettingsDropdown.js → tableControls/TableSettingsDropdown.js} +7 -6
- package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -0
- package/dist/components/table/useTableSettings.d.ts +1 -1
- package/dist/components/table/useTableSettings.d.ts.map +1 -1
- package/dist/components/table/useTableSettings.js +1 -1
- package/dist/components/table/useTableSettings.js.map +1 -1
- package/dist/index.css +19 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/setAgGridLicenseKey.js +1 -1
- package/package.json +1 -1
- package/src/components/table/DSDefaultColDef.ts +2 -2
- package/src/components/table/Table.stories.tsx +202 -35
- package/src/components/table/Table.test.tsx +134 -8
- package/src/components/table/Table.tsx +12 -22
- package/src/components/table/TableSettingsContext.ts +15 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.test.tsx +74 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +28 -0
- package/src/components/table/table.scss +23 -1
- package/src/components/table/tableConsts.ts +6 -0
- package/src/components/table/{BulkActionsDropdown.tsx → tableControls/BulkActionsDropdown.tsx} +2 -2
- package/src/components/table/{HideColumnsDropdown.tsx → tableControls/HideColumnsDropdown.tsx} +2 -2
- package/src/components/table/tableControls/TableControls.test.tsx +150 -0
- package/src/components/table/tableControls/TableControls.tsx +143 -0
- package/src/components/table/{TableSettingsDropdown.tsx → tableControls/TableSettingsDropdown.tsx} +2 -1
- package/src/components/table/useTableSettings.ts +1 -1
- package/src/index.ts +1 -0
- package/src/utils/setAgGridLicenseKey.ts +1 -1
- package/dist/components/table/BulkActionsDropdown.d.ts.map +0 -1
- package/dist/components/table/BulkActionsDropdown.js.map +0 -1
- package/dist/components/table/HideColumnsDropdown.d.ts.map +0 -1
- package/dist/components/table/HideColumnsDropdown.js.map +0 -1
- package/dist/components/table/TableSettingsDropdown.d.ts.map +0 -1
- package/dist/components/table/TableSettingsDropdown.js.map +0 -1
- /package/dist/components/table/{TableSettingsDropdown.d.ts → tableControls/TableSettingsDropdown.d.ts} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Blanche Designspert - Persistent Memory
|
|
2
|
+
|
|
3
|
+
## Key File Locations
|
|
4
|
+
- Design tokens: `src/tokens.scss` (CSS custom properties, NOT Sass vars - globally available, never import)
|
|
5
|
+
- Component public API: `src/index.ts`
|
|
6
|
+
- Styles entry: `src/index.scss`
|
|
7
|
+
- `src/pages/` does NOT exist on the current branch (confirmed 2026-04-17) — was on a prior branch
|
|
8
|
+
|
|
9
|
+
## Token Conventions (confirmed from src/tokens.scss)
|
|
10
|
+
- Spacing tokens: `--spacing-xsmall` (0.25rem), `--spacing-small` (0.5rem), `--spacing-medium` (0.75rem), `--spacing-large` (1rem), `--spacing-xlarge` (1.5rem), `--spacing-xxlarge` (2rem), `--spacing-xxxlarge` (4rem)
|
|
11
|
+
- Grey scale: `--color-grey-050` through `--color-grey-900` (050, 100, 200, 300, 400, 500, 600, 700, 800, 900)
|
|
12
|
+
- Mono: `--color-mono-black` (#202020), `--color-mono-white` (#ffffff)
|
|
13
|
+
- Font sizes: `--font-size-1-11` through `--font-size-8-40` (no `--font-size-5-18` listed on line 9-16 but IS defined at line 16)
|
|
14
|
+
- Font weights: `--font-weight-regular`, `--font-weight-medium`, `--font-weight-semi-bold`, `--font-weight-bold`
|
|
15
|
+
- Border radius: `--border-radius-xsmall` (4px), `--border-radius-small` (8px), `--border-radius-large` (16px), `--border-radius-round` (99px)
|
|
16
|
+
- Line heights: `--line-height-tight` (1.25), `--line-height-default` (1.5)
|
|
17
|
+
|
|
18
|
+
## Semantic / Component Tokens (use over base tokens)
|
|
19
|
+
- Hyperlink color: `--type-body-hyperlink-color` (maps to `--color-brand-700`) - use for link text
|
|
20
|
+
- Hyperlink weight: `--type-body-hyperlink-weight` (maps to `--font-weight-medium`)
|
|
21
|
+
- Body text size: `--type-body-p-size` (maps to `--font-size-2-13`)
|
|
22
|
+
- Page background: `--page-color-background` (maps to `--color-grey-050`)
|
|
23
|
+
- Page border: `--page-base-color-border` (maps to `--color-grey-050`)
|
|
24
|
+
- Page heading text: `--page-heading-color-text` (maps to `--color-mono-black`)
|
|
25
|
+
- Page heading gap: `--page-heading-spacing-gap` (maps to `--spacing-small`)
|
|
26
|
+
- Default icon color: `--icons-icon-default` (maps to `--color-grey-900`)
|
|
27
|
+
- Focus color: `--focus-color-focus` (maps to `--color-brand-500`)
|
|
28
|
+
|
|
29
|
+
## CSS Naming Conventions
|
|
30
|
+
- Prefix: `ds-` (all design system classes)
|
|
31
|
+
- BEM: `ds-{block}`, `ds-{block}__{element}`, `ds-{block}--{modifier}`
|
|
32
|
+
- SCSS file: camelCase matching directory name (e.g. `assessmentsPage.scss`)
|
|
33
|
+
- Use `classnames` library for conditional classes
|
|
34
|
+
|
|
35
|
+
## Typography Color Patterns (for body text in pages)
|
|
36
|
+
- Primary / heading text: `--color-grey-900` or `--color-mono-black`
|
|
37
|
+
- Secondary / supporting text: `--color-grey-600` or `--color-grey-500`
|
|
38
|
+
- Muted / disabled: `--color-grey-400`
|
|
39
|
+
- Links: use breadcrumb component tokens when in breadcrumbs (NOT raw `--type-body-hyperlink-color` or `--color-grey-600`)
|
|
40
|
+
- Current breadcrumb text: `--breadcrumbs-breadcrumb-link-active-color-text` (maps to `--color-grey-900`)
|
|
41
|
+
|
|
42
|
+
## Breadcrumb Component Tokens (tokens exist — line numbers may drift as tokens.scss grows)
|
|
43
|
+
- List gap: `--breadcrumbs-spacing-gap-horizontal` (maps to `--spacing-small`)
|
|
44
|
+
- Divider color: `--breadcrumbs-divider-default-color` (maps to `--color-grey-600`)
|
|
45
|
+
- Link default color: `--breadcrumbs-breadcrumb-link-default-color-text` (maps to `--color-grey-600`)
|
|
46
|
+
- Link hover color: `--breadcrumbs-breadcrumb-link-hover-color-text` (maps to `--color-brand-600`)
|
|
47
|
+
- Link active/current color: `--breadcrumbs-breadcrumb-link-active-color-text` (maps to `--color-grey-900`)
|
|
48
|
+
- Link hover icon color: `--breadcrumbs-breadcrumb-link-hover-color-icon` (maps to `--color-brand-600`)
|
|
49
|
+
- Link default icon color: `--breadcrumbs-breadcrumb-link-default-color-icon` (maps to `--color-grey-600`)
|
|
50
|
+
- No breadcrumb-specific font-weight token exists; use `--type-body-hyperlink-weight` for link weight
|
|
51
|
+
|
|
52
|
+
## Design Token Hierarchy to Enforce
|
|
53
|
+
1. Component tokens (e.g. `--breadcrumbs-breadcrumb-link-default-color-text`) - most specific, prefer always
|
|
54
|
+
2. Semantic tokens (e.g. `--type-body-hyperlink-color`, `--page-color-background`)
|
|
55
|
+
3. Base tokens (e.g. `--color-grey-600`) - only if no semantic equivalent
|
|
56
|
+
|
|
57
|
+
## Known Issues / Patterns
|
|
58
|
+
- Breadcrumb implementations commonly use `--color-grey-600` or `--type-body-hyperlink-color` when dedicated `--breadcrumbs-*` component tokens exist and should be used instead
|
|
59
|
+
- Breadcrumb hover state commonly missing color change; `--breadcrumbs-breadcrumb-link-hover-color-text` should be applied on hover alongside text-decoration
|
|
60
|
+
- `--type-body-bold-weight` DOES exist in tokens.scss (maps to `--font-weight-semi-bold`). It IS a valid semantic token. Use it for bold body text emphasis instead of reaching for the base token directly.
|
|
61
|
+
- Also note: `--hyperlink-default`, `--hyperlink-hover`, `--hyperlink-active` are component tokens for hyperlinks. These are the most specific link tokens and should be used in preference to `--type-body-hyperlink-color` for actual inline hyperlinks.
|
|
62
|
+
- `src/examples/` does NOT exist on the current branch (confirmed 2026-04-17) — was on a prior branch
|
|
63
|
+
- No `@use` import needed for tokens.scss in SCSS files - tokens are CSS custom properties, globally available
|
|
64
|
+
- Do NOT use breadcrumb component tokens (e.g. `--breadcrumbs-breadcrumb-link-default-color-text`) for non-breadcrumb elements like table row counts. Use `--color-grey-600` for secondary/supporting body text when no semantic token exists.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Token Review Patterns
|
|
2
|
+
|
|
3
|
+
## Breadcrumb Link Colors
|
|
4
|
+
- WRONG: `color: var(--color-grey-600)` on `<a>` links
|
|
5
|
+
- RIGHT: `color: var(--type-body-hyperlink-color)` — this is the semantic token that maps to `--color-brand-700`
|
|
6
|
+
- Hover color should also align: consider `--color-brand-800` or leaving underline as the affordance
|
|
7
|
+
- The raw grey is not the design system's intended link color
|
|
8
|
+
|
|
9
|
+
## Page Background
|
|
10
|
+
- Pages should have `background-color: var(--page-color-background)` on the root element
|
|
11
|
+
- The token maps to `--color-grey-050` — a light wash that distinguishes page from white cards
|
|
12
|
+
|
|
13
|
+
## Assessment Row Separators
|
|
14
|
+
- The `Separator` component is already used in AssessmentsPage.tsx between items
|
|
15
|
+
- The SCSS `__assessment-item` block is empty — no border-bottom needed since Separator handles it
|
|
16
|
+
- BUT `__assessment-row` uses `padding: var(--spacing-medium) 0` which is fine for internal padding
|
|
17
|
+
|
|
18
|
+
## Hardcoded Values
|
|
19
|
+
- Always check for hardcoded `content: '/'` in pseudo-elements — this is acceptable for BEM separators (not a token)
|
|
20
|
+
- Hardcoded `flex: 1` is acceptable (not a design token concern)
|
|
21
|
+
- Hardcoded `white-space: nowrap` is acceptable
|
|
22
|
+
|
|
23
|
+
## Missing min-height / line-height
|
|
24
|
+
- Body text blocks benefit from `line-height: var(--line-height-default)` for readability
|
|
25
|
+
- Name fields (`__assessment-name`) in list rows should usually have line-height set
|
|
26
|
+
|
|
27
|
+
## Assessment List Row Spacing
|
|
28
|
+
- `padding: var(--spacing-medium) 0` on rows = 0.75rem top/bottom — confirm against Figma
|
|
29
|
+
- Gap between row elements `var(--spacing-medium)` = 0.75rem — consistent
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Dorothy Fact-Checker Memory
|
|
2
|
+
|
|
3
|
+
## Agent File Locations
|
|
4
|
+
- Agent definitions (all four): `.claude/agents/{blanche-designspert,dorothy-fact-checker,rose-storybookspert,sophia-componentspert}.md`
|
|
5
|
+
- Agent memory directories: `.claude/agent-memory/{agent-name}/`
|
|
6
|
+
- These files use relative paths (from project root) for portability across developer machines
|
|
7
|
+
- Frontmatter `name` field must match the filename (without .md extension)
|
|
8
|
+
|
|
9
|
+
## The Golden Girls Team
|
|
10
|
+
- blanche-designspert: model sonnet, color purple, design tokens & styling
|
|
11
|
+
- dorothy-fact-checker: model opus, color blue, QA & fact-checking
|
|
12
|
+
- rose-storybookspert: model sonnet, color pink, Storybook stories
|
|
13
|
+
- sophia-componentspert: model sonnet, color gold, component guidance
|
|
14
|
+
- Emojis: blanche=lipstick, dorothy=magnifying glass, rose=rose, sophia=purse
|
|
15
|
+
|
|
16
|
+
## Create-Page Skill Integration
|
|
17
|
+
- Skill at `.claude/skills/create-page/SKILL.md` calls agents at steps 3/4 (Sophia), 6 (Blanche), 8 (Rose), 10 (Dorothy)
|
|
18
|
+
- Agent names in backtick code refs are what matter for resolution, not the heading text
|
|
19
|
+
|
|
20
|
+
## Verification Patterns
|
|
21
|
+
- When checking agent file changes, compare against what was loaded into the system prompt (which reflects the pre-change state) since these files may be untracked and have no git history to diff against
|
|
22
|
+
- The Grep tool and memory system resolve relative paths against the project working directory
|
|
23
|
+
- Claude Code injects absolute paths at runtime even when files use relative paths -- this is expected behavior
|
|
24
|
+
|
|
25
|
+
## Common Issues to Watch For
|
|
26
|
+
- Absolute paths leaking into config files (especially `/Users/{username}/...` patterns)
|
|
27
|
+
- Files claimed to be committed but actually untracked (check `git ls-files` and `git status`)
|
|
28
|
+
- Agent memory directories may be empty (no MEMORY.md) until agents run for the first time -- this is by design
|
|
29
|
+
|
|
30
|
+
## Project Structure Notes
|
|
31
|
+
- `src/pages/` is a new directory added for page-level components (not in original architecture)
|
|
32
|
+
- No `Pages/*` path alias exists in tsconfig.json -- only `Components/*` and `Utils/*`
|
|
33
|
+
- Therefore page exports in `src/index.ts` must use relative paths (`./pages/...`) not aliases
|
|
34
|
+
- ESLint catches stylistic issues that `check-types` and `style-lint` do not -- always run all three
|
|
35
|
+
|
|
36
|
+
## Common Hallucination Patterns
|
|
37
|
+
- Agents may claim "all quality checks passed" but only run check-types and style-lint, missing ESLint errors
|
|
38
|
+
- ESLint stylistic rules (@stylistic/arrow-parens, @stylistic/brace-style, @stylistic/operator-linebreak, @stylistic/jsx-one-expression-per-line) are frequently violated in generated code
|
|
39
|
+
- The `yarn eslint` command is not listed in CLAUDE.md's common commands but is critical for quality
|
|
40
|
+
- **NEW PAGE REGISTRATION**: Agents frequently create page component files but forget to register them in `src/index.ts` (export) and `src/index.scss` (@use). The existing pattern (see AssessmentsPage) requires BOTH. Without these, the SCSS is dead code and the component is not part of the library's public API
|
|
41
|
+
- Icon name grep: allowedIcons file is `.tsx` not `.ts` -- use correct extension when searching
|
|
42
|
+
- **Components that DO exist (agents have hallucinated these as missing):**
|
|
43
|
+
- `Badge` IS exported (index.ts line 20) with `BadgeColour`, `BadgeProps`, `BadgeSize` — `'sm'|'md'|'lg'` sizes, 7 colours
|
|
44
|
+
- `Dot` IS exported (index.ts line 18) with `DotColour`
|
|
45
|
+
- `CheckboxInput` IS exported (index.ts line 24)
|
|
46
|
+
- `SearchBar` IS exported (index.ts line 40)
|
|
47
|
+
- `BooleanCellRenderer` IS exported (index.ts line 47), also registered as `'dsBooleanCellRenderer'`
|
|
48
|
+
- **Sophia prop hallucinations (confirmed 2026-02-19):**
|
|
49
|
+
- Button `ghost` variant does NOT exist (actual: primary, secondary, tertiary, primary-destructive, secondary-destructive, text-link, dropdown) ✅ CORRECT
|
|
50
|
+
- Section `defaultExpanded` does NOT exist (actual: `collapsed` boolean, inverted logic) ✅ CORRECT
|
|
51
|
+
- Section `headerContent` does NOT exist (Section has buttonText/buttonOnClick for a single button, not an arbitrary ReactNode slot -- Table has headerContent) ✅ CORRECT
|
|
52
|
+
- Icon `grip-vertical` does NOT exist (actual name: `'grab'` which maps to GripVertical lucide icon) ✅ CORRECT
|
|
53
|
+
- CheckboxInput IS exported from index.ts (line 24, confirmed 2026-04-17) -- DO NOT claim it's internal
|
|
54
|
+
- Tree data: codebase uses `treeDataChildrenField` pattern, not `getDataPath` ✅ CORRECT
|
|
55
|
+
- TextInput has NO icon/prefix support -- it's a bare `<input>` wrapper with only `size` and `hasError` custom props; everything else is passthrough from InputHTMLAttributes ✅ CORRECT
|
|
56
|
+
- Dropdown has `Dropdown.SelectItem` in addition to `Dropdown.Item` -- agents often omit SelectItem ✅ CORRECT
|
|
57
|
+
- Table's `treeData`, `getDataPath`, `rowDragManaged` are AG Grid passthroughs (via AgGridReactProps), not Arbor-specific features -- agents should not present them as Table component features ✅ CORRECT
|
|
58
|
+
- **Dorothy's mistakes (corrected):**
|
|
59
|
+
- ❌ I incorrectly claimed Button `iconLeftName`/`iconRightName` props don't exist - THEY DO EXIST (Button.tsx). User caught this error. These props are real and should be used.
|
|
60
|
+
- ❌ I claimed CheckboxInput was NOT exported — WRONG. CheckboxInput IS exported (index.ts line 24, confirmed 2026-04-17).
|
|
61
|
+
- ❌ I claimed Badge does NOT exist — WRONG. Badge IS exported (index.ts line 20, confirmed 2026-04-17) with BadgeColour/BadgeProps/BadgeSize types.
|
|
62
|
+
|
|
63
|
+
## Table Cell Renderers (verified 2026-02-19)
|
|
64
|
+
- All three registered in Table.tsx `components` prop by string name:
|
|
65
|
+
- `dsInlineTextCellRenderer` -> InlineTextCellRenderer (renders span with value)
|
|
66
|
+
- `dsSelectDropdownCellRenderer` -> SelectDropdownCellRenderer (renders dropdown Button, paired with dsSelectDropdownCellEditor)
|
|
67
|
+
- `dsButtonCellRenderer` -> ButtonCellRenderer (spreads ButtonProps from value, supports iconLeftName/iconRightName for icon buttons)
|
|
68
|
+
- Only `Table.ButtonCellRenderer` is exposed as a static property; others used via string names in colDef
|
|
69
|
+
- `Table.DefaultValueFormatter` also exposed as static property
|
|
70
|
+
|
|
71
|
+
## Table Themes (verified 2026-02-19)
|
|
72
|
+
- `tidyTheme`: activated via `tableTheme="tidy"` prop. White bg, no borders, clean look. Full example in TidyTable story.
|
|
73
|
+
- `defaultTheme`: the standard theme, supports hasColumnBorders and tableSpacing settings
|
|
74
|
+
- TidyTable story demonstrates: treeData + treeDataChildrenField + inline editing + all cell renderers together
|
|
75
|
+
|
|
76
|
+
## Section Component (verified 2026-02-19)
|
|
77
|
+
- `title` prop is typed as `string` (NOT ReactNode) -- cannot directly embed JSX like Pill
|
|
78
|
+
- Chevron icon IS auto-added when `collapsible={true}` (chevron-down/chevron-up with aria-expanded)
|
|
79
|
+
- `collapsed` prop sets initial state (inverted from defaultExpanded)
|
|
80
|
+
- `buttonText`/`buttonOnClick` for optional action button in heading
|
|
81
|
+
- `titleIconName`/`titleIconColor`/`titleIconScreenReaderText` for icon next to title
|
|
82
|
+
|
|
83
|
+
## Sophia Accuracy Trend
|
|
84
|
+
- 2026-02-19 (earlier): Multiple hallucinations (ghost variant, defaultExpanded, headerContent on Section, grip-vertical icon)
|
|
85
|
+
- 2026-02-19 (Student Profile analysis): 100% accuracy on all prop claims across 8 components. Zero hallucinations. Only omissions were Dropdown.SelectItem, some Button variants, and SearchBar.placeholderText -- all editorial choices, not errors.
|
|
86
|
+
- 2026-02-19 (Migration mapping): 14/14 claims verified. Zero hallucinations. Correct on: Heading.InnerContainer, Button type Omit, Tabs semantic HTML, BulkActionsDropdown actions.length (not selected rows), both '3-dot' and 'ellipsis-vertical' icon aliases, setAgGridLicenseKey auto-call, all Table sub-component props. Minor omissions: Tabs.Item link mode, headerContent gatekeeper for search.
|
|
87
|
+
- TooltipWrapper: triggerProps.asChild is technically valid but redundant -- TooltipTrigger already hardcodes asChild={true}
|
|
88
|
+
|
|
89
|
+
## Icon Alias Gotcha (verified 2026-02-19)
|
|
90
|
+
- `'3-dot'` and `'ellipsis-vertical'` both map to Lucide `EllipsisVertical` -- they are interchangeable aliases
|
|
91
|
+
- `'grab'` maps to Lucide `GripVertical` (NOT `'grip-vertical'`)
|
|
92
|
+
- Prefer Lucide-style naming ('ellipsis-vertical') over legacy aliases ('3-dot') for consistency
|
|
93
|
+
|
|
94
|
+
## Table Search Gatekeeper (verified 2026-02-19)
|
|
95
|
+
- SearchBar in Table only renders when BOTH `headerContent` is truthy AND `hasSearch` is true (default)
|
|
96
|
+
- `headerContent` controls whether `<TableHeader>` renders at all (Table.tsx line 149)
|
|
97
|
+
- If `headerContent` is falsy, `hasSearch={true}` does nothing -- no search bar appears
|
|
98
|
+
- `quickFilterText` is wired to search state (Table.tsx line 196)
|
|
99
|
+
|
|
100
|
+
## Export Status (verified 2026-04-17 against src/index.ts)
|
|
101
|
+
- SearchBar: exported (line 40) ✅
|
|
102
|
+
- CheckboxInput: exported (line 24) ✅
|
|
103
|
+
- CheckboxGroup: NOT exported — internal only ✅
|
|
104
|
+
- RadioButtonGroup: NOT exported — internal only ✅
|
|
105
|
+
- BooleanCellRenderer: exported (line 47) ✅ — also registered as `'dsBooleanCellRenderer'` in Table
|
|
106
|
+
- New exports added recently: Toggle, Row, SingleUser, Combobox (+ types), TimeInput (+ types), DatePicker, DateTimePicker (+ types)
|
|
107
|
+
|
|
108
|
+
## Pill Component API
|
|
109
|
+
- `onclick` prop (lowercase c) accepts `(checked: boolean) => void`
|
|
110
|
+
- Uses `useEffect` to fire onclick on checked state change, including on mount
|
|
111
|
+
- State setters from `useState` are stable references, so passing them directly as onclick is safe
|
|
112
|
+
|
|
113
|
+
## Test Quality Benchmarks
|
|
114
|
+
- Tests should use accessible queries (getByRole, getByLabelText) over getByText/getByTestId
|
|
115
|
+
- userEvent is preferred over fireEvent for user interactions
|
|
116
|
+
- Tests should verify callback arguments, not just that callbacks were called
|
|
117
|
+
- Edge cases (empty state, no data) should be covered
|
|
118
|
+
|
|
119
|
+
## Recurring Bugs in Generated Pages (confirmed 2026-02-19)
|
|
120
|
+
- **Icon name `'edit'` does NOT exist** in allowedIcons.tsx -- correct name is `'pencil'`
|
|
121
|
+
- **CSS ds- prefix mismatch**: SCSS uses `.ds-{page-name}` but component JSX omits the `ds-` prefix. Always verify SCSS selectors match JSX classNames
|
|
122
|
+
- **Direct SCSS import in page components**: Pages in `src/pages/` should NOT `import './foo.scss'` directly (causes TS2307). Pages in `src/examples/pages/` CAN use direct imports because Storybook/Vitest handle them fine (global.d.ts declares `*.scss` modules). The `src/examples/` path is for example/demo pages that are NOT part of the library build
|
|
123
|
+
- **Pill renders as `<span>`, NOT `<button>`**: Tests that use `getByRole('button')` to find Pills will fail. Use `getByText` instead
|
|
124
|
+
- **SearchBar inactive state**: SearchBar with empty `searchValue` renders as a collapsed Button, not an input. Tests must click to activate it first, or initialize with non-empty searchValue
|
|
125
|
+
- **TS error downplaying**: Agents may call real TS compilation errors "warnings" or "expected" -- always verify exit code of `yarn check-types`
|
|
126
|
+
- **Page registration still forgotten**: AssessmentBuilderPage was missing from both index.ts and index.scss (same pattern as before)
|
|
127
|
+
- **`@stylistic/jsx-one-expression-per-line` is the #1 ESLint violation**: `<br />` tags inline with text content always trigger this. 12 of 13 ESLint errors in StudentProfilePage were this exact rule. The `--fix` flag can auto-resolve these
|
|
128
|
+
- **Unused imports in test files**: Agents import `beforeEach` from vitest but never use it (1 of 13 errors in StudentProfilePage)
|
|
129
|
+
- **`src/examples/pages/` is a separate convention** from `src/pages/`: example pages are NOT library exports and do NOT need registration in index.ts/index.scss. Direct SCSS imports are fine here
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Rose's Storybookspert Memory
|
|
2
|
+
|
|
3
|
+
See `patterns.md` for full details on codebase conventions.
|
|
4
|
+
|
|
5
|
+
## Quick Reference
|
|
6
|
+
|
|
7
|
+
- Meta/StoryObj import: `from '@storybook/react-vite'`
|
|
8
|
+
- fn() import: `from 'storybook/test'` (NOT `@storybook/test`)
|
|
9
|
+
- Meta pattern: `satisfies Meta<typeof ComponentName>` with `export default meta`
|
|
10
|
+
- Story type: `type Story = StoryObj<typeof meta>`
|
|
11
|
+
- Storybook version: v9 (storybook package) with `@storybook/react-vite` ^9.1.8
|
|
12
|
+
- Page-level stories: use `layout: 'fullscreen'` in parameters
|
|
13
|
+
- `src/pages/` does NOT exist on the current branch (confirmed 2026-04-17) — this directory was on a previous branch and may not be present
|
|
14
|
+
- Story files use `.stories.tsx` extension (not `.story.tsx` for new files)
|
|
15
|
+
- tsconfig excludes `*.story.tsx` but includes `*.stories.tsx` and `*.test.tsx`
|
|
16
|
+
|
|
17
|
+
## useState in Story Render Functions
|
|
18
|
+
|
|
19
|
+
- Do NOT use `eslint-disable-next-line react-hooks/rules-of-hooks` — the `react-hooks` plugin
|
|
20
|
+
is NOT configured in this project's eslint.config.mts, so the disable comment itself causes
|
|
21
|
+
an ESLint error ("Definition for rule not found").
|
|
22
|
+
- Instead, extract stateful render logic into a named template component defined above the story:
|
|
23
|
+
`const MyTemplate = (args: React.ComponentProps<typeof MyComponent>) => { ... }`
|
|
24
|
+
then reference it: `render: MyTemplate`. See Toast.stories.tsx for the inline render alternative
|
|
25
|
+
(useState directly in the render arrow function also works fine without any disable comment).
|
|
26
|
+
|
|
27
|
+
## Known Pre-existing Issues
|
|
28
|
+
|
|
29
|
+
- `src/pages/` directory does not exist on the current branch — notes about AssessmentsPage TS errors are stale (from a prior branch)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Storybook Patterns in This Codebase
|
|
2
|
+
|
|
3
|
+
## Import Patterns
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
7
|
+
import { fn } from 'storybook/test';
|
|
8
|
+
import { ComponentName } from 'Components/componentName/ComponentName';
|
|
9
|
+
// OR for pages:
|
|
10
|
+
import { PageName } from './PageName';
|
|
11
|
+
import type { SomeType } from './PageName';
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Meta Definition Pattern
|
|
15
|
+
|
|
16
|
+
Use `satisfies Meta<typeof X>` (preferred modern pattern, matches Tabs/TextInput):
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
const meta = {
|
|
20
|
+
title: 'Components/ComponentName', // OR 'Pages/PageName'
|
|
21
|
+
component: ComponentName,
|
|
22
|
+
parameters: {
|
|
23
|
+
layout: 'centered', // or 'fullscreen' for pages, 'padded' for layout components
|
|
24
|
+
},
|
|
25
|
+
tags: ['autodocs'],
|
|
26
|
+
args: {
|
|
27
|
+
// shared default args (e.g. fn() callbacks)
|
|
28
|
+
onClick: fn(),
|
|
29
|
+
},
|
|
30
|
+
argTypes: {
|
|
31
|
+
someProp: {
|
|
32
|
+
control: 'select',
|
|
33
|
+
options: ['a', 'b'],
|
|
34
|
+
description: 'What this prop does',
|
|
35
|
+
},
|
|
36
|
+
children: {
|
|
37
|
+
control: false, // disable control for children
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
} satisfies Meta<typeof ComponentName>;
|
|
41
|
+
|
|
42
|
+
export default meta;
|
|
43
|
+
type Story = StoryObj<typeof meta>;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Older pattern (still valid, used in Card/Pill/Modal):
|
|
47
|
+
```tsx
|
|
48
|
+
const meta: Meta<typeof ComponentName> = { ... };
|
|
49
|
+
export default meta;
|
|
50
|
+
// stories without StoryObj type annotation
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Story Definition
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
export const Default: Story = {
|
|
57
|
+
name: 'Human-readable Name', // optional override
|
|
58
|
+
args: {
|
|
59
|
+
// story-specific args, merged with meta args
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Action Callbacks
|
|
65
|
+
|
|
66
|
+
Always use `fn()` from `'storybook/test'`. Put shared callbacks in meta `args`,
|
|
67
|
+
story-specific ones in story `args`.
|
|
68
|
+
|
|
69
|
+
## Tags
|
|
70
|
+
|
|
71
|
+
- `tags: ['autodocs']` enables automatic docs page generation
|
|
72
|
+
- Most components use this
|
|
73
|
+
|
|
74
|
+
## Layout Options
|
|
75
|
+
|
|
76
|
+
- `layout: 'centered'` - for small components (inputs, buttons, etc.)
|
|
77
|
+
- `layout: 'fullscreen'` - for page-level components
|
|
78
|
+
- `layout: 'padded'` - for components that need some breathing room
|
|
79
|
+
|
|
80
|
+
## Path Aliases
|
|
81
|
+
|
|
82
|
+
- Components: `Components/button/Button` (no `src/` prefix)
|
|
83
|
+
- Utils: `Utils/hooks/useHook`
|
|
84
|
+
- Pages: use relative imports (`./PageName`) since they live in `src/pages/`
|
|
85
|
+
|
|
86
|
+
## Story Descriptions
|
|
87
|
+
|
|
88
|
+
JSDoc comments above story exports appear in Storybook docs. Use them liberally.
|
|
89
|
+
Component-level description goes in `parameters.docs.description.component`.
|
|
90
|
+
|
|
91
|
+
## Fixture Data
|
|
92
|
+
|
|
93
|
+
Define fixtures as `const` arrays/objects above the story exports. Use realistic,
|
|
94
|
+
domain-appropriate data (school assessments, not "foo/bar").
|
|
95
|
+
|
|
96
|
+
## Page Components with AG Grid Tables
|
|
97
|
+
|
|
98
|
+
Pages that wrap Table (AG Grid) do NOT need to mock the Table in stories - the
|
|
99
|
+
real Table component renders fine in Storybook. Tests mock it with vi.mock().
|
|
100
|
+
For stories, supply realistic `rowData` fixtures via the page's data props (e.g.
|
|
101
|
+
`activeGradeSets`, `archivedGradeSets`). The table will render with real AG Grid.
|
|
102
|
+
|
|
103
|
+
Story fixture arrays for grade-set-style pages should include realistic UK school
|
|
104
|
+
data: GCSE 9 to 1, BTEC, Below/At/Above, T-Levels, Cambridge Nationals, etc.
|
|
105
|
+
|
|
106
|
+
## Tab-Switching Page Pattern
|
|
107
|
+
|
|
108
|
+
For pages with internally-controlled tab state (like GradeSetsPage), stories
|
|
109
|
+
should supply data for BOTH tabs so reviewers can actually switch tabs and see
|
|
110
|
+
different content. Document in the JSDoc which tab is selected by default and
|
|
111
|
+
what happens when the other tab is clicked.
|
|
112
|
+
|
|
113
|
+
## Example Pages Location
|
|
114
|
+
|
|
115
|
+
Pages under `src/examples/pages/` (not `src/pages/`) are Figma-to-code
|
|
116
|
+
compositions used as design system demos. They use relative imports (e.g.
|
|
117
|
+
`./StudentProfilePage`). Story files go alongside the component:
|
|
118
|
+
`src/examples/pages/studentProfile/StudentProfilePage.stories.tsx`.
|
|
119
|
+
|
|
120
|
+
## Placeholder SVG Pattern in Page Stories
|
|
121
|
+
|
|
122
|
+
When a page uses placeholder SVGs for missing components, document the pattern
|
|
123
|
+
in the component JSDoc. Include a markdown table listing each placeholder,
|
|
124
|
+
its Figma layer ID, and the reason it is a placeholder. This helps readers
|
|
125
|
+
understand what they are seeing and track which components still need building.
|
|
126
|
+
|
|
127
|
+
## Default Story With No Args
|
|
128
|
+
|
|
129
|
+
When a component has sensible built-in mock data (e.g. `educationHistory`
|
|
130
|
+
defaulting to `MOCK_EDUCATION_HISTORY` internally), the Default story can
|
|
131
|
+
omit `args` entirely - just `export const Default: Story = { name: '...' }`.
|
|
132
|
+
All shared callbacks are already wired via meta `args` with `fn()`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Sophia Componentspert Memory
|
|
2
|
+
|
|
3
|
+
See topic files for details:
|
|
4
|
+
- [components.md](./components.md) - Component APIs, gotchas, and patterns
|
|
5
|
+
|
|
6
|
+
## Key Project Facts
|
|
7
|
+
- Path aliases: `Components/*` → `src/components/*`, `Utils/*` → `src/utils/*`
|
|
8
|
+
- CSS prefix: `ds-` (e.g. `ds-button`, `ds-button--primary`)
|
|
9
|
+
- Package manager: yarn (NOT npm)
|
|
10
|
+
- Button prop is `variant` not `type` - common gotcha
|
|
11
|
+
- SearchBar IS exported from src/index.ts (confirmed 2026-04-17) - available to consumers
|
|
12
|
+
- CheckboxGroup EXISTS but is NOT exported from src/index.ts — internal only (confirmed 2026-04-17)
|
|
13
|
+
- New components added 2026-04-17: Toggle, Row, SingleUser, DatePicker, DateTimePicker, TimeInput, Combobox, BooleanCellRenderer
|
|
14
|
+
- BooleanCellRenderer registered in Table as `'dsBooleanCellRenderer'` string name AND exported directly
|