@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
|
@@ -1,68 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Shared **centered** chrome for list-hub split surfaces (finder / tree / multi-column explorers).
|
|
5
|
-
*
|
|
6
|
-
* Composes `ListPageViewFrame` (gutter + max width) with a single bordered card + fixed viewport
|
|
7
|
-
* height so panel and tree views match across routes (`AGENTS.md` §4.5).
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import * as React from "react"
|
|
11
|
-
import { cn } from "@/lib/utils"
|
|
12
|
-
import {
|
|
13
|
-
ListPageViewFrame,
|
|
14
|
-
LIST_PAGE_VIEW_FRAME_GUTTER,
|
|
15
|
-
LIST_PAGE_VIEW_FRAME_MAX_WIDE,
|
|
16
|
-
} from "@/components/data-views/list-page-view-frame"
|
|
17
|
-
|
|
18
|
-
/** Default height band for split views under `ListPageTemplate` + toolbar. */
|
|
19
|
-
export const LIST_PAGE_SPLIT_HUB_HEIGHT_STYLE: React.CSSProperties = {
|
|
20
|
-
height: "calc(100vh - 280px)",
|
|
21
|
-
minHeight: 420,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Viewport band for calendar under `ListPageTemplate` + hub toolbar (+ optional metrics).
|
|
26
|
-
* Uses a fixed height (not min-height) so the week strip scrolls inside the card, not the page.
|
|
27
|
-
*/
|
|
28
|
-
export const LIST_PAGE_CALENDAR_HEIGHT_STYLE: React.CSSProperties = {
|
|
29
|
-
height: "clamp(420px, calc(100dvh - 22rem), 880px)",
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const SURFACE_CLASS =
|
|
33
|
-
"flex min-h-0 flex-1 flex-col overflow-hidden rounded-xl border border-border bg-card"
|
|
34
|
-
|
|
35
|
-
export interface ListPageSplitHubChromeProps {
|
|
36
|
-
children: React.ReactNode
|
|
37
|
-
"aria-label"?: string
|
|
38
|
-
gutterClassName?: string
|
|
39
|
-
maxWidthClassName?: string
|
|
40
|
-
/** Override default split viewport height / min-height */
|
|
41
|
-
surfaceStyle?: React.CSSProperties
|
|
42
|
-
surfaceClassName?: string
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function ListPageSplitHubChrome({
|
|
46
|
-
children,
|
|
47
|
-
"aria-label": ariaLabel,
|
|
48
|
-
gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,
|
|
49
|
-
maxWidthClassName = LIST_PAGE_VIEW_FRAME_MAX_WIDE,
|
|
50
|
-
surfaceStyle,
|
|
51
|
-
surfaceClassName,
|
|
52
|
-
}: ListPageSplitHubChromeProps) {
|
|
53
|
-
return (
|
|
54
|
-
<ListPageViewFrame
|
|
55
|
-
gutterClassName={gutterClassName}
|
|
56
|
-
maxWidthClassName={maxWidthClassName}
|
|
57
|
-
className="flex min-h-0 flex-1 flex-col"
|
|
58
|
-
>
|
|
59
|
-
<div
|
|
60
|
-
className={cn(SURFACE_CLASS, surfaceClassName)}
|
|
61
|
-
style={{ ...LIST_PAGE_SPLIT_HUB_HEIGHT_STYLE, ...surfaceStyle }}
|
|
62
|
-
aria-label={ariaLabel}
|
|
63
|
-
>
|
|
64
|
-
{children}
|
|
65
|
-
</div>
|
|
66
|
-
</ListPageViewFrame>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/list-page-split-hub-chrome"
|
|
@@ -1,16 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Shared layout tokens for list-hub split surfaces (Miller columns, tree + details).
|
|
3
|
-
* Keeps Question bank panel / tree and generic `FinderPanelView` visually aligned.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** `ResizableHandle` between miller / tree columns — matches Question bank panel. */
|
|
7
|
-
export const LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS =
|
|
8
|
-
"w-1 bg-border/40 hover:bg-brand/20 transition-colors"
|
|
9
|
-
|
|
10
|
-
/** Primary column stack (scope list, folder list, record list, …). */
|
|
11
|
-
export const LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS =
|
|
12
|
-
"flex min-h-0 min-w-0 flex-col bg-card"
|
|
13
|
-
|
|
14
|
-
/** Right-hand inspector / detail column shell. */
|
|
15
|
-
export const LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS =
|
|
16
|
-
"flex min-h-0 min-w-0 flex-col bg-card"
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/list-page-split-hub-tokens"
|
|
@@ -1,31 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { cn } from "@/lib/utils"
|
|
5
|
-
|
|
6
|
-
export interface ListPageTreeColumnHeaderProps {
|
|
7
|
-
title: string
|
|
8
|
-
/** Right side (e.g. icon buttons) — keep touch targets ≥ 24px */
|
|
9
|
-
trailing?: React.ReactNode
|
|
10
|
-
className?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Shared left-column header for tree / outline surfaces — matches Question bank “Questions” bar.
|
|
15
|
-
*/
|
|
16
|
-
export function ListPageTreeColumnHeader({
|
|
17
|
-
title,
|
|
18
|
-
trailing,
|
|
19
|
-
className,
|
|
20
|
-
}: ListPageTreeColumnHeaderProps) {
|
|
21
|
-
return (
|
|
22
|
-
<div className={cn("shrink-0 border-b border-border/50 bg-card px-3 py-2", className)}>
|
|
23
|
-
<div className="flex h-9 items-center justify-between gap-2">
|
|
24
|
-
<h3 className="min-w-0 flex-1 truncate text-sm font-medium text-foreground">{title}</h3>
|
|
25
|
-
{trailing ? (
|
|
26
|
-
<div className="flex shrink-0 items-center gap-0.5">{trailing}</div>
|
|
27
|
-
) : null}
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/list-page-tree-column-header"
|
|
@@ -1,91 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generic two-pane layout: scrollable **tree / outline** column + **details** column,
|
|
5
|
-
* with persisted split sizes (`ResizablePanelGroup` `id`) and shared **split hub chrome**
|
|
6
|
-
* (`ListPageSplitHubChrome`) so tree views match finder / folder panels across the app.
|
|
7
|
-
*
|
|
8
|
-
* Domain hubs pass `tree` and `details` nodes; this module stays entity-agnostic.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import * as React from "react"
|
|
12
|
-
import {
|
|
13
|
-
ResizableHandle,
|
|
14
|
-
ResizablePanel,
|
|
15
|
-
ResizablePanelGroup,
|
|
16
|
-
} from "@/components/ui/resizable"
|
|
17
|
-
import { ListPageSplitHubChrome } from "@/components/data-views/list-page-split-hub-chrome"
|
|
18
|
-
import {
|
|
19
|
-
LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,
|
|
20
|
-
LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS,
|
|
21
|
-
LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS,
|
|
22
|
-
} from "@/components/data-views/list-page-split-hub-tokens"
|
|
23
|
-
import {
|
|
24
|
-
LIST_PAGE_VIEW_FRAME_GUTTER,
|
|
25
|
-
LIST_PAGE_VIEW_FRAME_MAX_WIDE,
|
|
26
|
-
} from "@/components/data-views/list-page-view-frame"
|
|
27
|
-
|
|
28
|
-
export interface ListPageTreePanelShellProps {
|
|
29
|
-
/** Stable id for `react-resizable-panels` layout persistence (per hub / route). */
|
|
30
|
-
resizableGroupId: string
|
|
31
|
-
/** Left column (tree chrome + body). */
|
|
32
|
-
tree: React.ReactNode
|
|
33
|
-
/** Right column (detail / inspector). */
|
|
34
|
-
details: React.ReactNode
|
|
35
|
-
/** Accessible name for the split surface, e.g. “Curriculum tree and details”. */
|
|
36
|
-
ariaLabel: string
|
|
37
|
-
treePanelId?: string
|
|
38
|
-
detailsPanelId?: string
|
|
39
|
-
treeDefaultSize?: string
|
|
40
|
-
treeMinSize?: string
|
|
41
|
-
treeMaxSize?: string
|
|
42
|
-
detailsDefaultSize?: string
|
|
43
|
-
detailsMinSize?: string
|
|
44
|
-
gutterClassName?: string
|
|
45
|
-
maxWidthClassName?: string
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function ListPageTreePanelShell({
|
|
49
|
-
resizableGroupId,
|
|
50
|
-
tree,
|
|
51
|
-
details,
|
|
52
|
-
ariaLabel,
|
|
53
|
-
treePanelId = "tree",
|
|
54
|
-
detailsPanelId = "details",
|
|
55
|
-
treeDefaultSize = "40%",
|
|
56
|
-
treeMinSize = "20%",
|
|
57
|
-
treeMaxSize = "60%",
|
|
58
|
-
detailsDefaultSize = "60%",
|
|
59
|
-
detailsMinSize = "30%",
|
|
60
|
-
gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,
|
|
61
|
-
maxWidthClassName = LIST_PAGE_VIEW_FRAME_MAX_WIDE,
|
|
62
|
-
}: ListPageTreePanelShellProps) {
|
|
63
|
-
return (
|
|
64
|
-
<ListPageSplitHubChrome
|
|
65
|
-
aria-label={ariaLabel}
|
|
66
|
-
gutterClassName={gutterClassName}
|
|
67
|
-
maxWidthClassName={maxWidthClassName}
|
|
68
|
-
>
|
|
69
|
-
<ResizablePanelGroup id={resizableGroupId} direction="horizontal" className="h-full min-h-0 w-full flex-1">
|
|
70
|
-
<ResizablePanel
|
|
71
|
-
id={treePanelId}
|
|
72
|
-
defaultSize={treeDefaultSize}
|
|
73
|
-
minSize={treeMinSize}
|
|
74
|
-
maxSize={treeMaxSize}
|
|
75
|
-
className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}
|
|
76
|
-
>
|
|
77
|
-
{tree}
|
|
78
|
-
</ResizablePanel>
|
|
79
|
-
<ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />
|
|
80
|
-
<ResizablePanel
|
|
81
|
-
id={detailsPanelId}
|
|
82
|
-
defaultSize={detailsDefaultSize}
|
|
83
|
-
minSize={detailsMinSize}
|
|
84
|
-
className={LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS}
|
|
85
|
-
>
|
|
86
|
-
{details}
|
|
87
|
-
</ResizablePanel>
|
|
88
|
-
</ResizablePanelGroup>
|
|
89
|
-
</ListPageSplitHubChrome>
|
|
90
|
-
)
|
|
91
|
-
}
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/list-page-tree-panel-shell"
|
|
@@ -1,53 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* **MUST** be used instead of ad-hoc `mx-4 lg:mx-6` + `mx-auto max-w-*` pairs on each page — see
|
|
8
|
-
* `AGENTS.md` §4.5 and `.cursor/rules/exxat-list-page-view-shells.mdc`.
|
|
9
|
-
*
|
|
10
|
-
* **MUST NOT** wrap `DataTable` when its toolbar already applies the same inset (avoid double gutter);
|
|
11
|
-
* use this for **non-table** view branches or **sections below** the shared toolbar.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import * as React from "react"
|
|
15
|
-
import { cn } from "@/lib/utils"
|
|
16
|
-
|
|
17
|
-
/** Default horizontal rhythm for view bodies under `ListPageTemplate` (matches `FolderGridView`). */
|
|
18
|
-
export const LIST_PAGE_VIEW_FRAME_GUTTER = "mx-4 mb-6 lg:mx-6"
|
|
19
|
-
|
|
20
|
-
/** Typical max width for icon grids / dense tile views on ultra-wide monitors. */
|
|
21
|
-
export const LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID = "max-w-6xl"
|
|
22
|
-
|
|
23
|
-
/** Slightly wider shell when a view includes toolbar + breadcrumbs + grid (e.g. OS folder explorer). */
|
|
24
|
-
export const LIST_PAGE_VIEW_FRAME_MAX_WIDE = "max-w-7xl"
|
|
25
|
-
|
|
26
|
-
export interface ListPageViewFrameProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
27
|
-
children: React.ReactNode
|
|
28
|
-
/**
|
|
29
|
-
* When set, children are wrapped in `mx-auto w-full min-w-0` + this max-width so the block stays
|
|
30
|
-
* centered inside the primary page column.
|
|
31
|
-
*/
|
|
32
|
-
maxWidthClassName?: string
|
|
33
|
-
/** Override outer gutter; default `LIST_PAGE_VIEW_FRAME_GUTTER`. */
|
|
34
|
-
gutterClassName?: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function ListPageViewFrame({
|
|
38
|
-
children,
|
|
39
|
-
className,
|
|
40
|
-
maxWidthClassName,
|
|
41
|
-
gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,
|
|
42
|
-
...rest
|
|
43
|
-
}: ListPageViewFrameProps) {
|
|
44
|
-
return (
|
|
45
|
-
<div className={cn(gutterClassName, className)} {...rest}>
|
|
46
|
-
{maxWidthClassName ? (
|
|
47
|
-
<div className={cn("mx-auto w-full min-w-0", maxWidthClassName)}>{children}</div>
|
|
48
|
-
) : (
|
|
49
|
-
children
|
|
50
|
-
)}
|
|
51
|
-
</div>
|
|
52
|
-
)
|
|
53
|
-
}
|
|
1
|
+
// ListPageViewFrame was promoted to `@exxatdesignux/ui` on 2026-05-20.
|
|
2
|
+
// This shim keeps every existing
|
|
3
|
+
// `import … from "@/components/data-views/list-page-view-frame"` site
|
|
4
|
+
// working — including the `data-views/index.ts` barrel re-export.
|
|
5
|
+
export * from "@exxatdesignux/ui/components/list-page-view-frame"
|
|
@@ -1,129 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Windows 11–style folder art (Icons8) + optional FA glyph on the pocket.
|
|
5
|
-
* Static asset: `public/folders/icons8-folder-windows-11.svg`
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import * as React from "react"
|
|
9
|
-
import { cn } from "@/lib/utils"
|
|
10
|
-
import type { QuestionBankFolderColorKey } from "@/lib/mock/question-bank-folders"
|
|
11
|
-
|
|
12
|
-
/** Served from `apps/web/public/folders/` (copied from Icons8 “folder windows 11 color”). */
|
|
13
|
-
export const OS_FOLDER_GLYPH_SRC = "/folders/icons8-folder-windows-11.svg"
|
|
14
|
-
|
|
15
|
-
/** Subtle hue tweak so “color” choice still reads on the shared yellow asset. */
|
|
16
|
-
const COLOR_TINT_FILTER: Record<QuestionBankFolderColorKey, string> = {
|
|
17
|
-
brand: "hue-rotate(-42deg) saturate(1.25) brightness(0.97)",
|
|
18
|
-
success: "hue-rotate(82deg) saturate(1.2) brightness(0.95)",
|
|
19
|
-
warning: "hue-rotate(-5deg) saturate(1.35) brightness(1.02)",
|
|
20
|
-
destructive: "hue-rotate(300deg) saturate(1.15) brightness(0.92)",
|
|
21
|
-
muted: "saturate(0.15) brightness(1.08)",
|
|
22
|
-
chart1: "hue-rotate(200deg) saturate(1.2) brightness(0.96)",
|
|
23
|
-
chart2: "hue-rotate(95deg) saturate(1.15) brightness(0.96)",
|
|
24
|
-
chart3: "hue-rotate(265deg) saturate(1.2) brightness(0.96)",
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const SIZE_MAP = {
|
|
28
|
-
/** Compact — folder inspector / column headers (matches ~36px row height). */
|
|
29
|
-
xs: "h-9 w-[2.6rem]",
|
|
30
|
-
sm: "h-[3.35rem] w-[3.85rem]",
|
|
31
|
-
md: "h-[4.6rem] w-[5.25rem]",
|
|
32
|
-
lg: "h-[6.5rem] w-[7.25rem]",
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const ICON_TEXT: Record<keyof typeof SIZE_MAP, string> = {
|
|
36
|
-
xs: "text-[13px] leading-none",
|
|
37
|
-
sm: "text-lg",
|
|
38
|
-
md: "text-2xl",
|
|
39
|
-
lg: "text-4xl",
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Darker version of each folder color for punched icon appearance. */
|
|
43
|
-
const ICON_COLOR: Record<QuestionBankFolderColorKey, string> = {
|
|
44
|
-
brand: "text-orange-800 dark:text-orange-600",
|
|
45
|
-
success: "text-emerald-800 dark:text-emerald-600",
|
|
46
|
-
warning: "text-amber-800 dark:text-amber-600",
|
|
47
|
-
destructive: "text-red-800 dark:text-red-600",
|
|
48
|
-
muted: "text-slate-600 dark:text-slate-400",
|
|
49
|
-
chart1: "text-blue-800 dark:text-blue-600",
|
|
50
|
-
chart2: "text-lime-800 dark:text-lime-600",
|
|
51
|
-
chart3: "text-purple-800 dark:text-purple-600",
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface OsFolderGlyphProps {
|
|
55
|
-
colorKey: QuestionBankFolderColorKey
|
|
56
|
-
/** Font Awesome icon classes without weight (e.g. `fa-stethoscope`). */
|
|
57
|
-
icon: string
|
|
58
|
-
size?: keyof typeof SIZE_MAP
|
|
59
|
-
className?: string
|
|
60
|
-
variant?: "solid" | "outline"
|
|
61
|
-
/**
|
|
62
|
-
* When false, exposes `role="img"` + `aria-label` (use with a short label, e.g. sheet preview).
|
|
63
|
-
* When true (default), hides the glyph from AT — parent control should name the action.
|
|
64
|
-
*/
|
|
65
|
-
decorative?: boolean
|
|
66
|
-
/** Required when `decorative={false}` */
|
|
67
|
-
label?: string
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function OsFolderGlyph({
|
|
71
|
-
colorKey,
|
|
72
|
-
icon,
|
|
73
|
-
size = "md",
|
|
74
|
-
className,
|
|
75
|
-
variant = "solid",
|
|
76
|
-
decorative = true,
|
|
77
|
-
label,
|
|
78
|
-
}: OsFolderGlyphProps) {
|
|
79
|
-
const outline = variant === "outline"
|
|
80
|
-
const tint = COLOR_TINT_FILTER[colorKey]
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<div
|
|
84
|
-
className={cn(
|
|
85
|
-
"group relative shrink-0 select-none transition-[transform,box-shadow] duration-200 ease-out",
|
|
86
|
-
"hover:z-[1] hover:scale-105 motion-reduce:transform-none motion-reduce:hover:scale-100",
|
|
87
|
-
SIZE_MAP[size],
|
|
88
|
-
className,
|
|
89
|
-
)}
|
|
90
|
-
role={!decorative && label ? "img" : undefined}
|
|
91
|
-
aria-label={!decorative ? label : undefined}
|
|
92
|
-
aria-hidden={decorative ? true : undefined}
|
|
93
|
-
>
|
|
94
|
-
{/* Static SVG — `next/image` can't optimize SVGs without
|
|
95
|
-
`dangerouslyAllowSVG`, so we stay on plain <img> but add the same
|
|
96
|
-
loading/decoding hints `next/image` would. Folder grids render many
|
|
97
|
-
of these at once; lazy-loading lets the browser skip off-screen
|
|
98
|
-
glyphs until they scroll near the viewport. */}
|
|
99
|
-
{/* eslint-disable-next-line @next/next/no-img-element -- SVG; next/image can't optimize without dangerouslyAllowSVG */}
|
|
100
|
-
<img
|
|
101
|
-
src={OS_FOLDER_GLYPH_SRC}
|
|
102
|
-
alt=""
|
|
103
|
-
width={240}
|
|
104
|
-
height={240}
|
|
105
|
-
draggable={false}
|
|
106
|
-
loading="lazy"
|
|
107
|
-
decoding="async"
|
|
108
|
-
className={cn(
|
|
109
|
-
"h-full w-full object-contain",
|
|
110
|
-
"transition-[filter] duration-200",
|
|
111
|
-
outline && "opacity-75 saturate-[0.65]",
|
|
112
|
-
)}
|
|
113
|
-
style={outline ? undefined : { filter: tint }}
|
|
114
|
-
/>
|
|
115
|
-
<span
|
|
116
|
-
className={cn(
|
|
117
|
-
"pointer-events-none absolute inset-0 flex items-center justify-center",
|
|
118
|
-
size === "xs" ? "translate-y-[0.18rem]" : "translate-y-[0.35rem]",
|
|
119
|
-
ICON_TEXT[size],
|
|
120
|
-
outline
|
|
121
|
-
? "text-muted-foreground"
|
|
122
|
-
: cn(ICON_COLOR[colorKey], "opacity-100"),
|
|
123
|
-
)}
|
|
124
|
-
>
|
|
125
|
-
<i className={cn("fa-solid", icon)} aria-hidden="true" />
|
|
126
|
-
</span>
|
|
127
|
-
</div>
|
|
128
|
-
)
|
|
129
|
-
}
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/os-folder-glyph"
|
|
@@ -1,157 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Central outline-tree chrome — mirrors shadcn/ui **Sidebar** file-tree structure
|
|
5
|
-
* (`SidebarMenu` → `SidebarMenuItem` + `Collapsible` → `SidebarMenuSub` → rows) without
|
|
6
|
-
* coupling to `useSidebar`.
|
|
7
|
-
*
|
|
8
|
-
* - **`guideLayout="inset"`** — same rhythm as `SidebarMenuSub` (`mx-3.5` + `translate-x-px`).
|
|
9
|
-
* - **`guideLayout="chevronRail"`** — use with **`OutlineTreeCollapsibleContentRail`**: a **`w-6`**
|
|
10
|
-
* spacer lines up the vertical guide with the **horizontal center** of a **`size-8`** chevron
|
|
11
|
-
* when the folder row uses **`px-2`** (8px padding + 16px half of 32px chevron hit target).
|
|
12
|
-
*
|
|
13
|
-
* @see packages/ui/src/components/ui/sidebar.tsx — `SidebarMenuSub`, `SidebarMenuSubItem`
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import * as React from "react"
|
|
17
|
-
import { CollapsibleContent } from "@/components/ui/collapsible"
|
|
18
|
-
import { cn } from "@/lib/utils"
|
|
19
|
-
|
|
20
|
-
export type OutlineTreeSurface = "sidebar" | "panel"
|
|
21
|
-
|
|
22
|
-
export type OutlineTreeGuideLayout = "inset" | "chevronRail"
|
|
23
|
-
|
|
24
|
-
const outlineTreeSubInsetClass: Record<OutlineTreeSurface, string> = {
|
|
25
|
-
sidebar:
|
|
26
|
-
"mx-3.5 flex min-w-0 list-none translate-x-px flex-col gap-1 border-s border-sidebar-border px-2.5 py-0.5 rtl:-translate-x-px",
|
|
27
|
-
panel:
|
|
28
|
-
"mx-3.5 flex min-w-0 list-none translate-x-px flex-col gap-1 border-s border-border/60 px-2.5 py-0.5 rtl:-translate-x-px",
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const outlineTreeSubChevronRailClass: Record<OutlineTreeSurface, string> = {
|
|
32
|
-
sidebar:
|
|
33
|
-
"flex min-w-0 flex-1 list-none flex-col gap-1 border-s border-sidebar-border py-0.5 ps-2.5",
|
|
34
|
-
panel: "flex min-w-0 flex-1 list-none flex-col gap-1 border-s border-border/60 py-0.5 ps-2.5",
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Pull row content onto the guide line — matches `SidebarMenuSubButton` horizontal nudge (inset layout only). */
|
|
38
|
-
export const OUTLINE_TREE_SUB_ROW_SHIFT_CLASS = "-translate-x-px rtl:translate-x-px"
|
|
39
|
-
|
|
40
|
-
/** `CollapsibleContent` row: spacer width = `px-2` (8px) + half of `size-8` chevron (16px) → guide under chevron center. */
|
|
41
|
-
export const OUTLINE_TREE_COLLAPSIBLE_CONTENT_RAIL_CLASS = "flex min-w-0 w-full"
|
|
42
|
-
|
|
43
|
-
/** Spacer column — keep in sync with folder row `px-2` + `size-8` chevron. */
|
|
44
|
-
export const OUTLINE_TREE_CHEVRON_GUIDE_SPACER_CLASS = "w-6 shrink-0"
|
|
45
|
-
|
|
46
|
-
/** Wrap `OutlineTreeSub` with `guideLayout="chevronRail"` so the vertical border meets the chevron center. */
|
|
47
|
-
export function OutlineTreeCollapsibleContentRail({
|
|
48
|
-
className,
|
|
49
|
-
children,
|
|
50
|
-
...props
|
|
51
|
-
}: React.ComponentProps<typeof CollapsibleContent>) {
|
|
52
|
-
return (
|
|
53
|
-
<CollapsibleContent
|
|
54
|
-
className={cn(OUTLINE_TREE_COLLAPSIBLE_CONTENT_RAIL_CLASS, className)}
|
|
55
|
-
{...props}
|
|
56
|
-
>
|
|
57
|
-
<div className={OUTLINE_TREE_CHEVRON_GUIDE_SPACER_CLASS} aria-hidden />
|
|
58
|
-
{children}
|
|
59
|
-
</CollapsibleContent>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Nested list under a folder — vertical guide + indent. */
|
|
64
|
-
export function OutlineTreeSub({
|
|
65
|
-
surface = "panel",
|
|
66
|
-
guideLayout = "inset",
|
|
67
|
-
className,
|
|
68
|
-
...props
|
|
69
|
-
}: React.ComponentProps<"ul"> & {
|
|
70
|
-
surface?: OutlineTreeSurface
|
|
71
|
-
guideLayout?: OutlineTreeGuideLayout
|
|
72
|
-
}) {
|
|
73
|
-
return (
|
|
74
|
-
<ul
|
|
75
|
-
data-slot="outline-tree-sub"
|
|
76
|
-
data-guide-layout={guideLayout}
|
|
77
|
-
className={cn(
|
|
78
|
-
guideLayout === "inset" && outlineTreeSubInsetClass[surface],
|
|
79
|
-
guideLayout === "chevronRail" && outlineTreeSubChevronRailClass[surface],
|
|
80
|
-
className,
|
|
81
|
-
)}
|
|
82
|
-
{...props}
|
|
83
|
-
/>
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/** Root or nested branch list — matches `SidebarMenu` spacing. */
|
|
88
|
-
export function OutlineTreeMenu({ className, ...props }: React.ComponentProps<"ul">) {
|
|
89
|
-
return (
|
|
90
|
-
<ul
|
|
91
|
-
data-slot="outline-tree-menu"
|
|
92
|
-
className={cn("flex w-full min-w-0 list-none flex-col gap-0", className)}
|
|
93
|
-
{...props}
|
|
94
|
-
/>
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Expandable folder row wrapper — matches `SidebarMenuItem`. */
|
|
99
|
-
export function OutlineTreeMenuItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
100
|
-
return (
|
|
101
|
-
<li
|
|
102
|
-
data-slot="outline-tree-menu-item"
|
|
103
|
-
className={cn("group/menu-item relative min-w-0 w-full list-none", className)}
|
|
104
|
-
{...props}
|
|
105
|
-
/>
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/** Leaf / nested row inside `OutlineTreeSub` — matches `SidebarMenuSubItem`. */
|
|
110
|
-
export function OutlineTreeSubItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
111
|
-
return (
|
|
112
|
-
<li
|
|
113
|
-
data-slot="outline-tree-sub-item"
|
|
114
|
-
className={cn("group/menu-sub-item relative min-w-0 w-full list-none", className)}
|
|
115
|
-
{...props}
|
|
116
|
-
/>
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface OutlineTreeLeafButtonProps extends React.ComponentProps<"button"> {
|
|
121
|
-
surface?: OutlineTreeSurface
|
|
122
|
-
isActive?: boolean
|
|
123
|
-
/** Inset `OutlineTreeSub` only — nudge like `SidebarMenuSubButton`. Ignored when parent uses `chevronRail`. */
|
|
124
|
-
subGuideAlign?: boolean
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** Selectable leaf row (file / terminal row) — `SidebarMenuSubButton`–aligned rhythm. */
|
|
128
|
-
export function OutlineTreeLeafButton({
|
|
129
|
-
surface = "panel",
|
|
130
|
-
isActive = false,
|
|
131
|
-
subGuideAlign = false,
|
|
132
|
-
className,
|
|
133
|
-
...props
|
|
134
|
-
}: OutlineTreeLeafButtonProps) {
|
|
135
|
-
return (
|
|
136
|
-
<button
|
|
137
|
-
type="button"
|
|
138
|
-
data-active={isActive || undefined}
|
|
139
|
-
className={cn(
|
|
140
|
-
"flex min-h-8 w-full min-w-0 cursor-pointer select-none items-center gap-2 overflow-hidden rounded-md px-2 text-start text-sm outline-none ring-ring focus-visible:ring-2 focus-visible:ring-inset [&>svg]:size-4 [&>svg]:shrink-0",
|
|
141
|
-
subGuideAlign && OUTLINE_TREE_SUB_ROW_SHIFT_CLASS,
|
|
142
|
-
surface === "panel" &&
|
|
143
|
-
cn(
|
|
144
|
-
"text-foreground hover:bg-muted/50",
|
|
145
|
-
isActive && "bg-accent font-medium text-accent-foreground",
|
|
146
|
-
),
|
|
147
|
-
surface === "sidebar" &&
|
|
148
|
-
cn(
|
|
149
|
-
"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
150
|
-
isActive && "bg-sidebar-accent font-medium text-sidebar-accent-foreground",
|
|
151
|
-
),
|
|
152
|
-
className,
|
|
153
|
-
)}
|
|
154
|
-
{...props}
|
|
155
|
-
/>
|
|
156
|
-
)
|
|
157
|
-
}
|
|
1
|
+
export * from "@exxatdesignux/ui/components/data-views/outline-tree-menu"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExportDrawer — render smoke tests
|
|
3
|
+
*
|
|
4
|
+
* Verify the promoted component renders without throwing and exposes the
|
|
5
|
+
* correct accessible structure when open. ExportDrawer is fully controlled
|
|
6
|
+
* (no built-in trigger); it must be wrapped in TooltipProvider.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { render, screen } from "@testing-library/react"
|
|
10
|
+
import { describe, expect, it, vi } from "vitest"
|
|
11
|
+
|
|
12
|
+
import { TooltipProvider } from "@/components/ui/tooltip"
|
|
13
|
+
import { ExportDrawer } from "./export-drawer"
|
|
14
|
+
|
|
15
|
+
function Wrapper({ children }: { children: React.ReactNode }) {
|
|
16
|
+
return <TooltipProvider>{children}</TooltipProvider>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("ExportDrawer", () => {
|
|
20
|
+
const noop = vi.fn()
|
|
21
|
+
|
|
22
|
+
it("renders without throwing when closed", () => {
|
|
23
|
+
expect(() =>
|
|
24
|
+
render(<ExportDrawer open={false} onOpenChange={noop} />, { wrapper: Wrapper }),
|
|
25
|
+
).not.toThrow()
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it("renders the drawer title when open", () => {
|
|
29
|
+
render(
|
|
30
|
+
<ExportDrawer open onOpenChange={noop} />,
|
|
31
|
+
{ wrapper: Wrapper },
|
|
32
|
+
)
|
|
33
|
+
expect(screen.getByRole("heading", { name: /export/i })).toBeInTheDocument()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("renders the Export submit button when open", () => {
|
|
37
|
+
render(
|
|
38
|
+
<ExportDrawer open onOpenChange={noop} />,
|
|
39
|
+
{ wrapper: Wrapper },
|
|
40
|
+
)
|
|
41
|
+
const buttons = screen.getAllByRole("button", { name: /export/i })
|
|
42
|
+
expect(buttons.length).toBeGreaterThan(0)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("renders the Cancel button when open", () => {
|
|
46
|
+
render(
|
|
47
|
+
<ExportDrawer open onOpenChange={noop} />,
|
|
48
|
+
{ wrapper: Wrapper },
|
|
49
|
+
)
|
|
50
|
+
expect(screen.getByRole("button", { name: /cancel/i })).toBeInTheDocument()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("renders the date range helper text when open", () => {
|
|
54
|
+
const { baseElement } = render(
|
|
55
|
+
<ExportDrawer open onOpenChange={noop} />,
|
|
56
|
+
{ wrapper: Wrapper },
|
|
57
|
+
)
|
|
58
|
+
// The form shows a date range section — confirmed by looking for the "Date range" label
|
|
59
|
+
expect(baseElement.textContent).toMatch(/date range/i)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it("shows file format options when open", () => {
|
|
63
|
+
render(
|
|
64
|
+
<ExportDrawer open onOpenChange={noop} />,
|
|
65
|
+
{ wrapper: Wrapper },
|
|
66
|
+
)
|
|
67
|
+
// The format field renders radio tiles — at least one "CSV" label should be visible
|
|
68
|
+
const csvElements = screen.getAllByText(/csv/i)
|
|
69
|
+
expect(csvElements.length).toBeGreaterThan(0)
|
|
70
|
+
})
|
|
71
|
+
})
|