@exxatdesignux/ui 0.2.19 → 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 +60 -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 +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 +4 -15
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
- 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/consumer-upgrade-checklist.md +0 -20
- package/consumer-extras/patterns/data-views-pattern.md +17 -54
- 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 +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 -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 +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/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/.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 +104 -78
- package/template/app/(app)/dashboard/loading.tsx +15 -3
- package/template/app/(app)/dashboard/page.tsx +14 -2
- package/template/app/(app)/examples/page.tsx +0 -2
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/loading.tsx +18 -1
- package/template/app/(app)/question-bank/find/page.tsx +1 -2
- package/template/app/(app)/question-bank/layout.tsx +1 -1
- package/template/app/(app)/question-bank/library/page.tsx +1 -2
- package/template/app/(app)/question-bank/list/page.tsx +1 -2
- package/template/app/(app)/question-bank/new/page.tsx +15 -20
- package/template/app/(app)/question-bank/page.tsx +1 -2
- package/template/app/(app)/settings/page.tsx +5 -4
- package/template/app/globals.css +14 -16
- 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-board-view.tsx +142 -0
- package/template/components/compliance-client.tsx +92 -0
- package/template/components/compliance-page-header.tsx +89 -0
- package/template/components/compliance-table.tsx +468 -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-view-dashboard-charts-compliance.tsx +963 -0
- package/template/components/data-view-dashboard-charts-team.tsx +971 -0
- package/template/components/data-view-dashboard-charts.tsx +1503 -0
- 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 +50 -37
- 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/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 +28 -0
- package/template/components/new-placement-form.tsx +942 -0
- package/template/components/new-question-composer.tsx +456 -408
- 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 +250 -0
- package/template/components/placement-detail.tsx +438 -0
- package/template/components/placements-board-view.tsx +397 -0
- package/template/components/placements-client.tsx +220 -0
- package/template/components/placements-list-view.tsx +124 -0
- package/template/components/placements-page-header.tsx +166 -0
- package/template/components/placements-table-cells.test.tsx +22 -0
- package/template/components/placements-table-cells.tsx +173 -0
- package/template/components/placements-table-columns.tsx +210 -0
- package/template/components/placements-table.tsx +934 -0
- package/template/components/product-switcher.tsx +3 -4
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/question-bank-client.tsx +5 -5
- 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 +541 -431
- package/template/components/rotations-empty-state.tsx +50 -0
- package/template/components/rotations-panel-activator.tsx +8 -0
- 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} +59 -74
- 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} +50 -7
- 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-board-view.tsx +67 -0
- package/template/components/sites-client.tsx +154 -0
- package/template/components/sites-table.tsx +249 -0
- 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/team-board-view.tsx +122 -0
- package/template/components/team-client.tsx +100 -0
- package/template/components/team-page-header.tsx +92 -0
- package/template/components/team-table.tsx +553 -0
- 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 -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 +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 +17 -54
- package/template/docs/drawer-vs-dialog-pattern.md +1 -3
- 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/shell-surface-elevation-pattern.md +3 -5
- 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/command-menu-search-data.ts +27 -11
- 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 -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-placements-layout.ts +215 -0
- 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/list-page-table-properties.ts +1 -48
- package/template/lib/list-status-badges.ts +97 -4
- package/template/lib/mock/compliance-kpi.ts +61 -0
- package/template/lib/mock/compliance.ts +146 -0
- package/template/lib/mock/navigation.tsx +0 -9
- package/template/lib/mock/placements-kpi.ts +134 -0
- package/template/lib/mock/placements.ts +176 -0
- package/template/lib/mock/sites-directory.ts +16 -0
- package/template/lib/mock/sites-kpi.ts +25 -0
- package/template/lib/mock/team-kpi.ts +60 -0
- package/template/lib/mock/team.ts +118 -0
- package/template/lib/placement-board-card-layout.ts +79 -0
- package/template/lib/placements-supported-views.ts +12 -0
- package/template/lib/question-bank-supported-views.ts +0 -1
- 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/table-state-lifecycle.ts +2 -2
- package/template/lib/team-supported-views.ts +10 -0
- 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/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/secondary-panel/nav-link-rows.tsx +0 -83
- 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/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/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/page-loading-variant.ts +0 -40
- /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)
|
|
@@ -38,45 +38,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
|
|
|
38
38
|
|
|
39
39
|
**Handbook:** **`AGENTS.md` §4.5**. **Cursor:** **`.cursor/rules/exxat-list-page-view-shells.mdc`**. **Skill:** **`.cursor/skills/exxat-list-page-view-shells/SKILL.md`**. **Do not** wrap **`DataTable`** in the frame if that stacks padding with the table toolbar (**`AGENTS.md` §5**).
|
|
40
40
|
|
|
41
|
-
## View registry and connected bodies (extensibility)
|
|
42
|
-
|
|
43
|
-
To add a **new view type** without breaking existing hubs:
|
|
44
|
-
|
|
45
|
-
1. **Register once** — Add a tile in `lib/data-list-view.ts` (`DATA_LIST_VIEW_TILES`). Capabilities (hub KPI strip, render kind) derive automatically in `lib/data-list-view-registry.ts`.
|
|
46
|
-
2. **Build the body once** — Add or extend a generic surface under `components/data-views/` (e.g. `ListPageCalendarView`). Entity-specific wiring stays in props (`getEventDate`, board `renderCard`), not a second calendar implementation per hub.
|
|
47
|
-
3. **Declare what each hub supports** — `lib/<hub>-supported-views.ts` exports a `const` array; pass the same array to **`ListPageTemplate`** (`supportedViewTypes`), the hub table (`supportedViewTypes` → `TablePropertiesDrawerButton`), and rely on defaults if omitted. **Add view**, **⌘1–9** shortcuts, and **Properties → View type** tiles all use `dataListViewTilesForHub` / `dataListViewSelectionTilesForHub` so users cannot pick a view the hub never implemented.
|
|
48
|
-
4. **Route in the hub table with `ListPageConnectedViewBody`** — Switch on **`getDataListViewRenderKind(view)`**, not raw `view === "…"` chains. Pass one renderer per kind the hub supports via **`defineHubViewRenderers(MY_HUB_SUPPORTED_VIEWS, { … })`** (`lib/hub-connected-view-renderers.ts`) so dev builds warn when a supported view has no body. **Do not** use a default branch that renders dashboard/KPIs; missing renderers show `ListPageViewNotConfigured`.
|
|
49
|
-
5. **Let the template own hub chrome** — `ListPageTemplate` hides the metrics strip on calendar/dashboard via `showsListPageHubMetricsStrip(activeTab.viewType)`. Hub clients pass `showMetrics` only; they do not reimplement per-tab KPI visibility.
|
|
50
|
-
6. **Panel / Miller columns** — Reuse **`ListPageFolderColumnsPanel`** (`components/data-views/list-page-folder-columns-panel.tsx`) for folder + record columns; hub-specific chrome (folder colors, actions) lives in a thin wrapper (e.g. `QuestionBankFolderColumnsPanel`). **Do not** export question-bank-only tree/folder nav from the generic `data-views` barrel.
|
|
51
|
-
|
|
52
|
-
```tsx
|
|
53
|
-
// lib/my-hub-supported-views.ts
|
|
54
|
-
export const MY_HUB_SUPPORTED_VIEWS = ["table", "list", "calendar"] as const satisfies readonly DataListViewType[]
|
|
55
|
-
|
|
56
|
-
// my-hub-client.tsx
|
|
57
|
-
<ListPageTemplate supportedViewTypes={MY_HUB_SUPPORTED_VIEWS} showMetrics={showMetrics} … />
|
|
58
|
-
|
|
59
|
-
// my-hub-table.tsx
|
|
60
|
-
import { defineHubViewRenderers } from "@/lib/hub-connected-view-renderers"
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<ListPageConnectedViewBody
|
|
64
|
-
view={view}
|
|
65
|
-
hubLabel="My hub"
|
|
66
|
-
renderers={defineHubViewRenderers(MY_HUB_SUPPORTED_VIEWS, {
|
|
67
|
-
"data-table": <DataTable … />,
|
|
68
|
-
"calendar-with-toolbar": toolbarShell(<ListPageCalendarView rows={tableState.rows} getEventDate={…} />),
|
|
69
|
-
})}
|
|
70
|
-
/>
|
|
71
|
-
)
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Checklist for a new view type:** registry tile → `data-views/` component → update each `*-supported-views.ts` that should expose it → add renderer in each `*-table.tsx` (via `defineHubViewRenderers`) → Properties drawer copy in `table-properties/drawer.tsx` if needed → `table-state-lifecycle` picks up types via `DATA_LIST_VIEW_TILES` (no separate allowlist).
|
|
75
|
-
|
|
76
41
|
## Architecture
|
|
77
42
|
|
|
78
43
|
- **Page shell** — `ListPageTemplate` owns the views toolbar (tabs), optional metrics, and export drawer. Content for the active tab is rendered via `renderContent`.
|
|
79
|
-
- **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.
|
|
80
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.
|
|
81
46
|
|
|
82
47
|
## Mock data and connected views
|
|
@@ -94,10 +59,10 @@ return (
|
|
|
94
59
|
|
|
95
60
|
| Concern | Table | List | Board | Dashboard (view tab) |
|
|
96
61
|
| --- | --- | --- | --- | --- |
|
|
97
|
-
| 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) |
|
|
98
63
|
| Data source | `useTableState` | **`tableState.rows`** | **`tableState.rows`** | **`tableState.rows`** via KPI helpers |
|
|
99
64
|
| Column headers / labels | `showColumnLabels` | Same source columns, list layout | Phase columns + optional board column menu | N/A (metrics from same columns/filters) |
|
|
100
|
-
| Row click / navigation | From `
|
|
65
|
+
| Row click / navigation | From `PlacementsTable` | From list shell | Card `onOpen` | N/A |
|
|
101
66
|
| Pagination | Optional `PaginationBar` + `CountSyncer` | Same pattern | N/A (board uses phase columns) | N/A |
|
|
102
67
|
|
|
103
68
|
## Toolbar and properties
|
|
@@ -134,10 +99,10 @@ return (
|
|
|
134
99
|
|
|
135
100
|
## Persistence
|
|
136
101
|
|
|
137
|
-
- **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `
|
|
138
|
-
- **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.
|
|
139
104
|
|
|
140
|
-
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.
|
|
141
106
|
|
|
142
107
|
## Rules of thumb
|
|
143
108
|
|
|
@@ -181,13 +146,11 @@ Reference: `components/placements-page-header.tsx`, `components/team-page-header
|
|
|
181
146
|
|
|
182
147
|
**When to use a new page (route):** The flow is **primary**, **long-form**, **multi-step**, or should have its **own URL** / bookmark / history **without** the parent page behind it — e.g. full create/edit, wizards, or detail that *is* the task.
|
|
183
148
|
|
|
184
|
-
**
|
|
185
|
-
|
|
186
|
-
**Rule of thumb:** **Context + quick** → **drawer**; **blocking short choice** → **dialog**; **primary / long / wizard / settings** → **focused workflow route** (or other dedicated page).
|
|
149
|
+
**Rule of thumb:** **Context + quick** → **drawer**; **blocking short choice** → **dialog**; **otherwise** → **new page**.
|
|
187
150
|
|
|
188
151
|
**Modal vs side panel (same route):** When the overlay stays on the same URL, prefer **`docs/drawer-vs-dialog-pattern.md`** and **`.cursor/rules/exxat-drawer-vs-dialog.mdc`** — drawers keep the hub visible; dialogs trap focus for confirms.
|
|
189
152
|
|
|
190
|
-
Canonical rules: **`AGENTS.md` §6.4**,
|
|
153
|
+
Canonical rules: **`AGENTS.md` §6.4**, root **`.cursor/rules/exxat-page-vs-drawer.mdc`**, **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**.
|
|
191
154
|
|
|
192
155
|
---
|
|
193
156
|
|
|
@@ -195,7 +158,7 @@ Canonical rules: **`AGENTS.md` §6.4**, **§14**, root **`.cursor/rules/exxat-pa
|
|
|
195
158
|
|
|
196
159
|
When a route is a **primary** destination in nav (main hub for an entity) **and** the dataset is **large** or **highly interactive**:
|
|
197
160
|
|
|
198
|
-
- 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.
|
|
199
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.
|
|
200
163
|
|
|
201
164
|
---
|
|
@@ -207,7 +170,7 @@ When a route is a **primary** destination in nav (main hub for an entity) **and*
|
|
|
207
170
|
- [ ] **>10 items** → search, filter, sort, properties (per surface type above).
|
|
208
171
|
- [ ] **Has data to export** → **More** menu with **Export** + shared `ExportDrawer` pattern.
|
|
209
172
|
- [ ] **Primary + large / main hub** → `ListPageTemplate`-style shell where applicable.
|
|
210
|
-
- [ ] **Page vs drawer vs dialog (§6.4)** — Quick with parent **context** → drawer/sheet; **blocking** confirm → **dialog**; primary or long flows → **
|
|
173
|
+
- [ ] **Page vs drawer vs dialog (§6.4)** — Quick with parent **context** → drawer/sheet; **blocking** confirm → **dialog**; primary or long flows → **new route** (`docs/drawer-vs-dialog-pattern.md`).
|
|
211
174
|
- [ ] **Primary button** → `Button` default variant (`size="lg"` for parity with Placements), not outline.
|
|
212
175
|
- [ ] **Dashboard view tab** → `KeyMetrics` + shared KPI helpers from **`tableState.rows`**; no duplicate one-off metric cards.
|
|
213
176
|
- [ ] **Data view charts** → `ChartFigure` + `chart-keyboard-selection`; layout persistence via **`data-view-dashboard-storage`** (see `AGENTS.md` §4.3).
|
|
@@ -30,15 +30,13 @@
|
|
|
30
30
|
|
|
31
31
|
Use when the work is **primary**, **long**, **multi-step**, or deserves its **own URL** — see **`exxat-page-vs-drawer.mdc`** and **`AGENTS.md` §6.4**.
|
|
32
32
|
|
|
33
|
-
For **large forms, wizards, and sectioned settings**, use **`FocusedWorkflowPageTemplate`** and body layouts — **`docs/focused-workflow-page-pattern.md`**, **`AGENTS.md` §14**, **`.cursor/skills/exxat-focused-workflow-page/SKILL.md`**.
|
|
34
|
-
|
|
35
33
|
## Quick matrix
|
|
36
34
|
|
|
37
35
|
| Need | Drawer | Dialog | Route |
|
|
38
36
|
| --- | --- | --- | --- |
|
|
39
37
|
| Keep hub visible | Yes | No (blocks) | No |
|
|
40
38
|
| Short confirm / alert | Rare | Yes | Overkill |
|
|
41
|
-
| Long form / wizard | Cramped | No | Yes
|
|
39
|
+
| Long form / wizard | Cramped | No | Yes |
|
|
42
40
|
| Properties tied to a table | Yes | Too small | Optional |
|
|
43
41
|
|
|
44
42
|
## Accessibility
|
|
@@ -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)
|