@exxatdesignux/ui 0.2.19 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -7
- package/bin/sync-extras.mjs +116 -29
- package/consumer-extras/README.md +42 -7
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
- package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
- package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +4 -15
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
- package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
- package/consumer-extras/handbook/HANDBOOK.md +185 -0
- package/consumer-extras/handbook/glossary.md +57 -0
- package/consumer-extras/handbook/reference-implementations.md +126 -0
- package/consumer-extras/handbook/voice-and-tone.md +262 -0
- package/consumer-extras/patterns/command-menu-pattern.md +1 -1
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
- package/consumer-extras/patterns/data-views-pattern.md +17 -54
- package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
- package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
- package/dist/components/data-table/filter-date-calendar.js +280 -0
- package/dist/components/data-table/filter-date-calendar.js.map +1 -0
- package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
- package/dist/components/data-table/filter-text-value-input.js +561 -0
- package/dist/components/data-table/filter-text-value-input.js.map +1 -0
- package/dist/components/data-table/index.d.ts +45 -0
- package/dist/components/data-table/index.js +3085 -0
- package/dist/components/data-table/index.js.map +1 -0
- package/dist/components/data-table/pagination.d.ts +28 -0
- package/dist/components/data-table/pagination.js +3264 -0
- package/dist/components/data-table/pagination.js.map +1 -0
- package/dist/components/data-table/types.d.ts +84 -0
- package/dist/components/data-table/types.js +3 -0
- package/dist/components/data-table/types.js.map +1 -0
- package/dist/components/data-table/use-table-state.d.ts +116 -0
- package/dist/components/data-table/use-table-state.js +670 -0
- package/dist/components/data-table/use-table-state.js.map +1 -0
- package/dist/components/data-views/board-card-primitives.d.ts +22 -0
- package/dist/components/data-views/board-card-primitives.js +84 -0
- package/dist/components/data-views/board-card-primitives.js.map +1 -0
- package/dist/components/data-views/data-row-list.d.ts +33 -0
- package/dist/components/data-views/data-row-list.js +106 -0
- package/dist/components/data-views/data-row-list.js.map +1 -0
- package/dist/components/data-views/finder-panel-view.d.ts +54 -0
- package/dist/components/data-views/finder-panel-view.js +388 -0
- package/dist/components/data-views/finder-panel-view.js.map +1 -0
- package/dist/components/data-views/folder-grid-view.d.ts +22 -0
- package/dist/components/data-views/folder-grid-view.js +58 -0
- package/dist/components/data-views/folder-grid-view.js.map +1 -0
- package/dist/components/data-views/hub-table.d.ts +167 -0
- package/dist/components/data-views/hub-table.js +5561 -0
- package/dist/components/data-views/hub-table.js.map +1 -0
- package/dist/components/data-views/index.d.ts +27 -0
- package/dist/components/data-views/index.js +6575 -0
- package/dist/components/data-views/index.js.map +1 -0
- package/dist/components/data-views/list-page-board-card.d.ts +72 -0
- package/dist/components/data-views/list-page-board-card.js +264 -0
- package/dist/components/data-views/list-page-board-card.js.map +1 -0
- package/dist/components/data-views/list-page-board-template.d.ts +24 -0
- package/dist/components/data-views/list-page-board-template.js +137 -0
- package/dist/components/data-views/list-page-board-template.js.map +1 -0
- package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
- package/dist/components/data-views/list-page-connected-view-body.js +116 -0
- package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
- package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
- package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
- package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
- package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
- package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
- package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
- package/dist/components/data-views/list-page-tree-column-header.js +22 -0
- package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
- package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
- package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
- package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
- package/dist/components/data-views/os-folder-glyph.js +104 -0
- package/dist/components/data-views/os-folder-glyph.js.map +1 -0
- package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
- package/dist/components/data-views/outline-tree-menu.js +131 -0
- package/dist/components/data-views/outline-tree-menu.js.map +1 -0
- package/dist/components/table-properties/column-row.d.ts +22 -0
- package/dist/components/table-properties/column-row.js +153 -0
- package/dist/components/table-properties/column-row.js.map +1 -0
- package/dist/components/table-properties/draggable-list.d.ts +24 -0
- package/dist/components/table-properties/draggable-list.js +53 -0
- package/dist/components/table-properties/draggable-list.js.map +1 -0
- package/dist/components/table-properties/drawer-button.d.ts +110 -0
- package/dist/components/table-properties/drawer-button.js +2748 -0
- package/dist/components/table-properties/drawer-button.js.map +1 -0
- package/dist/components/table-properties/drawer.d.ts +100 -0
- package/dist/components/table-properties/drawer.js +2595 -0
- package/dist/components/table-properties/drawer.js.map +1 -0
- package/dist/components/table-properties/filter-card.d.ts +24 -0
- package/dist/components/table-properties/filter-card.js +854 -0
- package/dist/components/table-properties/filter-card.js.map +1 -0
- package/dist/components/table-properties/index.d.ts +14 -0
- package/dist/components/table-properties/index.js +2768 -0
- package/dist/components/table-properties/index.js.map +1 -0
- package/dist/components/table-properties/sort-card.d.ts +20 -0
- package/dist/components/table-properties/sort-card.js +102 -0
- package/dist/components/table-properties/sort-card.js.map +1 -0
- package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
- package/dist/components/templates/dedicated-search-landing-template.js +254 -0
- package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
- package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
- package/dist/components/templates/dedicated-search-results-template.js +16 -0
- package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
- package/dist/components/templates/index.d.ts +9 -0
- package/dist/components/templates/index.js +2720 -0
- package/dist/components/templates/index.js.map +1 -0
- package/dist/components/templates/list-page.d.ts +83 -0
- package/dist/components/templates/list-page.js +2433 -0
- package/dist/components/templates/list-page.js.map +1 -0
- package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
- package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
- package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +10 -0
- package/dist/components/ui/accordion.js +74 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +37 -0
- package/dist/components/ui/alert-dialog.js +201 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +84 -0
- package/dist/components/ui/avatar.js +328 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +13 -0
- package/dist/components/ui/badge.js +49 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/banner.d.ts +62 -0
- package/dist/components/ui/banner.js +364 -0
- package/dist/components/ui/banner.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +14 -0
- package/dist/components/ui/breadcrumb.js +114 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +16 -0
- package/dist/components/ui/button.js +59 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +13 -0
- package/dist/components/ui/calendar.js +238 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +14 -0
- package/dist/components/ui/card.js +102 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/chart.d.ts +58 -0
- package/dist/components/ui/chart.js +292 -0
- package/dist/components/ui/chart.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +23 -0
- package/dist/components/ui/checkbox.js +155 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/coach-mark.d.ts +27 -0
- package/dist/components/ui/coach-mark.js +306 -0
- package/dist/components/ui/coach-mark.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +8 -0
- package/dist/components/ui/collapsible.js +35 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +36 -0
- package/dist/components/ui/command.js +274 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +32 -0
- package/dist/components/ui/context-menu.js +245 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/date-picker-field.d.ts +38 -0
- package/dist/components/ui/date-picker-field.js +550 -0
- package/dist/components/ui/date-picker-field.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.js +200 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dot-pattern.d.ts +21 -0
- package/dist/components/ui/dot-pattern.js +139 -0
- package/dist/components/ui/dot-pattern.js.map +1 -0
- package/dist/components/ui/drag-handle-grip.d.ts +10 -0
- package/dist/components/ui/drag-handle-grip.js +15 -0
- package/dist/components/ui/drag-handle-grip.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +16 -0
- package/dist/components/ui/drawer.js +125 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +45 -0
- package/dist/components/ui/dropdown-menu.js +353 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/export-drawer.d.ts +11 -0
- package/dist/components/ui/export-drawer.js +1658 -0
- package/dist/components/ui/export-drawer.js.map +1 -0
- package/dist/components/ui/field.d.ts +30 -0
- package/dist/components/ui/field.js +249 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +28 -0
- package/dist/components/ui/form.js +110 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +9 -0
- package/dist/components/ui/hover-card.js +43 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +20 -0
- package/dist/components/ui/input-group.js +219 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-mask.d.ts +39 -0
- package/dist/components/ui/input-mask.js +118 -0
- package/dist/components/ui/input-mask.js.map +1 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +30 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +20 -0
- package/dist/components/ui/kbd.js +45 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-metrics-context.d.ts +19 -0
- package/dist/components/ui/key-metrics-context.js +26 -0
- package/dist/components/ui/key-metrics-context.js.map +1 -0
- package/dist/components/ui/key-metrics.d.ts +131 -0
- package/dist/components/ui/key-metrics.js +1015 -0
- package/dist/components/ui/key-metrics.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.js +28 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/list-page-view-frame.d.ts +22 -0
- package/dist/components/ui/list-page-view-frame.js +24 -0
- package/dist/components/ui/list-page-view-frame.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +51 -0
- package/dist/components/ui/page-header.js +372 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/payment-card-fields.d.ts +10 -0
- package/dist/components/ui/payment-card-fields.js +80 -0
- package/dist/components/ui/payment-card-fields.js.map +1 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +47 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +29 -0
- package/dist/components/ui/radio-group.js +190 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +16 -0
- package/dist/components/ui/resizable.js +51 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +8 -0
- package/dist/components/ui/scroll-area.js +66 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/select.js +186 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/selection-tile-grid.d.ts +52 -0
- package/dist/components/ui/selection-tile-grid.js +347 -0
- package/dist/components/ui/selection-tile-grid.js.map +1 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +33 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +18 -0
- package/dist/components/ui/sheet.js +181 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +94 -0
- package/dist/components/ui/sidebar.js +805 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +5 -0
- package/dist/components/ui/skeleton.js +22 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +7 -0
- package/dist/components/ui/slider.js +66 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +6 -0
- package/dist/components/ui/sonner.js +38 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/status-badge.d.ts +38 -0
- package/dist/components/ui/status-badge.js +77 -0
- package/dist/components/ui/status-badge.js.map +1 -0
- package/dist/components/ui/table.d.ts +13 -0
- package/dist/components/ui/table.js +115 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +15 -0
- package/dist/components/ui/tabs.js +93 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.js +25 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tip.d.ts +12 -0
- package/dist/components/ui/tip.js +61 -0
- package/dist/components/ui/tip.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +14 -0
- package/dist/components/ui/toggle-group.js +104 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle-switch.d.ts +10 -0
- package/dist/components/ui/toggle-switch.js +33 -0
- package/dist/components/ui/toggle-switch.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +13 -0
- package/dist/components/ui/toggle.js +51 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.js +68 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components/ui/view-segmented-control.d.ts +31 -0
- package/dist/components/ui/view-segmented-control.js +167 -0
- package/dist/components/ui/view-segmented-control.js.map +1 -0
- package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
- package/dist/hooks/use-app-theme.d.ts +24 -0
- package/dist/hooks/use-app-theme.js +286 -0
- package/dist/hooks/use-app-theme.js.map +1 -0
- package/dist/hooks/use-coach-mark.d.ts +86 -0
- package/dist/hooks/use-coach-mark.js +218 -0
- package/dist/hooks/use-coach-mark.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +29 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/hooks/use-mod-key-label.d.ts +6 -0
- package/dist/hooks/use-mod-key-label.js +25 -0
- package/dist/hooks/use-mod-key-label.js.map +1 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +13324 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/compose-refs.d.ts +6 -0
- package/dist/lib/compose-refs.js +17 -0
- package/dist/lib/compose-refs.js.map +1 -0
- package/dist/lib/conditional-rule-match.d.ts +30 -0
- package/dist/lib/conditional-rule-match.js +66 -0
- package/dist/lib/conditional-rule-match.js.map +1 -0
- package/dist/lib/data-list-display-options.d.ts +26 -0
- package/dist/lib/data-list-display-options.js +14 -0
- package/dist/lib/data-list-display-options.js.map +1 -0
- package/dist/lib/data-list-view-registry.d.ts +2 -0
- package/dist/lib/data-list-view-registry.js +102 -0
- package/dist/lib/data-list-view-registry.js.map +1 -0
- package/dist/lib/data-list-view-surface.d.ts +2 -0
- package/dist/lib/data-list-view-surface.js +80 -0
- package/dist/lib/data-list-view-surface.js.map +1 -0
- package/dist/lib/data-list-view.d.ts +21 -0
- package/dist/lib/data-list-view.js +25 -0
- package/dist/lib/data-list-view.js.map +1 -0
- package/dist/lib/date-filter.d.ts +22 -0
- package/dist/lib/date-filter.js +61 -0
- package/dist/lib/date-filter.js.map +1 -0
- package/dist/lib/dev-log.d.ts +8 -0
- package/dist/lib/dev-log.js +10 -0
- package/dist/lib/dev-log.js.map +1 -0
- package/dist/lib/dropdown-menu-surface.d.ts +14 -0
- package/dist/lib/dropdown-menu-surface.js +6 -0
- package/dist/lib/dropdown-menu-surface.js.map +1 -0
- package/dist/lib/editable-target.d.ts +12 -0
- package/dist/lib/editable-target.js +12 -0
- package/dist/lib/editable-target.js.map +1 -0
- package/dist/lib/list-page-table-properties.d.ts +35 -0
- package/dist/lib/list-page-table-properties.js +81 -0
- package/dist/lib/list-page-table-properties.js.map +1 -0
- package/dist/lib/raf-throttle.d.ts +23 -0
- package/dist/lib/raf-throttle.js +27 -0
- package/dist/lib/raf-throttle.js.map +1 -0
- package/dist/lib/row-height.d.ts +16 -0
- package/dist/lib/row-height.js +10 -0
- package/dist/lib/row-height.js.map +1 -0
- package/dist/lib/table-properties-types.d.ts +83 -0
- package/dist/lib/table-properties-types.js +19 -0
- package/dist/lib/table-properties-types.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +83 -19
- package/src/components/data-table/filter-date-calendar.tsx +38 -0
- package/src/components/data-table/filter-text-value-input.tsx +77 -0
- package/src/components/data-table/index.tsx +1678 -0
- package/src/components/data-table/pagination.tsx +255 -0
- package/src/components/data-table/types.ts +96 -0
- package/src/components/data-table/use-table-state.ts +767 -0
- package/src/components/data-views/board-card-primitives.tsx +93 -0
- package/src/components/data-views/data-row-list.tsx +183 -0
- package/src/components/data-views/finder-panel-view.tsx +405 -0
- package/src/components/data-views/folder-grid-view.tsx +86 -0
- package/src/components/data-views/hub-table.tsx +498 -0
- package/src/components/data-views/index.ts +28 -0
- package/src/components/data-views/list-page-board-card.tsx +192 -0
- package/src/components/data-views/list-page-board-template.tsx +122 -0
- package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
- package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
- package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
- package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
- package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
- package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
- package/src/components/data-views/os-folder-glyph.tsx +141 -0
- package/src/components/data-views/outline-tree-menu.tsx +157 -0
- package/src/components/table-properties/column-row.tsx +90 -0
- package/src/components/table-properties/draggable-list.ts +54 -0
- package/src/components/table-properties/drawer-button.tsx +300 -0
- package/src/components/table-properties/drawer.tsx +1148 -0
- package/src/components/table-properties/filter-card.tsx +251 -0
- package/src/components/table-properties/index.ts +36 -0
- package/src/components/table-properties/sort-card.tsx +63 -0
- package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
- package/src/components/templates/dedicated-search-results-template.tsx +19 -0
- package/src/components/templates/index.ts +33 -0
- package/src/components/templates/list-page.tsx +602 -0
- package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
- package/src/components/ui/accordion.tsx +92 -0
- package/src/components/ui/alert-dialog.tsx +221 -0
- package/src/components/ui/avatar.tsx +13 -2
- package/src/components/ui/banner.tsx +2 -2
- package/src/components/ui/button.tsx +4 -4
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/coach-mark.tsx +1 -1
- package/src/components/ui/context-menu.tsx +291 -0
- package/src/components/ui/date-picker-field.tsx +2 -2
- package/src/components/ui/dot-pattern.tsx +183 -0
- package/src/components/ui/export-drawer.tsx +375 -0
- package/src/components/ui/hover-card.tsx +66 -0
- package/src/components/ui/key-metrics-context.tsx +78 -0
- package/src/components/ui/key-metrics.tsx +1133 -0
- package/src/components/ui/list-page-view-frame.tsx +64 -0
- package/src/components/ui/page-header.tsx +244 -0
- package/src/components/ui/payment-card-fields.tsx +2 -2
- package/src/components/ui/resizable.tsx +68 -0
- package/src/components/ui/scroll-area.tsx +72 -0
- package/src/components/ui/selection-tile-grid.tsx +9 -2
- package/src/components/ui/sidebar.tsx +84 -12
- package/src/components/ui/slider.tsx +83 -0
- package/src/globals.css +2201 -7
- package/src/globals.d.ts +20 -0
- package/src/index.ts +68 -1
- package/src/lib/conditional-rule-match.ts +119 -0
- package/src/lib/data-list-display-options.ts +35 -0
- package/src/lib/data-list-view-registry.ts +104 -0
- package/src/lib/data-list-view-surface.ts +83 -0
- package/src/lib/data-list-view.ts +47 -0
- package/src/lib/dev-log.ts +10 -0
- package/src/lib/editable-target.ts +20 -0
- package/src/lib/list-page-table-properties.ts +48 -0
- package/src/lib/raf-throttle.ts +45 -0
- package/src/lib/row-height.ts +19 -0
- package/src/lib/table-properties-types.ts +98 -0
- package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
- package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
- package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +104 -78
- package/template/app/(app)/dashboard/loading.tsx +15 -3
- package/template/app/(app)/dashboard/page.tsx +14 -2
- package/template/app/(app)/examples/page.tsx +0 -2
- package/template/app/(app)/layout.tsx +17 -4
- package/template/app/(app)/loading.tsx +18 -1
- package/template/app/(app)/question-bank/find/page.tsx +1 -2
- package/template/app/(app)/question-bank/layout.tsx +1 -1
- package/template/app/(app)/question-bank/library/page.tsx +1 -2
- package/template/app/(app)/question-bank/list/page.tsx +1 -2
- package/template/app/(app)/question-bank/new/page.tsx +15 -20
- package/template/app/(app)/question-bank/page.tsx +1 -2
- package/template/app/(app)/settings/page.tsx +5 -4
- package/template/app/globals.css +14 -16
- package/template/components/ask-leo-sidebar.tsx +5 -1
- package/template/components/brand-color-picker.tsx +2 -2
- package/template/components/charts-overview.tsx +1 -1
- package/template/components/compliance-board-view.tsx +142 -0
- package/template/components/compliance-client.tsx +92 -0
- package/template/components/compliance-page-header.tsx +89 -0
- package/template/components/compliance-table.tsx +468 -0
- package/template/components/dashboard-report-charts.tsx +1 -1
- package/template/components/dashboard-tabs.tsx +1 -1
- package/template/components/data-table/filter-date-calendar.tsx +1 -38
- package/template/components/data-table/filter-text-value-input.tsx +1 -77
- package/template/components/data-table/index.tsx +1 -1634
- package/template/components/data-table/pagination.tsx +1 -255
- package/template/components/data-table/types.ts +1 -94
- package/template/components/data-table/use-table-state.test.ts +420 -0
- package/template/components/data-table/use-table-state.ts +1 -758
- package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
- package/template/components/data-view-dashboard-charts-team.tsx +971 -0
- package/template/components/data-view-dashboard-charts.tsx +1503 -0
- package/template/components/data-views/board-card-primitives.tsx +1 -93
- package/template/components/data-views/data-row-list.tsx +1 -183
- package/template/components/data-views/finder-panel-view.tsx +1 -405
- package/template/components/data-views/folder-grid-view.tsx +1 -86
- package/template/components/data-views/hub-table.tsx +1 -0
- package/template/components/data-views/index.ts +50 -37
- package/template/components/data-views/list-page-board-card.tsx +1 -192
- package/template/components/data-views/list-page-board-template.tsx +1 -122
- package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
- package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
- package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
- package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
- package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
- package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
- package/template/components/data-views/list-page-view-frame.tsx +5 -53
- package/template/components/data-views/os-folder-glyph.tsx +1 -129
- package/template/components/data-views/outline-tree-menu.tsx +1 -157
- package/template/components/export-drawer.test.tsx +71 -0
- package/template/components/export-drawer.tsx +1 -375
- package/template/components/exxat-product-logo.tsx +5 -5
- package/template/components/hub-tree-panel-view.tsx +2 -2
- package/template/components/invite-collaborators-drawer.tsx +3 -3
- package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
- package/template/components/key-metrics.tsx +1 -1063
- package/template/components/leo-insight-indicator.tsx +2 -2
- package/template/components/new-placement-back-btn.tsx +28 -0
- package/template/components/new-placement-form.tsx +942 -0
- package/template/components/new-question-composer.tsx +456 -408
- package/template/components/onboarding/index.ts +9 -0
- package/template/components/onboarding/onboarding-01.tsx +1 -1
- package/template/components/onboarding/onboarding-02.tsx +1 -1
- package/template/components/onboarding/onboarding-03.tsx +1 -1
- package/template/components/onboarding/onboarding-04.tsx +1 -1
- package/template/components/page-header.tsx +8 -226
- package/template/components/placement-board-card.tsx +250 -0
- package/template/components/placement-detail.tsx +438 -0
- package/template/components/placements-board-view.tsx +397 -0
- package/template/components/placements-client.tsx +220 -0
- package/template/components/placements-list-view.tsx +124 -0
- package/template/components/placements-page-header.tsx +166 -0
- package/template/components/placements-table-cells.test.tsx +22 -0
- package/template/components/placements-table-cells.tsx +173 -0
- package/template/components/placements-table-columns.tsx +210 -0
- package/template/components/placements-table.tsx +934 -0
- package/template/components/product-switcher.tsx +3 -4
- package/template/components/product-wordmark.tsx +2 -1
- package/template/components/question-bank-client.tsx +5 -5
- package/template/components/question-bank-hub-client.tsx +1 -1
- package/template/components/question-bank-new-folder-sheet.tsx +2 -2
- package/template/components/question-bank-secondary-nav.tsx +3 -3
- package/template/components/question-bank-table.tsx +541 -431
- package/template/components/rotations-empty-state.tsx +50 -0
- package/template/components/rotations-panel-activator.tsx +8 -0
- package/template/components/settings-appearance-card.tsx +3 -4
- package/template/components/settings-client.tsx +15 -59
- package/template/components/settings-form-row.tsx +4 -9
- package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
- package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
- package/template/components/sidebar/index.ts +16 -0
- package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
- package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
- package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
- package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
- package/template/components/site-header.tsx +1 -1
- package/template/components/sites-board-view.tsx +67 -0
- package/template/components/sites-client.tsx +154 -0
- package/template/components/sites-table.tsx +249 -0
- package/template/components/table-properties/column-row.tsx +1 -90
- package/template/components/table-properties/draggable-list.ts +1 -49
- package/template/components/table-properties/drawer-button.tsx +1 -262
- package/template/components/table-properties/drawer.tsx +1 -1166
- package/template/components/table-properties/filter-card.tsx +1 -251
- package/template/components/table-properties/sort-card.tsx +1 -59
- package/template/components/table-properties/types.ts +28 -71
- package/template/components/team-board-view.tsx +122 -0
- package/template/components/team-client.tsx +100 -0
- package/template/components/team-page-header.tsx +92 -0
- package/template/components/team-table.tsx +553 -0
- package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
- package/template/components/templates/dedicated-search-results-template.tsx +1 -19
- package/template/components/templates/list-page.tsx +1 -608
- package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
- package/template/components/templates/new-focus-template.tsx +659 -0
- package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
- package/template/components/ui/accordion.tsx +1 -0
- package/template/components/ui/alert-dialog.tsx +1 -0
- package/template/components/ui/context-menu.tsx +1 -0
- package/template/components/ui/dot-pattern.tsx +1 -183
- package/template/components/ui/hover-card.tsx +1 -0
- package/template/components/ui/resizable.tsx +1 -68
- package/template/components/ui/scroll-area.tsx +1 -0
- package/template/components/ui/slider.tsx +1 -0
- package/template/docs/blueprints/README.md +86 -0
- package/template/docs/blueprints/_template.md +91 -0
- package/template/docs/blueprints/board-card.md +123 -0
- package/template/docs/blueprints/data-table.md +139 -0
- package/template/docs/blueprints/key-metrics.md +128 -0
- package/template/docs/blueprints/list-page-template.md +123 -0
- package/template/docs/blueprints/page-header.md +130 -0
- package/template/docs/command-menu-pattern.md +1 -1
- package/template/docs/component-selection-guide.md +224 -0
- package/template/docs/components-audit-2026-05.md +158 -0
- package/template/docs/data-views-pattern.md +17 -54
- package/template/docs/drawer-vs-dialog-pattern.md +1 -3
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
- package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
- package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
- package/template/docs/migrations/README.md +100 -0
- package/template/docs/migrations/_template.md +64 -0
- package/template/docs/shell-surface-elevation-pattern.md +3 -5
- package/template/docs/token-taxonomy.md +416 -0
- package/template/eslint.config.mjs +27 -0
- package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template/lib/command-menu-config.ts +0 -1
- package/template/lib/command-menu-search-data.ts +27 -11
- package/template/lib/compliance-supported-views.ts +10 -0
- package/template/lib/conditional-rule-match.ts +6 -97
- package/template/lib/data-list-display-options.ts +1 -49
- package/template/lib/data-list-view-registry.ts +1 -104
- package/template/lib/data-list-view-surface.ts +1 -83
- package/template/lib/data-list-view.ts +1 -47
- package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
- package/template/lib/data-view-dashboard-storage.ts +35 -38
- package/template/lib/dev-log.ts +1 -8
- package/template/lib/editable-target.ts +1 -10
- package/template/lib/list-page-table-properties.ts +1 -48
- package/template/lib/list-status-badges.ts +97 -4
- package/template/lib/mock/compliance-kpi.ts +61 -0
- package/template/lib/mock/compliance.ts +146 -0
- package/template/lib/mock/navigation.tsx +0 -9
- package/template/lib/mock/placements-kpi.ts +134 -0
- package/template/lib/mock/placements.ts +176 -0
- package/template/lib/mock/sites-directory.ts +16 -0
- package/template/lib/mock/sites-kpi.ts +25 -0
- package/template/lib/mock/team-kpi.ts +60 -0
- package/template/lib/mock/team.ts +118 -0
- package/template/lib/placement-board-card-layout.ts +79 -0
- package/template/lib/placements-supported-views.ts +12 -0
- package/template/lib/question-bank-supported-views.ts +0 -1
- package/template/lib/raf-throttle.ts +1 -45
- package/template/lib/row-height.ts +4 -10
- package/template/lib/sidebar-state-cookie.ts +11 -2
- package/template/lib/sites-supported-views.ts +10 -0
- package/template/lib/table-state-lifecycle.ts +2 -2
- package/template/lib/team-supported-views.ts +10 -0
- package/template/package.json +1 -0
- package/template/tests/setup.ts +25 -0
- package/consumer-extras/AGENTS.md +0 -76
- package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
- package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
- package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
- package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
- package/src/components/ui/button-group.tsx +0 -81
- package/src/theme.css +0 -16
- package/src/tokens/README.md +0 -15
- package/src/tokens/base.css +0 -337
- package/src/tokens/high-contrast.css +0 -1195
- package/src/tokens/layers.css +0 -224
- package/src/tokens/tailwind-bridge.css +0 -118
- package/src/tokens/themes.css +0 -201
- package/template/app/(app)/data-list/layout.tsx +0 -43
- package/template/app/(app)/data-list/page.tsx +0 -10
- package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
- package/template/components/app-route-loading.tsx +0 -14
- package/template/components/dashboard-onboarding-gallery.tsx +0 -13
- package/template/components/dashboard-onboarding.tsx +0 -21
- package/template/components/data-views/list-page-calendar-view.tsx +0 -593
- package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
- package/template/components/examples/focused-workflow-showcase.tsx +0 -183
- package/template/components/list-hub-board-view.tsx +0 -68
- package/template/components/list-hub-client.tsx +0 -186
- package/template/components/list-hub-list-view.tsx +0 -36
- package/template/components/list-hub-panel-activator.tsx +0 -8
- package/template/components/list-hub-secondary-nav.tsx +0 -121
- package/template/components/list-hub-table.tsx +0 -336
- package/template/components/question-bank-folder-columns-panel.tsx +0 -104
- package/template/components/question-bank-list-view.tsx +0 -53
- package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
- package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
- package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
- package/template/components/secondary-panels/registry.tsx +0 -15
- package/template/components/section-cards.tsx +0 -106
- package/template/components/templates/focused-workflow-layouts.tsx +0 -448
- package/template/components/templates/focused-workflow-page-template.tsx +0 -69
- package/template/components/templates/page-loading-shell.tsx +0 -262
- package/template/components/ui/button-group.tsx +0 -1
- package/template/docs/consumer-app-pattern.md +0 -39
- package/template/docs/focused-workflow-page-pattern.md +0 -84
- package/template/lib/list-hub-nav.ts +0 -121
- package/template/lib/mock/list-hub-directory.ts +0 -27
- package/template/lib/mock/list-hub-kpi.ts +0 -27
- package/template/lib/page-loading-variant.ts +0 -40
- /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
- /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
- /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
- /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
- /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
- /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rotations hub — main canvas when no rotation detail is selected.
|
|
5
|
+
* Pairs with SecondaryPanel (nested sidebar); CTA reopens the panel if closed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Button } from "@/components/ui/button"
|
|
9
|
+
import { useSecondaryPanel } from "@/components/sidebar"
|
|
10
|
+
|
|
11
|
+
export function RotationsEmptyState() {
|
|
12
|
+
const { openPanel } = useSecondaryPanel()
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<section
|
|
16
|
+
aria-labelledby="rotations-empty-title"
|
|
17
|
+
className="flex flex-1 flex-col items-center justify-center rounded-xl border border-dashed border-border/80 bg-muted/25 px-6 py-12 text-center min-h-[min(420px,calc(100svh-var(--header-height)-6rem))]"
|
|
18
|
+
>
|
|
19
|
+
<div className="mb-6 w-full max-w-[min(100%,280px)] shrink-0">
|
|
20
|
+
{/* Static SVG hero, above the fold — next/image can't optimize SVGs
|
|
21
|
+
without `dangerouslyAllowSVG`, and lazy-loading is wrong here. */}
|
|
22
|
+
{/* eslint-disable-next-line @next/next/no-img-element -- SVG; next/image can't optimize without dangerouslyAllowSVG */}
|
|
23
|
+
<img
|
|
24
|
+
src="/Illustration/Rotation.svg"
|
|
25
|
+
alt=""
|
|
26
|
+
width={622}
|
|
27
|
+
height={559}
|
|
28
|
+
decoding="async"
|
|
29
|
+
className="h-auto w-full select-none"
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
<h2
|
|
33
|
+
id="rotations-empty-title"
|
|
34
|
+
className="font-heading text-xl font-semibold tracking-tight text-foreground sm:text-2xl"
|
|
35
|
+
>
|
|
36
|
+
Select a rotation
|
|
37
|
+
</h2>
|
|
38
|
+
<p className="mt-2 max-w-md text-sm leading-relaxed text-muted-foreground">
|
|
39
|
+
Use the rotations panel next to the sidebar to browse cycles, open a rotation for
|
|
40
|
+
details, or review schedules and assigned students.
|
|
41
|
+
</p>
|
|
42
|
+
<div className="mt-8 flex flex-wrap items-center justify-center gap-3">
|
|
43
|
+
<Button type="button" size="lg" onClick={() => openPanel("rotations")}>
|
|
44
|
+
<i className="fa-light fa-sidebar text-[15px]" aria-hidden="true" />
|
|
45
|
+
Open rotations panel
|
|
46
|
+
</Button>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
@@ -518,7 +518,7 @@ export function SettingsAppearanceCard() {
|
|
|
518
518
|
)
|
|
519
519
|
|
|
520
520
|
return (
|
|
521
|
-
|
|
521
|
+
<section id="appearance" className="scroll-mt-20">
|
|
522
522
|
<header className="mb-8 space-y-1">
|
|
523
523
|
<h2 className="text-lg font-semibold text-foreground">Appearance & display</h2>
|
|
524
524
|
<p className="text-sm text-muted-foreground">Saved in this browser.</p>
|
|
@@ -529,7 +529,6 @@ export function SettingsAppearanceCard() {
|
|
|
529
529
|
) : (
|
|
530
530
|
<FieldGroup className="gap-8">
|
|
531
531
|
<SettingsFormRow
|
|
532
|
-
layout="stacked"
|
|
533
532
|
label="Products"
|
|
534
533
|
description="Recolour the brand mark + wordmark for each product. Switch the active product from the sidebar."
|
|
535
534
|
>
|
|
@@ -623,7 +622,7 @@ export function SettingsAppearanceCard() {
|
|
|
623
622
|
side="top"
|
|
624
623
|
>
|
|
625
624
|
<span
|
|
626
|
-
className="inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[
|
|
625
|
+
className="inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium uppercase tracking-wide text-foreground"
|
|
627
626
|
aria-label="Active product"
|
|
628
627
|
>
|
|
629
628
|
<i
|
|
@@ -863,6 +862,6 @@ export function SettingsAppearanceCard() {
|
|
|
863
862
|
</DialogFooter>
|
|
864
863
|
</DialogContent>
|
|
865
864
|
</Dialog>
|
|
866
|
-
|
|
865
|
+
</section>
|
|
867
866
|
)
|
|
868
867
|
}
|
|
@@ -39,19 +39,6 @@ import { SettingsAppearanceCard } from "@/components/settings-appearance-card"
|
|
|
39
39
|
import { SettingsFormRow } from "@/components/settings-form-row"
|
|
40
40
|
import { FieldGroup } from "@/components/ui/field"
|
|
41
41
|
import { FilterTextValueInput } from "@/components/data-table/filter-text-value-input"
|
|
42
|
-
import {
|
|
43
|
-
FocusedWorkflowSidebarSections,
|
|
44
|
-
type FocusedWorkflowSidebarSection,
|
|
45
|
-
} from "@/components/templates/focused-workflow-layouts"
|
|
46
|
-
import { PageHeader } from "@/components/page-header"
|
|
47
|
-
|
|
48
|
-
const SETTINGS_SECTIONS: readonly FocusedWorkflowSidebarSection[] = [
|
|
49
|
-
{ id: "account", label: "Account" },
|
|
50
|
-
{ id: "appearance", label: "Appearance" },
|
|
51
|
-
{ id: "input-formats", label: "Input formats" },
|
|
52
|
-
{ id: "banner", label: "System banner" },
|
|
53
|
-
{ id: "tours", label: "Guided tours" },
|
|
54
|
-
]
|
|
55
42
|
|
|
56
43
|
const SYSTEM_BANNER_VARIANTS: SystemBannerVariant[] = [
|
|
57
44
|
"info",
|
|
@@ -376,32 +363,8 @@ function buildFlowStatuses() {
|
|
|
376
363
|
}))
|
|
377
364
|
}
|
|
378
365
|
|
|
379
|
-
function sectionIdFromHash(hash: string): string {
|
|
380
|
-
const id = hash.startsWith("#") ? hash.slice(1) : hash
|
|
381
|
-
if (id && SETTINGS_SECTIONS.some(s => s.id === id)) return id
|
|
382
|
-
return SETTINGS_SECTIONS[0]!.id
|
|
383
|
-
}
|
|
384
|
-
|
|
385
366
|
export function SettingsClient() {
|
|
386
367
|
const router = useRouter()
|
|
387
|
-
const [activeSection, setActiveSection] = React.useState(() =>
|
|
388
|
-
typeof window !== "undefined" ? sectionIdFromHash(window.location.hash) : SETTINGS_SECTIONS[0]!.id,
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
React.useEffect(() => {
|
|
392
|
-
const syncFromHash = () => {
|
|
393
|
-
const id = sectionIdFromHash(window.location.hash)
|
|
394
|
-
setActiveSection(id)
|
|
395
|
-
if (window.location.hash) {
|
|
396
|
-
requestAnimationFrame(() => {
|
|
397
|
-
document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" })
|
|
398
|
-
})
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
syncFromHash()
|
|
402
|
-
window.addEventListener("hashchange", syncFromHash)
|
|
403
|
-
return () => window.removeEventListener("hashchange", syncFromHash)
|
|
404
|
-
}, [])
|
|
405
368
|
|
|
406
369
|
const [demoPhone, setDemoPhone] = React.useState("")
|
|
407
370
|
const [demoZip, setDemoZip] = React.useState("")
|
|
@@ -440,27 +403,20 @@ export function SettingsClient() {
|
|
|
440
403
|
}
|
|
441
404
|
|
|
442
405
|
return (
|
|
443
|
-
<
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
title="Settings"
|
|
458
|
-
subtitle="Preferences and tools for this workspace. Display options apply on this device and are stored in your browser."
|
|
459
|
-
className="px-0 pt-0 pb-0 lg:px-0"
|
|
460
|
-
/>
|
|
461
|
-
}
|
|
462
|
-
>
|
|
463
|
-
<div className="flex flex-col gap-20">
|
|
406
|
+
<div className="flex w-full min-w-0 flex-col">
|
|
407
|
+
<div>
|
|
408
|
+
<h1
|
|
409
|
+
className="text-2xl font-semibold tracking-tight leading-tight text-foreground"
|
|
410
|
+
style={{ fontFamily: "var(--font-heading)" }}
|
|
411
|
+
>
|
|
412
|
+
Settings
|
|
413
|
+
</h1>
|
|
414
|
+
<p className="mt-1 text-sm leading-relaxed text-muted-foreground">
|
|
415
|
+
Preferences and tools for this workspace. Display options apply on this device and are stored in your browser.
|
|
416
|
+
</p>
|
|
417
|
+
</div>
|
|
418
|
+
|
|
419
|
+
<div className="mt-10 flex flex-col gap-20">
|
|
464
420
|
<section id="account" className="scroll-mt-20">
|
|
465
421
|
<header className="mb-6 space-y-1">
|
|
466
422
|
<h2 className="text-lg font-semibold text-foreground">Account</h2>
|
|
@@ -578,6 +534,6 @@ export function SettingsClient() {
|
|
|
578
534
|
</div>
|
|
579
535
|
</section>
|
|
580
536
|
</div>
|
|
581
|
-
</
|
|
537
|
+
</div>
|
|
582
538
|
)
|
|
583
539
|
}
|
|
@@ -5,7 +5,7 @@ import { Label } from "@/components/ui/label"
|
|
|
5
5
|
import { cn } from "@/lib/utils"
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Two-column settings row: label + helper on the left, controls on the right.
|
|
9
9
|
*/
|
|
10
10
|
export function SettingsFormRow({
|
|
11
11
|
label,
|
|
@@ -13,27 +13,22 @@ export function SettingsFormRow({
|
|
|
13
13
|
htmlFor,
|
|
14
14
|
children,
|
|
15
15
|
className,
|
|
16
|
-
layout = "inline",
|
|
17
16
|
}: {
|
|
18
17
|
label: string
|
|
19
18
|
description?: string
|
|
20
19
|
htmlFor?: string
|
|
21
20
|
children: React.ReactNode
|
|
22
21
|
className?: string
|
|
23
|
-
/** `stacked` — label block above full-width controls (wide panels, product lists). */
|
|
24
|
-
layout?: "inline" | "stacked"
|
|
25
22
|
}) {
|
|
26
23
|
return (
|
|
27
24
|
<div
|
|
28
25
|
className={cn(
|
|
29
|
-
"grid grid-cols-1 gap-3 sm:gap-4
|
|
30
|
-
|
|
31
|
-
"lg:grid-cols-[minmax(0,220px)_minmax(0,1fr)] lg:gap-10 lg:items-start",
|
|
32
|
-
layout === "stacked" && "gap-4",
|
|
26
|
+
"grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-[minmax(0,220px)_minmax(0,1fr)] lg:gap-10 lg:items-start",
|
|
27
|
+
"border-b border-border/70 pb-8 last:border-0 last:pb-0",
|
|
33
28
|
className,
|
|
34
29
|
)}
|
|
35
30
|
>
|
|
36
|
-
<div className="space-y-1
|
|
31
|
+
<div className="space-y-1 lg:pt-1 text-start">
|
|
37
32
|
<Label htmlFor={htmlFor} className="text-sm font-medium text-foreground">
|
|
38
33
|
{label}
|
|
39
34
|
</Label>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Radix ID mismatch is suppressed at the CollapsibleContent level instead.
|
|
8
8
|
*/
|
|
9
9
|
import type { ComponentProps } from "react"
|
|
10
|
-
import { AppSidebar } from "
|
|
10
|
+
import { AppSidebar } from "./app-sidebar"
|
|
11
11
|
import type { Sidebar } from "@/components/ui/sidebar"
|
|
12
12
|
|
|
13
13
|
export function AppSidebarDynamic(props: ComponentProps<typeof Sidebar>) {
|
|
@@ -67,8 +67,8 @@ import { useModKeyLabel } from "@/hooks/use-mod-key-label"
|
|
|
67
67
|
import { useLocationHash } from "@/hooks/use-location-hash"
|
|
68
68
|
import { useSidebarReflowZoom } from "@/hooks/use-sidebar-reflow-zoom"
|
|
69
69
|
import { useProduct, type Product } from "@/contexts/product-context"
|
|
70
|
-
import { NavUser } from "
|
|
71
|
-
import { useSecondaryPanel } from "
|
|
70
|
+
import { NavUser } from "./nav-user"
|
|
71
|
+
import { useSecondaryPanel } from "./secondary-panel"
|
|
72
72
|
import { ExxatProductLogo, ExxatProductMark } from "@/components/exxat-product-logo"
|
|
73
73
|
import { motionHeaderEnter } from "@/lib/motion-ui"
|
|
74
74
|
import { customProductBrandConfig, productBrandLabel } from "@/lib/product-brand"
|
|
@@ -105,22 +105,11 @@ function normalizedLocationHash(locationHash: string): string {
|
|
|
105
105
|
return locationHash.startsWith("#") ? locationHash.slice(1) : locationHash
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
/**
|
|
109
|
-
* Paths where a sibling sidebar row uses `#fragment` on the same pathname
|
|
110
|
-
* (e.g. Settings vs Tokens & themes). The plain-path row must not stay active
|
|
111
|
-
* when the hash belongs to that sibling.
|
|
112
|
-
*/
|
|
113
|
-
const NAV_EXCLUSIVE_HASH_BY_PATH: Readonly<Record<string, readonly string[]>> = {
|
|
114
|
-
"/settings": ["appearance"],
|
|
115
|
-
"/help": ["more"],
|
|
116
|
-
}
|
|
117
|
-
|
|
118
108
|
/**
|
|
119
109
|
* Whether `pathname` (+ optional `location.hash`) matches a sidebar `href`.
|
|
120
110
|
* When several links share the same path (e.g. `/settings`), disambiguate with `#fragment`
|
|
121
111
|
* in each `href` — those rows use the `frag !== null` branch below.
|
|
122
|
-
* For `href` without `#…`, an in-page hash (e.g. QB view tabs) does not clear the match
|
|
123
|
-
* except when the hash is reserved for a hash-sibling row on that path.
|
|
112
|
+
* For `href` without `#…`, an in-page hash (e.g. QB view tabs) does not clear the match.
|
|
124
113
|
*/
|
|
125
114
|
function isNavActive(pathname: string, url: string, locationHash = ""): boolean {
|
|
126
115
|
const pathOnly = navUrlPath(url)
|
|
@@ -142,13 +131,7 @@ function isNavActive(pathname: string, url: string, locationHash = ""): boolean
|
|
|
142
131
|
|
|
143
132
|
if (pathOnly === "/") return pathname === "/" && h === ""
|
|
144
133
|
/** Exact path match — ignore `location.hash` when the nav `href` has no `#…` fragment (QB view tabs use hash). */
|
|
145
|
-
if (pathname === pathOnly)
|
|
146
|
-
if (h !== "") {
|
|
147
|
-
const exclusive = NAV_EXCLUSIVE_HASH_BY_PATH[pathOnly]
|
|
148
|
-
if (exclusive?.includes(h)) return false
|
|
149
|
-
}
|
|
150
|
-
return true
|
|
151
|
-
}
|
|
134
|
+
if (pathname === pathOnly) return true
|
|
152
135
|
// Design system library — active on hub and detail routes.
|
|
153
136
|
if (pathOnly === "/library") {
|
|
154
137
|
return pathname.startsWith("/library/")
|
|
@@ -440,7 +423,7 @@ function CollapsibleNavItem({ item, pathname }: { item: NavLinkItem; pathname: s
|
|
|
440
423
|
</span>
|
|
441
424
|
<span>{item.title}</span>
|
|
442
425
|
<i
|
|
443
|
-
className="fa-light fa-chevron-right
|
|
426
|
+
className="fa-light fa-chevron-right ms-auto text-xs text-current transition-transform duration-200 ease-out group-data-[state=open]/collapsible:rotate-90 motion-reduce:transition-none"
|
|
444
427
|
aria-hidden="true"
|
|
445
428
|
/>
|
|
446
429
|
</SidebarMenuButton>
|
|
@@ -844,58 +827,60 @@ function ProductLogoButton() {
|
|
|
844
827
|
|
|
845
828
|
return (
|
|
846
829
|
<DropdownMenu>
|
|
847
|
-
<
|
|
848
|
-
<
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
830
|
+
<Tooltip>
|
|
831
|
+
<TooltipTrigger asChild>
|
|
832
|
+
<DropdownMenuTrigger asChild>
|
|
833
|
+
<SidebarMenuButton
|
|
834
|
+
size="lg"
|
|
835
|
+
className={cn(
|
|
836
|
+
"py-2 text-sidebar-foreground data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
|
|
837
|
+
expandedOrMobile &&
|
|
838
|
+
"h-auto min-h-12 !overflow-visible items-center [&>span:last-child]:!overflow-visible [&>span:last-child]:!whitespace-normal [&>span:last-child]:text-clip",
|
|
839
|
+
"group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:justify-center",
|
|
840
|
+
iconRail &&
|
|
841
|
+
"group-data-[collapsible=icon]:!size-9 group-data-[collapsible=icon]:!min-h-9 group-data-[collapsible=icon]:!max-h-9 group-data-[collapsible=icon]:!p-0 group-data-[collapsible=icon]:overflow-visible",
|
|
842
|
+
)}
|
|
843
|
+
aria-label={`Current product: ${current.label}. Switch product`}
|
|
844
|
+
suppressHydrationWarning
|
|
845
|
+
>
|
|
846
|
+
{iconRail ? (
|
|
847
|
+
// Match the school selector footprint in the icon rail (32px frame,
|
|
848
|
+
// 28px mark — same visual weight as the avatar with inset padding).
|
|
849
|
+
<span className="flex size-8 shrink-0 items-center justify-center">
|
|
850
|
+
<ExxatProductMark product={current.id} className="size-7" />
|
|
851
|
+
</span>
|
|
852
|
+
) : (
|
|
853
|
+
<span className="flex min-h-0 min-w-0 flex-1 items-stretch gap-2">
|
|
854
|
+
<span
|
|
855
|
+
className="flex min-h-0 min-w-0 flex-1 items-center justify-start overflow-visible"
|
|
856
|
+
aria-hidden="true"
|
|
857
|
+
>
|
|
858
|
+
<ExxatProductLogo
|
|
859
|
+
product={current.id}
|
|
860
|
+
variant="mutedSuffix"
|
|
861
|
+
className="w-auto max-w-[min(100%,280px)] object-left object-contain"
|
|
862
|
+
/>
|
|
863
|
+
</span>
|
|
864
|
+
<span
|
|
865
|
+
className="flex w-6 shrink-0 items-center justify-center self-stretch text-muted-foreground"
|
|
866
|
+
aria-hidden="true"
|
|
867
|
+
>
|
|
868
|
+
<i
|
|
869
|
+
className="fa-light fa-chevron-down block text-xs leading-none"
|
|
870
|
+
aria-hidden="true"
|
|
871
|
+
/>
|
|
872
|
+
</span>
|
|
873
|
+
</span>
|
|
874
|
+
)}
|
|
875
|
+
</SidebarMenuButton>
|
|
876
|
+
</DropdownMenuTrigger>
|
|
877
|
+
</TooltipTrigger>
|
|
878
|
+
<TooltipContent side="right" align="center" hidden={state !== "collapsed" || isMobile}>
|
|
879
|
+
{current.label}
|
|
880
|
+
</TooltipContent>
|
|
881
|
+
</Tooltip>
|
|
893
882
|
|
|
894
|
-
<DropdownMenuContent
|
|
895
|
-
align="start"
|
|
896
|
-
side={iconRail ? "right" : "bottom"}
|
|
897
|
-
sideOffset={iconRail ? 8 : 4}
|
|
898
|
-
>
|
|
883
|
+
<DropdownMenuContent align="start" side="right" sideOffset={8}>
|
|
899
884
|
<DropdownMenuLabel className="text-xs text-muted-foreground">
|
|
900
885
|
Switch product
|
|
901
886
|
</DropdownMenuLabel>
|
|
@@ -913,7 +898,7 @@ function ProductLogoButton() {
|
|
|
913
898
|
className="w-auto shrink-0 max-w-[min(100%,260px)]"
|
|
914
899
|
/>
|
|
915
900
|
{p.id === product && (
|
|
916
|
-
<i className="fa-solid fa-check
|
|
901
|
+
<i className="fa-solid fa-check ms-auto text-brand text-xs" aria-hidden="true" />
|
|
917
902
|
)}
|
|
918
903
|
</DropdownMenuItem>
|
|
919
904
|
))}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Barrel re-export for the sidebar shell.
|
|
2
|
+
// Consumers SHOULD import via `@/components/sidebar`; per-file paths still
|
|
3
|
+
// work as escape hatch (e.g. `@/components/sidebar/secondary-panel`).
|
|
4
|
+
//
|
|
5
|
+
// See apps/web/docs/components-audit-2026-05.md §2.3.
|
|
6
|
+
export * from "./app-sidebar"
|
|
7
|
+
export * from "./app-sidebar-dynamic"
|
|
8
|
+
export * from "./sidebar-shell"
|
|
9
|
+
export * from "./sidebar-auto-collapse"
|
|
10
|
+
export * from "./sidebar-auto-open"
|
|
11
|
+
export * from "./nav-main"
|
|
12
|
+
export * from "./nav-secondary"
|
|
13
|
+
export * from "./nav-documents"
|
|
14
|
+
export * from "./nav-user"
|
|
15
|
+
export * from "./secondary-nav"
|
|
16
|
+
export * from "./secondary-panel"
|
|
@@ -293,7 +293,7 @@ export function SecondaryNavPanel({
|
|
|
293
293
|
title={section.action.label}
|
|
294
294
|
onClick={section.action.onClick}
|
|
295
295
|
className={cn(
|
|
296
|
-
"inline-flex size-6 items-center justify-center rounded-md -
|
|
296
|
+
"inline-flex size-6 items-center justify-center rounded-md -me-1",
|
|
297
297
|
"text-muted-foreground hover:text-interactive-hover-foreground hover:bg-interactive-hover-strong",
|
|
298
298
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
299
299
|
)}
|
|
@@ -318,7 +318,7 @@ export function SecondaryNavPanel({
|
|
|
318
318
|
placeholder={section.searchPlaceholder ?? "Search"}
|
|
319
319
|
aria-label={`Search ${section.label}`}
|
|
320
320
|
className={cn(
|
|
321
|
-
"w-full h-7
|
|
321
|
+
"w-full h-7 ps-7 pe-2 rounded-md text-xs bg-background border border-border",
|
|
322
322
|
"placeholder:text-muted-foreground/70",
|
|
323
323
|
"focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent"
|
|
324
324
|
)}
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
* SecondaryPanel — nested rail between the primary icon sidebar and content.
|
|
5
5
|
* Full width shows hub scope nav; **compact** matches the primary sidebar icon rail (`w-12`).
|
|
6
6
|
*
|
|
7
|
-
* Chrome uses {@link NestedSecondaryPanelShell}.
|
|
8
|
-
* `
|
|
7
|
+
* Chrome uses {@link NestedSecondaryPanelShell}. Question bank body stays in
|
|
8
|
+
* `question-bank-secondary-nav.tsx` (domain-specific), not duplicated here.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import * as React from "react"
|
|
12
12
|
import { useSidebar } from "@/components/ui/sidebar"
|
|
13
|
+
import { Tip } from "@/components/ui/tip"
|
|
14
|
+
import { Button } from "@/components/ui/button"
|
|
15
|
+
import { QuestionBankSecondaryNav } from "@/components/question-bank-secondary-nav"
|
|
13
16
|
import { NestedSecondaryPanelShell } from "@/components/templates/nested-secondary-panel-shell"
|
|
14
|
-
import { SECONDARY_PANELS } from "@/components/secondary-panels/registry"
|
|
15
17
|
import { useSidebarReflowZoom } from "@/hooks/use-sidebar-reflow-zoom"
|
|
16
18
|
import type { QuestionBankItem } from "@/lib/mock/question-bank"
|
|
17
19
|
import type { QuestionBankFolder } from "@/lib/mock/question-bank-folders"
|
|
@@ -109,7 +111,10 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
|
|
|
109
111
|
// zoom this stays the legacy behavior (full-width on open).
|
|
110
112
|
setSecondaryPanelCompact(reflowZoom)
|
|
111
113
|
setActivePanel(id)
|
|
112
|
-
|
|
114
|
+
// `persist: false` — collapsing the rail to make room for the secondary
|
|
115
|
+
// panel is an incidental layout side-effect; the user's saved
|
|
116
|
+
// expanded/collapsed preference (cookie) must not be overwritten by it.
|
|
117
|
+
setOpen(false, { persist: false }) // collapse main sidebar to icon rail
|
|
113
118
|
},
|
|
114
119
|
[setOpen, reflowZoom],
|
|
115
120
|
)
|
|
@@ -120,9 +125,9 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
|
|
|
120
125
|
const mainSidebar = opts?.mainSidebar ?? "leave"
|
|
121
126
|
if (mainSidebar === "leave") return
|
|
122
127
|
if (mainSidebar === "collapse") {
|
|
123
|
-
setOpen(false)
|
|
128
|
+
setOpen(false, { persist: false })
|
|
124
129
|
} else {
|
|
125
|
-
setOpen(true) // expand main sidebar back
|
|
130
|
+
setOpen(true, { persist: false }) // expand main sidebar back
|
|
126
131
|
}
|
|
127
132
|
}, [setOpen])
|
|
128
133
|
|
|
@@ -164,9 +169,47 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
|
|
|
164
169
|
// SecondaryPanel — the actual rendered panel
|
|
165
170
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
166
171
|
|
|
172
|
+
function QuestionBankPanel() {
|
|
173
|
+
const { collapseActiveSecondaryPanel, secondaryPanelCompact } = useSecondaryPanel()
|
|
174
|
+
|
|
175
|
+
if (secondaryPanelCompact) {
|
|
176
|
+
return <QuestionBankSecondaryNav />
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<>
|
|
181
|
+
<div className="flex items-center justify-between gap-2 px-4 pt-4 pb-2">
|
|
182
|
+
<h2
|
|
183
|
+
className="text-xl font-semibold leading-tight text-sidebar-foreground"
|
|
184
|
+
style={{ fontFamily: "var(--font-heading)" }}
|
|
185
|
+
>
|
|
186
|
+
Library
|
|
187
|
+
</h2>
|
|
188
|
+
<Tip label="Collapse to icons" side="bottom">
|
|
189
|
+
<Button
|
|
190
|
+
type="button"
|
|
191
|
+
size="icon"
|
|
192
|
+
variant="ghost"
|
|
193
|
+
onClick={() => collapseActiveSecondaryPanel()}
|
|
194
|
+
aria-label="Collapse to icons"
|
|
195
|
+
>
|
|
196
|
+
<i className="fa-light fa-angles-left" aria-hidden="true" />
|
|
197
|
+
</Button>
|
|
198
|
+
</Tip>
|
|
199
|
+
</div>
|
|
200
|
+
<QuestionBankSecondaryNav />
|
|
201
|
+
</>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Register panel components by id when a route opts into `secondaryPanel` in nav. */
|
|
206
|
+
const PANELS: Record<string, React.FC> = {
|
|
207
|
+
"question-bank": QuestionBankPanel,
|
|
208
|
+
}
|
|
209
|
+
|
|
167
210
|
export function SecondaryPanel() {
|
|
168
211
|
const { activePanel, secondaryPanelCompact } = useSecondaryPanel()
|
|
169
|
-
const PanelContent = activePanel ?
|
|
212
|
+
const PanelContent = activePanel ? PANELS[activePanel] : null
|
|
170
213
|
|
|
171
214
|
return (
|
|
172
215
|
<NestedSecondaryPanelShell open={Boolean(activePanel)} compact={secondaryPanelCompact}>
|
|
@@ -7,6 +7,10 @@ import { useSidebar } from "@/components/ui/sidebar"
|
|
|
7
7
|
* Collapses the sidebar on mount. Restores previous state on unmount.
|
|
8
8
|
* Used on the new-placement page so the sidebar collapses when entering
|
|
9
9
|
* and reverts to whatever it was when leaving.
|
|
10
|
+
*
|
|
11
|
+
* Both transitions pass `{ persist: false }` so the visual collapse never
|
|
12
|
+
* overwrites the user's saved sidebar preference (the `sidebar_state_v2`
|
|
13
|
+
* cookie). Only an explicit toggle (⌘B / sidebar button) persists.
|
|
10
14
|
*/
|
|
11
15
|
export function SidebarAutoCollapse() {
|
|
12
16
|
const { open, setOpen } = useSidebar()
|
|
@@ -14,8 +18,8 @@ export function SidebarAutoCollapse() {
|
|
|
14
18
|
|
|
15
19
|
useEffect(() => {
|
|
16
20
|
prevOpen.current = open
|
|
17
|
-
setOpen(false)
|
|
18
|
-
return () => { setOpen(prevOpen.current) }
|
|
21
|
+
setOpen(false, { persist: false })
|
|
22
|
+
return () => { setOpen(prevOpen.current, { persist: false }) }
|
|
19
23
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20
24
|
}, [])
|
|
21
25
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* SidebarShell — SidebarProvider with layout-aware widths.
|
|
5
|
-
* Desktop expanded/collapsed is persisted in the `
|
|
5
|
+
* Desktop expanded/collapsed is persisted in the `sidebar_state_v2` cookie by `@exxatdesignux/ui`
|
|
6
6
|
* `SidebarProvider` (read on mount + write on toggle). `(app)/layout` passes
|
|
7
7
|
* `defaultOpen` from the same cookie on the server so SSR matches the first client paint.
|
|
8
8
|
*/
|