@exxatdesignux/ui 0.2.19 → 0.4.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/CHANGELOG.md +662 -7
- package/bin/sync-extras.mjs +116 -29
- package/consumer-extras/README.md +42 -7
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +43 -0
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
- package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +3 -3
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +5 -16
- package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
- package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +19 -34
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +10 -12
- package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
- package/consumer-extras/handbook/HANDBOOK.md +187 -0
- package/consumer-extras/handbook/glossary.md +58 -0
- package/consumer-extras/handbook/reference-implementations.md +153 -0
- package/consumer-extras/handbook/voice-and-tone.md +262 -0
- package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
- package/consumer-extras/patterns/command-menu-pattern.md +1 -1
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
- package/consumer-extras/patterns/data-views-pattern.md +31 -66
- package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
- package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
- package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
- package/dist/components/data-table/filter-date-calendar.js +280 -0
- package/dist/components/data-table/filter-date-calendar.js.map +1 -0
- package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
- package/dist/components/data-table/filter-text-value-input.js +561 -0
- package/dist/components/data-table/filter-text-value-input.js.map +1 -0
- package/dist/components/data-table/index.d.ts +45 -0
- package/dist/components/data-table/index.js +3085 -0
- package/dist/components/data-table/index.js.map +1 -0
- package/dist/components/data-table/pagination.d.ts +28 -0
- package/dist/components/data-table/pagination.js +3264 -0
- package/dist/components/data-table/pagination.js.map +1 -0
- package/dist/components/data-table/types.d.ts +84 -0
- package/dist/components/data-table/types.js +3 -0
- package/dist/components/data-table/types.js.map +1 -0
- package/dist/components/data-table/use-table-state.d.ts +116 -0
- package/dist/components/data-table/use-table-state.js +670 -0
- package/dist/components/data-table/use-table-state.js.map +1 -0
- package/dist/components/data-views/board-card-primitives.d.ts +22 -0
- package/dist/components/data-views/board-card-primitives.js +84 -0
- package/dist/components/data-views/board-card-primitives.js.map +1 -0
- package/dist/components/data-views/data-row-list.d.ts +33 -0
- package/dist/components/data-views/data-row-list.js +106 -0
- package/dist/components/data-views/data-row-list.js.map +1 -0
- package/dist/components/data-views/finder-panel-view.d.ts +54 -0
- package/dist/components/data-views/finder-panel-view.js +388 -0
- package/dist/components/data-views/finder-panel-view.js.map +1 -0
- package/dist/components/data-views/folder-grid-view.d.ts +22 -0
- package/dist/components/data-views/folder-grid-view.js +58 -0
- package/dist/components/data-views/folder-grid-view.js.map +1 -0
- package/dist/components/data-views/hub-table.d.ts +173 -0
- package/dist/components/data-views/hub-table.js +5783 -0
- package/dist/components/data-views/hub-table.js.map +1 -0
- package/dist/components/data-views/index.d.ts +27 -0
- package/dist/components/data-views/index.js +6797 -0
- package/dist/components/data-views/index.js.map +1 -0
- package/dist/components/data-views/list-page-board-card.d.ts +72 -0
- package/dist/components/data-views/list-page-board-card.js +264 -0
- package/dist/components/data-views/list-page-board-card.js.map +1 -0
- package/dist/components/data-views/list-page-board-template.d.ts +24 -0
- package/dist/components/data-views/list-page-board-template.js +137 -0
- package/dist/components/data-views/list-page-board-template.js.map +1 -0
- package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
- package/dist/components/data-views/list-page-connected-view-body.js +116 -0
- package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
- package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
- package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
- package/dist/components/data-views/list-page-tree-column-header.js +22 -0
- package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
- package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
- package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
- package/dist/components/data-views/os-folder-glyph.js +104 -0
- package/dist/components/data-views/os-folder-glyph.js.map +1 -0
- package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
- package/dist/components/data-views/outline-tree-menu.js +131 -0
- package/dist/components/data-views/outline-tree-menu.js.map +1 -0
- package/dist/components/table-properties/column-row.d.ts +22 -0
- package/dist/components/table-properties/column-row.js +153 -0
- package/dist/components/table-properties/column-row.js.map +1 -0
- package/dist/components/table-properties/draggable-list.d.ts +24 -0
- package/dist/components/table-properties/draggable-list.js +53 -0
- package/dist/components/table-properties/draggable-list.js.map +1 -0
- package/dist/components/table-properties/drawer-button.d.ts +110 -0
- package/dist/components/table-properties/drawer-button.js +2748 -0
- package/dist/components/table-properties/drawer-button.js.map +1 -0
- package/dist/components/table-properties/drawer.d.ts +100 -0
- package/dist/components/table-properties/drawer.js +2595 -0
- package/dist/components/table-properties/drawer.js.map +1 -0
- package/dist/components/table-properties/filter-card.d.ts +24 -0
- package/dist/components/table-properties/filter-card.js +854 -0
- package/dist/components/table-properties/filter-card.js.map +1 -0
- package/dist/components/table-properties/index.d.ts +14 -0
- package/dist/components/table-properties/index.js +2768 -0
- package/dist/components/table-properties/index.js.map +1 -0
- package/dist/components/table-properties/sort-card.d.ts +20 -0
- package/dist/components/table-properties/sort-card.js +102 -0
- package/dist/components/table-properties/sort-card.js.map +1 -0
- package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
- package/dist/components/templates/dedicated-search-landing-template.js +254 -0
- package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
- package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
- package/dist/components/templates/dedicated-search-results-template.js +16 -0
- package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
- package/dist/components/templates/index.d.ts +9 -0
- package/dist/components/templates/index.js +2720 -0
- package/dist/components/templates/index.js.map +1 -0
- package/dist/components/templates/list-page.d.ts +83 -0
- package/dist/components/templates/list-page.js +2433 -0
- package/dist/components/templates/list-page.js.map +1 -0
- package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
- package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
- package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +10 -0
- package/dist/components/ui/accordion.js +74 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +37 -0
- package/dist/components/ui/alert-dialog.js +201 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +84 -0
- package/dist/components/ui/avatar.js +328 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +49 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/banner.d.ts +62 -0
- package/dist/components/ui/banner.js +364 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +14 -0
- package/dist/components/ui/breadcrumb.js +114 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +16 -0
- package/dist/components/ui/button.js +59 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +13 -0
- package/dist/components/ui/calendar.js +238 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +14 -0
- package/dist/components/ui/card.js +102 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/chart.d.ts +58 -0
- package/dist/components/ui/chart.js +292 -0
- package/dist/components/ui/chart.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +23 -0
- package/dist/components/ui/checkbox.js +155 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/coach-mark.d.ts +27 -0
- package/dist/components/ui/coach-mark.js +306 -0
- package/dist/components/ui/coach-mark.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +8 -0
- package/dist/components/ui/collapsible.js +35 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +36 -0
- package/dist/components/ui/command.js +274 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +32 -0
- package/dist/components/ui/context-menu.js +245 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/date-picker-field.d.ts +38 -0
- package/dist/components/ui/date-picker-field.js +550 -0
- package/dist/components/ui/date-picker-field.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.js +200 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dot-pattern.d.ts +21 -0
- package/dist/components/ui/dot-pattern.js +139 -0
- package/dist/components/ui/dot-pattern.js.map +1 -0
- package/dist/components/ui/drag-handle-grip.d.ts +10 -0
- package/dist/components/ui/drag-handle-grip.js +15 -0
- package/dist/components/ui/drag-handle-grip.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +16 -0
- package/dist/components/ui/drawer.js +125 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +45 -0
- package/dist/components/ui/dropdown-menu.js +353 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/export-drawer.d.ts +11 -0
- package/dist/components/ui/export-drawer.js +1658 -0
- package/dist/components/ui/export-drawer.js.map +1 -0
- package/dist/components/ui/field.d.ts +30 -0
- package/dist/components/ui/field.js +249 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +28 -0
- package/dist/components/ui/form.js +110 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +9 -0
- package/dist/components/ui/hover-card.js +43 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +20 -0
- package/dist/components/ui/input-group.js +219 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-mask.d.ts +39 -0
- package/dist/components/ui/input-mask.js +118 -0
- package/dist/components/ui/input-mask.js.map +1 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +30 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +20 -0
- package/dist/components/ui/kbd.js +45 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-metrics-context.d.ts +19 -0
- package/dist/components/ui/key-metrics-context.js +26 -0
- package/dist/components/ui/key-metrics-context.js.map +1 -0
- package/dist/components/ui/key-metrics.d.ts +131 -0
- package/dist/components/ui/key-metrics.js +1015 -0
- package/dist/components/ui/key-metrics.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.js +28 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/list-page-view-frame.d.ts +22 -0
- package/dist/components/ui/list-page-view-frame.js +24 -0
- package/dist/components/ui/list-page-view-frame.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +51 -0
- package/dist/components/ui/page-header.js +372 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/payment-card-fields.d.ts +10 -0
- package/dist/components/ui/payment-card-fields.js +80 -0
- package/dist/components/ui/payment-card-fields.js.map +1 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +47 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +29 -0
- package/dist/components/ui/radio-group.js +190 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +16 -0
- package/dist/components/ui/resizable.js +51 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +8 -0
- package/dist/components/ui/scroll-area.js +66 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/select.js +186 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/selection-tile-grid.d.ts +52 -0
- package/dist/components/ui/selection-tile-grid.js +347 -0
- package/dist/components/ui/selection-tile-grid.js.map +1 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +33 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +18 -0
- package/dist/components/ui/sheet.js +181 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +94 -0
- package/dist/components/ui/sidebar.js +805 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +5 -0
- package/dist/components/ui/skeleton.js +22 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +7 -0
- package/dist/components/ui/slider.js +66 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +6 -0
- package/dist/components/ui/sonner.js +38 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/status-badge.d.ts +38 -0
- package/dist/components/ui/status-badge.js +77 -0
- package/dist/components/ui/status-badge.js.map +1 -0
- package/dist/components/ui/table.d.ts +13 -0
- package/dist/components/ui/table.js +115 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +15 -0
- package/dist/components/ui/tabs.js +93 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.js +25 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tip.d.ts +12 -0
- package/dist/components/ui/tip.js +61 -0
- package/dist/components/ui/tip.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +14 -0
- package/dist/components/ui/toggle-group.js +104 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle-switch.d.ts +10 -0
- package/dist/components/ui/toggle-switch.js +33 -0
- package/dist/components/ui/toggle-switch.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +13 -0
- package/dist/components/ui/toggle.js +51 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.js +68 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components/ui/view-segmented-control.d.ts +31 -0
- package/dist/components/ui/view-segmented-control.js +167 -0
- package/dist/components/ui/view-segmented-control.js.map +1 -0
- package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
- package/dist/hooks/use-app-theme.d.ts +24 -0
- package/dist/hooks/use-app-theme.js +286 -0
- package/dist/hooks/use-app-theme.js.map +1 -0
- package/dist/hooks/use-coach-mark.d.ts +86 -0
- package/dist/hooks/use-coach-mark.js +218 -0
- package/dist/hooks/use-coach-mark.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +29 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-mod-key-label.d.ts +6 -0
- package/dist/hooks/use-mod-key-label.js +25 -0
- package/dist/hooks/use-mod-key-label.js.map +1 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +13421 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/compose-refs.d.ts +6 -0
- package/dist/lib/compose-refs.js +17 -0
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/conditional-rule-match.d.ts +30 -0
- package/dist/lib/conditional-rule-match.js +66 -0
- package/dist/lib/conditional-rule-match.js.map +1 -0
- package/dist/lib/data-list-display-options.d.ts +26 -0
- package/dist/lib/data-list-display-options.js +14 -0
- package/dist/lib/data-list-display-options.js.map +1 -0
- package/dist/lib/data-list-view-registry.d.ts +2 -0
- package/dist/lib/data-list-view-registry.js +102 -0
- package/dist/lib/data-list-view-registry.js.map +1 -0
- package/dist/lib/data-list-view-surface.d.ts +2 -0
- package/dist/lib/data-list-view-surface.js +80 -0
- package/dist/lib/data-list-view-surface.js.map +1 -0
- package/dist/lib/data-list-view.d.ts +21 -0
- package/dist/lib/data-list-view.js +25 -0
- package/dist/lib/data-list-view.js.map +1 -0
- package/dist/lib/date-filter.d.ts +22 -0
- package/dist/lib/date-filter.js +61 -0
- package/dist/lib/date-filter.js.map +1 -0
- package/dist/lib/dev-log.d.ts +8 -0
- package/dist/lib/dev-log.js +10 -0
- package/dist/lib/dev-log.js.map +1 -0
- package/dist/lib/dropdown-menu-surface.d.ts +14 -0
- package/dist/lib/dropdown-menu-surface.js +6 -0
- package/dist/lib/dropdown-menu-surface.js.map +1 -0
- package/dist/lib/editable-target.d.ts +12 -0
- package/dist/lib/editable-target.js +12 -0
- package/dist/lib/editable-target.js.map +1 -0
- package/dist/lib/list-page-table-properties.d.ts +35 -0
- package/dist/lib/list-page-table-properties.js +81 -0
- package/dist/lib/list-page-table-properties.js.map +1 -0
- package/dist/lib/raf-throttle.d.ts +23 -0
- package/dist/lib/raf-throttle.js +27 -0
- package/dist/lib/raf-throttle.js.map +1 -0
- package/dist/lib/row-height.d.ts +16 -0
- package/dist/lib/row-height.js +10 -0
- package/dist/lib/row-height.js.map +1 -0
- package/dist/lib/table-properties-types.d.ts +83 -0
- package/dist/lib/table-properties-types.js +19 -0
- package/dist/lib/table-properties-types.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +83 -19
- package/src/components/data-table/filter-date-calendar.tsx +38 -0
- package/src/components/data-table/filter-text-value-input.tsx +77 -0
- package/src/components/data-table/index.tsx +1678 -0
- package/src/components/data-table/pagination.tsx +259 -0
- package/src/components/data-table/types.ts +96 -0
- package/src/components/data-table/use-table-state.ts +767 -0
- package/src/components/data-views/board-card-primitives.tsx +93 -0
- package/src/components/data-views/data-row-list.tsx +183 -0
- package/src/components/data-views/finder-panel-view.tsx +405 -0
- package/src/components/data-views/folder-grid-view.tsx +86 -0
- package/src/components/data-views/hub-table.tsx +606 -0
- package/src/components/data-views/index.ts +28 -0
- package/src/components/data-views/list-page-board-card.tsx +192 -0
- package/src/components/data-views/list-page-board-template.tsx +122 -0
- package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
- package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
- package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
- package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
- package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
- package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
- package/src/components/data-views/os-folder-glyph.tsx +141 -0
- package/src/components/data-views/outline-tree-menu.tsx +157 -0
- package/src/components/table-properties/column-row.tsx +90 -0
- package/src/components/table-properties/draggable-list.ts +54 -0
- package/src/components/table-properties/drawer-button.tsx +300 -0
- package/src/components/table-properties/drawer.tsx +1148 -0
- package/src/components/table-properties/filter-card.tsx +251 -0
- package/src/components/table-properties/index.ts +36 -0
- package/src/components/table-properties/sort-card.tsx +63 -0
- package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
- package/src/components/templates/dedicated-search-results-template.tsx +19 -0
- package/src/components/templates/index.ts +33 -0
- package/src/components/templates/list-page.tsx +602 -0
- package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
- package/src/components/ui/accordion.tsx +92 -0
- package/src/components/ui/alert-dialog.tsx +221 -0
- package/src/components/ui/avatar.tsx +13 -2
- package/src/components/ui/banner.tsx +2 -2
- package/src/components/ui/button.tsx +4 -4
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/coach-mark.tsx +1 -1
- package/src/components/ui/context-menu.tsx +291 -0
- package/src/components/ui/date-picker-field.tsx +2 -2
- package/src/components/ui/dot-pattern.tsx +183 -0
- package/src/components/ui/export-drawer.tsx +375 -0
- package/src/components/ui/hover-card.tsx +66 -0
- package/src/components/ui/key-metrics-context.tsx +78 -0
- package/src/components/ui/key-metrics.tsx +1133 -0
- package/src/components/ui/list-page-view-frame.tsx +64 -0
- package/src/components/ui/page-header.tsx +244 -0
- package/src/components/ui/payment-card-fields.tsx +2 -2
- package/src/components/ui/resizable.tsx +68 -0
- package/src/components/ui/scroll-area.tsx +72 -0
- package/src/components/ui/selection-tile-grid.tsx +9 -2
- package/src/components/ui/sidebar.tsx +84 -12
- package/src/components/ui/slider.tsx +83 -0
- package/src/globals.css +2201 -7
- package/src/globals.d.ts +20 -0
- package/src/index.ts +68 -1
- package/src/lib/conditional-rule-match.ts +119 -0
- package/src/lib/data-list-display-options.ts +35 -0
- package/src/lib/data-list-view-registry.ts +104 -0
- package/src/lib/data-list-view-surface.ts +83 -0
- package/src/lib/data-list-view.ts +47 -0
- package/src/lib/dev-log.ts +10 -0
- package/src/lib/editable-target.ts +20 -0
- package/src/lib/list-page-table-properties.ts +48 -0
- package/src/lib/raf-throttle.ts +45 -0
- package/src/lib/row-height.ts +19 -0
- package/src/lib/table-properties-types.ts +98 -0
- package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
- package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
- package/template/.cursor/rules/exxat-command-menu.mdc +2 -2
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +7 -7
- package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
- package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +7 -7
- package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
- package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +135 -103
- package/template/app/(app)/columns/page.tsx +11 -0
- package/template/app/(app)/dashboard/loading.tsx +15 -3
- package/template/app/(app)/dashboard/page.tsx +14 -2
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/library/all/page.tsx +11 -0
- package/template/app/(app)/library/find/page.tsx +12 -0
- package/template/app/(app)/{question-bank → library}/layout.tsx +17 -17
- package/template/app/(app)/library/list/page.tsx +12 -0
- package/template/app/(app)/library/new/page.tsx +45 -0
- package/template/app/(app)/library/page.tsx +11 -0
- package/template/app/(app)/loading.tsx +18 -1
- package/template/app/(app)/settings/page.tsx +5 -4
- package/template/app/(app)/tokens-themes/page.tsx +11 -0
- package/template/app/globals.css +14 -16
- package/template/components/ask-leo-composer.tsx +2 -2
- package/template/components/ask-leo-sidebar.tsx +5 -1
- package/template/components/brand-color-picker.tsx +2 -2
- package/template/components/charts-overview.tsx +1 -1
- package/template/components/columns-client.tsx +158 -0
- package/template/components/columns-showcase.tsx +541 -0
- package/template/components/dashboard-report-charts.tsx +1 -1
- package/template/components/dashboard-tabs.tsx +1 -1
- package/template/components/data-table/filter-date-calendar.tsx +1 -38
- package/template/components/data-table/filter-text-value-input.tsx +1 -77
- package/template/components/data-table/index.tsx +1 -1634
- package/template/components/data-table/pagination.tsx +1 -255
- package/template/components/data-table/types.ts +1 -94
- package/template/components/data-table/use-table-state.test.ts +420 -0
- package/template/components/data-table/use-table-state.ts +1 -758
- package/template/components/data-views/board-card-primitives.tsx +1 -93
- package/template/components/data-views/data-row-list.tsx +1 -183
- package/template/components/data-views/finder-panel-view.tsx +1 -405
- package/template/components/data-views/folder-grid-view.tsx +1 -86
- package/template/components/data-views/hub-table.tsx +1 -0
- package/template/components/data-views/index.ts +77 -38
- package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
- package/template/components/data-views/list-page-board-card.tsx +1 -192
- package/template/components/data-views/list-page-board-template.tsx +1 -122
- package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
- package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
- package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
- package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
- package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
- package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
- package/template/components/data-views/list-page-view-frame.tsx +5 -53
- package/template/components/data-views/os-folder-glyph.tsx +1 -129
- package/template/components/data-views/outline-tree-menu.tsx +1 -157
- package/template/components/data-views/table-cells.tsx +673 -0
- package/template/components/export-drawer.test.tsx +71 -0
- package/template/components/export-drawer.tsx +1 -375
- package/template/components/exxat-product-logo.tsx +5 -5
- package/template/components/folder-details-shell.tsx +11 -11
- package/template/components/hub-tree-panel-view.tsx +26 -26
- package/template/components/invite-collaborators-drawer.tsx +3 -3
- package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
- package/template/components/key-metrics.tsx +1 -1063
- package/template/components/leo-insight-indicator.tsx +2 -2
- package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
- package/template/components/{question-bank-client.tsx → library-client.tsx} +83 -83
- package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
- package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
- package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +44 -44
- package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +16 -16
- package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
- package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
- package/template/components/library-panel-activator.tsx +8 -0
- package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +63 -63
- package/template/components/library-table.tsx +839 -0
- package/template/components/list-hub-status-badge.tsx +2 -2
- package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +489 -441
- package/template/components/onboarding/index.ts +9 -0
- package/template/components/onboarding/onboarding-01.tsx +1 -1
- package/template/components/onboarding/onboarding-02.tsx +1 -1
- package/template/components/onboarding/onboarding-03.tsx +1 -1
- package/template/components/onboarding/onboarding-04.tsx +1 -1
- package/template/components/page-header.tsx +8 -226
- package/template/components/product-switcher.tsx +3 -4
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/settings-appearance-card.tsx +3 -4
- package/template/components/settings-client.tsx +15 -59
- package/template/components/settings-form-row.tsx +4 -9
- package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
- package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +114 -73
- package/template/components/sidebar/index.ts +16 -0
- package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
- package/template/components/sidebar/secondary-panel.tsx +316 -0
- package/template/components/sidebar/sidebar-auto-collapse.tsx +27 -0
- package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +2 -1
- package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
- package/template/components/site-header.tsx +1 -1
- package/template/components/table-properties/column-row.tsx +1 -90
- package/template/components/table-properties/draggable-list.ts +1 -49
- package/template/components/table-properties/drawer-button.tsx +1 -262
- package/template/components/table-properties/drawer.tsx +1 -1166
- package/template/components/table-properties/filter-card.tsx +1 -251
- package/template/components/table-properties/sort-card.tsx +1 -59
- package/template/components/table-properties/types.ts +28 -71
- package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
- package/template/components/templates/dedicated-search-results-template.tsx +1 -19
- package/template/components/templates/discovery-hub-template.tsx +1 -1
- package/template/components/templates/list-page.tsx +1 -608
- package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
- package/template/components/templates/new-focus-template.tsx +659 -0
- package/template/components/templates/secondary-panel-hub-template.tsx +2 -2
- package/template/components/tokens-secondary-nav.tsx +192 -0
- package/template/components/tokens-themes-client.tsx +476 -0
- package/template/components/tokens-themes-section.tsx +386 -0
- package/template/components/ui/accordion.tsx +1 -0
- package/template/components/ui/alert-dialog.tsx +1 -0
- package/template/components/ui/context-menu.tsx +1 -0
- package/template/components/ui/dot-pattern.tsx +1 -183
- package/template/components/ui/hover-card.tsx +1 -0
- package/template/components/ui/resizable.tsx +1 -68
- package/template/components/ui/scroll-area.tsx +1 -0
- package/template/components/ui/slider.tsx +1 -0
- package/template/docs/HANDBOOK.md +187 -0
- package/template/docs/blueprints/README.md +86 -0
- package/template/docs/blueprints/_template.md +91 -0
- package/template/docs/blueprints/board-card.md +123 -0
- package/template/docs/blueprints/data-table.md +139 -0
- package/template/docs/blueprints/key-metrics.md +128 -0
- package/template/docs/blueprints/list-page-template.md +123 -0
- package/template/docs/blueprints/page-header.md +130 -0
- package/template/docs/collaboration-access-pattern.md +7 -7
- package/template/docs/command-menu-pattern.md +1 -1
- package/template/docs/component-selection-guide.md +224 -0
- package/template/docs/components-audit-2026-05.md +158 -0
- package/template/docs/data-views-pattern.md +31 -66
- package/template/docs/drawer-vs-dialog-pattern.md +1 -3
- package/template/docs/glossary.md +58 -0
- package/template/docs/kpi-flat-band-pattern.md +3 -3
- package/template/docs/kpi-trend-pattern.md +18 -3
- package/template/docs/large-dataset-strategy.md +155 -0
- package/template/docs/library-hub-header-pattern.md +25 -0
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
- package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
- package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
- package/template/docs/migrations/README.md +100 -0
- package/template/docs/migrations/_template.md +64 -0
- package/template/docs/reference-implementations.md +151 -0
- package/template/docs/shell-surface-elevation-pattern.md +3 -5
- package/template/docs/token-taxonomy.md +416 -0
- package/template/docs/voice-and-tone.md +262 -0
- package/template/eslint.config.mjs +27 -0
- package/template/hooks/use-secondary-panel-hub-nav.ts +11 -11
- package/template/lib/ask-leo-route-context.ts +6 -18
- package/template/lib/coach-mark-registry.ts +0 -16
- package/template/lib/command-menu-config.ts +5 -13
- package/template/lib/command-menu-search-data.ts +8 -23
- package/template/lib/conditional-rule-match.ts +6 -97
- package/template/lib/data-list-display-options.ts +1 -49
- package/template/lib/data-list-view-registry.ts +1 -104
- package/template/lib/data-list-view-surface.ts +1 -83
- package/template/lib/data-list-view.ts +1 -47
- package/template/lib/data-view-dashboard-storage.ts +35 -38
- package/template/lib/dev-log.ts +1 -8
- package/template/lib/editable-target.ts +1 -10
- package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
- package/template/lib/library-dedicated-search.ts +19 -0
- package/template/lib/library-hub-search.ts +90 -0
- package/template/lib/library-nav.ts +477 -0
- package/template/lib/library-recent-searches.ts +22 -0
- package/template/lib/{question-bank-supported-views.ts → library-supported-views.ts} +2 -3
- package/template/lib/list-page-table-properties.ts +1 -48
- package/template/lib/list-status-badges.ts +16 -11
- package/template/lib/mock/dashboard.ts +1 -1
- package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
- package/template/lib/mock/library-header-collaborators.ts +54 -0
- package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
- package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
- package/template/lib/mock/library.ts +249 -0
- package/template/lib/mock/navigation.tsx +32 -35
- package/template/lib/raf-throttle.ts +1 -45
- package/template/lib/row-height.ts +4 -10
- package/template/lib/sidebar-state-cookie.ts +11 -2
- package/template/lib/table-state-lifecycle.ts +3 -3
- package/template/next.config.mjs +7 -4
- package/template/package.json +1 -0
- package/template/tests/setup.ts +25 -0
- package/consumer-extras/AGENTS.md +0 -76
- package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
- package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
- package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
- package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
- package/src/components/ui/button-group.tsx +0 -81
- package/src/theme.css +0 -16
- package/src/tokens/README.md +0 -15
- package/src/tokens/base.css +0 -337
- package/src/tokens/high-contrast.css +0 -1195
- package/src/tokens/layers.css +0 -224
- package/src/tokens/tailwind-bridge.css +0 -118
- package/src/tokens/themes.css +0 -201
- package/template/app/(app)/data-list/layout.tsx +0 -43
- package/template/app/(app)/data-list/page.tsx +0 -10
- package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
- package/template/app/(app)/examples/page.tsx +0 -43
- package/template/app/(app)/question-bank/find/page.tsx +0 -13
- package/template/app/(app)/question-bank/library/page.tsx +0 -12
- package/template/app/(app)/question-bank/list/page.tsx +0 -13
- package/template/app/(app)/question-bank/new/page.tsx +0 -50
- package/template/app/(app)/question-bank/page.tsx +0 -12
- package/template/components/app-route-loading.tsx +0 -14
- package/template/components/dashboard-onboarding-gallery.tsx +0 -13
- package/template/components/dashboard-onboarding.tsx +0 -21
- package/template/components/data-views/list-page-calendar-view.tsx +0 -593
- package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
- package/template/components/examples/focused-workflow-showcase.tsx +0 -183
- package/template/components/list-hub-board-view.tsx +0 -68
- package/template/components/list-hub-client.tsx +0 -186
- package/template/components/list-hub-list-view.tsx +0 -36
- package/template/components/list-hub-panel-activator.tsx +0 -8
- package/template/components/list-hub-secondary-nav.tsx +0 -121
- package/template/components/list-hub-table.tsx +0 -336
- package/template/components/question-bank-folder-columns-panel.tsx +0 -104
- package/template/components/question-bank-list-view.tsx +0 -53
- package/template/components/question-bank-panel-activator.tsx +0 -8
- package/template/components/question-bank-table.tsx +0 -729
- package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
- package/template/components/secondary-panel.tsx +0 -220
- package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
- package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
- package/template/components/secondary-panels/registry.tsx +0 -15
- package/template/components/section-cards.tsx +0 -106
- package/template/components/sidebar-auto-collapse.tsx +0 -23
- package/template/components/templates/focused-workflow-layouts.tsx +0 -448
- package/template/components/templates/focused-workflow-page-template.tsx +0 -69
- package/template/components/templates/page-loading-shell.tsx +0 -262
- package/template/components/ui/button-group.tsx +0 -1
- package/template/docs/consumer-app-pattern.md +0 -39
- package/template/docs/focused-workflow-page-pattern.md +0 -84
- package/template/docs/question-bank-hub-header-pattern.md +0 -25
- package/template/lib/list-hub-nav.ts +0 -121
- package/template/lib/mock/list-hub-directory.ts +0 -27
- package/template/lib/mock/list-hub-kpi.ts +0 -27
- package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
- package/template/lib/mock/question-bank.ts +0 -249
- package/template/lib/page-loading-variant.ts +0 -40
- package/template/lib/question-bank-dedicated-search.ts +0 -19
- package/template/lib/question-bank-hub-search.ts +0 -90
- package/template/lib/question-bank-nav.ts +0 -477
- package/template/lib/question-bank-recent-searches.ts +0 -22
- /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
- /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
- /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
- /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
- /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Primary sidebar item opens nested SecondaryPanel (Library pattern)
|
|
3
|
+
globs: apps/web/components/**/*.tsx
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Exxat DS — primary nav → secondary panel
|
|
8
|
+
|
|
9
|
+
Some hubs expose **scoped navigation** (All / My / tree / filters) in a **nested panel** between the **icon rail** and **main content** — not as **primary nav child rows**.
|
|
10
|
+
|
|
11
|
+
**Reference:** **Library** — **`lib/mock/navigation.tsx`** (`secondaryPanel: "library"`), **`components/app-sidebar.tsx`**, **`components/secondary-panel.tsx`**, **`components/library-panel-activator.tsx`**, **`components/library-secondary-nav.tsx`**, **`lib/library-nav.ts`** (URL scope).
|
|
12
|
+
|
|
13
|
+
## MUST (wiring)
|
|
14
|
+
|
|
15
|
+
1. **`NavLinkItem`** — On the **primary** row that should drive the panel, set **`secondaryPanel`** to a **stable string id** (e.g. **`"library"`**). Keep **`url`** pointing at the **hub route**.
|
|
16
|
+
2. **`SecondaryPanel` registry** — In **`components/secondary-panel.tsx`**, add **`PANELS[id]`** → component that renders **panel chrome** (title, optional search) + **your secondary nav** list. **MUST** keep ids in sync with **`NAV_PRIMARY`**.
|
|
17
|
+
3. **Auto-open on route** — The hub **`client`** (or layout slot) **MUST** mount **`*PanelActivator`** that calls **`useAutoPanel(id)`** with the **same id**, so deep links and first visit open the panel while the route is mounted (e.g. **`LibraryPanelActivator`** + **`beforeSiteHeader`** on **`LibraryClient`**).
|
|
18
|
+
4. **Same-route reopen** — **`AppSidebar`** already calls **`openPanel(secondaryPanel)`** when the user clicks the primary item **again** while already on that **`url`** (prevents no-op navigation). Secondary nav rows that stay on the same path **SHOULD** call **`openPanel`** on click where **Next.js `Link`** would not fire (same **`href`**).
|
|
19
|
+
|
|
20
|
+
## Surface elevation (brand chrome)
|
|
21
|
+
|
|
22
|
+
The nested panel sits **between** the icon rail and main content. **MUST** use the three-level stack (darkest → lightest):
|
|
23
|
+
|
|
24
|
+
| Level | Surface | Token |
|
|
25
|
+
|-------|---------|--------|
|
|
26
|
+
| **0** | Primary sidebar | `--sidebar` (= `--brand-tint` on product themes) |
|
|
27
|
+
| **1** | Secondary panel | `--secondary-panel-bg` |
|
|
28
|
+
| **2** | Page canvas | `--background` |
|
|
29
|
+
|
|
30
|
+
- **`NestedSecondaryPanelShell`** — **`bg-[var(--secondary-panel-bg)]`**, not **`bg-sidebar`** (same as level 0).
|
|
31
|
+
- **OKLCH** — light: `color-mix(in oklch, var(--background) 40%, var(--brand-tint-light) 60%)`; dark: `color-mix(in oklch, var(--card) 32%, var(--brand-tint) 68%)`. **MUST** follow **active product** (`theme-one`, `theme-prism`, `theme-custom`) — **MUST NOT** hardcode rose for all products.
|
|
32
|
+
- **`ProductProvider`** — `theme-custom` only when stored accent **differs** from product default (`accentOverrideActive`).
|
|
33
|
+
|
|
34
|
+
**Authoritative detail:** **`apps/web/docs/shell-surface-elevation-pattern.md`**.
|
|
35
|
+
|
|
36
|
+
## SHOULD
|
|
37
|
+
|
|
38
|
+
- Drive **hub scope** from the **URL** (**`useSearchParams`** + helpers like **`parseLibraryNav`**) so **refresh**, **share link**, and **breadcrumbs** match the secondary list.
|
|
39
|
+
- Keep **panel content** **Font Awesome**-aligned with the rest of the app (**`.cursor/rules/exxat-fontawesome-icons.mdc`**).
|
|
40
|
+
|
|
41
|
+
## MUST NOT
|
|
42
|
+
|
|
43
|
+
- Register a **`secondaryPanel`** id in **`NAV_PRIMARY`** **without** a **`PANELS`** entry and a matching **`useAutoPanel`** on the hub — users get a **collapsed sidebar** with **empty** panel space.
|
|
44
|
+
- Use **`secondaryPanel`** for **full** app sections that deserve their **own primary nav rows** — reserve this for **one hub** + **inner scope** UI.
|
|
45
|
+
|
|
46
|
+
## See also
|
|
47
|
+
|
|
48
|
+
- **`apps/web/AGENTS.md` §4.6** — handbook summary.
|
|
49
|
+
- **`apps/web/docs/shell-surface-elevation-pattern.md`** — OKLCH tokens + product theme.
|
|
50
|
+
- **`.cursor/rules/exxat-library-hub-header.mdc`** — folder-scoped library header **⋯** → **Customize folder** + client-mounted sheet.
|
|
51
|
+
- **`.cursor/rules/exxat-page-vs-drawer.mdc`** — when **drawer** vs **route**; secondary panel is **nav chrome**, not a workflow drawer.
|
|
52
|
+
- **`.cursor/rules/exxat-kpi-flat-band.mdc`** — flat KPI strip (separate from panel fill).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — prefer centralized reusable components; ask the user before new bespoke primitives.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — reuse before custom
|
|
7
|
+
|
|
8
|
+
## MUST
|
|
9
|
+
|
|
10
|
+
1. **Compose first** — Use existing **`components/ui/`**, **`components/data-views/`**, **`components/templates/`**, **`PageHeader`**, **`ListPageTemplate`**, **`DataTable`**, **`KeyMetrics`**, and patterns in **`AGENTS.md` §9** before writing new layout or interaction chrome.
|
|
11
|
+
2. **Search the codebase** — Grep or open the nearest hub (Placements, Team, Library) for the same UX (toolbar, drawer, metrics, board card, `ListPageViewFrame`, etc.).
|
|
12
|
+
3. **Extend in place** — Prefer adding a variant, slot, or prop to a shared component over a one-off duplicate under a single route.
|
|
13
|
+
|
|
14
|
+
## When the tool must ask the user
|
|
15
|
+
|
|
16
|
+
**MUST pause and ask the user** (with a short option list) when, after scanning, **no reasonable reuse** exists and the implementation would add **any** of:
|
|
17
|
+
|
|
18
|
+
- A **new reusable primitive** (new file under `components/` meant for multiple routes), or
|
|
19
|
+
- A **non-trivial bespoke widget** (custom data grid, chart system, modal stack, or parallel design-system fork) that is not already implied by the task.
|
|
20
|
+
|
|
21
|
+
Do **not** silently ship a second stack for the same product pattern (e.g. another “table”, another metrics strip, another sidebar).
|
|
22
|
+
|
|
23
|
+
If the **user or task already explicitly** approved a greenfield component (“build a new X from scratch”), you may proceed without re-asking.
|
|
24
|
+
|
|
25
|
+
## MUST NOT
|
|
26
|
+
|
|
27
|
+
- Add **route-only copies** of patterns that already live in **`components/`** or **`packages/ui`** without product reason.
|
|
28
|
+
- Introduce **parallel primitives** (second button row, second card shell, second command surface) when an existing one can be parameterized.
|
|
29
|
+
|
|
30
|
+
## See also
|
|
31
|
+
|
|
32
|
+
- **`apps/web/AGENTS.md` §1** (compose / scan before new UI), **§9** architecture table
|
|
33
|
+
- **`.cursor/rules/exxat-ds-agents.mdc`**
|
|
34
|
+
- **`.cursor/rules/exxat-centralized-list-dataset.mdc`** — one dataset / one presentation path for hubs
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: TablePropertiesDrawer must receive currentView and onViewChange when used with ListPageTemplate view tabs
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — Table properties + active view
|
|
7
|
+
|
|
8
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.2**.
|
|
9
|
+
|
|
10
|
+
## Why this exists
|
|
11
|
+
|
|
12
|
+
`TablePropertiesDrawer` uses **`currentView`** (`DataListViewType`) for the first summary row (“Board display” vs “Table display”, matching icons/descriptions) and to show **table-only** vs **board-only** sub-panels. If **`currentView`** is omitted, the drawer assumes **table** — wrong when the tab is **Board**, **List**, or **Dashboard**.
|
|
13
|
+
|
|
14
|
+
## MUST
|
|
15
|
+
|
|
16
|
+
When **`ListPageTemplate`** drives **`tab.viewType`** and the page renders **`TablePropertiesDrawer`** (directly or via a toolbar slot):
|
|
17
|
+
|
|
18
|
+
1. Pass **`currentView={view}`** (same value as **`tab.viewType`** passed into your table component).
|
|
19
|
+
2. Pass **`onViewChange`** from **`renderContent={(tab, updateTab) => ...}`** so the drawer’s view-type tiles stay in sync with the tab:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { dataListViewIcon, type DataListViewType } from "@/lib/data-list-view"
|
|
23
|
+
|
|
24
|
+
onViewChange={(v: DataListViewType) =>
|
|
25
|
+
updateTab({ viewType: v, icon: dataListViewIcon(v) })
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. Thread **`view`** and **`onViewChange`** through: **client → table component → drawer toolbar → `TablePropertiesDrawer`**.
|
|
30
|
+
|
|
31
|
+
**Reference implementations:** `components/placements-table.tsx` (`PlacementsTable`), `components/team-client.tsx` + `team-table.tsx`, `components/compliance-client.tsx` + `compliance-table.tsx`.
|
|
32
|
+
|
|
33
|
+
## Deep-linking into a specific panel
|
|
34
|
+
|
|
35
|
+
`TablePropertiesDrawer` accepts an optional **`initialPanel`** prop so callsites can open the drawer focused on a named panel — `"main"` (default), `"table-display"`, `"filter"`, `"sort"`, `"group"`, `"columns"`, or `"conditional-rules"`. The current built-in use is the **Add Conditional Rule** item in every column header menu, which deep-links to the **Conditional rules** panel.
|
|
36
|
+
|
|
37
|
+
### MUST
|
|
38
|
+
|
|
39
|
+
1. **One state pair owns it.** `useTableState` exposes **`sheetInitialPanel`** + **`setSheetInitialPanel`** alongside `sheetOpen` / `setSheetOpen`. Read both in the drawer button; pass **`initialPanel={sheetInitialPanel}`** to `TablePropertiesDrawer`. Reference: `packages/ui/src/components/table-properties/drawer-button.tsx`.
|
|
40
|
+
2. **The toolbar Properties button MUST clear the deep-link.** Otherwise the next plain "Properties" click re-opens onto whatever panel the previous deep-link set:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
onClick={() => {
|
|
44
|
+
setSheetInitialPanel?.(null)
|
|
45
|
+
setSheetOpen(true)
|
|
46
|
+
}}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. **Deep-link callsites MUST set panel + open in the same batched setState call.** Two setters in one callback land in one render, so the drawer mounts with `initialPanel` already populated — no panel-flash:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
setSheetInitialPanel("conditional-rules")
|
|
53
|
+
setSheetOpen(true)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. **From inside a Radix DropdownMenu, queue the action into `onCloseAutoFocus`.** Opening the non-modal Sheet synchronously from `DropdownMenuItem.onSelect` races with the menu close cycle. Use the `columnMenuPendingActionRef` pattern in `packages/ui/src/components/data-table/index.tsx` (or copy it) so the drawer opens after focus has returned to the trigger.
|
|
57
|
+
|
|
58
|
+
### MUST NOT
|
|
59
|
+
|
|
60
|
+
- Don't introduce a second source of truth for "which panel" — `sheetInitialPanel` is the only deep-link channel. The drawer's internal `sheetPanel` state stays internal.
|
|
61
|
+
- Don't call `setSheetInitialPanel` from a non-deep-link callsite (e.g. a generic "open Properties" toolbar button). Leave it `null` for index opens.
|
|
62
|
+
|
|
63
|
+
## View-type tile grid is uniformly square
|
|
64
|
+
|
|
65
|
+
The drawer's "View type" tile grid (and the Export drawer's "File format" grid) renders through `SelectionTileGrid` with `interaction="button"` + `labelPlacement="inside"`. The shared `selectionTileClassNames` utility now applies **`aspect-square`** so every tile is the same shape regardless of how many tiles populate the last row of a `grid-cols-N` track. Two-word labels (e.g. "List & details") wrap inside the square because `leading-tight` keeps line height compact.
|
|
66
|
+
|
|
67
|
+
When you compose your own tile-style picker, **prefer the shared `SelectionTileGrid`** (or `selectionTileClassNames` directly) instead of inventing flex/grid wrappers — that's the only way to keep the squares uniform across the system.
|
|
68
|
+
|
|
69
|
+
## MUST NOT (overall)
|
|
70
|
+
|
|
71
|
+
- Mount **`TablePropertiesDrawer`** on a multi-view list page **without** **`currentView`** when the active view is known from the tab.
|
|
72
|
+
- Omit **`onViewChange`** if the product shows the **view type** control inside Properties (otherwise tiles cannot update the tab).
|
|
73
|
+
|
|
74
|
+
## See also
|
|
75
|
+
|
|
76
|
+
- **`apps/web/AGENTS.md` §4.2**, **§13** checklist
|
|
77
|
+
- **`.cursor/rules/exxat-list-page-connected-views.mdc`**
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Exxat DS — token discipline
|
|
2
|
+
|
|
3
|
+
**Authoritative reference:** [`apps/web/docs/token-taxonomy.md`](mdc:apps/web/docs/token-taxonomy.md).
|
|
4
|
+
**Machine-readable index:** [`packages/ui/tokens/hooks-index.json`](mdc:packages/ui/tokens/hooks-index.json) (163 tokens · 36 namespaces; regenerate via `pnpm --filter @exxatdesignux/ui tokens:index`).
|
|
5
|
+
**Enforcement:** [`@exxatdesignux/eslint-plugin`](mdc:packages/eslint-plugin-exxat-ds/README.md) (rules `exxat-ds/no-hex-color`, `exxat-ds/no-deprecated-tokens`).
|
|
6
|
+
|
|
7
|
+
Use this rule when adding **any** color, spacing, radius, shadow, or
|
|
8
|
+
transition value to JSX, CSS, or Tailwind class strings.
|
|
9
|
+
|
|
10
|
+
## MUST
|
|
11
|
+
|
|
12
|
+
1. **Prefer the Exxat L0 namespace** for new code — `var(--exxat-color-surface-1)`,
|
|
13
|
+
`bg-surface-1`, `bg-brand-1`, `rounded-2`, `--exxat-spacing-4`, … (taxonomy §2.0).
|
|
14
|
+
L1 shadcn names (`--background`, `bg-brand`, `rounded-md`, …) remain as
|
|
15
|
+
back-compat aliases and continue to work — but new product surfaces should
|
|
16
|
+
read in the canonical brand-prefixed namespace.
|
|
17
|
+
2. **Reach for a semantic token first.** If the value carries semantic intent
|
|
18
|
+
("danger", "warning", "muted text", "card surface"), use the matching
|
|
19
|
+
token family from §2 of the taxonomy. Never reinvent semantic colors.
|
|
20
|
+
3. **Use Tailwind utilities backed by tokens** (e.g. `bg-card`,
|
|
21
|
+
`text-muted-foreground`, `border-border-control`, `ring-ring`,
|
|
22
|
+
`bg-chip-2`, `text-chart-4`, **`bg-surface-1`**, **`bg-brand-1`**,
|
|
23
|
+
**`rounded-2`**). The L2 bridges in `globals.css` already wire
|
|
24
|
+
`--color-*` → `var(--*)` so utilities flip with theme + dark mode.
|
|
25
|
+
3. **Brand accent comes from `--brand-color` / `bg-brand`** (and its family),
|
|
26
|
+
**not** `--primary` / `bg-primary`. Primary is **neutral charcoal** in
|
|
27
|
+
Exxat — see taxonomy §3.
|
|
28
|
+
4. **Form-field borders** use `--control-border` (or `border-control-3` /
|
|
29
|
+
`border-control-35`) — never `--border` (which is decorative and < 3:1
|
|
30
|
+
contrast). Taxonomy §6.
|
|
31
|
+
5. **Status chips and badges** route through
|
|
32
|
+
[`lib/list-status-badges.ts`](mdc:apps/web/lib/list-status-badges.ts)
|
|
33
|
+
(`LIST_HUB_STATUS_TINT_*` + `ListHubStatusBadge`) — not direct
|
|
34
|
+
`bg-green-500` / `bg-red-500` / hex literals.
|
|
35
|
+
6. **KPI tints** route through `--insight-severity-*` (info / warning) — not
|
|
36
|
+
direct chart-color reuse. Trend polarity is set via
|
|
37
|
+
`MetricItem.trendPolarity` ([`exxat-kpi-trends.mdc`](mdc:.cursor/rules/exxat-kpi-trends.mdc)).
|
|
38
|
+
7. **Scoped surface tokens stay scoped.** `--dt-*` is `DataTable` only,
|
|
39
|
+
`--key-metrics-*` is `KeyMetrics` only, `--leo-*` is Ask Leo only,
|
|
40
|
+
`--secondary-panel-bg` is the nested panel only. Do **not** reuse these
|
|
41
|
+
tokens outside their owning surface.
|
|
42
|
+
8. **Adding a new token** — Follow the checklist in
|
|
43
|
+
[`token-taxonomy.md` §4](mdc:apps/web/docs/token-taxonomy.md). Declare
|
|
44
|
+
the primitive in `packages/ui/src/globals.css` (canonical CSS), bridge it in the same file's `@theme inline`
|
|
45
|
+
files when Tailwind utilities are needed, document it in the taxonomy,
|
|
46
|
+
and regenerate `tokens/hooks-index.json`.
|
|
47
|
+
|
|
48
|
+
## MUST NOT
|
|
49
|
+
|
|
50
|
+
1. **No raw hex / rgb / hsl color literals** in JSX `className` strings,
|
|
51
|
+
inline `style={{...}}`, or `.css` files outside of `globals.css` /
|
|
52
|
+
`globals.css` / theme overrides. The only places hex is legal are:
|
|
53
|
+
- `--theme-color-chrome` (consumed by `<meta name="theme-color">`)
|
|
54
|
+
- Status icon SVG paths that are part of a vendored asset
|
|
55
|
+
- **Documentation** examples (this rule, blueprints, migrations)
|
|
56
|
+
2. **No raw `oklch(...)` literals** in component code — those belong in
|
|
57
|
+
`globals.css` theme blocks only. If you need a derived value, use
|
|
58
|
+
`color-mix(in oklch, var(--token) <pct>%, var(--other))` inside a token
|
|
59
|
+
declaration, not at the call site.
|
|
60
|
+
3. **No deprecated tokens.** Inspect
|
|
61
|
+
[`tokens/hooks-index.json`](mdc:packages/ui/tokens/hooks-index.json) —
|
|
62
|
+
any entry with `"deprecated": true` is removed at the version named in
|
|
63
|
+
`deprecatedMessage`. Migrate before the removal window per
|
|
64
|
+
`apps/web/docs/migrations/`.
|
|
65
|
+
4. **No ad-hoc Tailwind shades** for product chrome (e.g. `bg-slate-50`,
|
|
66
|
+
`text-zinc-600`, `border-gray-200`) when an Exxat semantic equivalent
|
|
67
|
+
exists. Tailwind shade utilities are reserved for transient prototyping
|
|
68
|
+
only; product code uses the semantic tokens.
|
|
69
|
+
5. **No `text-primary` for the brand accent.** That maps to neutral charcoal
|
|
70
|
+
(see MUST #3).
|
|
71
|
+
6. **No utility-class typos that look like tokens.** Examples that look
|
|
72
|
+
right but aren't:
|
|
73
|
+
- `bg-brand-color` — that's the *raw L1 name*; the L2 utility is `bg-brand`.
|
|
74
|
+
- `border-control` — there's no such utility; the field-border alias is `border-control-3` (3:1) or `border-control-35` (3.5:1+), or `border-[var(--control-border)]`.
|
|
75
|
+
- `text-foreground-muted` — the token is `--muted-foreground` (note the order).
|
|
76
|
+
7. **No SLDS tokens** (`--slds-g-color-*`) — see
|
|
77
|
+
[`exxat-no-slds-leakage.mdc`](mdc:.cursor/rules/exxat-no-slds-leakage.mdc).
|
|
78
|
+
|
|
79
|
+
## Aliases that ARE official
|
|
80
|
+
|
|
81
|
+
Some L2 bridges intentionally use a **shorter alias** than the L1 primitive
|
|
82
|
+
because the long name would be awkward in Tailwind utilities. Use the alias
|
|
83
|
+
form, but be aware of the underlying primitive:
|
|
84
|
+
|
|
85
|
+
| Alias (use in code) | L0 canonical | L1 primitive | Notes |
|
|
86
|
+
|---|---|---|---|
|
|
87
|
+
| `bg-brand` / `text-brand` | `--exxat-color-brand-1` | `--brand-color` | Brand accent |
|
|
88
|
+
| `bg-brand-deep` / `text-brand-deep` | `--exxat-color-brand-deep` | `--brand-color-deep` | Coach marks, hero callouts |
|
|
89
|
+
| `bg-brand-tint` | `--exxat-color-brand-tint-1` | `--brand-tint` | Sidebar wash |
|
|
90
|
+
| `bg-surface-1` / `text-ink-1` | `--exxat-color-surface-1` / `--exxat-color-ink-1` | `--background` / `--foreground` | Page canvas + primary text — new code SHOULD prefer L0 form |
|
|
91
|
+
| `rounded-1` … `rounded-6` | `--exxat-radius-1` … `--exxat-radius-6` | (no L1 equivalent — L0 is canonical for radius) | Numeric radius scale (4 / 8 / 12 / 16 / 20 / 24 px) |
|
|
92
|
+
|
|
93
|
+
The full alias table is in [`token-taxonomy.md` §2.0](mdc:apps/web/docs/token-taxonomy.md) and [§2.2](mdc:apps/web/docs/token-taxonomy.md).
|
|
94
|
+
|
|
95
|
+
## See also
|
|
96
|
+
|
|
97
|
+
- [`apps/web/docs/token-taxonomy.md`](mdc:apps/web/docs/token-taxonomy.md) — full namespace + naming rules
|
|
98
|
+
- [`apps/web/docs/migrations/`](mdc:apps/web/docs/migrations) — deprecation index
|
|
99
|
+
- [`packages/ui/tokens/hooks-index.json`](mdc:packages/ui/tokens/hooks-index.json) — machine-readable
|
|
100
|
+
- [`.cursor/rules/exxat-no-slds-leakage.mdc`](mdc:.cursor/rules/exxat-no-slds-leakage.mdc)
|
|
101
|
+
- [`.cursor/rules/exxat-kpi-trends.mdc`](mdc:.cursor/rules/exxat-kpi-trends.mdc)
|
|
102
|
+
- [`.cursor/rules/exxat-kpi-flat-band.mdc`](mdc:.cursor/rules/exxat-kpi-flat-band.mdc)
|
|
103
|
+
- [`.cursor/rules/exxat-no-toast.mdc`](mdc:.cursor/rules/exxat-no-toast.mdc)
|
|
@@ -8,7 +8,7 @@ user-invocable: true
|
|
|
8
8
|
|
|
9
9
|
Standard target: **WCAG 2.1 Level AA** (and 2.2 where noted).
|
|
10
10
|
|
|
11
|
-
**Canonical for agents (MUST/MUST NOT, checklist):** `
|
|
11
|
+
**Canonical for agents (MUST/MUST NOT, checklist):** `apps/web/AGENTS.md` **§8** in the repo (same content summarized there; this skill stays the detailed checklist + product tokens).
|
|
12
12
|
|
|
13
13
|
## ARIA roles & structure (SC 1.3.1)
|
|
14
14
|
|
|
@@ -7,7 +7,7 @@ user-invocable: true
|
|
|
7
7
|
|
|
8
8
|
# Exxat DS — board (kanban) cards
|
|
9
9
|
|
|
10
|
-
**Canonical MUST/MUST NOT:** **`
|
|
10
|
+
**Canonical MUST/MUST NOT:** **`apps/web/AGENTS.md` §4.4** (or **`./AGENTS.md`** when the workspace is the `apps/web/` app folder only). **Claude:** **`.claude/skills/exxat-board-cards/SKILL.md`** (repo root) — same body as this file. This skill is the **how-to**; the handbook stays the contract.
|
|
11
11
|
|
|
12
12
|
## When to use this skill
|
|
13
13
|
|
|
@@ -39,13 +39,13 @@ Import from **`@/components/data-views/list-page-board-card`**:
|
|
|
39
39
|
|
|
40
40
|
Prefer **two-line blocks** for stacked **primary / secondary** facts so cards match Placements’ visual rhythm.
|
|
41
41
|
|
|
42
|
-
## Status badges (list hubs: Team, Compliance,
|
|
42
|
+
## Status badges (list hubs: Team, Compliance, Library, …)
|
|
43
43
|
|
|
44
44
|
- **Maps (single source):** **`lib/list-status-badges.ts`** — per-entity `*_STATUS_LABEL`, `*_STATUS_BADGE_CLASS`, `*_STATUS_ICON`, plus semantic **`LIST_HUB_STATUS_TINT_*`** (success / warning / neutral / danger) for new domains.
|
|
45
45
|
- **Component:** **`ListHubStatusBadge`** from **`@/components/list-hub-status-badge`** — **`surface="table"`** for **DataTable** cells and **list** rows; **`surface="board"`** inside **`ListPageBoardCardBadgeRow`**. Do not duplicate the shell classes on each page.
|
|
46
46
|
- Use the **same** maps everywhere for that entity so copy and colors never drift.
|
|
47
47
|
- **Do not** add **`uppercase`** or **`tracking-wide`** — **sentence / title case**, consistent with **`BoardStatusBadge`** on Placements (`placement-board-card.tsx`).
|
|
48
|
-
- **Placements** lifecycle uses **`StatusBadge`** in **`
|
|
48
|
+
- **Placements** lifecycle uses **`StatusBadge`** in **`placements-table-cells.tsx`** — thin wrapper over **`ListHubStatusBadge`** + **`PLACEMENT_STATUS_*`** in **`list-status-badges.ts`** (same visuals as Team / Library).
|
|
49
49
|
|
|
50
50
|
## Avatar when mock has no `initials`
|
|
51
51
|
|
|
@@ -60,18 +60,7 @@ Goal: **one row model**, **one filtered bag** (`tableState.rows`), **one place f
|
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
|
-
## 6.
|
|
64
|
-
|
|
65
|
-
- [ ] **`lib/<hub>-supported-views.ts`** — same array on **`ListPageTemplate`** (`supportedViewTypes`) and **`TablePropertiesDrawerButton`**.
|
|
66
|
-
- [ ] **`ListPageConnectedViewBody`** + **`defineHubViewRenderers(supported, { … })`** — one renderer per **`DataListViewRenderKind`**; missing → **`ListPageViewNotConfigured`** (never silent dashboard).
|
|
67
|
-
- [ ] Branch on **`getDataListViewRenderKind(view)`** via the connected body — not long **`if (view === "table")`** chains in the table file.
|
|
68
|
-
- [ ] **`lib/data-list-view-registry.ts`** — labels/icons/render kinds stay centralized.
|
|
69
|
-
|
|
70
|
-
**Canon:** `docs/data-views-pattern.md` § “View registry and connected bodies”, **`AGENTS.md` §4.1.1**.
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 7. Implementation checklist (new hub or new view)
|
|
63
|
+
## 6. Implementation checklist (new hub or new view)
|
|
75
64
|
|
|
76
65
|
- [ ] Exactly **one** primary row array shape in **`lib/mock/<entity>.ts`** (or API).
|
|
77
66
|
- [ ] **`useTableState`** seeded from that array; **child views** receive **`tableState.rows`** (or equivalent), **not** a fresh import of the mock list.
|
|
@@ -83,15 +72,15 @@ Goal: **one row model**, **one filtered bag** (`tableState.rows`), **one place f
|
|
|
83
72
|
|
|
84
73
|
---
|
|
85
74
|
|
|
86
|
-
##
|
|
75
|
+
## 7. Reference implementations
|
|
87
76
|
|
|
88
|
-
- **`components/
|
|
77
|
+
- **`components/placements-client.tsx`** + **`placements-table.tsx`** — Placements pattern.
|
|
89
78
|
- **`components/team-client.tsx`** + **`team-table.tsx`**.
|
|
90
|
-
- **`components/
|
|
79
|
+
- **`components/library-table.tsx`** — multiple **`DataListViewType`** branches sharing **`tableState`** / **`folders`** / **`items`**.
|
|
91
80
|
|
|
92
81
|
---
|
|
93
82
|
|
|
94
|
-
##
|
|
83
|
+
## 8. Centralized presentation (with the same dataset)
|
|
95
84
|
|
|
96
85
|
**Layout:** Non-table view branches wrap in **`ListPageViewFrame`** (constants in **`list-page-view-frame.tsx`**) — see **`.cursor/rules/exxat-list-page-view-shells.mdc`**.
|
|
97
86
|
|
|
@@ -9,7 +9,7 @@ user-invocable: true
|
|
|
9
9
|
**Handbook:** `apps/web/AGENTS.md` §4.7
|
|
10
10
|
**Narrative:** `apps/web/docs/collaboration-access-pattern.md`
|
|
11
11
|
**Cursor rule:** `.cursor/rules/exxat-collaboration-access.mdc`
|
|
12
|
-
**Related (
|
|
12
|
+
**Related (Library folder scope + ⋯ Customize folder):** `.cursor/rules/exxat-library-hub-header.mdc` · `docs/library-hub-header-pattern.md`
|
|
13
13
|
|
|
14
14
|
## Wiring checklist
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ user-invocable: true
|
|
|
20
20
|
5. **Access maps** — `lib/collaborator-access.ts` for Owner / Editor / Commenter / Viewer, invite options, and **`COLLABORATION_HEADER_ADD_LABEL`**.
|
|
21
21
|
6. **Header** — empty roster → outline **Add collaborator**; non-empty → face rail; both open the invite sheet.
|
|
22
22
|
7. **Invite sheet** — `InviteCollaboratorsDrawer`: export-style **`Sheet`**, combined email + access menu, grouped roster (name → email → role tags → access badge).
|
|
23
|
-
8. **
|
|
23
|
+
8. **Library — folder URL scope** — When **`?scope=folder`**, **`LibraryPageHeader`** **⋯** also lists **Customize folder**; **`LibraryNewFolderSheet`** on **`LibraryClient`** — **`.cursor/rules/exxat-library-hub-header.mdc`**, **`docs/library-hub-header-pattern.md`**.
|
|
24
24
|
|
|
25
25
|
## MUST NOT
|
|
26
26
|
|
|
@@ -31,5 +31,5 @@ user-invocable: true
|
|
|
31
31
|
|
|
32
32
|
## Reference
|
|
33
33
|
|
|
34
|
-
- `components/collaboration-access-flow.tsx`, `components/
|
|
34
|
+
- `components/collaboration-access-flow.tsx`, `components/library-page-header.tsx`, `components/library-client.tsx`
|
|
35
35
|
- `components/invite-collaborators-drawer.tsx`, `components/export-drawer.tsx`
|
|
@@ -37,8 +37,8 @@ description: >-
|
|
|
37
37
|
| Recents list | `components/dedicated-search-recents.tsx` |
|
|
38
38
|
| Recents storage factory | `lib/dedicated-search-recents.ts` |
|
|
39
39
|
| Optional default `q` patcher | `lib/dedicated-search-url.ts` |
|
|
40
|
-
|
|
|
41
|
-
|
|
|
40
|
+
| Library adapter (placeholders + patch) | `lib/library-dedicated-search.ts` |
|
|
41
|
+
| Library wiring | `components/library-client.tsx` |
|
|
42
42
|
|
|
43
43
|
## Cursor rule
|
|
44
44
|
|
|
@@ -19,10 +19,10 @@ description: >
|
|
|
19
19
|
## 1. Project Overview
|
|
20
20
|
|
|
21
21
|
- **Stack:** Next.js 16 (App Router), React, TypeScript, Tailwind CSS, shadcn/ui primitives, Font Awesome icons
|
|
22
|
-
- **App root:** `
|
|
23
|
-
- **Single source of truth:** `
|
|
24
|
-
- **Companion skills (narrow topics):** `exxat-fontawesome-icons`, `exxat-mono-ids`, `exxat-primary-nav-secondary-panel`, `exxat-centralized-list-dataset`, `exxat-list-page-view-shells`, `exxat-dedicated-search-surfaces`, `exxat-
|
|
25
|
-
- **
|
|
22
|
+
- **App root:** `apps/web/app/(app)/` — route group that wraps all authenticated pages
|
|
23
|
+
- **Single source of truth:** `apps/web/AGENTS.md` for full prose explanations; this skill is the actionable summary
|
|
24
|
+
- **Companion skills (narrow topics):** `exxat-fontawesome-icons`, `exxat-mono-ids`, `exxat-primary-nav-secondary-panel`, `exxat-centralized-list-dataset`, `exxat-list-page-view-shells`, `exxat-dedicated-search-surfaces`, `exxat-accessibility`, `exxat-board-cards`, `exxat-collaboration-access` — live under `.cursor/skills/`; vetted copies ship with **`@exxatdesignux/ui`** in `consumer-extras/cursor-skills/` after **`pnpm --filter @exxatdesignux/ui vendor:consumer-extras`**.
|
|
25
|
+
- **Library folder-scoped header (rule + doc):** **`.cursor/rules/exxat-library-hub-header.mdc`** and **`docs/library-hub-header-pattern.md`** — pair with **`exxat-primary-nav-secondary-panel`** when URL **`scope=folder`** drives the hub title.
|
|
26
26
|
- **Consumer repos (npm install of `@exxatdesignux/ui`):** After a version bump, read **`node_modules/@exxatdesignux/ui/CHANGELOG.md`**, run **`npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras`** so **`docs/exxat-ds/consumer-upgrade-checklist.md`** and Cursor skills match the tarball, and diff the host app against **`node_modules/@exxatdesignux/ui/template/`** for anything new to port (routes, re-exports, AGENTS). Use **`exxat-ui changelog`**, **`exxat-ui update`**, and **`exxat-ui doctor`** for CLI guidance.
|
|
27
27
|
|
|
28
28
|
---
|
|
@@ -105,15 +105,15 @@ A primary nav row that owns sub-routes has **three possible shapes** — pick ex
|
|
|
105
105
|
|
|
106
106
|
| Shape | When to use | Where it lives |
|
|
107
107
|
|---|---|---|
|
|
108
|
-
| **A. Collapsible children** (e.g.
|
|
108
|
+
| **A. Collapsible children** (e.g. Library → All / My / Favorites / Folders) | Small finite child list that benefits from inline browsing (≤ 40 items, no extra page chrome). | `NavLinkItem.children` rendered by **`CollapsibleNavItem`** in `app-sidebar.tsx`. |
|
|
109
109
|
| **B. Secondary panel** (separate nested rail) | Same nav row needs **scoped search / tree / metrics** alongside the hub content. | `NavLinkItem.secondaryPanel = "<id>"` + `PANELS[id]` — see companion skill `exxat-primary-nav-secondary-panel`. |
|
|
110
|
-
| **C. Both A + B on one row** (
|
|
110
|
+
| **C. Both A + B on one row** (Library does this) | Most cases when a hub has a sub-list AND a rich rail. The sidebar still shows the collapsible children; clicking the parent route also opens the secondary panel via `useAutoPanel`. | Combine A + B; the active-state and animation rules in §3.2 still apply to the sidebar children. |
|
|
111
111
|
|
|
112
112
|
#### Active-state rules — **the single biggest mistake to avoid**
|
|
113
113
|
|
|
114
114
|
1. **Expanded sidebar (full rail):** parent stays **visually neutral** when a child is active — **never double-highlight**. `isCollapsibleParentMenuButtonActive` returns `false` if `anyChildActive` so the active child row carries `data-active` alone.
|
|
115
115
|
2. **Collapsed sidebar (icon rail):** the parent icon is the **only** affordance, so it lights up when **any child** route is active. Implementation: `iconRailActive = isAnyChildActive` is fed into `SidebarMenuButton.isActive` and selects `item.iconActive` (`fa-solid`) over `item.icon` (`fa-light`).
|
|
116
|
-
3. **Tooltip / aria copy** in icon mode names the parent (e.g. "
|
|
116
|
+
3. **Tooltip / aria copy** in icon mode names the parent (e.g. "Library — open subpages"); the **popover** content lists children with their own active state so users see which sub-route is selected.
|
|
117
117
|
|
|
118
118
|
```tsx
|
|
119
119
|
// Inside CollapsibleNavItem
|
|
@@ -259,21 +259,8 @@ ListPageTemplate
|
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
**Reference implementations:**
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
### 4.1 View registry (do not fork `if (view === …)`)
|
|
266
|
-
|
|
267
|
-
1. **`lib/data-list-view.ts`** — `DATA_LIST_VIEW_TILES` (labels/icons).
|
|
268
|
-
2. **`lib/data-list-view-registry.ts`** — `renderKind`, `showsListPageHubMetricsStrip`, `dataListViewTilesForHub`.
|
|
269
|
-
3. **`lib/foo-supported-views.ts`** — `export const FOO_SUPPORTED_VIEWS = ["table", "list", …] as const`.
|
|
270
|
-
4. **`ListPageTemplate`** — `supportedViewTypes={FOO_SUPPORTED_VIEWS}`.
|
|
271
|
-
5. **`foo-table.tsx`** — `ListPageConnectedViewBody` with renderers per kind; **`TablePropertiesDrawerButton`** gets the same **`supportedViewTypes`**.
|
|
272
|
-
6. Generic bodies under **`components/data-views/`** — calendar, board template, folder grid, etc.
|
|
273
|
-
|
|
274
|
-
**MUST NOT** default unknown views to dashboard KPIs — missing renderers use **`ListPageViewNotConfigured`**.
|
|
275
|
-
|
|
276
|
-
**Narrative:** `docs/data-views-pattern.md` § “View registry and connected bodies”.
|
|
262
|
+
- `components/team-client.tsx` + `components/team-table.tsx` — canonical pattern
|
|
263
|
+
- `components/placements-client.tsx` + `components/placements-table.tsx` — Placements (most complete)
|
|
277
264
|
|
|
278
265
|
**Files to create for a new hub page `Foo`:**
|
|
279
266
|
| File | Purpose |
|
|
@@ -281,21 +268,19 @@ ListPageTemplate
|
|
|
281
268
|
| `lib/mock/foo.ts` | Mock data + TypeScript interface (12+ rows) |
|
|
282
269
|
| `lib/mock/foo-kpi.ts` | `fooKpiMetrics()` + `fooKpiInsight()` |
|
|
283
270
|
| `components/foo-page-header.tsx` | `PageHeader` + primary CTA + ⋯ menu |
|
|
284
|
-
| `
|
|
285
|
-
| `components/foo-
|
|
286
|
-
| `components/foo-client.tsx` | `ListPageTemplate` + `supportedViewTypes` |
|
|
271
|
+
| `components/foo-table.tsx` | `DataTable` + `useTableState` + `TablePropertiesDrawer` |
|
|
272
|
+
| `components/foo-client.tsx` | `ListPageTemplate` orchestrator |
|
|
287
273
|
| `app/(app)/foo/page.tsx` | Thin server component |
|
|
288
274
|
|
|
289
|
-
**Do not** ship a **nav-linked hub** as an **empty page** or a single “replace this later” paragraph. If the route appears in **`lib/mock/navigation.tsx`**, implement the full hub (mock rows, **`ListPageTemplate`**, connected views per **`
|
|
275
|
+
**Do not** ship a **nav-linked hub** as an **empty page** or a single “replace this later” paragraph. If the route appears in **`lib/mock/navigation.tsx`**, implement the full hub (mock rows, **`ListPageTemplate`**, connected views per **`apps/web/AGENTS.md` §4.1**) unless the product explicitly defines a non-data shell.
|
|
290
276
|
|
|
291
277
|
### Page vs drawer (actions)
|
|
292
278
|
|
|
293
279
|
- **Drawer / sheet** — Use when the user needs **the current page behind them** *and* a **quick view**, **quick actions**, or a **short step** (e.g. properties, export, glance at a row).
|
|
294
280
|
- **Dialog** — **Blocking** confirm/alert/short choice — **`docs/drawer-vs-dialog-pattern.md`**, **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**.
|
|
295
281
|
- **New page** — Use **otherwise**: **primary**, **long-form**, **multi-step**, or flows that need their **own URL** without the hub visible.
|
|
296
|
-
- **Focused workflow route** — **`FocusedWorkflowPageTemplate`** + **`FocusedWorkflowSingleColumn`** | **`FocusedWorkflowStepForm`** | **`FocusedWorkflowSidebarSections`** | **`FocusedWorkflowEmptyState`** — **`docs/focused-workflow-page-pattern.md`**, **`AGENTS.md` §14**, **`exxat-focused-workflow-page`** skill. **Not** list hubs; **not** Miller columns.
|
|
297
282
|
|
|
298
|
-
Align with **`
|
|
283
|
+
Align with **`apps/web/AGENTS.md` §6.4**, **`docs/data-views-pattern.md`**, **`docs/drawer-vs-dialog-pattern.md`**, **`.cursor/rules/exxat-page-vs-drawer.mdc`**, **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**.
|
|
299
284
|
|
|
300
285
|
---
|
|
301
286
|
|
|
@@ -311,7 +296,7 @@ Align with **`exxat-ds/AGENTS.md` §6.4**, **§14**, **`docs/data-views-pattern.
|
|
|
311
296
|
| `ColumnDef` from `@/components/data-table/types` | Column type |
|
|
312
297
|
| `FilterFieldDef`, `FilterOperator`, `ConditionalRule` from `@/components/table-properties/types` | Filter types |
|
|
313
298
|
|
|
314
|
-
**Board (kanban) cards:** Use **`ListPageBoardCard`** and related parts from **`components/data-views/list-page-board-card.tsx`**; **`BoardCardTwoLineBlock`** / **`BoardCardIconRow`** from **`board-card-primitives.tsx`**. **List hub** status (Team, Compliance,
|
|
299
|
+
**Board (kanban) cards:** Use **`ListPageBoardCard`** and related parts from **`components/data-views/list-page-board-card.tsx`**; **`BoardCardTwoLineBlock`** / **`BoardCardIconRow`** from **`board-card-primitives.tsx`**. **List hub** status (Team, Compliance, Library, …): maps in **`lib/list-status-badges.ts`**; render with **`ListHubStatusBadge`** (**`surface="table"`** in table/list, **`surface="board"`** on cards); semantic tints **`LIST_HUB_STATUS_TINT_*`** for new domains; no **`uppercase`**. **Placements** uses **`StatusBadge`** in **`placements-table-cells.tsx`** (wrapper over **`ListHubStatusBadge`** + **`PLACEMENT_STATUS_*`**). **Full rules:** **`apps/web/AGENTS.md` §4.4**, **`.cursor/rules/exxat-board-cards.mdc`**, **`.cursor/skills/exxat-board-cards/SKILL.md`**.
|
|
315
300
|
|
|
316
301
|
**Minimum required features on any data list page:**
|
|
317
302
|
- Search (wire `searchable={displayOptions.showToolbarSearch}`)
|
|
@@ -416,9 +401,9 @@ Use `PageHeader` from `@/components/page-header` for the content-area header (be
|
|
|
416
401
|
|
|
417
402
|
When a hub is **shared**, use **`PageHeader` `variant="collaboration"`**: **empty roster** → outline **Add collaborator**; **non-empty** → face rail (faces / **`+N`** open the invite sheet). **Invite people** also lives under the entity header **⋯ More** and opens **`InviteCollaboratorsDrawer`** via **`CollaborationAccessFlow`** when possible. Library access (Owner / Editor / Commenter / Viewer) comes from **`lib/collaborator-access.ts`**; directory tags (Faculty, Program coordinator, Director) use **`PageHeaderCollaborator.roles`**.
|
|
418
403
|
|
|
419
|
-
**
|
|
404
|
+
**Library library — folder URL scope:** When **`?scope=folder&folderId=`** applies, **⋯ More** must also offer **Customize folder** (**`LibraryPageHeader`** **`onCustomizeFolder`**) and the **`LibraryNewFolderSheet`** must be mounted on **`LibraryClient`** so it works on every **`ListPageTemplate`** view tab. **`.cursor/rules/exxat-library-hub-header.mdc`** · **`docs/library-hub-header-pattern.md`** (app: **`apps/web/docs/...`**).
|
|
420
405
|
|
|
421
|
-
**Handbook:** `apps/web/AGENTS.md` §4.7 · **Doc:** `docs/collaboration-access-pattern.md` · **Skill:** `.cursor/skills/exxat-collaboration-access/SKILL.md` · **Reference:**
|
|
406
|
+
**Handbook:** `apps/web/AGENTS.md` §4.7 · **Doc:** `docs/collaboration-access-pattern.md` · **Skill:** `.cursor/skills/exxat-collaboration-access/SKILL.md` · **Reference:** Library header + client.
|
|
422
407
|
|
|
423
408
|
---
|
|
424
409
|
|
|
@@ -621,7 +606,7 @@ Reference implementations: `new-placement-form.tsx` (Create placement = Enter on
|
|
|
621
606
|
- **Natural language / AI:** Product **SHOULD** show **quick results in the palette** when the response fits; use **Ask Leo** (**⌘⌥K**) for **longer or complex** answers.
|
|
622
607
|
- **Do not** treat the palette as a static link list only—leave room for inline AI results as they ship.
|
|
623
608
|
|
|
624
|
-
**Details:** `
|
|
609
|
+
**Details:** `apps/web/docs/command-menu-pattern.md`, **`apps/web/AGENTS.md` §7.1** (or `./` when the app folder is the workspace root).
|
|
625
610
|
|
|
626
611
|
---
|
|
627
612
|
|
|
@@ -876,8 +861,8 @@ Copy and complete for every list/table/hub page:
|
|
|
876
861
|
- [ ] Sidebar item added to `lib/mock/navigation.tsx` with light/solid icon pair
|
|
877
862
|
- [ ] **Shell sidebar:** Product header uses **`ExxatProductLogo`**; school **`logoDevUrl`** + **`lib/logo-dev`**; team switcher menu **`!w-max`** (not trigger-width-only); expanded switcher **`h-auto min-h-12`** so school + program lines are not clipped; no **`CollapsibleTrigger` → `SidebarMenuButton` with `tooltip` prop**; child nav uses **popover** on icon rail per **§3.1**
|
|
878
863
|
- [ ] Hub pages: `ListPageTemplate` + `DataTable` + `useTableState` + `TablePropertiesDrawer`
|
|
879
|
-
- [ ] Board view: `ListPageBoardCard` shell + `ListHubStatusBadge` + `list-status-badges` when applicable (`
|
|
880
|
-
- [ ] New primary hubs: not placeholder-only — full template + data + views (`
|
|
864
|
+
- [ ] Board view: `ListPageBoardCard` shell + `ListHubStatusBadge` + `list-status-badges` when applicable (`apps/web/AGENTS.md` §4.4)
|
|
865
|
+
- [ ] New primary hubs: not placeholder-only — full template + data + views (`apps/web/AGENTS.md` §4.1)
|
|
881
866
|
- [ ] **§6.4:** Parent **context** + quick view/actions → drawer/sheet; primary or long flows → **new page** (`AGENTS.md`, `docs/data-views-pattern.md`)
|
|
882
867
|
- [ ] No raw `<table>` or `ui/table` for product data lists
|
|
883
868
|
- [ ] No double horizontal padding around `DataTable`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Data Table Pattern — Full Implementation Guide
|
|
2
2
|
|
|
3
|
-
Reference implementation: `components/team-table.tsx` (Team) and `components/
|
|
3
|
+
Reference implementation: `components/team-table.tsx` (Team) and `components/placements-table.tsx` (Placements).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -30,7 +30,7 @@ user-invocable: true
|
|
|
30
30
|
|
|
31
31
|
- `apps/web/components/key-metrics.tsx` — `flatMetricsHairlineClass`, `flatBandStyle`
|
|
32
32
|
- `apps/web/app/globals.css` — `--key-metrics-flat-*`
|
|
33
|
-
- `
|
|
33
|
+
- `library-client.tsx`, `dashboard-tabs.tsx` — reference usage
|
|
34
34
|
|
|
35
35
|
## Pair with
|
|
36
36
|
|
|
@@ -21,7 +21,7 @@ description: >-
|
|
|
21
21
|
- Pass **`maxWidthClassName={LIST_PAGE_VIEW_FRAME_MAX_WIDE}`** when the view includes toolbar rows + breadcrumbs + grid.
|
|
22
22
|
2. **Do not double-gutter** — If **`DataTable`** already provides horizontal inset for the **table** view, do **not** wrap that branch in **`ListPageViewFrame`**. Use the frame on **sibling** view branches (folder, panel, etc.) only.
|
|
23
23
|
3. **Reuse before inventing** — Prefer **`FolderGridView`**, **`FinderPanelView`**, **`ListPageBoardTemplate`**, **`ListPageViewFrame`**. If a new pattern appears twice, **promote** it to **`components/data-views/`** with domain-agnostic props.
|
|
24
|
-
4. **Entity-specific → generic** — If logic is “any tree + any row type”, build **`components/data-views/<generic-name>.tsx`** and keep **`
|
|
24
|
+
4. **Entity-specific → generic** — If logic is “any tree + any row type”, build **`components/data-views/<generic-name>.tsx`** and keep **`library-*`** (or similar) as a thin composition + mock types.
|
|
25
25
|
|
|
26
26
|
## Checklist
|
|
27
27
|
|
|
@@ -39,11 +39,11 @@ Always include **`tabular-nums`** with **`font-mono`** so fixed-width digits ali
|
|
|
39
39
|
|
|
40
40
|
| Surface | File |
|
|
41
41
|
|---------|------|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
| New question subtitle | `components/new-
|
|
42
|
+
| Library table | `components/library-table.tsx` — `row.questionId` |
|
|
43
|
+
| Library list | `components/library-list-view.tsx` |
|
|
44
|
+
| New question subtitle | `components/new-library-item-form.tsx` — `questionId` in `PageHeader` subtitle |
|
|
45
45
|
| Sites record id | `components/sites-table.tsx` — `row.id` |
|
|
46
|
-
| OS folder tiles | `components/
|
|
46
|
+
| OS folder tiles | `components/library-os-folder-view.tsx` |
|
|
47
47
|
|
|
48
48
|
## Review checklist
|
|
49
49
|
|