@exxatdesignux/ui 0.2.18 → 0.3.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 +69 -1
- package/bin/sync-extras.mjs +116 -29
- package/consumer-extras/README.md +43 -4
- 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 +41 -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-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-question-bank-hub-header.mdc +28 -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 +2 -2
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +9 -9
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/handbook/HANDBOOK.md +185 -0
- package/consumer-extras/handbook/glossary.md +57 -0
- package/consumer-extras/handbook/reference-implementations.md +126 -0
- package/consumer-extras/handbook/voice-and-tone.md +262 -0
- package/consumer-extras/patterns/command-menu-pattern.md +1 -1
- package/consumer-extras/patterns/data-views-pattern.md +14 -14
- 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 +167 -0
- package/dist/components/data-views/hub-table.js +5561 -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 +6575 -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 +13324 -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 -18
- 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 +255 -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 +498 -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/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 +494 -151
- 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/.cursor/rules/exxat-command-menu.mdc +1 -1
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
- package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
- package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +84 -20
- package/template/app/(app)/examples/page.tsx +0 -1
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/question-bank/layout.tsx +1 -1
- package/template/app/(app)/question-bank/new/page.tsx +11 -24
- package/template/app/globals.css +13 -1972
- 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/compliance-table.tsx +240 -384
- 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-view-dashboard-charts-compliance.tsx +2 -2
- package/template/components/data-view-dashboard-charts-team.tsx +2 -2
- package/template/components/data-view-dashboard-charts.tsx +2 -2
- 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 +42 -1
- 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 -0
- 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 -60
- 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/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/hub-tree-panel-view.tsx +2 -2
- 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/new-placement-back-btn.tsx +1 -1
- package/template/components/new-placement-form.tsx +63 -189
- package/template/components/new-question-composer.tsx +432 -402
- 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/placement-board-card.tsx +71 -83
- package/template/components/placements-board-view.tsx +3 -10
- package/template/components/placements-client.tsx +10 -42
- package/template/components/placements-list-view.tsx +22 -69
- package/template/components/placements-table-columns.tsx +8 -438
- package/template/components/placements-table.tsx +588 -1296
- package/template/components/product-switcher.tsx +1 -1
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/question-bank-client.tsx +4 -1
- package/template/components/question-bank-hub-client.tsx +1 -1
- package/template/components/question-bank-new-folder-sheet.tsx +2 -2
- package/template/components/question-bank-secondary-nav.tsx +3 -3
- package/template/components/question-bank-table.tsx +294 -526
- package/template/components/rotations-empty-state.tsx +1 -1
- package/template/components/rotations-panel-activator.tsx +1 -1
- package/template/components/settings-appearance-card.tsx +1 -1
- package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
- package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +4 -4
- package/template/components/sidebar/index.ts +16 -0
- package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
- package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +6 -3
- package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
- package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
- package/template/components/site-header.tsx +1 -1
- package/template/components/{sites-all-client.tsx → sites-client.tsx} +1 -1
- package/template/components/sites-table.tsx +124 -257
- 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 -249
- package/template/components/table-properties/drawer.tsx +1 -1105
- 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/team-table.tsx +242 -382
- 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/list-page.tsx +1 -584
- package/template/components/templates/nested-secondary-panel-shell.tsx +1 -62
- package/template/components/templates/new-focus-template.tsx +659 -0
- package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
- 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/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/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 +14 -14
- 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/token-taxonomy.md +416 -0
- package/template/eslint.config.mjs +27 -0
- package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template/lib/command-menu-config.ts +0 -1
- package/template/lib/compliance-supported-views.ts +10 -0
- package/template/lib/conditional-rule-match.ts +6 -97
- package/template/lib/data-list-display-options.ts +1 -35
- package/template/lib/data-list-view-registry.ts +1 -0
- package/template/lib/data-list-view-surface.ts +1 -69
- package/template/lib/data-list-view.ts +1 -38
- package/template/lib/dev-log.ts +1 -8
- package/template/lib/editable-target.ts +1 -10
- package/template/lib/hub-connected-view-renderers.ts +58 -0
- package/template/lib/list-hub-supported-views.ts +10 -0
- package/template/lib/list-page-table-properties.ts +1 -52
- package/template/lib/mock/navigation.tsx +0 -8
- package/template/lib/mock/placements.ts +0 -7
- package/template/lib/placement-board-card-layout.ts +41 -41
- package/template/lib/placements-supported-views.ts +12 -0
- package/template/lib/question-bank-supported-views.ts +12 -0
- 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/sites-supported-views.ts +10 -0
- package/template/lib/team-supported-views.ts +10 -0
- package/template/package.json +1 -0
- package/template/tests/setup.ts +25 -0
- package/src/theme.css +0 -1132
- package/template/app/(app)/data-list/[id]/page.tsx +0 -44
- package/template/app/(app)/data-list/new/page.tsx +0 -34
- package/template/app/(app)/data-list/page.tsx +0 -10
- package/template/components/compliance-list-view.tsx +0 -54
- package/template/components/dashboard-onboarding-gallery.tsx +0 -13
- package/template/components/dashboard-onboarding.tsx +0 -21
- package/template/components/question-bank-list-view.tsx +0 -53
- package/template/components/section-cards.tsx +0 -106
- package/template/components/sites-list-view.tsx +0 -42
- package/template/components/team-list-view.tsx +0 -59
- package/template/lib/placement-lifecycle.ts +0 -5
- /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
- /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Exxat DS — Component Selection Guide
|
|
2
|
+
|
|
3
|
+
**Audience:** humans + AI agents. **Companion to:** [`token-taxonomy.md`](./token-taxonomy.md), [`blueprints/`](./blueprints/).
|
|
4
|
+
|
|
5
|
+
When you're about to build a UI, **start here**. Follow the decision tree
|
|
6
|
+
to find the right composition before you write any markup. The rule is
|
|
7
|
+
always: **compose existing components first**; only create a new shared
|
|
8
|
+
primitive after asking the user
|
|
9
|
+
([`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc)).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 0. Quick chart
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────────────────────────────┐
|
|
17
|
+
│ What is the surface? │
|
|
18
|
+
└──┬──────────────────────────────────┘
|
|
19
|
+
│
|
|
20
|
+
┌───────────┴────────────────────────────┐
|
|
21
|
+
│ │
|
|
22
|
+
PRIMARY HUB OVERLAY / SECONDARY
|
|
23
|
+
(route w/ many records, (on top of a hub,
|
|
24
|
+
filters, properties) modal task, side panel)
|
|
25
|
+
│ │
|
|
26
|
+
│ ▼
|
|
27
|
+
│ See § 3
|
|
28
|
+
▼
|
|
29
|
+
See § 1
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 1. Building a primary hub (route with records)
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Q: Is the data > ~10 comparable records?
|
|
38
|
+
─────────────────────────────────────────
|
|
39
|
+
│ yes ──────────────────────────────► DataTable inside ListPageTemplate (§1.1)
|
|
40
|
+
│ no ──┬─ all rows shown at once?
|
|
41
|
+
│ │ yes ── simple `<dl>` / card list (no Properties / Filters needed)
|
|
42
|
+
│ │ no ── still use DataTable — future growth is expected
|
|
43
|
+
└─────►
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 1.1 DataTable hub (canonical)
|
|
47
|
+
|
|
48
|
+
| Need | Use |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Browsable grid | **`DataTable`** + **`useTableState`** ([blueprint](./blueprints/data-table.md)) |
|
|
51
|
+
| View tabs (table/list/board/dashboard) | **`ListPageTemplate`** + connected views ([`exxat-list-page-connected-views.mdc`](../../.cursor/rules/exxat-list-page-connected-views.mdc)) |
|
|
52
|
+
| Column/density/properties | **`TablePropertiesDrawer`** (pass `currentView` + `onViewChange`) |
|
|
53
|
+
| Filters | Shared `FilterFieldDef` chips |
|
|
54
|
+
| Find-in-list | Toolbar search (`⌘K`) |
|
|
55
|
+
| Metrics strip | **`KeyMetrics`** `variant="flat"` ([`kpi-flat-band-pattern.md`](./kpi-flat-band-pattern.md)) — **max 4 tiles** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)) |
|
|
56
|
+
| Export | Filled primary CTA + `⋯` → `ExportDrawer` |
|
|
57
|
+
| Kanban view body | **`ListPageBoardCard`** + `ListPageBoardTemplate` ([`exxat-board-cards.mdc`](../../.cursor/rules/exxat-board-cards.mdc)) |
|
|
58
|
+
| Folder / panel view body | **`FolderGridView`** / **`FinderPanelView`** wrapped in **`ListPageViewFrame`** ([`exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc)) |
|
|
59
|
+
| Dashboard view body | **`KeyMetrics variant="card"`** + chart sections from `data-view-dashboard-charts*.tsx` |
|
|
60
|
+
| Nested scope nav (All / Mine / tree) | **`secondaryPanel`** + `PANELS` + `useAutoPanel` ([`exxat-primary-nav-secondary-panel.mdc`](../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc)) |
|
|
61
|
+
| Shared hub w/ invite | **`PageHeader` `variant="collaboration"`** + `InviteCollaboratorsDrawer` |
|
|
62
|
+
| Dedicated search (empty `?q=` vs results) | **`DedicatedSearchLandingTemplate`** + **`DedicatedSearchResultsHeaderChrome`** |
|
|
63
|
+
|
|
64
|
+
**Reference:** `PlacementsClient` (Placements) is the most complete example.
|
|
65
|
+
|
|
66
|
+
### 1.2 Visual-browse hub (kanban / gallery)
|
|
67
|
+
|
|
68
|
+
If the product wants a **kanban-first** experience and the table is the
|
|
69
|
+
fallback rather than primary:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
ListPageTemplate
|
|
73
|
+
├── PageHeader
|
|
74
|
+
├── KeyMetrics (optional, ≤4)
|
|
75
|
+
└── viewType="board" → ListPageBoardTemplate + ListPageBoardCard
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Even here, **back the board with `useTableState`** so switching to the table
|
|
79
|
+
tab is consistent. Don't fork the data.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 2. Naming a card / row / list
|
|
84
|
+
|
|
85
|
+
| Pattern | What to reach for |
|
|
86
|
+
|---|---|
|
|
87
|
+
| Dense comparable rows | `DataTable` row (don't card-wall it — see [`card-vs-rows-pattern.md`](./card-vs-rows-pattern.md)) |
|
|
88
|
+
| Kanban column card | `ListPageBoardCard` + `BoardCardTwoLineBlock` + `BoardCardIconRow` |
|
|
89
|
+
| OS-folder grid | `FolderGridView` in `ListPageViewFrame` |
|
|
90
|
+
| Finder split (list + preview) | `FinderPanelView` |
|
|
91
|
+
| Sidebar nav row | `SidebarMenuButton` (do not roll your own) |
|
|
92
|
+
| KPI tile | `KeyMetrics` `MetricItem` — never a custom `Card` w/ number |
|
|
93
|
+
| Coach mark tile | `CoachMark` step — never an ad-hoc onboarding popover |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 3. Same-route overlay vs new route
|
|
98
|
+
|
|
99
|
+
Always ask: **does the user need the hub visible behind them?**
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
┌────────────────────────────┐
|
|
103
|
+
│ Does the user need the hub │
|
|
104
|
+
│ visible behind them? │
|
|
105
|
+
└─────────────┬──────────────┘
|
|
106
|
+
│
|
|
107
|
+
┌───── YES ─────┴───── NO ─────┐
|
|
108
|
+
▼ ▼
|
|
109
|
+
Same route New route
|
|
110
|
+
(overlay) (own URL)
|
|
111
|
+
│ │
|
|
112
|
+
┌─────┴──────┐ │
|
|
113
|
+
│ Is the task│ │
|
|
114
|
+
│ short + │ │
|
|
115
|
+
│ blocking? │ │
|
|
116
|
+
└─────┬──────┘ │
|
|
117
|
+
│ │
|
|
118
|
+
┌─ YES ┴ NO ──┐ │
|
|
119
|
+
▼ ▼ ▼
|
|
120
|
+
Dialog Drawer / Sheet Page route
|
|
121
|
+
(AlertDialog, (TablePropertiesDrawer, (full create/edit
|
|
122
|
+
delete confirm) ExportDrawer, wizard, deep detail)
|
|
123
|
+
InviteCollaboratorsDrawer)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
See [`drawer-vs-dialog-pattern.md`](./drawer-vs-dialog-pattern.md) and
|
|
127
|
+
[`exxat-page-vs-drawer.mdc`](../../.cursor/rules/exxat-page-vs-drawer.mdc).
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 4. Search / Find / Command
|
|
132
|
+
|
|
133
|
+
| Need | Use | Shortcut |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| Find inside a table | `DataTableToolbar` search | `⌘K` / `Ctrl K` (no Alt) |
|
|
136
|
+
| Find inside a hub (across tabs/views) | Same `⌘K` while focus is on the hub | `⌘K` |
|
|
137
|
+
| Global navigation + AI starter | `CommandMenu` ([`command-menu-pattern.md`](./command-menu-pattern.md)) | `⌘K` while no input has focus |
|
|
138
|
+
| Long AI / chat | `AskLeoSidebar` | `⌘⌥K` |
|
|
139
|
+
| Dedicated search page (results view) | `DedicatedSearchLandingTemplate` + `DedicatedSearchResultsHeaderChrome` | — |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 5. Feedback / messaging
|
|
144
|
+
|
|
145
|
+
| Need | Use |
|
|
146
|
+
|---|---|
|
|
147
|
+
| Persistent banner ("system maintenance") | `SystemBanner` |
|
|
148
|
+
| Per-page contextual info | `LocalBanner` |
|
|
149
|
+
| Per-control success/error | Inline text next to the field |
|
|
150
|
+
| Confirm a destructive action | `AlertDialog` |
|
|
151
|
+
| **Never** | `toast()` / Sonner / snackbars ([`exxat-no-toast.mdc`](../../.cursor/rules/exxat-no-toast.mdc)) |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 6. Icons
|
|
156
|
+
|
|
157
|
+
| Use case | Pattern |
|
|
158
|
+
|---|---|
|
|
159
|
+
| Icon next to a label | FA glyph + `aria-hidden` (Case A) |
|
|
160
|
+
| Icon standing alone (meaning-bearing) | `<span role="img" aria-label="…" tabIndex={0}>` + `Tooltip` (Case B) |
|
|
161
|
+
| Icon-only button / link | `<button aria-label="…">` wrapped in `Tooltip` (Case C) |
|
|
162
|
+
| Product mark | `ExxatProductLogo` |
|
|
163
|
+
| School / org mark | `logoDevUrl()` |
|
|
164
|
+
|
|
165
|
+
Source: `apps/web/AGENTS.md` §8.6.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 7. KPIs / metrics
|
|
170
|
+
|
|
171
|
+
| Need | Use |
|
|
172
|
+
|---|---|
|
|
173
|
+
| Hub metric strip on top of `ListPageTemplate` | `KeyMetrics variant="flat"` |
|
|
174
|
+
| Dashboard view tab key-metrics card | `KeyMetrics variant="card"` (1–4 tiles) |
|
|
175
|
+
| Chart + mini-metric next to it | `ChartCard` + chart's own KPI helpers |
|
|
176
|
+
| Trend arrow on a metric | Set `MetricItem.trend` to match delta sign; set `trendPolarity` when "up" is bad |
|
|
177
|
+
|
|
178
|
+
Cap visible KPIs at **4** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)).
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 8. Identifiers and typography
|
|
183
|
+
|
|
184
|
+
| Carries | Use |
|
|
185
|
+
|---|---|
|
|
186
|
+
| System ID (`questionId`, record key) | `font-mono tabular-nums` ([`exxat-mono-ids.mdc`](../../.cursor/rules/exxat-mono-ids.mdc)) |
|
|
187
|
+
| Page title | `<h1>` with `font-heading` (Ivy Presto) inside `PageHeader` |
|
|
188
|
+
| Body | Default Inter, ≥ 11px (`text-xs` minimum) |
|
|
189
|
+
| Status label | `ListHubStatusBadge` from `lib/list-status-badges.ts` — never raw text |
|
|
190
|
+
| Currency / counts | `tabular-nums` (no `font-mono`) |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## 9. When NOTHING here fits
|
|
195
|
+
|
|
196
|
+
You are now in the territory covered by
|
|
197
|
+
[`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc):
|
|
198
|
+
|
|
199
|
+
1. Re-scan `apps/web/components/`, `packages/ui/src/components/`, and `apps/web/components/data-views/`.
|
|
200
|
+
2. Check `AGENTS.md` §9 architecture table.
|
|
201
|
+
3. If still no fit, **ask the user** with a short option list:
|
|
202
|
+
- extend an existing primitive (preferred),
|
|
203
|
+
- add a new component under `components/data-views/` or `components/templates/`,
|
|
204
|
+
- or open a packaged shared primitive in `packages/ui`.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 10. Cheat sheet — one-line rules
|
|
209
|
+
|
|
210
|
+
- **Data list, > 10 rows** → `DataTable` + `ListPageTemplate`.
|
|
211
|
+
- **Visual browse / kanban** → `ListPageBoardCard`.
|
|
212
|
+
- **Folder / panel / OS-folder view** → `data-views/` primitive in `ListPageViewFrame`.
|
|
213
|
+
- **Quick auxiliary task with hub behind** → drawer.
|
|
214
|
+
- **Blocking short confirm** → dialog.
|
|
215
|
+
- **Primary / long / own-URL flow** → new route.
|
|
216
|
+
- **Global ⌘K** → `CommandMenu` (search + quick AI).
|
|
217
|
+
- **Long AI** → Ask Leo (`⌘⌥K`).
|
|
218
|
+
- **Feedback** → banner / inline / dialog — **never** toast.
|
|
219
|
+
- **Icon-only button** → `aria-label` + `Tooltip` (Case C).
|
|
220
|
+
- **System ID** → `font-mono tabular-nums`.
|
|
221
|
+
- **KPI strip** → ≤ 4 tiles, `variant="flat"` on hubs.
|
|
222
|
+
- **Hex color in code** → no. Use a token.
|
|
223
|
+
|
|
224
|
+
See also: [`AGENTS.md` §13 checklist](../AGENTS.md) — run it before shipping a hub.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# `apps/web/components/` audit — 2026-05
|
|
2
|
+
|
|
3
|
+
**Author:** Exxat DS hardening sweep · **Scope:** observation only — no code moved.
|
|
4
|
+
|
|
5
|
+
This audit was triggered by formalizing the design system (token taxonomy +
|
|
6
|
+
blueprints + selection guide + ESLint guardrails) so that any future
|
|
7
|
+
component refactor has a clear target structure. **No file is moved or
|
|
8
|
+
deleted by this audit itself.** Treat each finding as a follow-up PR
|
|
9
|
+
candidate; bundle them as you like.
|
|
10
|
+
|
|
11
|
+
## 1. Sizes & shape
|
|
12
|
+
|
|
13
|
+
| Bucket | Count | Notes |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| Top-level `components/*.tsx` | **99** | Mix of hub clients, hub tables, hub views, page headers, dashboard charts, sidebar bits, leaf primitives |
|
|
16
|
+
| `components/data-table/` | 5 | Correct — base table stack |
|
|
17
|
+
| `components/data-views/` | 14 | Correct — generic view primitives + board card |
|
|
18
|
+
| `components/onboarding/` | 5 (4 demos + index) | Demo variants of `GettingStarted` |
|
|
19
|
+
| `components/table-properties/` | (drawer + parts) | Correct |
|
|
20
|
+
| `components/templates/` | 7 | Correct — page-level templates |
|
|
21
|
+
| `components/ui/` | 40+ | Reserved for shadcn primitives bridged from `packages/ui` |
|
|
22
|
+
|
|
23
|
+
## 2. Findings
|
|
24
|
+
|
|
25
|
+
### 2.1 Dead components (zero importers found)
|
|
26
|
+
|
|
27
|
+
> **Resolved 2026-05-19.** A re-verification scan confirmed that
|
|
28
|
+
> `form-layout-01.tsx` and `section-cards.tsx` are **not present** in either
|
|
29
|
+
> `apps/web/components/` or `packages/ui/template/components/` — the audit's
|
|
30
|
+
> initial finding was based on a stale snapshot. No action needed.
|
|
31
|
+
|
|
32
|
+
### 2.2 Onboarding components split between two locations
|
|
33
|
+
|
|
34
|
+
> **Resolved 2026-05-19.** Option A landed:
|
|
35
|
+
> - `getting-started.tsx` moved into `components/onboarding/getting-started.tsx`
|
|
36
|
+
> (both `apps/web/` and `packages/ui/template/`).
|
|
37
|
+
> - Deprecated shims `dashboard-onboarding.tsx` and
|
|
38
|
+
> `dashboard-onboarding-gallery.tsx` deleted in both locations
|
|
39
|
+
> (no consumers outside themselves).
|
|
40
|
+
> - `components/onboarding/index.ts` now re-exports `GettingStarted`,
|
|
41
|
+
> `GettingStartedProgressCard`, `GettingStartedVariantView`,
|
|
42
|
+
> `renderGettingStartedVariant`, `GETTING_STARTED_STORAGE_KEY`, and
|
|
43
|
+
> the `Onboarding01`–`Onboarding04` variant cards.
|
|
44
|
+
> - Dashboard consumers (`dashboard-tabs.tsx`, `dashboard-report-charts.tsx`)
|
|
45
|
+
> import via `@/components/onboarding/getting-started`; intra-folder
|
|
46
|
+
> variants use the relative `./getting-started` path.
|
|
47
|
+
|
|
48
|
+
### 2.3 Sidebar shell — high top-level density
|
|
49
|
+
|
|
50
|
+
> **Resolved 2026-05-19.** All 11 sidebar files relocated into
|
|
51
|
+
> `components/sidebar/` (both `apps/web/` and `packages/ui/template/`):
|
|
52
|
+
>
|
|
53
|
+
> ```
|
|
54
|
+
> components/sidebar/
|
|
55
|
+
> ├── index.ts ← barrel re-export
|
|
56
|
+
> ├── app-sidebar.tsx
|
|
57
|
+
> ├── app-sidebar-dynamic.tsx
|
|
58
|
+
> ├── sidebar-shell.tsx
|
|
59
|
+
> ├── sidebar-auto-collapse.tsx
|
|
60
|
+
> ├── sidebar-auto-open.tsx
|
|
61
|
+
> ├── nav-main.tsx
|
|
62
|
+
> ├── nav-secondary.tsx
|
|
63
|
+
> ├── nav-documents.tsx
|
|
64
|
+
> ├── nav-user.tsx
|
|
65
|
+
> ├── secondary-nav.tsx
|
|
66
|
+
> └── secondary-panel.tsx
|
|
67
|
+
> ```
|
|
68
|
+
>
|
|
69
|
+
> **External consumers** now import via the barrel:
|
|
70
|
+
> `import { AppSidebar, SidebarShell, useSecondaryPanel } from "@/components/sidebar"`.
|
|
71
|
+
> Per-file paths still resolve (escape hatch), e.g.
|
|
72
|
+
> `@/components/sidebar/secondary-panel`.
|
|
73
|
+
>
|
|
74
|
+
> **Intra-folder** imports use relative paths (`./nav-user`, `./secondary-panel`)
|
|
75
|
+
> so internal restructure does not ripple out.
|
|
76
|
+
>
|
|
77
|
+
> Dead-import audit at completion: zero references to `@/components/<sidebar-file>"`
|
|
78
|
+
> remain outside the new folder.
|
|
79
|
+
>
|
|
80
|
+
> `nav-main`, `nav-secondary`, `nav-documents`, `sidebar-auto-open` are
|
|
81
|
+
> currently zero-import (only mentioned in docs/skills). They were moved for
|
|
82
|
+
> directory consistency; pruning truly dead files is a separate concern.
|
|
83
|
+
|
|
84
|
+
### 2.4 Dedicated-search files — naming consistent
|
|
85
|
+
|
|
86
|
+
`dedicated-search-recents.tsx`, `dedicated-search-url-composer.tsx`,
|
|
87
|
+
`components/templates/dedicated-search-{landing,results}-template.tsx` —
|
|
88
|
+
generic family already lives across `templates/` + top-level. **No action.**
|
|
89
|
+
|
|
90
|
+
### 2.5 Entity-bound views — correctly at top level
|
|
91
|
+
|
|
92
|
+
`*-list-view.tsx`, `*-board-view.tsx`, `*-page-header.tsx`, `*-client.tsx`,
|
|
93
|
+
`*-table.tsx`, `*-dashboard-charts*.tsx`, `*-os-folder-view.tsx`,
|
|
94
|
+
`*-panel-activator.tsx` — these are entity-specific compositions that
|
|
95
|
+
**must** stay co-located with the hub they serve. **No action.**
|
|
96
|
+
|
|
97
|
+
### 2.6 Possibly generic — re-evaluate during reuse work
|
|
98
|
+
|
|
99
|
+
- `tinted-icon-disc.tsx` — used in KPI/empty states. If the API has stabilized,
|
|
100
|
+
consider moving to `components/data-views/` or `packages/ui/src/components/ui/`.
|
|
101
|
+
- `task-list-panel.tsx`, `task-priority-badge.tsx` — generic-sounding but
|
|
102
|
+
bound to a Task entity. Confirm scope before any move.
|
|
103
|
+
- `tree-panel-view.tsx`-style: `hub-tree-panel-view.tsx`,
|
|
104
|
+
`folder-details-shell.tsx` — already generic-sounding. If imported by
|
|
105
|
+
≥ 2 hubs, move under `data-views/`.
|
|
106
|
+
|
|
107
|
+
A quick rule of thumb:
|
|
108
|
+
|
|
109
|
+
> If a component is imported by **only one** hub, it stays at the top level
|
|
110
|
+
> next to that hub.
|
|
111
|
+
> If it is (or could be) imported by **≥ 2** hubs, promote it into
|
|
112
|
+
> `components/data-views/` (record-bearing) or `components/templates/`
|
|
113
|
+
> (page chrome).
|
|
114
|
+
|
|
115
|
+
### 2.7 `packages/ui/template/` parity
|
|
116
|
+
|
|
117
|
+
Most top-level files are mirrored under `packages/ui/template/components/`
|
|
118
|
+
(starter scaffold for `create-exxat-app`). When a file moves in
|
|
119
|
+
`apps/web/components/`, `pnpm --filter @exxatdesignux/ui sync-template`
|
|
120
|
+
will also move it under `template/`. **Always run `sync-template` after any
|
|
121
|
+
refactor under §2.3 / §2.6** so the published starter stays buildable.
|
|
122
|
+
|
|
123
|
+
## 3. Non-findings — what's already healthy
|
|
124
|
+
|
|
125
|
+
- **`components/ui/`** is reserved for shadcn-aligned primitives; no
|
|
126
|
+
duplicates appear at the top level (e.g. no rogue `button.tsx` next to the
|
|
127
|
+
one in `ui/`).
|
|
128
|
+
- **`components/data-views/`** is the right home for generic record-bearing
|
|
129
|
+
surfaces (`FolderGridView`, `FinderPanelView`, `ListPageBoardCard`).
|
|
130
|
+
Entity-specific board cards (`placement-board-card.tsx`) correctly stay
|
|
131
|
+
at top level.
|
|
132
|
+
- **`components/templates/`** is the right home for page-level wrappers
|
|
133
|
+
(`ListPageTemplate`, `DedicatedSearch*Template`,
|
|
134
|
+
`SecondaryPanelHubTemplate`, `DiscoveryHubTemplate`). No drift.
|
|
135
|
+
- **No `components/lightning/`** folder anywhere — `exxat-no-slds-leakage`
|
|
136
|
+
rule already passes.
|
|
137
|
+
- **No second toast surface** — only `components/ui/sonner.tsx` exists, and
|
|
138
|
+
it's gated by `exxat-no-toast` + the new `exxat-ds/no-sonner-toast` lint.
|
|
139
|
+
|
|
140
|
+
## 4. Suggested follow-up PRs
|
|
141
|
+
|
|
142
|
+
| # | Title | Scope | Risk |
|
|
143
|
+
|---|---|---|---|
|
|
144
|
+
| 1 | Remove dead `form-layout-01.tsx` + `section-cards.tsx` from `apps/web/` and `packages/ui/template/` | Trivial | Low |
|
|
145
|
+
| 2 | Consolidate `getting-started.tsx` + `dashboard-onboarding*.tsx` under `components/onboarding/` | Small | Low (import rename) |
|
|
146
|
+
| 3 | ~~Move sidebar files into `components/sidebar/`~~ — **done 2026-05-19** (§2.3) | Medium | — |
|
|
147
|
+
| 4 | Promote `tinted-icon-disc.tsx`, `hub-tree-panel-view.tsx`, `folder-details-shell.tsx` to `data-views/` if used by ≥ 2 hubs | Small per file | Low |
|
|
148
|
+
| 5 | Run `sync-template` after each of 1–4 to keep `packages/ui/template/` aligned | Single command | Low |
|
|
149
|
+
|
|
150
|
+
None of these is urgent. They become valuable when the top-level file count
|
|
151
|
+
exceeds ~110 or when a new hub joins the codebase.
|
|
152
|
+
|
|
153
|
+
## 5. References
|
|
154
|
+
|
|
155
|
+
- [`apps/web/AGENTS.md`](../AGENTS.md) §9 — architecture pointers
|
|
156
|
+
- [`apps/web/docs/component-selection-guide.md`](./component-selection-guide.md)
|
|
157
|
+
- [`.cursor/rules/exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc) — ask before adding new primitives
|
|
158
|
+
- [`.cursor/rules/exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc) — when to extract to `data-views/`
|
|
@@ -10,17 +10,17 @@ This document describes how list pages combine **views**, **toolbar** behavior,
|
|
|
10
10
|
|
|
11
11
|
| Need | Reuse | Where Placements uses it |
|
|
12
12
|
| --- | --- | --- |
|
|
13
|
-
| **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/
|
|
14
|
-
| **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/
|
|
15
|
-
| **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `
|
|
16
|
-
| **Board / list** | `PlacementsBoardView`, `
|
|
13
|
+
| **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/placements-client.tsx` + `components/templates/list-page.tsx` |
|
|
14
|
+
| **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/placements-table.tsx` |
|
|
15
|
+
| **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `placements-table.tsx` |
|
|
16
|
+
| **Board / list** | `PlacementsBoardView`, `PlacementListRowContent` (wrapped by `HubTable.renderListRow` → `DataRowList`) + same `useTableState` | `PlacementsTable` |
|
|
17
17
|
| **Page header** (primary CTA + More ⋯ + export) | `PlacementsPageHeader` or `TeamPageHeader` | `components/placements-page-header.tsx`, `components/team-page-header.tsx` |
|
|
18
|
-
| **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `
|
|
18
|
+
| **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `PlacementsClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
|
|
19
19
|
| **Team roster** | `TeamTable` — `DataTable` + `useTableState` + `TablePropertiesDrawer`; list/board/dashboard read **`tableState.rows`** | `components/team-table.tsx` |
|
|
20
20
|
| **Dashboard view (list tab)** | **`KeyMetrics`** (`variant="flat"` or `"card"`) — same KPI system as the template metrics strip; **do not** add ad-hoc `Card` grids for entity summaries | `TeamTable` dashboard branch, `lib/mock/team-kpi.ts` |
|
|
21
21
|
| **List hub metrics strip** | **`KeyMetrics variant="flat"`** — transparent cells, OKLCH brand glow only, border hairlines (**no** grey panel) | **`docs/kpi-flat-band-pattern.md`**, Placements / Team / Question bank clients |
|
|
22
22
|
| **Secondary panel chrome** | **`--secondary-panel-bg`** on **`NestedSecondaryPanelShell`** (lighter than sidebar, follows active product) | **`docs/shell-surface-elevation-pattern.md`**, Question bank |
|
|
23
|
-
| **Export** | `ExportDrawer` | `ListPageTemplate` export props; `
|
|
23
|
+
| **Export** | `ExportDrawer` | `ListPageTemplate` export props; `PlacementsClient` |
|
|
24
24
|
| **View body layout** (gutter + centered max-width for folder / icon / panel-style content) | **`ListPageViewFrame`** (`components/data-views/list-page-view-frame.tsx`, re-exported from `components/data-views`) | **`FolderGridView`** (uses the frame); **`QuestionBankOsFolderView`** — see **`AGENTS.md` §4.5** |
|
|
25
25
|
|
|
26
26
|
**Rules:** (1) Import and compose these components; pass **props** and **column defs** for your entity. (2) If something is missing, **extend the shared component** under `components/` (e.g. a new optional slot on `DataTableToolbar`) rather than copying markup into a single page. (3) Card-only or lightweight pages may use a smaller **Properties** sheet only when there is **no** table—otherwise use `TablePropertiesDrawer` with `DataTable` (see Team).
|
|
@@ -29,7 +29,7 @@ This document describes how list pages combine **views**, **toolbar** behavior,
|
|
|
29
29
|
|
|
30
30
|
If the page uses a **`DataTable`** (or equivalent data grid) as the main surface, it **must** sit under **`ListPageTemplate`** so users get the **views toolbar** (tabs, add view, per-tab settings). The default `ViewTab` entries should include at least one tab whose `viewType` is **`table`** when the primary experience is tabular data. **Do not** render a `DataTable` alone under only `PageHeader` + body.
|
|
31
31
|
|
|
32
|
-
- **Reference:** `
|
|
32
|
+
- **Reference:** `PlacementsClient` (Placements) and `TeamClient` (Team).
|
|
33
33
|
- **Rationale:** Consistent navigation, saved views, per-tab view type (table / list / board), and export at the template level.
|
|
34
34
|
|
|
35
35
|
## View layout frame (centered, reusable)
|
|
@@ -41,7 +41,7 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
|
|
|
41
41
|
## Architecture
|
|
42
42
|
|
|
43
43
|
- **Page shell** — `ListPageTemplate` owns the views toolbar (tabs), optional metrics, and export drawer. Content for the active tab is rendered via `renderContent`.
|
|
44
|
-
- **Per–lifecycle (or category) data** — `
|
|
44
|
+
- **Per–lifecycle (or category) data** — `PlacementsTable` swaps **columns** and **row sets** based on `lifecycleTabId` (e.g. All / Upcoming / Ongoing / Completed). Each lifecycle tab gets its **own** `PlacementsTable` instance (`key={tab.filterId}`) so `useTableState` resets correctly when columns change.
|
|
45
45
|
- **Shared table state** — `useTableState` holds sort, search, filters, grouping, column order/visibility/pins/widths, row height, gridlines, and pagination flags. **Table**, **list**, **board**, and **dashboard** all read the same state so switching view type keeps behavior aligned.
|
|
46
46
|
|
|
47
47
|
## Mock data and connected views
|
|
@@ -59,10 +59,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
|
|
|
59
59
|
|
|
60
60
|
| Concern | Table | List | Board | Dashboard (view tab) |
|
|
61
61
|
| --- | --- | --- | --- | --- |
|
|
62
|
-
| Primary surface | `DataTable` | `
|
|
62
|
+
| Primary surface | `DataTable` | `DataRowList` + entity row body (e.g. `PlacementListRowContent`) wired via `HubTable.renderListRow` | `PlacementsBoardView` / entity board | **`KeyMetrics`** (+ optional charts via shared dashboard components) |
|
|
63
63
|
| Data source | `useTableState` | **`tableState.rows`** | **`tableState.rows`** | **`tableState.rows`** via KPI helpers |
|
|
64
64
|
| Column headers / labels | `showColumnLabels` | Same source columns, list layout | Phase columns + optional board column menu | N/A (metrics from same columns/filters) |
|
|
65
|
-
| Row click / navigation | From `
|
|
65
|
+
| Row click / navigation | From `PlacementsTable` | From list shell | Card `onOpen` | N/A |
|
|
66
66
|
| Pagination | Optional `PaginationBar` + `CountSyncer` | Same pattern | N/A (board uses phase columns) | N/A |
|
|
67
67
|
|
|
68
68
|
## Toolbar and properties
|
|
@@ -99,10 +99,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
|
|
|
99
99
|
|
|
100
100
|
## Persistence
|
|
101
101
|
|
|
102
|
-
- **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `
|
|
103
|
-
- **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `
|
|
102
|
+
- **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `PlacementsClient` with `useLayoutEffect`, saved debounced on change. `ListPageTemplate` runs in **controlled** mode when `tabs` / `onTabsChange` / `activeTabId` / `onActiveTabChange` are passed.
|
|
103
|
+
- **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `PlacementsTable` with `useLayoutEffect`; saved debounced when those fields change.
|
|
104
104
|
|
|
105
|
-
To add a new page: copy the `
|
|
105
|
+
To add a new page: copy the `PlacementsClient` pattern (controlled `ListPageTemplate` + storage key namespace) or call `schedulePageSave` / `scheduleLifecycleSave` with your own keys.
|
|
106
106
|
|
|
107
107
|
## Rules of thumb
|
|
108
108
|
|
|
@@ -158,7 +158,7 @@ Canonical rules: **`AGENTS.md` §6.4**, root **`.cursor/rules/exxat-page-vs-draw
|
|
|
158
158
|
|
|
159
159
|
When a route is a **primary** destination in nav (main hub for an entity) **and** the dataset is **large** or **highly interactive**:
|
|
160
160
|
|
|
161
|
-
- Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`
|
|
161
|
+
- Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`PlacementsClient`** / **`PlacementsTable`** — not a minimal `PageHeader`-only layout.
|
|
162
162
|
- Smaller satellite pages may use **`PageHeader` + section content**; once the dataset grows past the dense-list threshold, add the toolbar rules above and consider promoting to the full template if the page becomes a main hub.
|
|
163
163
|
|
|
164
164
|
---
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Migration 0001 — `brand-deep` alias stabilization
|
|
2
|
+
|
|
3
|
+
> **Released in:** v0.2.18 · **Removed in:** — (no removal — alias is now official) · **Owner:** Exxat DS core
|
|
4
|
+
> **Type:** stabilization (clarifies an existing naming convention)
|
|
5
|
+
|
|
6
|
+
## Why
|
|
7
|
+
|
|
8
|
+
`bg-brand-deep` / `text-brand-deep` Tailwind utilities are used throughout
|
|
9
|
+
`CoachMark` and several skill docs, but the **only** declared primitive is
|
|
10
|
+
`--brand-color-deep`. The bridge `--color-brand-deep: var(--brand-color-deep)`
|
|
11
|
+
in `theme.css @theme inline` made the utilities work — but contributors kept
|
|
12
|
+
asking "is `--brand-deep` a real token or a typo of `--brand-color-deep`?".
|
|
13
|
+
|
|
14
|
+
This migration **does not rename anything**. It documents the alias as
|
|
15
|
+
**official** and codifies the rule for similar future cases:
|
|
16
|
+
|
|
17
|
+
> A Tailwind utility may use a **short, semantic alias** at the L2 bridge,
|
|
18
|
+
> distinct from the L1 primitive name, **only when the alias prevents an
|
|
19
|
+
> awkward utility class** (e.g. `bg-brand-color-deep` is unwieldy; `bg-brand-deep`
|
|
20
|
+
> reads naturally). The alias MUST be listed in `docs/token-taxonomy.md` and
|
|
21
|
+
> in the generated `hooks-index.json`.
|
|
22
|
+
|
|
23
|
+
Without this migration entry, future contributors might "fix" `bg-brand-deep`
|
|
24
|
+
by renaming it to `bg-brand-color-deep`, breaking every coach mark.
|
|
25
|
+
|
|
26
|
+
## Affected surface
|
|
27
|
+
|
|
28
|
+
| Surface | Was | Becomes |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| Tailwind utility | `bg-brand-deep`, `text-brand-deep` | **unchanged** (stabilized) |
|
|
31
|
+
| CSS custom prop (L2 bridge) | `--color-brand-deep` | **unchanged** (stabilized as alias) |
|
|
32
|
+
| CSS custom prop (L1 primitive) | `--brand-color-deep` | **unchanged** (canonical name) |
|
|
33
|
+
| Doc | _undocumented alias_ | Documented in `docs/token-taxonomy.md` §2.2 |
|
|
34
|
+
|
|
35
|
+
## Before
|
|
36
|
+
|
|
37
|
+
```css
|
|
38
|
+
/* packages/ui/src/theme.css */
|
|
39
|
+
@theme inline {
|
|
40
|
+
--color-brand-deep: var(--brand-color-deep); /* alias — was undocumented */
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:root {
|
|
44
|
+
--brand-color-deep: oklch(0.28 0.085 286.1); /* L1 primitive */
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
// packages/ui/src/components/ui/coach-mark.tsx — already correct
|
|
50
|
+
<div className="bg-brand-deep text-white">…</div>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The risk was that someone would "tidy up" `--color-brand-deep` to
|
|
54
|
+
`--color-brand-color-deep`, breaking `bg-brand-deep`.
|
|
55
|
+
|
|
56
|
+
## After
|
|
57
|
+
|
|
58
|
+
Same code; same tokens; **plus** an authoritative entry in
|
|
59
|
+
[`docs/token-taxonomy.md`](../token-taxonomy.md) §2.2 listing every L1 → L2
|
|
60
|
+
short-alias pair, and a regenerated [`packages/ui/tokens/hooks-index.json`](../../../packages/ui/tokens/hooks-index.json)
|
|
61
|
+
that exposes `--brand-color-deep` with `tailwindUtilities:
|
|
62
|
+
["bg-brand-deep", "text-brand-deep", …]` so tooling can discover the link.
|
|
63
|
+
|
|
64
|
+
## Migration recipe
|
|
65
|
+
|
|
66
|
+
### Automatic
|
|
67
|
+
|
|
68
|
+
None needed — this migration changes documentation only.
|
|
69
|
+
|
|
70
|
+
### Manual
|
|
71
|
+
|
|
72
|
+
For **future** short-alias additions, follow this pattern:
|
|
73
|
+
|
|
74
|
+
1. Declare the L1 primitive: `--brand-<name>: oklch(...)` in `:root` and any
|
|
75
|
+
theme overrides in `.dark` / `.theme-prism` / etc.
|
|
76
|
+
2. Declare the L2 alias in `@theme inline`: `--color-<short>: var(--brand-<name>)`.
|
|
77
|
+
3. Add a row to `docs/token-taxonomy.md` §2.2 listing the alias.
|
|
78
|
+
4. Run `pnpm --filter @exxatdesignux/ui tokens:index` and commit.
|
|
79
|
+
5. Use the alias **only** for the case where the long name is awkward; do
|
|
80
|
+
**not** create aliases for ergonomics alone.
|
|
81
|
+
|
|
82
|
+
## Verification
|
|
83
|
+
|
|
84
|
+
- [x] `pnpm --filter @exxatdesignux/ui tokens:index` runs and emits the alias
|
|
85
|
+
under `tailwindUtilities` for `--brand-color-deep`.
|
|
86
|
+
- [x] `docs/token-taxonomy.md` §2.2 lists `--brand-color-deep` and its alias.
|
|
87
|
+
- [x] `coach-mark.tsx` continues to render the deep-brand background.
|
|
88
|
+
|
|
89
|
+
## References
|
|
90
|
+
|
|
91
|
+
- `packages/ui/src/theme.css` — lines declaring `--brand-color-deep` and the alias
|
|
92
|
+
- `packages/ui/src/components/ui/coach-mark.tsx`
|
|
93
|
+
- `apps/web/docs/token-taxonomy.md` §2.2 (Brand)
|
|
94
|
+
- `apps/web/docs/blueprints/page-header.md` (uses `--brand-color-*` family)
|
|
95
|
+
- `.cursor/rules/exxat-token-discipline.mdc` (codifies the alias rule)
|