@exxatdesignux/ui 0.2.19 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +662 -7
- package/bin/sync-extras.mjs +116 -29
- package/consumer-extras/README.md +42 -7
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +43 -0
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
- package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +3 -3
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +5 -16
- package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
- package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +19 -34
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +10 -12
- package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
- package/consumer-extras/handbook/HANDBOOK.md +187 -0
- package/consumer-extras/handbook/glossary.md +58 -0
- package/consumer-extras/handbook/reference-implementations.md +153 -0
- package/consumer-extras/handbook/voice-and-tone.md +262 -0
- package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
- package/consumer-extras/patterns/command-menu-pattern.md +1 -1
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
- package/consumer-extras/patterns/data-views-pattern.md +31 -66
- package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
- package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
- package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
- package/dist/components/data-table/filter-date-calendar.js +280 -0
- package/dist/components/data-table/filter-date-calendar.js.map +1 -0
- package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
- package/dist/components/data-table/filter-text-value-input.js +561 -0
- package/dist/components/data-table/filter-text-value-input.js.map +1 -0
- package/dist/components/data-table/index.d.ts +45 -0
- package/dist/components/data-table/index.js +3085 -0
- package/dist/components/data-table/index.js.map +1 -0
- package/dist/components/data-table/pagination.d.ts +28 -0
- package/dist/components/data-table/pagination.js +3264 -0
- package/dist/components/data-table/pagination.js.map +1 -0
- package/dist/components/data-table/types.d.ts +84 -0
- package/dist/components/data-table/types.js +3 -0
- package/dist/components/data-table/types.js.map +1 -0
- package/dist/components/data-table/use-table-state.d.ts +116 -0
- package/dist/components/data-table/use-table-state.js +670 -0
- package/dist/components/data-table/use-table-state.js.map +1 -0
- package/dist/components/data-views/board-card-primitives.d.ts +22 -0
- package/dist/components/data-views/board-card-primitives.js +84 -0
- package/dist/components/data-views/board-card-primitives.js.map +1 -0
- package/dist/components/data-views/data-row-list.d.ts +33 -0
- package/dist/components/data-views/data-row-list.js +106 -0
- package/dist/components/data-views/data-row-list.js.map +1 -0
- package/dist/components/data-views/finder-panel-view.d.ts +54 -0
- package/dist/components/data-views/finder-panel-view.js +388 -0
- package/dist/components/data-views/finder-panel-view.js.map +1 -0
- package/dist/components/data-views/folder-grid-view.d.ts +22 -0
- package/dist/components/data-views/folder-grid-view.js +58 -0
- package/dist/components/data-views/folder-grid-view.js.map +1 -0
- package/dist/components/data-views/hub-table.d.ts +173 -0
- package/dist/components/data-views/hub-table.js +5783 -0
- package/dist/components/data-views/hub-table.js.map +1 -0
- package/dist/components/data-views/index.d.ts +27 -0
- package/dist/components/data-views/index.js +6797 -0
- package/dist/components/data-views/index.js.map +1 -0
- package/dist/components/data-views/list-page-board-card.d.ts +72 -0
- package/dist/components/data-views/list-page-board-card.js +264 -0
- package/dist/components/data-views/list-page-board-card.js.map +1 -0
- package/dist/components/data-views/list-page-board-template.d.ts +24 -0
- package/dist/components/data-views/list-page-board-template.js +137 -0
- package/dist/components/data-views/list-page-board-template.js.map +1 -0
- package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
- package/dist/components/data-views/list-page-connected-view-body.js +116 -0
- package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
- package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
- package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
- package/dist/components/data-views/list-page-tree-column-header.js +22 -0
- package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
- package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
- package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
- package/dist/components/data-views/os-folder-glyph.js +104 -0
- package/dist/components/data-views/os-folder-glyph.js.map +1 -0
- package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
- package/dist/components/data-views/outline-tree-menu.js +131 -0
- package/dist/components/data-views/outline-tree-menu.js.map +1 -0
- package/dist/components/table-properties/column-row.d.ts +22 -0
- package/dist/components/table-properties/column-row.js +153 -0
- package/dist/components/table-properties/column-row.js.map +1 -0
- package/dist/components/table-properties/draggable-list.d.ts +24 -0
- package/dist/components/table-properties/draggable-list.js +53 -0
- package/dist/components/table-properties/draggable-list.js.map +1 -0
- package/dist/components/table-properties/drawer-button.d.ts +110 -0
- package/dist/components/table-properties/drawer-button.js +2748 -0
- package/dist/components/table-properties/drawer-button.js.map +1 -0
- package/dist/components/table-properties/drawer.d.ts +100 -0
- package/dist/components/table-properties/drawer.js +2595 -0
- package/dist/components/table-properties/drawer.js.map +1 -0
- package/dist/components/table-properties/filter-card.d.ts +24 -0
- package/dist/components/table-properties/filter-card.js +854 -0
- package/dist/components/table-properties/filter-card.js.map +1 -0
- package/dist/components/table-properties/index.d.ts +14 -0
- package/dist/components/table-properties/index.js +2768 -0
- package/dist/components/table-properties/index.js.map +1 -0
- package/dist/components/table-properties/sort-card.d.ts +20 -0
- package/dist/components/table-properties/sort-card.js +102 -0
- package/dist/components/table-properties/sort-card.js.map +1 -0
- package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
- package/dist/components/templates/dedicated-search-landing-template.js +254 -0
- package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
- package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
- package/dist/components/templates/dedicated-search-results-template.js +16 -0
- package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
- package/dist/components/templates/index.d.ts +9 -0
- package/dist/components/templates/index.js +2720 -0
- package/dist/components/templates/index.js.map +1 -0
- package/dist/components/templates/list-page.d.ts +83 -0
- package/dist/components/templates/list-page.js +2433 -0
- package/dist/components/templates/list-page.js.map +1 -0
- package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
- package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
- package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +10 -0
- package/dist/components/ui/accordion.js +74 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +37 -0
- package/dist/components/ui/alert-dialog.js +201 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +84 -0
- package/dist/components/ui/avatar.js +328 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +49 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/banner.d.ts +62 -0
- package/dist/components/ui/banner.js +364 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +14 -0
- package/dist/components/ui/breadcrumb.js +114 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +16 -0
- package/dist/components/ui/button.js +59 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +13 -0
- package/dist/components/ui/calendar.js +238 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +14 -0
- package/dist/components/ui/card.js +102 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/chart.d.ts +58 -0
- package/dist/components/ui/chart.js +292 -0
- package/dist/components/ui/chart.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +23 -0
- package/dist/components/ui/checkbox.js +155 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/coach-mark.d.ts +27 -0
- package/dist/components/ui/coach-mark.js +306 -0
- package/dist/components/ui/coach-mark.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +8 -0
- package/dist/components/ui/collapsible.js +35 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +36 -0
- package/dist/components/ui/command.js +274 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +32 -0
- package/dist/components/ui/context-menu.js +245 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/date-picker-field.d.ts +38 -0
- package/dist/components/ui/date-picker-field.js +550 -0
- package/dist/components/ui/date-picker-field.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.js +200 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dot-pattern.d.ts +21 -0
- package/dist/components/ui/dot-pattern.js +139 -0
- package/dist/components/ui/dot-pattern.js.map +1 -0
- package/dist/components/ui/drag-handle-grip.d.ts +10 -0
- package/dist/components/ui/drag-handle-grip.js +15 -0
- package/dist/components/ui/drag-handle-grip.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +16 -0
- package/dist/components/ui/drawer.js +125 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +45 -0
- package/dist/components/ui/dropdown-menu.js +353 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/export-drawer.d.ts +11 -0
- package/dist/components/ui/export-drawer.js +1658 -0
- package/dist/components/ui/export-drawer.js.map +1 -0
- package/dist/components/ui/field.d.ts +30 -0
- package/dist/components/ui/field.js +249 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +28 -0
- package/dist/components/ui/form.js +110 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +9 -0
- package/dist/components/ui/hover-card.js +43 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +20 -0
- package/dist/components/ui/input-group.js +219 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-mask.d.ts +39 -0
- package/dist/components/ui/input-mask.js +118 -0
- package/dist/components/ui/input-mask.js.map +1 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +30 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +20 -0
- package/dist/components/ui/kbd.js +45 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-metrics-context.d.ts +19 -0
- package/dist/components/ui/key-metrics-context.js +26 -0
- package/dist/components/ui/key-metrics-context.js.map +1 -0
- package/dist/components/ui/key-metrics.d.ts +131 -0
- package/dist/components/ui/key-metrics.js +1015 -0
- package/dist/components/ui/key-metrics.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.js +28 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/list-page-view-frame.d.ts +22 -0
- package/dist/components/ui/list-page-view-frame.js +24 -0
- package/dist/components/ui/list-page-view-frame.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +51 -0
- package/dist/components/ui/page-header.js +372 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/payment-card-fields.d.ts +10 -0
- package/dist/components/ui/payment-card-fields.js +80 -0
- package/dist/components/ui/payment-card-fields.js.map +1 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +47 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +29 -0
- package/dist/components/ui/radio-group.js +190 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +16 -0
- package/dist/components/ui/resizable.js +51 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +8 -0
- package/dist/components/ui/scroll-area.js +66 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/select.js +186 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/selection-tile-grid.d.ts +52 -0
- package/dist/components/ui/selection-tile-grid.js +347 -0
- package/dist/components/ui/selection-tile-grid.js.map +1 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +33 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +18 -0
- package/dist/components/ui/sheet.js +181 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +94 -0
- package/dist/components/ui/sidebar.js +805 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +5 -0
- package/dist/components/ui/skeleton.js +22 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +7 -0
- package/dist/components/ui/slider.js +66 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +6 -0
- package/dist/components/ui/sonner.js +38 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/status-badge.d.ts +38 -0
- package/dist/components/ui/status-badge.js +77 -0
- package/dist/components/ui/status-badge.js.map +1 -0
- package/dist/components/ui/table.d.ts +13 -0
- package/dist/components/ui/table.js +115 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +15 -0
- package/dist/components/ui/tabs.js +93 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.js +25 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tip.d.ts +12 -0
- package/dist/components/ui/tip.js +61 -0
- package/dist/components/ui/tip.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +14 -0
- package/dist/components/ui/toggle-group.js +104 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle-switch.d.ts +10 -0
- package/dist/components/ui/toggle-switch.js +33 -0
- package/dist/components/ui/toggle-switch.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +13 -0
- package/dist/components/ui/toggle.js +51 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.js +68 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components/ui/view-segmented-control.d.ts +31 -0
- package/dist/components/ui/view-segmented-control.js +167 -0
- package/dist/components/ui/view-segmented-control.js.map +1 -0
- package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
- package/dist/hooks/use-app-theme.d.ts +24 -0
- package/dist/hooks/use-app-theme.js +286 -0
- package/dist/hooks/use-app-theme.js.map +1 -0
- package/dist/hooks/use-coach-mark.d.ts +86 -0
- package/dist/hooks/use-coach-mark.js +218 -0
- package/dist/hooks/use-coach-mark.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +29 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-mod-key-label.d.ts +6 -0
- package/dist/hooks/use-mod-key-label.js +25 -0
- package/dist/hooks/use-mod-key-label.js.map +1 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +13421 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/compose-refs.d.ts +6 -0
- package/dist/lib/compose-refs.js +17 -0
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/conditional-rule-match.d.ts +30 -0
- package/dist/lib/conditional-rule-match.js +66 -0
- package/dist/lib/conditional-rule-match.js.map +1 -0
- package/dist/lib/data-list-display-options.d.ts +26 -0
- package/dist/lib/data-list-display-options.js +14 -0
- package/dist/lib/data-list-display-options.js.map +1 -0
- package/dist/lib/data-list-view-registry.d.ts +2 -0
- package/dist/lib/data-list-view-registry.js +102 -0
- package/dist/lib/data-list-view-registry.js.map +1 -0
- package/dist/lib/data-list-view-surface.d.ts +2 -0
- package/dist/lib/data-list-view-surface.js +80 -0
- package/dist/lib/data-list-view-surface.js.map +1 -0
- package/dist/lib/data-list-view.d.ts +21 -0
- package/dist/lib/data-list-view.js +25 -0
- package/dist/lib/data-list-view.js.map +1 -0
- package/dist/lib/date-filter.d.ts +22 -0
- package/dist/lib/date-filter.js +61 -0
- package/dist/lib/date-filter.js.map +1 -0
- package/dist/lib/dev-log.d.ts +8 -0
- package/dist/lib/dev-log.js +10 -0
- package/dist/lib/dev-log.js.map +1 -0
- package/dist/lib/dropdown-menu-surface.d.ts +14 -0
- package/dist/lib/dropdown-menu-surface.js +6 -0
- package/dist/lib/dropdown-menu-surface.js.map +1 -0
- package/dist/lib/editable-target.d.ts +12 -0
- package/dist/lib/editable-target.js +12 -0
- package/dist/lib/editable-target.js.map +1 -0
- package/dist/lib/list-page-table-properties.d.ts +35 -0
- package/dist/lib/list-page-table-properties.js +81 -0
- package/dist/lib/list-page-table-properties.js.map +1 -0
- package/dist/lib/raf-throttle.d.ts +23 -0
- package/dist/lib/raf-throttle.js +27 -0
- package/dist/lib/raf-throttle.js.map +1 -0
- package/dist/lib/row-height.d.ts +16 -0
- package/dist/lib/row-height.js +10 -0
- package/dist/lib/row-height.js.map +1 -0
- package/dist/lib/table-properties-types.d.ts +83 -0
- package/dist/lib/table-properties-types.js +19 -0
- package/dist/lib/table-properties-types.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +83 -19
- package/src/components/data-table/filter-date-calendar.tsx +38 -0
- package/src/components/data-table/filter-text-value-input.tsx +77 -0
- package/src/components/data-table/index.tsx +1678 -0
- package/src/components/data-table/pagination.tsx +259 -0
- package/src/components/data-table/types.ts +96 -0
- package/src/components/data-table/use-table-state.ts +767 -0
- package/src/components/data-views/board-card-primitives.tsx +93 -0
- package/src/components/data-views/data-row-list.tsx +183 -0
- package/src/components/data-views/finder-panel-view.tsx +405 -0
- package/src/components/data-views/folder-grid-view.tsx +86 -0
- package/src/components/data-views/hub-table.tsx +606 -0
- package/src/components/data-views/index.ts +28 -0
- package/src/components/data-views/list-page-board-card.tsx +192 -0
- package/src/components/data-views/list-page-board-template.tsx +122 -0
- package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
- package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
- package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
- package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
- package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
- package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
- package/src/components/data-views/os-folder-glyph.tsx +141 -0
- package/src/components/data-views/outline-tree-menu.tsx +157 -0
- package/src/components/table-properties/column-row.tsx +90 -0
- package/src/components/table-properties/draggable-list.ts +54 -0
- package/src/components/table-properties/drawer-button.tsx +300 -0
- package/src/components/table-properties/drawer.tsx +1148 -0
- package/src/components/table-properties/filter-card.tsx +251 -0
- package/src/components/table-properties/index.ts +36 -0
- package/src/components/table-properties/sort-card.tsx +63 -0
- package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
- package/src/components/templates/dedicated-search-results-template.tsx +19 -0
- package/src/components/templates/index.ts +33 -0
- package/src/components/templates/list-page.tsx +602 -0
- package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
- package/src/components/ui/accordion.tsx +92 -0
- package/src/components/ui/alert-dialog.tsx +221 -0
- package/src/components/ui/avatar.tsx +13 -2
- package/src/components/ui/banner.tsx +2 -2
- package/src/components/ui/button.tsx +4 -4
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/coach-mark.tsx +1 -1
- package/src/components/ui/context-menu.tsx +291 -0
- package/src/components/ui/date-picker-field.tsx +2 -2
- package/src/components/ui/dot-pattern.tsx +183 -0
- package/src/components/ui/export-drawer.tsx +375 -0
- package/src/components/ui/hover-card.tsx +66 -0
- package/src/components/ui/key-metrics-context.tsx +78 -0
- package/src/components/ui/key-metrics.tsx +1133 -0
- package/src/components/ui/list-page-view-frame.tsx +64 -0
- package/src/components/ui/page-header.tsx +244 -0
- package/src/components/ui/payment-card-fields.tsx +2 -2
- package/src/components/ui/resizable.tsx +68 -0
- package/src/components/ui/scroll-area.tsx +72 -0
- package/src/components/ui/selection-tile-grid.tsx +9 -2
- package/src/components/ui/sidebar.tsx +84 -12
- package/src/components/ui/slider.tsx +83 -0
- package/src/globals.css +2201 -7
- package/src/globals.d.ts +20 -0
- package/src/index.ts +68 -1
- package/src/lib/conditional-rule-match.ts +119 -0
- package/src/lib/data-list-display-options.ts +35 -0
- package/src/lib/data-list-view-registry.ts +104 -0
- package/src/lib/data-list-view-surface.ts +83 -0
- package/src/lib/data-list-view.ts +47 -0
- package/src/lib/dev-log.ts +10 -0
- package/src/lib/editable-target.ts +20 -0
- package/src/lib/list-page-table-properties.ts +48 -0
- package/src/lib/raf-throttle.ts +45 -0
- package/src/lib/row-height.ts +19 -0
- package/src/lib/table-properties-types.ts +98 -0
- package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
- package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
- package/template/.cursor/rules/exxat-command-menu.mdc +2 -2
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +7 -7
- package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
- package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +7 -7
- package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
- package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +135 -103
- package/template/app/(app)/columns/page.tsx +11 -0
- package/template/app/(app)/dashboard/loading.tsx +15 -3
- package/template/app/(app)/dashboard/page.tsx +14 -2
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/library/all/page.tsx +11 -0
- package/template/app/(app)/library/find/page.tsx +12 -0
- package/template/app/(app)/{question-bank → library}/layout.tsx +17 -17
- package/template/app/(app)/library/list/page.tsx +12 -0
- package/template/app/(app)/library/new/page.tsx +45 -0
- package/template/app/(app)/library/page.tsx +11 -0
- package/template/app/(app)/loading.tsx +18 -1
- package/template/app/(app)/settings/page.tsx +5 -4
- package/template/app/(app)/tokens-themes/page.tsx +11 -0
- package/template/app/globals.css +14 -16
- package/template/components/ask-leo-composer.tsx +2 -2
- package/template/components/ask-leo-sidebar.tsx +5 -1
- package/template/components/brand-color-picker.tsx +2 -2
- package/template/components/charts-overview.tsx +1 -1
- package/template/components/columns-client.tsx +158 -0
- package/template/components/columns-showcase.tsx +541 -0
- package/template/components/dashboard-report-charts.tsx +1 -1
- package/template/components/dashboard-tabs.tsx +1 -1
- package/template/components/data-table/filter-date-calendar.tsx +1 -38
- package/template/components/data-table/filter-text-value-input.tsx +1 -77
- package/template/components/data-table/index.tsx +1 -1634
- package/template/components/data-table/pagination.tsx +1 -255
- package/template/components/data-table/types.ts +1 -94
- package/template/components/data-table/use-table-state.test.ts +420 -0
- package/template/components/data-table/use-table-state.ts +1 -758
- package/template/components/data-views/board-card-primitives.tsx +1 -93
- package/template/components/data-views/data-row-list.tsx +1 -183
- package/template/components/data-views/finder-panel-view.tsx +1 -405
- package/template/components/data-views/folder-grid-view.tsx +1 -86
- package/template/components/data-views/hub-table.tsx +1 -0
- package/template/components/data-views/index.ts +77 -38
- package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
- package/template/components/data-views/list-page-board-card.tsx +1 -192
- package/template/components/data-views/list-page-board-template.tsx +1 -122
- package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
- package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
- package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
- package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
- package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
- package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
- package/template/components/data-views/list-page-view-frame.tsx +5 -53
- package/template/components/data-views/os-folder-glyph.tsx +1 -129
- package/template/components/data-views/outline-tree-menu.tsx +1 -157
- package/template/components/data-views/table-cells.tsx +673 -0
- package/template/components/export-drawer.test.tsx +71 -0
- package/template/components/export-drawer.tsx +1 -375
- package/template/components/exxat-product-logo.tsx +5 -5
- package/template/components/folder-details-shell.tsx +11 -11
- package/template/components/hub-tree-panel-view.tsx +26 -26
- package/template/components/invite-collaborators-drawer.tsx +3 -3
- package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
- package/template/components/key-metrics.tsx +1 -1063
- package/template/components/leo-insight-indicator.tsx +2 -2
- package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
- package/template/components/{question-bank-client.tsx → library-client.tsx} +83 -83
- package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
- package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
- package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +44 -44
- package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +16 -16
- package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
- package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
- package/template/components/library-panel-activator.tsx +8 -0
- package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +63 -63
- package/template/components/library-table.tsx +839 -0
- package/template/components/list-hub-status-badge.tsx +2 -2
- package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +489 -441
- package/template/components/onboarding/index.ts +9 -0
- package/template/components/onboarding/onboarding-01.tsx +1 -1
- package/template/components/onboarding/onboarding-02.tsx +1 -1
- package/template/components/onboarding/onboarding-03.tsx +1 -1
- package/template/components/onboarding/onboarding-04.tsx +1 -1
- package/template/components/page-header.tsx +8 -226
- package/template/components/product-switcher.tsx +3 -4
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/settings-appearance-card.tsx +3 -4
- package/template/components/settings-client.tsx +15 -59
- package/template/components/settings-form-row.tsx +4 -9
- package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
- package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +114 -73
- package/template/components/sidebar/index.ts +16 -0
- package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
- package/template/components/sidebar/secondary-panel.tsx +316 -0
- package/template/components/sidebar/sidebar-auto-collapse.tsx +27 -0
- package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +2 -1
- package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
- package/template/components/site-header.tsx +1 -1
- package/template/components/table-properties/column-row.tsx +1 -90
- package/template/components/table-properties/draggable-list.ts +1 -49
- package/template/components/table-properties/drawer-button.tsx +1 -262
- package/template/components/table-properties/drawer.tsx +1 -1166
- package/template/components/table-properties/filter-card.tsx +1 -251
- package/template/components/table-properties/sort-card.tsx +1 -59
- package/template/components/table-properties/types.ts +28 -71
- package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
- package/template/components/templates/dedicated-search-results-template.tsx +1 -19
- package/template/components/templates/discovery-hub-template.tsx +1 -1
- package/template/components/templates/list-page.tsx +1 -608
- package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
- package/template/components/templates/new-focus-template.tsx +659 -0
- package/template/components/templates/secondary-panel-hub-template.tsx +2 -2
- package/template/components/tokens-secondary-nav.tsx +192 -0
- package/template/components/tokens-themes-client.tsx +476 -0
- package/template/components/tokens-themes-section.tsx +386 -0
- package/template/components/ui/accordion.tsx +1 -0
- package/template/components/ui/alert-dialog.tsx +1 -0
- package/template/components/ui/context-menu.tsx +1 -0
- package/template/components/ui/dot-pattern.tsx +1 -183
- package/template/components/ui/hover-card.tsx +1 -0
- package/template/components/ui/resizable.tsx +1 -68
- package/template/components/ui/scroll-area.tsx +1 -0
- package/template/components/ui/slider.tsx +1 -0
- package/template/docs/HANDBOOK.md +187 -0
- package/template/docs/blueprints/README.md +86 -0
- package/template/docs/blueprints/_template.md +91 -0
- package/template/docs/blueprints/board-card.md +123 -0
- package/template/docs/blueprints/data-table.md +139 -0
- package/template/docs/blueprints/key-metrics.md +128 -0
- package/template/docs/blueprints/list-page-template.md +123 -0
- package/template/docs/blueprints/page-header.md +130 -0
- package/template/docs/collaboration-access-pattern.md +7 -7
- package/template/docs/command-menu-pattern.md +1 -1
- package/template/docs/component-selection-guide.md +224 -0
- package/template/docs/components-audit-2026-05.md +158 -0
- package/template/docs/data-views-pattern.md +31 -66
- package/template/docs/drawer-vs-dialog-pattern.md +1 -3
- package/template/docs/glossary.md +58 -0
- package/template/docs/kpi-flat-band-pattern.md +3 -3
- package/template/docs/kpi-trend-pattern.md +18 -3
- package/template/docs/large-dataset-strategy.md +155 -0
- package/template/docs/library-hub-header-pattern.md +25 -0
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
- package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
- package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
- package/template/docs/migrations/README.md +100 -0
- package/template/docs/migrations/_template.md +64 -0
- package/template/docs/reference-implementations.md +151 -0
- package/template/docs/shell-surface-elevation-pattern.md +3 -5
- package/template/docs/token-taxonomy.md +416 -0
- package/template/docs/voice-and-tone.md +262 -0
- package/template/eslint.config.mjs +27 -0
- package/template/hooks/use-secondary-panel-hub-nav.ts +11 -11
- package/template/lib/ask-leo-route-context.ts +6 -18
- package/template/lib/coach-mark-registry.ts +0 -16
- package/template/lib/command-menu-config.ts +5 -13
- package/template/lib/command-menu-search-data.ts +8 -23
- package/template/lib/conditional-rule-match.ts +6 -97
- package/template/lib/data-list-display-options.ts +1 -49
- package/template/lib/data-list-view-registry.ts +1 -104
- package/template/lib/data-list-view-surface.ts +1 -83
- package/template/lib/data-list-view.ts +1 -47
- package/template/lib/data-view-dashboard-storage.ts +35 -38
- package/template/lib/dev-log.ts +1 -8
- package/template/lib/editable-target.ts +1 -10
- package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
- package/template/lib/library-dedicated-search.ts +19 -0
- package/template/lib/library-hub-search.ts +90 -0
- package/template/lib/library-nav.ts +477 -0
- package/template/lib/library-recent-searches.ts +22 -0
- package/template/lib/{question-bank-supported-views.ts → library-supported-views.ts} +2 -3
- package/template/lib/list-page-table-properties.ts +1 -48
- package/template/lib/list-status-badges.ts +16 -11
- package/template/lib/mock/dashboard.ts +1 -1
- package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
- package/template/lib/mock/library-header-collaborators.ts +54 -0
- package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
- package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
- package/template/lib/mock/library.ts +249 -0
- package/template/lib/mock/navigation.tsx +32 -35
- package/template/lib/raf-throttle.ts +1 -45
- package/template/lib/row-height.ts +4 -10
- package/template/lib/sidebar-state-cookie.ts +11 -2
- package/template/lib/table-state-lifecycle.ts +3 -3
- package/template/next.config.mjs +7 -4
- package/template/package.json +1 -0
- package/template/tests/setup.ts +25 -0
- package/consumer-extras/AGENTS.md +0 -76
- package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
- package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
- package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
- package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
- package/src/components/ui/button-group.tsx +0 -81
- package/src/theme.css +0 -16
- package/src/tokens/README.md +0 -15
- package/src/tokens/base.css +0 -337
- package/src/tokens/high-contrast.css +0 -1195
- package/src/tokens/layers.css +0 -224
- package/src/tokens/tailwind-bridge.css +0 -118
- package/src/tokens/themes.css +0 -201
- package/template/app/(app)/data-list/layout.tsx +0 -43
- package/template/app/(app)/data-list/page.tsx +0 -10
- package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
- package/template/app/(app)/examples/page.tsx +0 -43
- package/template/app/(app)/question-bank/find/page.tsx +0 -13
- package/template/app/(app)/question-bank/library/page.tsx +0 -12
- package/template/app/(app)/question-bank/list/page.tsx +0 -13
- package/template/app/(app)/question-bank/new/page.tsx +0 -50
- package/template/app/(app)/question-bank/page.tsx +0 -12
- package/template/components/app-route-loading.tsx +0 -14
- package/template/components/dashboard-onboarding-gallery.tsx +0 -13
- package/template/components/dashboard-onboarding.tsx +0 -21
- package/template/components/data-views/list-page-calendar-view.tsx +0 -593
- package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
- package/template/components/examples/focused-workflow-showcase.tsx +0 -183
- package/template/components/list-hub-board-view.tsx +0 -68
- package/template/components/list-hub-client.tsx +0 -186
- package/template/components/list-hub-list-view.tsx +0 -36
- package/template/components/list-hub-panel-activator.tsx +0 -8
- package/template/components/list-hub-secondary-nav.tsx +0 -121
- package/template/components/list-hub-table.tsx +0 -336
- package/template/components/question-bank-folder-columns-panel.tsx +0 -104
- package/template/components/question-bank-list-view.tsx +0 -53
- package/template/components/question-bank-panel-activator.tsx +0 -8
- package/template/components/question-bank-table.tsx +0 -729
- package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
- package/template/components/secondary-panel.tsx +0 -220
- package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
- package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
- package/template/components/secondary-panels/registry.tsx +0 -15
- package/template/components/section-cards.tsx +0 -106
- package/template/components/sidebar-auto-collapse.tsx +0 -23
- package/template/components/templates/focused-workflow-layouts.tsx +0 -448
- package/template/components/templates/focused-workflow-page-template.tsx +0 -69
- package/template/components/templates/page-loading-shell.tsx +0 -262
- package/template/components/ui/button-group.tsx +0 -1
- package/template/docs/consumer-app-pattern.md +0 -39
- package/template/docs/focused-workflow-page-pattern.md +0 -84
- package/template/docs/question-bank-hub-header-pattern.md +0 -25
- package/template/lib/list-hub-nav.ts +0 -121
- package/template/lib/mock/list-hub-directory.ts +0 -27
- package/template/lib/mock/list-hub-kpi.ts +0 -27
- package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
- package/template/lib/mock/question-bank.ts +0 -249
- package/template/lib/page-loading-variant.ts +0 -40
- package/template/lib/question-bank-dedicated-search.ts +0 -19
- package/template/lib/question-bank-hub-search.ts +0 -90
- package/template/lib/question-bank-nav.ts +0 -477
- package/template/lib/question-bank-recent-searches.ts +0 -22
- /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
- /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
- /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
- /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
- /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
package/bin/sync-extras.mjs
CHANGED
|
@@ -2,12 +2,20 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Consumer: copy packaged design-system extras into the app repo.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Writes (and overwrites) ONLY:
|
|
6
6
|
* - `.cursor/skills/<bundled exxat-* skill folders>/`
|
|
7
|
-
* -
|
|
7
|
+
* - `.claude/skills/<bundled exxat-* skill folders>/` (same SKILL.md shape;
|
|
8
|
+
* Claude Code reads from `.claude/skills/` instead of `.cursor/skills/`)
|
|
9
|
+
* - `.cursor/rules/<bundled exxat-*.mdc rule files>`
|
|
10
|
+
* - `docs/exxat-ds/*.md` (pattern reference docs + consumer-upgrade-checklist.md)
|
|
11
|
+
* - `docs/exxat-ds/handbook/*.md` (HANDBOOK, glossary, voice-and-tone, reference-implementations)
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* The CLI is **namespaced** — it only touches files starting with `exxat-`
|
|
14
|
+
* (skills + rules) so a consumer's own non-Exxat rules/skills are preserved.
|
|
15
|
+
* Product code under `app/`, `pages/`, `src/`, plus the consumer's `AGENTS.md`
|
|
16
|
+
* and any of their own docs are never modified.
|
|
17
|
+
*
|
|
18
|
+
* Run after every `npm install @exxatdesignux/ui@…` / `pnpm update @exxatdesignux/ui`.
|
|
11
19
|
*
|
|
12
20
|
* npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras
|
|
13
21
|
*/
|
|
@@ -20,46 +28,125 @@ const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
|
20
28
|
const pkgRoot = resolve(__dirname, "..")
|
|
21
29
|
const cwd = process.cwd()
|
|
22
30
|
|
|
23
|
-
const
|
|
24
|
-
|
|
31
|
+
const SOURCES = {
|
|
32
|
+
skills: join(pkgRoot, "consumer-extras", "cursor-skills"),
|
|
33
|
+
rules: join(pkgRoot, "consumer-extras", "cursor-rules"),
|
|
34
|
+
patterns: join(pkgRoot, "consumer-extras", "patterns"),
|
|
35
|
+
handbook: join(pkgRoot, "consumer-extras", "handbook"),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const DESTINATIONS = {
|
|
39
|
+
cursorSkills: join(cwd, ".cursor", "skills"),
|
|
40
|
+
claudeSkills: join(cwd, ".claude", "skills"),
|
|
41
|
+
cursorRules: join(cwd, ".cursor", "rules"),
|
|
42
|
+
patterns: join(cwd, "docs", "exxat-ds"),
|
|
43
|
+
handbook: join(cwd, "docs", "exxat-ds", "handbook"),
|
|
44
|
+
}
|
|
25
45
|
|
|
26
|
-
|
|
27
|
-
|
|
46
|
+
let wrote = 0
|
|
47
|
+
let skipped = 0
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
/** Replace `dest` with `src` (directory) — preserves only what we own. */
|
|
50
|
+
function replaceDir(src, dest) {
|
|
51
|
+
if (existsSync(dest)) rmSync(dest, { recursive: true, force: true })
|
|
52
|
+
cpSync(src, dest, { recursive: true })
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Skills are bundled as directories like `cursor-skills/exxat-board-cards/SKILL.md`.
|
|
57
|
+
* Copy every `exxat-*` directory into the destination, replacing any prior copy.
|
|
58
|
+
* The same source tree is written to BOTH Cursor and Claude (identical SKILL.md
|
|
59
|
+
* shape, two readers) so one upgrade lights up both clients.
|
|
60
|
+
*/
|
|
61
|
+
function syncSkillsTo(label, dest) {
|
|
62
|
+
if (!existsSync(SOURCES.skills)) {
|
|
63
|
+
console.error("[sync-extras] missing packaged skills:", SOURCES.skills)
|
|
35
64
|
process.exit(1)
|
|
36
65
|
}
|
|
37
|
-
mkdirSync(
|
|
38
|
-
for (const name of readdirSync(
|
|
39
|
-
const src = join(
|
|
66
|
+
mkdirSync(dest, { recursive: true })
|
|
67
|
+
for (const name of readdirSync(SOURCES.skills)) {
|
|
68
|
+
const src = join(SOURCES.skills, name)
|
|
40
69
|
if (!statSync(src).isDirectory()) continue
|
|
41
70
|
if (!name.startsWith("exxat-")) continue
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
71
|
+
replaceDir(src, join(dest, name))
|
|
72
|
+
console.log(`[sync-extras] wrote ${label}/${name}/`)
|
|
73
|
+
wrote++
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Rules ship as flat `.mdc` files under `consumer-extras/cursor-rules/`.
|
|
79
|
+
* Only files starting with `exxat-` are copied so the consumer's own rules
|
|
80
|
+
* (and any other vendor's rules) survive an upgrade untouched.
|
|
81
|
+
*/
|
|
82
|
+
function syncRules() {
|
|
83
|
+
if (!existsSync(SOURCES.rules)) {
|
|
84
|
+
console.warn("[sync-extras] no packaged cursor-rules (optional)")
|
|
85
|
+
skipped++
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
mkdirSync(DESTINATIONS.cursorRules, { recursive: true })
|
|
89
|
+
for (const name of readdirSync(SOURCES.rules)) {
|
|
90
|
+
const src = join(SOURCES.rules, name)
|
|
91
|
+
if (!statSync(src).isFile()) continue
|
|
92
|
+
if (!name.startsWith("exxat-") || !name.endsWith(".mdc")) continue
|
|
93
|
+
cpSync(src, join(DESTINATIONS.cursorRules, name))
|
|
94
|
+
console.log(`[sync-extras] wrote .cursor/rules/${name}`)
|
|
95
|
+
wrote++
|
|
46
96
|
}
|
|
47
97
|
}
|
|
48
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Pattern docs (data-views-pattern, command-menu-pattern, …) + the
|
|
101
|
+
* `consumer-upgrade-checklist.md` land flat in `docs/exxat-ds/`.
|
|
102
|
+
*/
|
|
49
103
|
function syncPatterns() {
|
|
50
|
-
if (!existsSync(
|
|
51
|
-
console.warn("[sync-extras] no packaged patterns (optional)
|
|
104
|
+
if (!existsSync(SOURCES.patterns)) {
|
|
105
|
+
console.warn("[sync-extras] no packaged patterns (optional)")
|
|
106
|
+
skipped++
|
|
52
107
|
return
|
|
53
108
|
}
|
|
54
|
-
mkdirSync(
|
|
55
|
-
for (const name of readdirSync(
|
|
56
|
-
const src = join(
|
|
109
|
+
mkdirSync(DESTINATIONS.patterns, { recursive: true })
|
|
110
|
+
for (const name of readdirSync(SOURCES.patterns)) {
|
|
111
|
+
const src = join(SOURCES.patterns, name)
|
|
57
112
|
if (!statSync(src).isFile()) continue
|
|
58
|
-
cpSync(src, join(
|
|
113
|
+
cpSync(src, join(DESTINATIONS.patterns, name))
|
|
59
114
|
console.log(`[sync-extras] wrote docs/exxat-ds/${name}`)
|
|
115
|
+
wrote++
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Handbook tier (HANDBOOK · glossary · voice-and-tone · reference-implementations)
|
|
121
|
+
* lands in a nested `docs/exxat-ds/handbook/` so the patterns dir stays flat
|
|
122
|
+
* and the handbook's internal cross-links resolve.
|
|
123
|
+
*
|
|
124
|
+
* The bundled handbook files are stage-rewritten copies of the workspace
|
|
125
|
+
* source (`apps/web/docs/*.md`) — links to shipped patterns use `../`, links
|
|
126
|
+
* to unshipped neighbours (blueprints, token-taxonomy, etc.) are absolute
|
|
127
|
+
* GitHub URLs so they continue to work in the consumer's repo.
|
|
128
|
+
*/
|
|
129
|
+
function syncHandbook() {
|
|
130
|
+
if (!existsSync(SOURCES.handbook)) {
|
|
131
|
+
console.warn("[sync-extras] no packaged handbook (optional)")
|
|
132
|
+
skipped++
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
mkdirSync(DESTINATIONS.handbook, { recursive: true })
|
|
136
|
+
for (const name of readdirSync(SOURCES.handbook)) {
|
|
137
|
+
const src = join(SOURCES.handbook, name)
|
|
138
|
+
if (!statSync(src).isFile()) continue
|
|
139
|
+
cpSync(src, join(DESTINATIONS.handbook, name))
|
|
140
|
+
console.log(`[sync-extras] wrote docs/exxat-ds/handbook/${name}`)
|
|
141
|
+
wrote++
|
|
60
142
|
}
|
|
61
143
|
}
|
|
62
144
|
|
|
63
|
-
|
|
145
|
+
syncSkillsTo(".cursor/skills", DESTINATIONS.cursorSkills)
|
|
146
|
+
syncSkillsTo(".claude/skills", DESTINATIONS.claudeSkills)
|
|
147
|
+
syncRules()
|
|
64
148
|
syncPatterns()
|
|
65
|
-
|
|
149
|
+
syncHandbook()
|
|
150
|
+
|
|
151
|
+
console.log(`[sync-extras] Done. ${wrote} files / dirs written; ${skipped} optional sources missing.`)
|
|
152
|
+
console.log("[sync-extras] Product routes and app content were not modified.")
|
|
@@ -6,16 +6,21 @@ touching product routes or pages.
|
|
|
6
6
|
|
|
7
7
|
| Path in this tarball | After `exxat-ui sync-extras` in your repo |
|
|
8
8
|
|----------------------|-------------------------------------------|
|
|
9
|
-
| `CHANGELOG.md` (package root) |
|
|
10
|
-
| `cursor-skills/exxat-*` | `.cursor/skills/exxat-*` (replaced) |
|
|
11
|
-
| `
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
9
|
+
| `CHANGELOG.md` (package root) | Stays in `node_modules/…` — read for release notes; **`exxat-ui changelog`** prints it |
|
|
10
|
+
| `cursor-skills/exxat-*` | `.cursor/skills/exxat-*` **and** `.claude/skills/exxat-*` (replaced; same `SKILL.md` shape, two readers) |
|
|
11
|
+
| `cursor-rules/exxat-*.mdc` | `.cursor/rules/exxat-*.mdc` (replaced) — binding **MUST / MUST NOT** files |
|
|
12
|
+
| `patterns/*.md` | `docs/exxat-ds/*.md` (replaced) — pattern docs + **`consumer-upgrade-checklist.md`** |
|
|
13
|
+
| `handbook/*.md` | `docs/exxat-ds/handbook/*.md` (replaced) — `HANDBOOK`, `glossary`, `voice-and-tone`, `reference-implementations` |
|
|
14
|
+
|
|
15
|
+
The CLI is **namespaced**: it only touches files starting with `exxat-` (skills + rules)
|
|
16
|
+
so a consumer's own non-Exxat rules / skills are preserved. Product code under `app/`,
|
|
17
|
+
`pages/`, `src/`, plus the consumer's `AGENTS.md` and any of their own docs are never
|
|
18
|
+
modified.
|
|
14
19
|
|
|
15
20
|
**Components and hooks** still come only from `node_modules/@exxatdesignux/ui`
|
|
16
21
|
via normal semver installs — `sync-extras` does not copy TS source into your app.
|
|
17
22
|
|
|
18
|
-
**Maintainers** (this monorepo): when skills or web docs change, run:
|
|
23
|
+
**Maintainers** (this monorepo): when skills, rules, or web docs change, run:
|
|
19
24
|
|
|
20
25
|
```bash
|
|
21
26
|
pnpm --filter @exxatdesignux/ui vendor:consumer-extras
|
|
@@ -23,4 +28,34 @@ pnpm --filter @exxatdesignux/ui vendor:consumer-extras
|
|
|
23
28
|
|
|
24
29
|
…then bump `packages/ui` version and publish so consumers get the new bundle.
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
## What lands where (full install map)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
<consumer-repo>/
|
|
35
|
+
├── .cursor/
|
|
36
|
+
│ ├── rules/exxat-*.mdc ← binding MUST / MUST NOT (cursor-rules/)
|
|
37
|
+
│ └── skills/exxat-*/SKILL.md ← agent workflows + checklists (cursor-skills/)
|
|
38
|
+
├── .claude/
|
|
39
|
+
│ └── skills/exxat-*/SKILL.md ← Claude mirror of the same skills (cursor-skills/)
|
|
40
|
+
└── docs/
|
|
41
|
+
└── exxat-ds/
|
|
42
|
+
├── *-pattern.md ← narrative pattern docs (patterns/)
|
|
43
|
+
├── consumer-upgrade-checklist.md
|
|
44
|
+
└── handbook/
|
|
45
|
+
├── HANDBOOK.md
|
|
46
|
+
├── glossary.md
|
|
47
|
+
├── voice-and-tone.md
|
|
48
|
+
└── reference-implementations.md
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Note on handbook link rewriting
|
|
52
|
+
|
|
53
|
+
The bundled handbook files (`handbook/*.md`) are stage-rewritten copies of the
|
|
54
|
+
workspace source (`apps/web/docs/*.md`). Inter-doc links are normalised at
|
|
55
|
+
bundle time:
|
|
56
|
+
|
|
57
|
+
- Links to files we ship → relative (`./glossary.md`, `../data-views-pattern.md`)
|
|
58
|
+
- Links to files we don't ship (blueprints, `token-taxonomy.md`, `component-selection-guide.md`, `lib/*`, root `AGENTS.md`) → absolute GitHub URLs
|
|
59
|
+
|
|
60
|
+
This keeps every link clickable from the consumer's `docs/exxat-ds/handbook/`
|
|
61
|
+
directory without requiring them to clone the workspace.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — WCAG 2.1 AA, ARIA tablists, 24px targets, contrast; see AGENTS.md §8 and exxat-accessibility skill
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — accessibility (binding summary)
|
|
7
|
+
|
|
8
|
+
**Full checklist (ARIA, touch targets, color, sidebar badges, audit follow-ups):** repo **`.cursor/skills/exxat-accessibility/SKILL.md`**.
|
|
9
|
+
|
|
10
|
+
**Product rules in prose + checklist:** **`apps/web/AGENTS.md` §8**.
|
|
11
|
+
|
|
12
|
+
## Non‑negotiables
|
|
13
|
+
|
|
14
|
+
1. **Target:** **WCAG 2.1 Level AA** (2.2 where noted — e.g. target size).
|
|
15
|
+
2. **`role="tablist"`** — only **`role="tab"`** (or equivalent) as direct tab semantics. **MUST NOT** put `role="button"`, menus (`aria-haspopup`), or other controls **inside** the same `tablist` container.
|
|
16
|
+
3. **Composite view switchers** (tabs + per-tab menu + remove): use **`role="toolbar"`** + **`aria-label`**; **`aria-pressed`** on toggles — **MUST NOT** misuse `tab`/`tablist` for those controls.
|
|
17
|
+
4. **Touch targets (2.5.8):** interactive controls **≥ 24×24 CSS px** or **24px** spacing so hit areas do not overlap — use **`min-h-6 min-w-6` / `size-6`** for icon-only targets; avoid **`size-4`** as the sole target.
|
|
18
|
+
5. **Contrast:** normal text **≥ 4.5:1**; UI components / focus where required **≥ 3:1**; muted text on tinted surfaces use tokens against the correct surface (e.g. sidebar), not only `--background`.
|
|
19
|
+
6. **Minimum text size:** visible product copy **≥ 11px** — use **`text-xs`** or larger; **MUST NOT** use arbitrary Tailwind font sizes below that (see **`apps/web/AGENTS.md` §8.3**, **`apps/web/app/globals.css`** `--text-xs`).
|
|
20
|
+
7. **Dialogs / sheets / drawers:** must expose a **Title** (`DialogTitle` / `SheetTitle` / `DrawerTitle`); use **`sr-only`** if visually hidden (shadcn pattern).
|
|
21
|
+
8. **Format hints are persistent, not placeholders (SC 3.3.2 Labels or Instructions, 1.3.1).** Any field that expects a specific format — **date, time, phone, currency, ID pattern, GPA scale, URL, hours, unit-bearing numbers** — MUST show the format as **persistent helper text** via **`FormDescription`** (or the field's description slot). Placeholders disappear on focus and are unreliable for AT, so **MUST NOT** be the sole carrier of the format. Example: GPA → "Out of 4.0"; Date → "MM/DD/YYYY"; Phone → "+1 (555) 555-0100"; Student ID → "STU-YYYY-####". Pair with `inputMode`, `pattern`, or a picker primitive (e.g. `DatePickerField`) where applicable; never rely on a free-text date input.
|
|
22
|
+
9. **Every icon that communicates information MUST have a text alternative** — not just icon-only buttons. Three cases (SC 1.1.1 Non-text Content, 3.3.2 Labels or Instructions, 2.4.6 Headings and Labels):
|
|
23
|
+
|
|
24
|
+
- **A. Decorative icon next to text that already names it** (e.g. `<i class="fa-light fa-calendar-days" aria-hidden /> 12/14/2025 – 12/20/2025`) → icon MUST be **`aria-hidden`**; MUST NOT add `aria-label` (screen readers would announce the meaning twice). No tooltip needed.
|
|
25
|
+
- **B. Informational icon standing alone** — a calendar glyph used to mean "date range", clock for "updated at", pin for "site", graduation cap for "student", trending arrow for direction, status dot, icon-only chart legend — MUST pair **`role="img"` + `aria-label`** (or `aria-labelledby` on a wrapping element) with a visible **`Tooltip`** so sighted users who don't recognise the glyph learn the meaning. The icon wrapper MUST be keyboard-focusable (`tabIndex={0}` on the `span[role="img"]`) so the tooltip opens on focus.
|
|
26
|
+
- **C. Interactive icon-only button/link** (close `×`, chevron, overflow `⋯`, sort direction, filter chip dismiss, copy, Ask Leo toggle, row actions) → MUST pair **`aria-label`** on the `<button>` with a wrapping **`Tooltip`**. `aria-label` alone is NOT enough — sighted mouse users and keyboard users rely on the tooltip to discover what a bare icon does.
|
|
27
|
+
|
|
28
|
+
In all three cases, the inner `<i>` / `<svg>` MUST be `aria-hidden`; the accessible name lives on the wrapping element. Tooltip text MUST match the accessible name. Narrow exception: a chevron inside a labelled composite (`Select`, `Combobox`) where the parent control already names the whole thing. See **§8.6 (Case A/B/C)** in `AGENTS.md` and the accessibility skill.
|
|
29
|
+
10. **Keyboard shortcut hints inside buttons** MUST use **`<Kbd variant="bare">`** (no background, no border, inherits `currentColor` at 70%). The default `tile` variant is reserved for **tooltips** and **menu `shortcut=` slots**. Glue multi-key chords into one bare kbd (e.g. `<Kbd variant="bare">⌘⌥K</Kbd>`), not one tile per key. Reference: `Next` / `Back` buttons in `new-placement-form.tsx`; see `.cursor/rules/exxat-kbd-shortcuts.mdc`.
|
|
30
|
+
|
|
31
|
+
After changing **views toolbar** or **tab** UIs, re-run **axe** (or equivalent) on **Placements** (or the affected page).
|
|
32
|
+
|
|
33
|
+
**Charts:** Keyboard exploration uses **`ChartFigure`**; selected data points should have **visible** focus feedback — see skill **§ Charts (keyboard exploration)** and **`AGENTS.md` §4.3** (`chart-keyboard-selection`).
|
|
34
|
+
|
|
35
|
+
## See also
|
|
36
|
+
|
|
37
|
+
- **`apps/web/AGENTS.md`** §8 — accessibility in project context.
|
|
38
|
+
- **`.cursor/rules/exxat-kbd-shortcuts.mdc`** — shortcuts paired with `Kbd` hints.
|
|
39
|
+
- **`apps/web/.cursor/rules/exxat-dashboard-view-charts.mdc`** — Data view chart keyboard parity.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — board (kanban) cards; ListPageBoardCard, badges, primitives
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — board cards
|
|
7
|
+
|
|
8
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.4** and **`.cursor/skills/exxat-board-cards/SKILL.md`**.
|
|
9
|
+
|
|
10
|
+
## MUST
|
|
11
|
+
|
|
12
|
+
1. **Shell** — Use **`ListPageBoardCard`** from **`components/data-views/list-page-board-card.tsx`** for product board cards (same **`Card` `size="sm"`** treatment as Placements).
|
|
13
|
+
2. **Hierarchy** — **Title** (`ListPageBoardCardTitleRow`) → optional **avatar** (`ListPageBoardCardAvatar` on `trailing`) → **status row** (`ListPageBoardCardBadgeRow` + **`ListHubStatusBadge`** **`surface="board"`**) when the entity has status → **body** (`ListPageBoardCardBody`) with **`BoardCardTwoLineBlock`** / **`BoardCardIconRow`** (**`components/data-views/board-card-primitives.tsx`**).
|
|
14
|
+
3. **Status** — **Placements** (**`PLACEMENT_STATUS_*`** + **`StatusBadge`** in **`placements-table-cells.tsx`**), **Team / Compliance / Library** (**`ListHubStatusBadge`** + entity maps): all labels/tints/icons live in **`lib/list-status-badges.ts`**. **`surface="table"`** in grid/list rows, **`surface="board"`** on kanban cards. Prefer semantic **`LIST_HUB_STATUS_TINT_*`**. **MUST NOT** use **`uppercase`** on those chips.
|
|
15
|
+
4. **Simple column boards** — **`ListPageBoardTemplate`** + **`renderCard`**; compose **`ListPageBoardCard`** inside **`renderCard`**.
|
|
16
|
+
|
|
17
|
+
## MUST NOT
|
|
18
|
+
|
|
19
|
+
- Duplicate **`ListPageBoardCard`** with ad-hoc **`<button>`** + border/padding classes for the same hub pattern.
|
|
20
|
+
- Show **status** only as plain text in the **body** when the hub uses **status** elsewhere — use the **badge row** + shared maps.
|
|
21
|
+
|
|
22
|
+
## See also
|
|
23
|
+
|
|
24
|
+
- **`apps/web/AGENTS.md` §4.4**, **§13** checklist
|
|
25
|
+
- **`apps/web/docs/data-views-pattern.md`** — Board UI reuse
|
|
26
|
+
- **`lib/initials-from-name.ts`** — owner initials when mock has no `initials` field
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Do not duplicate parent navigation with a Back control when breadcrumbs exist
|
|
3
|
+
globs: apps/web/**/*.tsx
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Exxat DS — breadcrumbs and back navigation
|
|
8
|
+
|
|
9
|
+
## MUST NOT
|
|
10
|
+
|
|
11
|
+
When a page uses **`SiteHeader`** with **`breadcrumbs`** (a visible trail such as Patterns → Library → current title), **do not** add a **“Back to …”** link or button in the page body that goes to the same parent as the breadcrumb segment. Breadcrumbs already provide hierarchy and one-click navigation up the tree.
|
|
12
|
+
|
|
13
|
+
## MAY
|
|
14
|
+
|
|
15
|
+
- Rely on **`SiteHeader`** breadcrumbs only for returning to parent routes.
|
|
16
|
+
- Use a **single** explicit back affordance on flows that **omit** breadcrumbs by design (e.g. full-screen step, modal route) where product copy requires it.
|
|
17
|
+
|
|
18
|
+
## See also
|
|
19
|
+
|
|
20
|
+
- `components/site-header.tsx`
|
|
21
|
+
- `components/templates/primary-page-template.tsx`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — when to use cards vs DataTable rows vs simple list rows.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — cards vs rows vs lists
|
|
7
|
+
|
|
8
|
+
## MUST
|
|
9
|
+
|
|
10
|
+
1. **Dense, comparable records (10+)** — **`DataTable`** + **`ListPageTemplate`** + **`useTableState`** for primary hubs (**`exxat-data-tables.mdc`**).
|
|
11
|
+
2. **Board / tiles / visual browse** — **`ListPageBoardCard`** (and related shells), **`ListPageViewFrame`** for non-table bodies (**`exxat-board-cards.mdc`**, **`exxat-list-page-view-shells.mdc`**).
|
|
12
|
+
3. **One dataset** — Cards and tables read the **same** **`tableState.rows`**; no forked mock arrays (**`exxat-centralized-list-dataset.mdc`**).
|
|
13
|
+
|
|
14
|
+
## MUST NOT
|
|
15
|
+
|
|
16
|
+
- Replace a **primary data hub grid** with a **card wall** when users need column sort, filter chips, and export parity.
|
|
17
|
+
- Introduce a **second table stack** for the same entity.
|
|
18
|
+
|
|
19
|
+
## See also
|
|
20
|
+
|
|
21
|
+
- **`docs/card-vs-rows-pattern.md`** · **`.cursor/skills/exxat-card-vs-list-rows/SKILL.md`**
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Single source of truth for hub rows, KPIs, table properties, detail views, and shared view chrome — dataset + presentation consistency across DataListViewType surfaces
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — centralized list hub dataset + presentation
|
|
7
|
+
|
|
8
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.1** and **§4.5** (connected views + view shells), **`docs/data-views-pattern.md`**, **`.cursor/rules/exxat-list-page-connected-views.mdc`**, and **`.cursor/rules/exxat-list-page-view-shells.mdc`**. This rule tightens **where data lives** and **where reusable view chrome lives** so **table, list, board, dashboard, folder, panel, tree, and inspectors** never drift.
|
|
9
|
+
|
|
10
|
+
## Single dataset
|
|
11
|
+
|
|
12
|
+
1. **Rows** — One typed collection per entity (**`lib/mock/<entity>.ts`** until API wiring). **MUST NOT** maintain a second parallel array (e.g. “tree only” or “panel only”) with overlapping IDs unless it is a **derived view** (computed from the same source via selectors).
|
|
13
|
+
|
|
14
|
+
2. **`useTableState`** — One instance per tab table; **`tableState.rows`** is the **only** filtered/sorted row bag that **list / board / dashboard / folder / panel / tree** surfaces read. **MUST NOT** bypass filters by importing raw mock arrays into alternate views.
|
|
15
|
+
|
|
16
|
+
3. **Detail / inspector / finder / split-panel bodies** — Resolve the active record by **`id`** (or stable key) against **`tableState.rows`** (or the same upstream state that feeds **`useTableState`**). **MUST NOT** hydrate inspector fields from ad-hoc literals when the row already exists on the dataset.
|
|
17
|
+
|
|
18
|
+
4. **Columns & table “properties”** — Column defs **`accessorKey` / cell renderers** map to the **same** row interface as KPI helpers and board cards. **MUST NOT** introduce incompatible duplicate TypeScript shapes per view.
|
|
19
|
+
|
|
20
|
+
5. **`TablePropertiesDrawer`** — Stays wired to the **`DataTable`** that owns **`useTableState`** (**§4.2**): **`currentView`**, **`onViewChange`**, column visibility/density — all reflect manipulation of the **same** underlying rows.
|
|
21
|
+
|
|
22
|
+
6. **Labels / status / chips** — Prefer shared maps (**`lib/list-status-badges.ts`**, **`lib/data-list-view.ts`** tiles, entity-specific maps **next to** **`lib/mock/<entity>.ts`**). **MUST NOT** fork label strings or badge colors per view file.
|
|
23
|
+
|
|
24
|
+
7. **KPIs & charts** — **`MetricItem`** / **`MetricInsight`** builders take **`tableState.rows`** (or equivalent filtered list). Same inputs as the grid after search/filters.
|
|
25
|
+
|
|
26
|
+
## Centralized presentation (layout + components)
|
|
27
|
+
|
|
28
|
+
8. **`ListPageViewFrame`** — Non-**`DataTable`** view bodies (**folder**, **panel**, icon grids, comparable dashboard sections) **MUST** use **`ListPageViewFrame`** (and exported max-width constants) instead of copy-pasted **`mx-*` / `max-w-*`** per hub (**`exxat-list-page-view-shells.mdc`**).
|
|
29
|
+
|
|
30
|
+
9. **`components/data-views/`** — New **record-bearing** view layouts (**grids**, **OS folder**, **finder split**) **MUST** land as **generic** building blocks under **`data-views/`** with **`rows`**, **`getRowId`**, render props — hub **`TeamTable`** / **`LibraryTable`** **only** wires props and branch logic (**`AGENTS.md` §4.5**).
|
|
31
|
+
|
|
32
|
+
10. **Hub client composition** — One **`*-client.tsx`** owns **`useTableState`**, passes **`tableState.rows`** into every **`viewType`** branch, and mounts **template** slots (**metrics**, **export**, **`beforeSiteHeader`**) — **MUST NOT** split the same hub across multiple clients with different row sources.
|
|
33
|
+
|
|
34
|
+
## MUST NOT
|
|
35
|
+
|
|
36
|
+
- Ship alternate mock datasets per **`DataListViewType`** for the same hub without documenting them as **computed derivatives** of one canonical list.
|
|
37
|
+
- Duplicate entity fields in inspector-only types that contradict **`LibraryItem`** / **`Placement`** / etc.; extend the shared interface **once**.
|
|
38
|
+
|
|
39
|
+
## See also
|
|
40
|
+
|
|
41
|
+
- **`.cursor/skills/exxat-centralized-list-dataset/SKILL.md`** — workflow + checklist.
|
|
42
|
+
- **`.cursor/rules/exxat-table-properties-drawer.mdc`** — **`currentView`** / **`onViewChange`**.
|
|
43
|
+
- **`exxat-list-page-connected-views.mdc`** — toolbar + **`tableState.rows`**.
|
|
44
|
+
- **`exxat-list-page-view-shells.mdc`** — **`ListPageViewFrame`** + **`data-views/`** extraction.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Shared hubs — collaboration header, invite sheet, library access vs directory roles
|
|
3
|
+
globs: apps/web/components/**/*.{tsx,ts},apps/web/lib/**/*.{tsx,ts}
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Exxat DS — collaboration & access
|
|
8
|
+
|
|
9
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.7** and **`apps/web/docs/collaboration-access-pattern.md`**.
|
|
10
|
+
|
|
11
|
+
## MUST
|
|
12
|
+
|
|
13
|
+
1. **Shared hubs** — Use **`PageHeader`** **`variant="collaboration"`** with **`collaborators`** (`PageHeaderCollaborator[]`) and optional **`accessInfo`**.
|
|
14
|
+
2. **Header chrome** — **Empty roster:** outline **Add collaborator** (`COLLABORATION_HEADER_ADD_LABEL` / **`addCollaboratorLabel`**) opens the invite sheet. **Non-empty roster:** face rail only; faces and **`+N`** open the same sheet via **`onCollaboratorsOpen`**.
|
|
15
|
+
3. **Invite entry** — **⋯ More** → **Invite people** on the entity page header; opens **`InviteCollaboratorsDrawer`** (floating sheet, same family as **`ExportDrawer`**).
|
|
16
|
+
4. **State** — Prefer **`CollaborationAccessFlow`** on hub **`*-client.tsx`**; otherwise own **`collaborators`** + **`inviteOpen`**. Successful invite updates **`collaborators`** so the header and sheet roster match.
|
|
17
|
+
5. **Library access** — Labels and invite options from **`lib/collaborator-access.ts`**; trailing roster badge = access (Owner / Editor / Commenter / Viewer).
|
|
18
|
+
6. **Directory roles** — Optional **`roles`** on **`PageHeaderCollaborator`** as **`Badge variant="outline"`** chips (Faculty, Program coordinator, Director) — **not** library access.
|
|
19
|
+
7. **Roster layout** — One bordered list with row dividers; per row: **name**, **email**, role tags, access badge — **not** one card per person.
|
|
20
|
+
8. **Invite field** — **`FieldGroup`** + **`Field`**; combined email + access row uses **`InputGroup`** + **`InputGroupInput`** + **`InputGroupAddon`** with shadcn **`Select`** (**`SelectGroup`** / **`SelectItem`**, **`position="popper"`**); persistent **`FieldDescription`** for email format; **no** **`toast()`** (**`exxat-no-toast.mdc`**).
|
|
21
|
+
|
|
22
|
+
## MUST NOT
|
|
23
|
+
|
|
24
|
+
- A second invite control **beside** a populated face rail.
|
|
25
|
+
- Fork access enums/labels per hub — extend **`collaborator-access.ts`** once.
|
|
26
|
+
- Use **`Select`** inside **`InputGroupAddon`** without **`InputGroupInput`** / **`SelectGroup`**; put email above name in the roster (order is **name → email → role tags**).
|
|
27
|
+
|
|
28
|
+
## See also
|
|
29
|
+
|
|
30
|
+
- **`exxat-page-vs-drawer.mdc`** — invite is a **sheet**, not a new route.
|
|
31
|
+
- **`exxat-kbd-shortcuts.mdc`** — workflow **Cancel** / **Send invite** shortcuts on the sheet.
|
|
32
|
+
- **`exxat-library-hub-header.mdc`** — Library library: when URL is **folder-scoped**, **⋯ More** also includes **Customize folder** (hub client hosts **`LibraryNewFolderSheet`**).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — global command palette (⌘K) as search + quick AI vs Ask Leo for long answers.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — global command palette (`CommandMenu`)
|
|
7
|
+
|
|
8
|
+
## Intent
|
|
9
|
+
|
|
10
|
+
- **`CommandMenu`** (**⌘K** / **Ctrl+K**) is **global search** (routes, library, patterns, AI starters, optional row data such as placements / student names) — see **`apps/web/AGENTS.md` §7.1** and **`apps/web/docs/command-menu-pattern.md`**.
|
|
11
|
+
- **Quick / lookup / short AI:** Prefer **results inside the palette** when the product can return compact answers or lightweight “research” without leaving the flow.
|
|
12
|
+
- **Long or complex answers:** **Ask Leo** side panel (**⌘⌥K** / **Ctrl+Alt+K**)—not forced into the palette.
|
|
13
|
+
|
|
14
|
+
## Implementation pointers
|
|
15
|
+
|
|
16
|
+
- Shell: `apps/web/components/command-menu.tsx`; config **`buildCommandMenuConfig()`** in **`apps/web/lib/command-menu-config.ts`**; optional **`dataGroups`** from **`apps/web/lib/command-menu-search-data.ts`** (e.g. **`getCommandMenuSearchDataGroups()`**), wired in **`apps/web/app/(app)/layout.tsx`**. Keep domain mapping out of the shell.
|
|
17
|
+
- Large indexes: set **`searchOnly: true`** on **`CommandMenuGroup`** so **`command-menu.tsx`** skips the group until the user types (avoids listing every row on open; cmdk shows all items when the search string is empty).
|
|
18
|
+
|
|
19
|
+
## See also
|
|
20
|
+
|
|
21
|
+
- **`apps/web/AGENTS.md` §7.1**
|
|
22
|
+
- **`exxat-kbd-shortcuts.mdc`** (⌘K vs ⌘⌥K)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Data view dashboard — centralized charts, storage, keyboard parity with gallery, edit layout, coach marks
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — Data view dashboard (list hubs)
|
|
7
|
+
|
|
8
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.3** and **`exxat-dashboard-view-charts`** (this rule).
|
|
9
|
+
|
|
10
|
+
## Two dashboard surfaces (do not fork chart engines)
|
|
11
|
+
|
|
12
|
+
| Surface | Entry | Shared building blocks |
|
|
13
|
+
|--------|--------|-------------------------|
|
|
14
|
+
| **Full-page dashboard** | `app/(app)/dashboard/page.tsx` | `DashboardTabs`, `ChartsOverview` / gallery demos in `charts-overview.tsx` |
|
|
15
|
+
| **Data tab** on Placements / Team / Compliance | `PlacementsTable`, `TeamTable`, `ComplianceTable` → `*DashboardChartsSection` | `ChartFigure`, `ChartCard`, `useChartVariant()`, `data-view-dashboard-charts*.tsx` |
|
|
16
|
+
|
|
17
|
+
**MUST NOT** duplicate “another” chart system for Data view — extend **`charts-overview`** patterns and **`lib/chart-keyboard-selection`**.
|
|
18
|
+
|
|
19
|
+
## MUST — accessibility & data
|
|
20
|
+
|
|
21
|
+
1. **`ChartFigure`** + **`ChartDataTable`** (`sr-only`) for every chart on the Data dashboard — same as **`charts-overview.tsx`**.
|
|
22
|
+
2. **`ChartCard`** wraps chart content; **`KeyMetrics`** **`variant="card"`** for the **`key-metrics`** tile; KPI count **1–4** persisted in layout.
|
|
23
|
+
|
|
24
|
+
## MUST — keyboard selection (parity with `/dashboard` gallery)
|
|
25
|
+
|
|
26
|
+
- Import **`CHART_KBD_ACTIVE_BAR`** and **`CHART_KBD_ACTIVE_PIE_SHAPE`** from **`@/lib/chart-keyboard-selection`**.
|
|
27
|
+
- **Bar** series: **`activeBar={CHART_KBD_ACTIVE_BAR}`** + **`activeIndex={activeIndex ?? undefined}`** (and **`Cell`** only for per-bar **fill**, not opacity-only selection).
|
|
28
|
+
- **Pie / donut:** **`activeShape={CHART_KBD_ACTIVE_PIE_SHAPE}`** + **`activeIndex`** + slice **`stroke`** / **`strokeWidth`** consistent with gallery donuts.
|
|
29
|
+
- **MUST NOT** use **`fillOpacity` dimming alone** on **`Cell`** as the sole “selected” state for keyboard exploration.
|
|
30
|
+
|
|
31
|
+
## MUST — customisation UX
|
|
32
|
+
|
|
33
|
+
- **Edit layout** control: **`aria-label="Edit dashboard layout"`** (toolbar pen-ruler). Coach marks may target **`[aria-label='Edit dashboard layout']`**.
|
|
34
|
+
- On-canvas: drag reorder, remove, width (half / full), chart type, add/remove cards, reset. **No** separate Sheet for layout.
|
|
35
|
+
- While **`layoutEditMode`**: hide **`DataTableToolbar`** (search / filters / Properties row); **Done** / **Cancel** on canvas.
|
|
36
|
+
|
|
37
|
+
## MUST — persistence (centralized)
|
|
38
|
+
|
|
39
|
+
- **One bundle:** **`lib/data-view-dashboard-storage.ts`** — key **`exxat-ds:data-view-dashboards:v1`**, scopes **`placements` | `team` | `compliance`**.
|
|
40
|
+
- Placements helpers: **`loadDashboardLayout`** / **`saveDashboardLayout`** in **`data-view-dashboard-charts.tsx`** (wrap storage API).
|
|
41
|
+
- **MUST NOT** introduce parallel **`localStorage`** keys for the same **`DashboardLayout`** shape without updating the storage module.
|
|
42
|
+
|
|
43
|
+
## SHOULD — coach marks
|
|
44
|
+
|
|
45
|
+
- Register **customize dashboard** flows in **`lib/coach-mark-registry.ts`**; shared copy in **`lib/dashboard-customize-coach-mark.ts`**.
|
|
46
|
+
- Use **`useCoachMark`** **`enabled`** / **`dependsOnDismissedFlowId`** when a tour only applies on **dashboard** view or after another flow (**`COACH_MARK_FLOW_COMPLETED_EVENT`**).
|
|
47
|
+
|
|
48
|
+
## Reference files
|
|
49
|
+
|
|
50
|
+
- `components/data-view-dashboard-charts.tsx` (Placements)
|
|
51
|
+
- `components/data-view-dashboard-charts-team.tsx`, `data-view-dashboard-charts-compliance.tsx`
|
|
52
|
+
- `components/placements-table.tsx` — dashboard tab body wires `PlacementsDashboardChartsSection` + layout-edit toolbar inline (no separate `DashboardShell` component)
|
|
53
|
+
- `lib/chart-keyboard-selection.ts`, `lib/data-view-dashboard-storage.ts`, `lib/dashboard-customize-coach-mark.ts`
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — product data tables must use DataTable with search, filters, and table properties; no alternate table stacks.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — data tables (mandatory pattern)
|
|
7
|
+
|
|
8
|
+
## Use one stack for product data lists
|
|
9
|
+
|
|
10
|
+
For **any app screen that shows a browsable, filterable grid of records** (lists, directories, placements, tokens, columns showcase, etc.):
|
|
11
|
+
|
|
12
|
+
1. **Inside `ListPageTemplate` (every primary hub + every showcase page that mounts a hub-style grid) MUST use `HubTable`** from `@/components/data-views`. `HubTable` is the **canonical** wrapper that wires `useTableState`, the toolbar (**search + filter chips + filter dropdown + sort**), the **Table properties drawer**, view-type tiles, bulk-actions, and conditional rules in one place. Pages that drop down to raw `<DataTable>` silently lose filters and Properties — **MUST NOT** ship a hub or showcase that way.
|
|
13
|
+
2. **Outside `ListPageTemplate`** (rare — e.g. embedded mini-grids, modal sub-tables, drawer body lists), use `DataTable` from `@/components/data-table` directly. Even then, prefer composing a small `toolbarSlot` with `TablePropertiesDrawerButton` whenever the grid is more than a handful of rows.
|
|
14
|
+
3. **Pagination:** Wrap with `DataTablePaginated` when server-style paging is required (Placements is the reference).
|
|
15
|
+
4. **Search:** `HubTable` wires the toolbar search automatically; only consumers that pass `searchable={false}` to `displayOptionsInit` can opt out, and they MUST justify it in the call-site comment.
|
|
16
|
+
5. **Filters:** Configure per-column `filter:` blocks in `ColumnDef` (text / select / date / number) — `HubTable` turns those into chips automatically via `columnsToFilterFields`. **MUST NOT** ship one-off filter inputs above the table that duplicate this.
|
|
17
|
+
6. **Table properties:** Always reachable. `HubTable` mounts `TablePropertiesDrawerButton` in `toolbarSlot`; on **`ListPageTemplate`** pages with **table / list / board / dashboard** tabs it **MUST** also receive **`currentView`** and **`onViewChange`** (see **`apps/web/AGENTS.md` §4.2** and **`.cursor/rules/exxat-table-properties-drawer.mdc`**) so Properties matches the selected view.
|
|
18
|
+
7. **Dropdown menus:** `DropdownMenuContent` uses the shared **`@exxatdesignux/ui`** default (**intrinsic `w-max`**, **`min-w-52`**, capped **`max-w`**) for view settings, row ⋯, column menus, and filter pickers — **pure CSS**, no **`ResizeObserver`**. Override only for deliberate narrow/wide rails (e.g. pagination **`w-20`**, account trigger-width, school switcher **`!w-max min-w-72 …`**). See **`docs/data-views-pattern.md`** (“Dropdown menus”).
|
|
19
|
+
8. **Cell renderers MUST come from `@/components/data-views` (`table-cells.tsx`).** The DS ships **`ProgressCell`**, **`CurrencyCell`**, **`NumericCell`**, **`RatingCell`**, **`SignalBarsCell`**, **`BooleanToggleCell`**, **`AttachmentCountCell`**, **`ExternalLinkCell`**, **`RelativeTimeCell`**, **`PeopleAvatarRailCell`**, **`PillCell`**, **`TagListCell`**, and a generic **`RowActionsCell<TRow>`**. A `ColumnDef['cell']` for these patterns is a **one-liner** that calls the named cell. **MUST NOT** inline `Intl.NumberFormat`, raw `<a target="_blank">`, `[1,2,3,4,5].map(s => …)` star loops, paperclip + count chips, custom face-rail `AvatarGroup`s, or per-hub `DropdownMenu` overflow menus inside `cell:` — those are signals you're re-deriving a shipped primitive. Catalog: `apps/web/components/columns-showcase.tsx` (`/columns`). Skill: `.cursor/skills/exxat-token-economy/SKILL.md` §3.
|
|
20
|
+
|
|
21
|
+
**Reference implementations:**
|
|
22
|
+
|
|
23
|
+
- `components/placements-table.tsx` — full hub: paged table, board, dashboard, list, conditional rules, dashboard customize, bulk actions.
|
|
24
|
+
- `components/sites-table.tsx` — table + finder/board.
|
|
25
|
+
- `components/team-table.tsx` — table + dashboard + list.
|
|
26
|
+
- `components/columns-showcase.tsx` — minimal hub (single `table` view); good reference for showcase pages.
|
|
27
|
+
- `components/tokens-themes-client.tsx` — minimal hub + secondary panel scope.
|
|
28
|
+
|
|
29
|
+
## Do not
|
|
30
|
+
|
|
31
|
+
- Do **not** build product list pages with `@/components/ui/table` alone, raw `<table>` markup, or third-party data grids.
|
|
32
|
+
- Do **not** mount raw `<DataTable>` inside `ListPageTemplate.renderContent` — use `HubTable`. Raw `<DataTable>` does not ship the Properties drawer or filter chips; users lose discoverability.
|
|
33
|
+
- Do **not** introduce a second “table component” pattern for the same product surfaces (splitting search/filters/properties across incompatible implementations).
|
|
34
|
+
- Do **not** inline-implement progress bars, currency formatters, rating stars, relative-time helpers, attachment chips, external-link wrappers, face rails, type pills, tag lists, or row-action dropdowns inside a `ColumnDef['cell']`. Import the named cell from `@/components/data-views` instead. New hub with novel cell needs MUST extend `table-cells.tsx` (and ship the catalog entry in `columns-showcase.tsx`), not fork inline JSX.
|
|
35
|
+
|
|
36
|
+
## Exceptions
|
|
37
|
+
|
|
38
|
+
- **Tiny, read-only tables inside charts or analytics cards** (e.g. chart figure captions / summary matrices) may use minimal markup when they are not primary data-list experiences — still prefer tokens and accessibility, but the full hub stack is not required there.
|
|
39
|
+
- **Drawer body and dialog sub-grids** (small, secondary, scoped to a transient flow) — raw `<DataTable>` is acceptable; still expose search if rows > ~10.
|
|
40
|
+
|
|
41
|
+
## See also
|
|
42
|
+
|
|
43
|
+
- **`apps/web/AGENTS.md`** — full MUST/MUST NOT, list-page template, primary hubs, checklist.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Exxat DS — dedicated search surfaces
|
|
2
|
+
|
|
3
|
+
**Authoritative detail:** **`apps/web/AGENTS.md` §4.8**, **`.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md`**.
|
|
4
|
+
|
|
5
|
+
## Intent
|
|
6
|
+
|
|
7
|
+
Some hubs use **one route** (or sibling routes) with **empty vs non-empty** primary search query:
|
|
8
|
+
|
|
9
|
+
- **Landing** — centered hero, composer, optional recents; no results grid (or minimal chrome).
|
|
10
|
+
- **Results** — `ListPageTemplate` + table/list driven by the same filtered row bag as the rest of the hub.
|
|
11
|
+
|
|
12
|
+
Shared building blocks use **generic** `DedicatedSearch*` names under `components/`, `components/templates/`, and `lib/dedicated-search-*.ts`. Domain code passes **`patchSearchParams`**, **recents controller**, and copy.
|
|
13
|
+
|
|
14
|
+
## MUST
|
|
15
|
+
|
|
16
|
+
- Keep **first paint** of recents **storage-free** (no `localStorage` in `useState` initial state) — see skill.
|
|
17
|
+
- Prefer **`DedicatedSearchLandingTemplate`**, **`DedicatedSearchUrlComposer`**, **`DedicatedSearchRecents`**, **`DedicatedSearchResultsHeaderChrome`**, **`DEDICATED_SEARCH_RESULTS_OUTER_CONTENT_CLASSNAME`** before copying markup into a new hub.
|
|
18
|
+
|
|
19
|
+
## MUST NOT
|
|
20
|
+
|
|
21
|
+
- Introduce parallel `*LibrarySearchLanding*` (or similar) components for another entity — extend the generic layer and compose in the hub client.
|
|
22
|
+
|
|
23
|
+
## See also
|
|
24
|
+
|
|
25
|
+
- **`exxat-list-page-connected-views.mdc`**, **`exxat-centralized-list-dataset.mdc`** — results branch still uses one row bag + `ListPageTemplate`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Exxat DS — drawer/sheet vs modal dialog vs route for flows and confirmations.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Exxat DS — drawer vs dialog
|
|
7
|
+
|
|
8
|
+
## MUST
|
|
9
|
+
|
|
10
|
+
1. **Drawer / sheet** — Hub-**adjacent** work where **parent context** (list, filters, selection) stays relevant: properties, export, invites, long option lists beside the grid.
|
|
11
|
+
2. **Dialog** — **Blocking**, **short** focus: destructive confirm, legal/acknowledgment, single-step choice, alert when the user must not interact with the page behind until resolved.
|
|
12
|
+
3. **Route** — **Primary**, **long**, or **bookmarkable** flows — **`AGENTS.md` §6.4**, **`.cursor/rules/exxat-page-vs-drawer.mdc`**.
|
|
13
|
+
|
|
14
|
+
## MUST NOT
|
|
15
|
+
|
|
16
|
+
- Put **irreversible delete** only in a dismissible toast — use **dialog** (or drawer with explicit confirm) per **`exxat-no-toast.mdc`**.
|
|
17
|
+
- Use a **centered dialog** for **wide tables of export columns** when a **drawer** matches mental model and space.
|
|
18
|
+
|
|
19
|
+
## See also
|
|
20
|
+
|
|
21
|
+
- **`docs/drawer-vs-dialog-pattern.md`** · **`.cursor/skills/exxat-drawer-vs-dialog/SKILL.md`**
|
|
22
|
+
- **`exxat-page-vs-drawer.mdc`** (drawer vs **route**)
|