@exxatdesignux/ui 0.5.10 → 0.5.12
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 +37 -0
- package/bin/cli.mjs +70 -1
- package/bin/init.mjs +18 -4
- package/bin/sync-extras.mjs +28 -4
- package/consumer-extras/README.md +41 -5
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +13 -2
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +92 -12
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
- package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +70 -17
- package/consumer-extras/patterns/command-menu-pattern.md +2 -2
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
- package/consumer-extras/patterns/jobs/README.md +1 -1
- package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
- package/consumer-extras/scripts/dev-guard.mjs +156 -0
- package/consumer-extras/templates/README.md +23 -0
- package/consumer-extras/templates/handoff.md +190 -0
- package/dist/hooks/use-app-theme.d.ts +1 -1
- package/package.json +2 -2
- package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
- package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
- package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
- package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
- package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
- package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
- package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
- package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
- package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
- package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
- package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
- package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
- package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
- package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
- package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
- package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
- package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
- package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
- package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
- package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
- package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
- package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
- package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
- package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
- package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
- package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
- package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
- package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
- package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
- package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
- package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
- package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
- package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
- package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
- package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
- package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
- package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
- package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
- package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
- package/{template → template-vite}/components/command-menu.tsx +1 -1
- package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
- package/{template → template-vite}/components/library-client.tsx +1 -1
- package/{template → template-vite}/components/library-hub-client.tsx +2 -2
- package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/library-table.tsx +35 -27
- package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
- package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
- package/{template → template-vite}/components/settings-client.tsx +1 -1
- package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
- package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
- package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
- package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
- package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
- package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
- package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
- package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
- package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template-vite/index.html +49 -0
- package/template-vite/lib/next-compat.tsx +98 -0
- package/{template → template-vite}/package.json +15 -27
- package/template-vite/scripts/port-next-imports.mjs +70 -0
- package/template-vite/src/App.tsx +103 -0
- package/template-vite/src/main.tsx +50 -0
- package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
- package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
- package/template-vite/src/pages/_not-found.tsx +17 -0
- package/template-vite/src/pages/dashboard.tsx +48 -0
- package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
- package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
- package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
- package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
- package/template-vite/src/routes.tsx +72 -0
- package/{template/app → template-vite/src/styles}/globals.css +6 -2
- package/{template → template-vite}/tsconfig.json +5 -14
- package/template-vite/vite.config.ts +52 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
- package/template/.agents/skills/shadcn/SKILL.md +0 -242
- package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/shadcn/cli.md +0 -257
- package/template/.agents/skills/shadcn/customization.md +0 -202
- package/template/.agents/skills/shadcn/evals/evals.json +0 -47
- package/template/.agents/skills/shadcn/mcp.md +0 -94
- package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/shadcn/rules/composition.md +0 -195
- package/template/.agents/skills/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/shadcn/rules/styling.md +0 -162
- package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
- package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
- package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
- package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
- package/template/.nvmrc +0 -1
- package/template/.prettierignore +0 -7
- package/template/Logo/Exxat_Prism.svg +0 -39
- package/template/Logo/Exxat_one.svg +0 -36
- package/template/app/(app)/dashboard/loading.tsx +0 -18
- package/template/app/(app)/dashboard/page.tsx +0 -36
- package/template/app/(app)/layout.tsx +0 -77
- package/template/app/global-error.tsx +0 -63
- package/template/app/layout.tsx +0 -133
- package/template/app/page.tsx +0 -9
- package/template/docs/HANDBOOK.md +0 -187
- package/template/docs/blueprints/README.md +0 -86
- package/template/docs/blueprints/_template.md +0 -91
- package/template/docs/blueprints/board-card.md +0 -123
- package/template/docs/blueprints/data-table.md +0 -139
- package/template/docs/blueprints/key-metrics.md +0 -128
- package/template/docs/blueprints/list-page-template.md +0 -123
- package/template/docs/blueprints/page-header.md +0 -130
- package/template/docs/card-vs-rows-pattern.md +0 -36
- package/template/docs/collaboration-access-pattern.md +0 -116
- package/template/docs/command-menu-pattern.md +0 -45
- package/template/docs/component-selection-guide.md +0 -224
- package/template/docs/components-audit-2026-05.md +0 -158
- package/template/docs/consumer-upgrade-checklist.md +0 -52
- package/template/docs/data-views-pattern.md +0 -185
- package/template/docs/drawer-vs-dialog-pattern.md +0 -50
- package/template/docs/glossary.md +0 -59
- package/template/docs/hub-supported-views-pattern.md +0 -53
- package/template/docs/jobs/README.md +0 -59
- package/template/docs/jobs/record-detail.md +0 -177
- package/template/docs/kpi-flat-band-pattern.md +0 -57
- package/template/docs/kpi-strip-max-four-pattern.md +0 -30
- package/template/docs/kpi-trend-pattern.md +0 -58
- package/template/docs/large-dataset-strategy.md +0 -155
- package/template/docs/library-hub-header-pattern.md +0 -25
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
- package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
- package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
- package/template/docs/migrations/README.md +0 -100
- package/template/docs/migrations/_template.md +0 -64
- package/template/docs/modern-saas-patterns.md +0 -165
- package/template/docs/perf-memory-pattern.md +0 -206
- package/template/docs/reference-implementations.md +0 -153
- package/template/docs/shell-surface-elevation-pattern.md +0 -52
- package/template/docs/token-taxonomy.md +0 -416
- package/template/docs/voice-and-tone.md +0 -262
- package/template/ecosystem.config.cjs +0 -32
- package/template/next.config.mjs +0 -216
- package/template/postcss.config.mjs +0 -8
- package/template/public/favicon/favicon.ico +0 -0
- package/template/tests/setup.ts +0 -26
- package/template/vitest.config.ts +0 -18
- /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
- /package/{template → template-vite}/.prettierrc +0 -0
- /package/{template → template-vite}/AGENTS.md +0 -0
- /package/{template → template-vite}/README.md +0 -0
- /package/{template → template-vite}/components/.gitkeep +0 -0
- /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
- /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
- /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
- /package/{template → template-vite}/components/charts-overview.tsx +0 -0
- /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
- /package/{template → template-vite}/components/columns-client.tsx +0 -0
- /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
- /package/{template → template-vite}/components/data-table/index.tsx +0 -0
- /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
- /package/{template → template-vite}/components/data-table/types.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
- /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
- /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
- /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
- /package/{template → template-vite}/components/data-views/index.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
- /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
- /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
- /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
- /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.tsx +0 -0
- /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
- /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
- /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
- /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics.tsx +0 -0
- /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
- /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
- /package/{template → template-vite}/components/library-board-view.tsx +0 -0
- /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
- /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
- /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
- /package/{template → template-vite}/components/library-page-header.tsx +0 -0
- /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
- /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
- /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/index.ts +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
- /package/{template → template-vite}/components/page-header.tsx +0 -0
- /package/{template → template-vite}/components/product-switcher.tsx +0 -0
- /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
- /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
- /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/index.ts +0 -0
- /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
- /package/{template → template-vite}/components/site-header.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
- /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/index.ts +0 -0
- /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/types.ts +0 -0
- /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
- /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
- /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
- /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
- /package/{template → template-vite}/components/theme-provider.tsx +0 -0
- /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
- /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
- /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
- /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
- /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
- /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
- /package/{template → template-vite}/components/ui/badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/banner.tsx +0 -0
- /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
- /package/{template → template-vite}/components/ui/button.tsx +0 -0
- /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
- /package/{template → template-vite}/components/ui/card.tsx +0 -0
- /package/{template → template-vite}/components/ui/chart.tsx +0 -0
- /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
- /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
- /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
- /package/{template → template-vite}/components/ui/command.tsx +0 -0
- /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
- /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
- /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
- /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/field.tsx +0 -0
- /package/{template → template-vite}/components/ui/form.tsx +0 -0
- /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
- /package/{template → template-vite}/components/ui/input.tsx +0 -0
- /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
- /package/{template → template-vite}/components/ui/label.tsx +0 -0
- /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
- /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
- /package/{template → template-vite}/components/ui/popover.tsx +0 -0
- /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
- /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
- /package/{template → template-vite}/components/ui/select.tsx +0 -0
- /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
- /package/{template → template-vite}/components/ui/separator.tsx +0 -0
- /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
- /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
- /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
- /package/{template → template-vite}/components/ui/slider.tsx +0 -0
- /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
- /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/table.tsx +0 -0
- /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
- /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
- /package/{template → template-vite}/components/ui/tip.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
- /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
- /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
- /package/{template → template-vite}/components.json +0 -0
- /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
- /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
- /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
- /package/{template → template-vite}/contexts/product-context.tsx +0 -0
- /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
- /package/{template → template-vite}/eslint.config.mjs +0 -0
- /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
- /package/{template → template-vite}/hooks/.gitkeep +0 -0
- /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
- /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
- /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
- /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
- /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
- /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
- /package/{template → template-vite}/lib/.gitkeep +0 -0
- /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
- /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
- /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
- /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
- /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
- /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
- /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
- /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view.ts +0 -0
- /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
- /package/{template → template-vite}/lib/date-filter.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.ts +0 -0
- /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
- /package/{template → template-vite}/lib/editable-target.ts +0 -0
- /package/{template → template-vite}/lib/exxat-palette.json +0 -0
- /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
- /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
- /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
- /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
- /package/{template → template-vite}/lib/library-authoring.ts +0 -0
- /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
- /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
- /package/{template → template-vite}/lib/library-nav.ts +0 -0
- /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
- /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
- /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
- /package/{template → template-vite}/lib/logo-dev.ts +0 -0
- /package/{template → template-vite}/lib/mailto.ts +0 -0
- /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
- /package/{template → template-vite}/lib/mock/library.ts +0 -0
- /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
- /package/{template → template-vite}/lib/motion-ui.ts +0 -0
- /package/{template → template-vite}/lib/product-brand.ts +0 -0
- /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
- /package/{template → template-vite}/lib/row-height.ts +0 -0
- /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
- /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
- /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
- /package/{template → template-vite}/lib/utils.test.ts +0 -0
- /package/{template → template-vite}/lib/utils.ts +0 -0
- /package/{template → template-vite}/public/.gitkeep +0 -0
- /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
- /package/{template → template-vite}/public/avatars/user.svg +0 -0
- /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
- /package/{template/app → template-vite/public}/favicon.ico +0 -0
- /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
- /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
- /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
- /package/{template → template-vite}/skills-lock.json +0 -0
- /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
- /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
- /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
- /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
- /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
- /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
- /package/{template → template-vite}/stores/app-store.ts +0 -0
- /package/{template → template-vite}/types/react-payment-inputs.d.ts +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" class="theme-one">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Exxat Design System</title>
|
|
8
|
+
<meta
|
|
9
|
+
name="description"
|
|
10
|
+
content="Shared UI component library for Exxat One and Exxat Prism — built to WCAG 2.1 Level AA."
|
|
11
|
+
/>
|
|
12
|
+
<meta name="theme-color" content="#f6f3ff" />
|
|
13
|
+
|
|
14
|
+
<!--
|
|
15
|
+
Adobe Fonts — Ivy Presto · Kit ID: wuk5wqn.
|
|
16
|
+
crossorigin="" pairs the preconnect/preload/fetch as one CORS-correct
|
|
17
|
+
connection so the stylesheet cannot read first-party cookies.
|
|
18
|
+
-->
|
|
19
|
+
<link rel="preconnect" href="https://use.typekit.net" crossorigin="" />
|
|
20
|
+
<link rel="preconnect" href="https://p.typekit.net" crossorigin="" />
|
|
21
|
+
<link
|
|
22
|
+
rel="preload"
|
|
23
|
+
href="https://use.typekit.net/wuk5wqn.css"
|
|
24
|
+
as="style"
|
|
25
|
+
crossorigin=""
|
|
26
|
+
/>
|
|
27
|
+
<link
|
|
28
|
+
rel="stylesheet"
|
|
29
|
+
href="https://use.typekit.net/wuk5wqn.css"
|
|
30
|
+
crossorigin=""
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
<!--
|
|
34
|
+
Font Awesome Pro Kit. CSP/origins documented in the Vite config /
|
|
35
|
+
consumer hosting setup; the kit URL is content-versioned so SRI is
|
|
36
|
+
not applied — origin pinning + crossorigin="anonymous" is the
|
|
37
|
+
trust model.
|
|
38
|
+
-->
|
|
39
|
+
<script
|
|
40
|
+
src="https://kit.fontawesome.com/d9bd5774e0.js"
|
|
41
|
+
crossorigin="anonymous"
|
|
42
|
+
></script>
|
|
43
|
+
</head>
|
|
44
|
+
<body class="bg-sidebar text-foreground font-sans">
|
|
45
|
+
<a href="#main-content" class="skip-to-content">Skip to main content</a>
|
|
46
|
+
<div id="root"></div>
|
|
47
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import {
|
|
3
|
+
useNavigate,
|
|
4
|
+
useLocation,
|
|
5
|
+
useSearchParams as useRouterSearchParams,
|
|
6
|
+
Link as RouterLink,
|
|
7
|
+
type LinkProps as RouterLinkProps,
|
|
8
|
+
} from "react-router-dom"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `next/*` → `react-router-dom` shim
|
|
12
|
+
* ----------------------------------
|
|
13
|
+
*
|
|
14
|
+
* The template-vite stack uses react-router-dom for navigation, but the
|
|
15
|
+
* porteable DS components keep Next-style import shapes so the codebase
|
|
16
|
+
* stays one source of truth for components shared with `apps/web`
|
|
17
|
+
* (which today still runs Next).
|
|
18
|
+
*
|
|
19
|
+
* Replace `import Link from "next/link"` with
|
|
20
|
+
* `import { Link } from "@/lib/next-compat"`, and
|
|
21
|
+
* `import { useRouter, ... } from "next/navigation"` with
|
|
22
|
+
* `import { useRouter, ... } from "@/lib/next-compat"`.
|
|
23
|
+
*
|
|
24
|
+
* When `apps/web` finishes migrating to Vite (PR-3 → PR-6) and the Next
|
|
25
|
+
* stack is removed entirely (PR-7), this shim is deleted and call sites
|
|
26
|
+
* import directly from `react-router-dom`.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// next/link
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
export type LinkProps = Omit<RouterLinkProps, "to"> & {
|
|
34
|
+
href: string
|
|
35
|
+
/** next/link prefetch — RR doesn't prefetch routes; no-op. */
|
|
36
|
+
prefetch?: boolean
|
|
37
|
+
/** next/link scroll — RR scrolls by default; no-op flag. */
|
|
38
|
+
scroll?: boolean
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
|
|
42
|
+
function Link({ href, prefetch: _prefetch, scroll: _scroll, ...rest }, ref) {
|
|
43
|
+
return <RouterLink ref={ref} to={href} {...rest} />
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// next/navigation
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Next-shape `useRouter`. The template only uses `push`, `replace`, `back`,
|
|
53
|
+
* `forward`, `refresh`, and `prefetch` from the Next router — we map each
|
|
54
|
+
* to the matching `useNavigate` / window primitives. `prefetch` is a no-op
|
|
55
|
+
* because RR doesn't ship a route-prefetch primitive.
|
|
56
|
+
*/
|
|
57
|
+
export function useRouter() {
|
|
58
|
+
const navigate = useNavigate()
|
|
59
|
+
return React.useMemo(
|
|
60
|
+
() => ({
|
|
61
|
+
push: (href: string) => navigate(href),
|
|
62
|
+
replace: (href: string) => navigate(href, { replace: true }),
|
|
63
|
+
back: () => navigate(-1),
|
|
64
|
+
forward: () => navigate(1),
|
|
65
|
+
refresh: () => window.location.reload(),
|
|
66
|
+
prefetch: (_href: string) => undefined,
|
|
67
|
+
}),
|
|
68
|
+
[navigate],
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function usePathname(): string {
|
|
73
|
+
return useLocation().pathname
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Next's `useSearchParams` returns `ReadonlyURLSearchParams`. RR's tuple
|
|
78
|
+
* returns `[URLSearchParams, setSearchParams]`. We expose just the
|
|
79
|
+
* params object — call sites that need to write delegate to `useRouter().push`.
|
|
80
|
+
*/
|
|
81
|
+
export function useSearchParams(): URLSearchParams {
|
|
82
|
+
const [params] = useRouterSearchParams()
|
|
83
|
+
return params
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Next's `redirect()` works in server components / actions — there's no
|
|
88
|
+
* SPA equivalent. Where Next code did `redirect("/x")`, the Vite port
|
|
89
|
+
* uses `<Navigate to="/x" replace />` JSX. This helper exists only so
|
|
90
|
+
* any straggler imports compile; it throws so call sites are surfaced.
|
|
91
|
+
*/
|
|
92
|
+
export function redirect(href: string): never {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`redirect("${href}") is server-only and unavailable in the Vite shim. ` +
|
|
95
|
+
`Use <Navigate to="${href}" replace /> from react-router-dom in JSX, ` +
|
|
96
|
+
`or useNavigate() inside a useEffect.`,
|
|
97
|
+
)
|
|
98
|
+
}
|
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-exxat-app",
|
|
3
3
|
"version": "0.0.1",
|
|
4
|
-
"description": "Starter app built on @exxatdesignux/ui design system.",
|
|
4
|
+
"description": "Starter app built on @exxatdesignux/ui design system. Vite + React + react-router-dom — the lightweight stack designers use to prototype against the DS without Next.js memory overhead.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": true,
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=20.0.0"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"
|
|
12
|
-
"dev
|
|
13
|
-
"dev:3001": "
|
|
14
|
-
"dev:3005": "
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"clean": "rm -rf .next",
|
|
18
|
-
"clean:cache": "rm -rf .next/dev/cache .next/dev/trace .next/diagnostics",
|
|
19
|
-
"dev:daemon": "pm2 start ecosystem.config.cjs",
|
|
20
|
-
"dev:daemon:stop": "pm2 stop exxat-ds",
|
|
21
|
-
"dev:daemon:restart": "pm2 restart exxat-ds",
|
|
22
|
-
"dev:daemon:delete": "pm2 delete exxat-ds",
|
|
23
|
-
"dev:daemon:logs": "pm2 logs exxat-ds --lines 80",
|
|
24
|
-
"dev:daemon:status": "pm2 status",
|
|
25
|
-
"build": "next build",
|
|
26
|
-
"analyze": "ANALYZE=true next build",
|
|
27
|
-
"start": "next start",
|
|
11
|
+
"predev": "exxat-ui dev-guard",
|
|
12
|
+
"dev": "vite",
|
|
13
|
+
"dev:3001": "vite --port 3001",
|
|
14
|
+
"dev:3005": "vite --port 3005",
|
|
15
|
+
"build": "tsc -b && vite build",
|
|
16
|
+
"preview": "vite preview",
|
|
28
17
|
"lint": "eslint",
|
|
29
18
|
"format": "prettier --write \"**/*.{ts,tsx}\"",
|
|
30
19
|
"typecheck": "tsc --noEmit",
|
|
@@ -38,6 +27,7 @@
|
|
|
38
27
|
"@dnd-kit/sortable": "^10.0.0",
|
|
39
28
|
"@dnd-kit/utilities": "^3.2.2",
|
|
40
29
|
"@exxatdesignux/ui": "latest",
|
|
30
|
+
"@fontsource-variable/inter": "^5.2.5",
|
|
41
31
|
"@hookform/resolvers": "^5.2.2",
|
|
42
32
|
"@tabler/icons-react": "^3.41.1",
|
|
43
33
|
"@tanstack/react-table": "^8.21.3",
|
|
@@ -47,13 +37,13 @@
|
|
|
47
37
|
"cmdk": "^1.1.1",
|
|
48
38
|
"lucide-react": "^0.577.0",
|
|
49
39
|
"motion": "^12.38.0",
|
|
50
|
-
"next": "16.2.6",
|
|
51
40
|
"next-themes": "^0.4.6",
|
|
52
41
|
"react": "^19.2.4",
|
|
53
42
|
"react-day-picker": "^9.14.0",
|
|
54
43
|
"react-dom": "^19.2.4",
|
|
55
44
|
"react-hook-form": "^7.72.0",
|
|
56
45
|
"react-resizable-panels": "^4.10.0",
|
|
46
|
+
"react-router-dom": "^7.1.1",
|
|
57
47
|
"recharts": "^2.15.4",
|
|
58
48
|
"shadcn": "^4.7.0",
|
|
59
49
|
"sonner": "^2.0.7",
|
|
@@ -64,8 +54,7 @@
|
|
|
64
54
|
},
|
|
65
55
|
"devDependencies": {
|
|
66
56
|
"@eslint/eslintrc": "^3",
|
|
67
|
-
"@
|
|
68
|
-
"@tailwindcss/postcss": "^4.2.1",
|
|
57
|
+
"@tailwindcss/vite": "^4.2.1",
|
|
69
58
|
"@testing-library/jest-dom": "^6.9.1",
|
|
70
59
|
"@testing-library/react": "^16.3.0",
|
|
71
60
|
"@types/node": "^25.5.0",
|
|
@@ -73,24 +62,23 @@
|
|
|
73
62
|
"@types/react-dom": "^19.2.3",
|
|
74
63
|
"@vitejs/plugin-react": "^4.7.0",
|
|
75
64
|
"eslint": "^9.39.4",
|
|
76
|
-
"eslint-
|
|
65
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
66
|
+
"eslint-plugin-react-refresh": "^0.4.16",
|
|
67
|
+
"globals": "^15.14.0",
|
|
77
68
|
"jsdom": "^26.1.0",
|
|
78
|
-
"pm2": "^7.0.1",
|
|
79
|
-
"postcss": "^8.5.14",
|
|
80
69
|
"prettier": "^3.8.1",
|
|
81
70
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
82
71
|
"tailwindcss": "^4.2.1",
|
|
83
72
|
"typescript": "^5.9.3",
|
|
73
|
+
"typescript-eslint": "^8.18.2",
|
|
84
74
|
"vite": "^6.4.1",
|
|
85
75
|
"vitest": "^3.2.4"
|
|
86
76
|
},
|
|
87
77
|
"overrides": {
|
|
88
|
-
"postcss": "^8.5.14",
|
|
89
78
|
"ws": "^8.20.1"
|
|
90
79
|
},
|
|
91
80
|
"pnpm": {
|
|
92
81
|
"overrides": {
|
|
93
|
-
"postcss@<8.5.10": "^8.5.14",
|
|
94
82
|
"ws@<8.20.1": "^8.20.1"
|
|
95
83
|
}
|
|
96
84
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* One-off port helper — rewrites next/* imports in template-vite/ to
|
|
4
|
+
* the @/lib/next-compat shim (or, for next/dynamic, to React.lazy).
|
|
5
|
+
*
|
|
6
|
+
* Run from packages/ui/template-vite root:
|
|
7
|
+
* node scripts/port-next-imports.mjs
|
|
8
|
+
*
|
|
9
|
+
* The script is idempotent: running twice leaves files unchanged. It is
|
|
10
|
+
* intentionally conservative — only rewrites import lines, never logic.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readFile, writeFile } from "node:fs/promises"
|
|
14
|
+
import { glob } from "node:fs/promises"
|
|
15
|
+
import path from "node:path"
|
|
16
|
+
|
|
17
|
+
const ROOT = path.resolve(import.meta.dirname, "..")
|
|
18
|
+
|
|
19
|
+
const REWRITES = [
|
|
20
|
+
// Default `Link` import — `import Link from "next/link"` → `import { Link } from "@/lib/next-compat"`
|
|
21
|
+
{
|
|
22
|
+
re: /import\s+Link\s+from\s+["']next\/link["']/g,
|
|
23
|
+
to: 'import { Link } from "@/lib/next-compat"',
|
|
24
|
+
},
|
|
25
|
+
// Named imports from next/navigation — keep the named list, swap source
|
|
26
|
+
{
|
|
27
|
+
re: /from\s+["']next\/navigation["']/g,
|
|
28
|
+
to: 'from "@/lib/next-compat"',
|
|
29
|
+
},
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
const patterns = ["**/*.ts", "**/*.tsx"]
|
|
34
|
+
const files = []
|
|
35
|
+
for (const pattern of patterns) {
|
|
36
|
+
for await (const f of glob(pattern, { cwd: ROOT })) {
|
|
37
|
+
if (
|
|
38
|
+
f.startsWith("node_modules/") ||
|
|
39
|
+
f.startsWith("dist/") ||
|
|
40
|
+
f.includes("/.next-compat") ||
|
|
41
|
+
f === "lib/next-compat.tsx" ||
|
|
42
|
+
f.startsWith("scripts/")
|
|
43
|
+
) {
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
files.push(f)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let changed = 0
|
|
51
|
+
for (const rel of files) {
|
|
52
|
+
const abs = path.join(ROOT, rel)
|
|
53
|
+
const src = await readFile(abs, "utf8")
|
|
54
|
+
let out = src
|
|
55
|
+
for (const { re, to } of REWRITES) {
|
|
56
|
+
out = out.replace(re, to)
|
|
57
|
+
}
|
|
58
|
+
if (out !== src) {
|
|
59
|
+
await writeFile(abs, out, "utf8")
|
|
60
|
+
changed += 1
|
|
61
|
+
console.log(` ✓ ${rel}`)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log(`\nport-next-imports: ${changed} file(s) updated.`)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main().catch(err => {
|
|
68
|
+
console.error("port-next-imports failed:", err)
|
|
69
|
+
process.exit(1)
|
|
70
|
+
})
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Outlet } from "react-router-dom"
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AppSidebar,
|
|
5
|
+
SidebarShell,
|
|
6
|
+
SecondaryPanelProvider,
|
|
7
|
+
SecondaryPanel,
|
|
8
|
+
} from "@/components/sidebar"
|
|
9
|
+
import {
|
|
10
|
+
SIDEBAR_STATE_COOKIE_NAME,
|
|
11
|
+
sidebarDefaultOpenFromCookie,
|
|
12
|
+
} from "@/lib/sidebar-state-cookie"
|
|
13
|
+
import { ThemeProvider } from "@/components/theme-provider"
|
|
14
|
+
import { TooltipProvider } from "@/components/ui/tooltip"
|
|
15
|
+
import { ProductProvider } from "@/contexts/product-context"
|
|
16
|
+
import { ThemeColorSync } from "@/components/theme-color-sync"
|
|
17
|
+
import { DashboardViewProvider } from "@/contexts/dashboard-view-context"
|
|
18
|
+
import { ChartVariantProvider } from "@/contexts/chart-variant-context"
|
|
19
|
+
import { AskLeoProvider, AskLeoSidebar } from "@/components/ask-leo-sidebar"
|
|
20
|
+
import { KeyMetricsAskLeoBridge } from "@/components/key-metrics-ask-leo-bridge"
|
|
21
|
+
import { SystemBannerProvider } from "@/contexts/system-banner-context"
|
|
22
|
+
import { SystemBannerSlot } from "@/components/system-banner-slot"
|
|
23
|
+
import { CommandMenu } from "@/components/command-menu"
|
|
24
|
+
import { CommandMenuProvider } from "@/contexts/command-menu-context"
|
|
25
|
+
import { buildCommandMenuConfig } from "@/lib/command-menu-config"
|
|
26
|
+
import { COMMAND_MENU_SEARCH_DATA_GROUPS } from "@/lib/command-menu-search-data"
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Root layout (replaces both `app/layout.tsx` and `app/(app)/layout.tsx`
|
|
30
|
+
* from the Next template).
|
|
31
|
+
*
|
|
32
|
+
* Cookie reading: Next read `cookies()` server-side. In Vite/SPA we read
|
|
33
|
+
* `document.cookie` synchronously on first render — the API is identical
|
|
34
|
+
* (default true if absent, otherwise the persisted state). No hydration
|
|
35
|
+
* mismatch because there's no server render to mismatch against.
|
|
36
|
+
*
|
|
37
|
+
* Provider order is preserved verbatim from the Next layout — these
|
|
38
|
+
* contexts are tightly coupled to DS components (KeyMetrics ↔ Ask Leo,
|
|
39
|
+
* SecondaryPanel ↔ Sidebar) and reorder would break runtime behaviour.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
function readCookie(name: string): string | undefined {
|
|
43
|
+
if (typeof document === "undefined") return undefined
|
|
44
|
+
const match = document.cookie
|
|
45
|
+
.split("; ")
|
|
46
|
+
.find(c => c.startsWith(`${name}=`))
|
|
47
|
+
return match ? decodeURIComponent(match.split("=")[1]) : undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function App() {
|
|
51
|
+
const sidebarDefaultOpen = sidebarDefaultOpenFromCookie(
|
|
52
|
+
readCookie(SIDEBAR_STATE_COOKIE_NAME),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
const commandMenuConfig = buildCommandMenuConfig({
|
|
56
|
+
dataGroups: COMMAND_MENU_SEARCH_DATA_GROUPS,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<ThemeProvider
|
|
61
|
+
attribute="class"
|
|
62
|
+
defaultTheme="system"
|
|
63
|
+
enableSystem
|
|
64
|
+
disableTransitionOnChange
|
|
65
|
+
>
|
|
66
|
+
<ProductProvider>
|
|
67
|
+
<ThemeColorSync />
|
|
68
|
+
<TooltipProvider delayDuration={300}>
|
|
69
|
+
<DashboardViewProvider>
|
|
70
|
+
<ChartVariantProvider>
|
|
71
|
+
<AskLeoProvider>
|
|
72
|
+
<KeyMetricsAskLeoBridge>
|
|
73
|
+
<SystemBannerProvider>
|
|
74
|
+
<CommandMenuProvider value={commandMenuConfig}>
|
|
75
|
+
<SidebarShell
|
|
76
|
+
defaultOpen={sidebarDefaultOpen}
|
|
77
|
+
wrapperClassName="flex min-h-svh flex-col"
|
|
78
|
+
>
|
|
79
|
+
<CommandMenu />
|
|
80
|
+
<SystemBannerSlot />
|
|
81
|
+
<div
|
|
82
|
+
className="flex min-h-0 w-full flex-1 items-stretch has-data-[variant=inset]:bg-sidebar"
|
|
83
|
+
suppressHydrationWarning
|
|
84
|
+
>
|
|
85
|
+
<SecondaryPanelProvider>
|
|
86
|
+
<AppSidebar variant="inset" />
|
|
87
|
+
<SecondaryPanel />
|
|
88
|
+
<Outlet />
|
|
89
|
+
</SecondaryPanelProvider>
|
|
90
|
+
<AskLeoSidebar />
|
|
91
|
+
</div>
|
|
92
|
+
</SidebarShell>
|
|
93
|
+
</CommandMenuProvider>
|
|
94
|
+
</SystemBannerProvider>
|
|
95
|
+
</KeyMetricsAskLeoBridge>
|
|
96
|
+
</AskLeoProvider>
|
|
97
|
+
</ChartVariantProvider>
|
|
98
|
+
</DashboardViewProvider>
|
|
99
|
+
</TooltipProvider>
|
|
100
|
+
</ProductProvider>
|
|
101
|
+
</ThemeProvider>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StrictMode } from "react"
|
|
2
|
+
import { createRoot } from "react-dom/client"
|
|
3
|
+
import { RouterProvider, createBrowserRouter } from "react-router-dom"
|
|
4
|
+
|
|
5
|
+
import "@fontsource-variable/inter/index.css"
|
|
6
|
+
import "./styles/globals.css"
|
|
7
|
+
|
|
8
|
+
import { App } from "./App"
|
|
9
|
+
import { routes } from "./routes"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Vite entry — replaces the Next root layout (`app/layout.tsx`).
|
|
13
|
+
*
|
|
14
|
+
* The HTML shell, theme-color meta, Adobe Fonts preconnect, and Font
|
|
15
|
+
* Awesome kit script live in `index.html` (static, no JS needed).
|
|
16
|
+
*
|
|
17
|
+
* `App` wraps the route tree with the same provider stack the Next
|
|
18
|
+
* layout used (Theme, Tooltip, Product, etc.). Per-section providers
|
|
19
|
+
* (Library secondary panel, dashboard view) live on the route shells
|
|
20
|
+
* that need them — see `src/App.tsx`.
|
|
21
|
+
*
|
|
22
|
+
* `next/font/google` Inter is replaced by `@fontsource-variable/inter`
|
|
23
|
+
* which loads the same weights as a self-hosted variable font with
|
|
24
|
+
* zero layout shift. The `--font-sans` CSS variable is set on
|
|
25
|
+
* `document.documentElement` once on boot so the rest of the DS
|
|
26
|
+
* (tokens-themes, surfaces) sees the same font-family token Next had.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
document.documentElement.style.setProperty(
|
|
30
|
+
"--font-sans",
|
|
31
|
+
"'Inter Variable', 'Inter', system-ui, sans-serif",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const router = createBrowserRouter([
|
|
35
|
+
{
|
|
36
|
+
element: <App />,
|
|
37
|
+
children: routes,
|
|
38
|
+
},
|
|
39
|
+
])
|
|
40
|
+
|
|
41
|
+
const rootEl = document.getElementById("root")
|
|
42
|
+
if (!rootEl) {
|
|
43
|
+
throw new Error("Root element #root not found in index.html")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
createRoot(rootEl).render(
|
|
47
|
+
<StrictMode>
|
|
48
|
+
<RouterProvider router={router} />
|
|
49
|
+
</StrictMode>,
|
|
50
|
+
)
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
1
|
import * as React from "react"
|
|
2
|
+
import { useRouteError } from "react-router-dom"
|
|
4
3
|
import { AlertCircle } from "lucide-react"
|
|
5
4
|
|
|
6
5
|
import { Button } from "@/components/ui/button"
|
|
7
6
|
import { isChunkLoadError } from "@/lib/chunk-load-error"
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
* Route error boundary
|
|
9
|
+
* Route error boundary — catches lazy-chunk failures and runtime errors
|
|
10
|
+
* within a route subtree. `useRouteError()` is React Router's equivalent
|
|
11
|
+
* of the Next error.tsx `error` prop. Reset = reload the route via
|
|
12
|
+
* `window.location.reload()` (RR doesn't ship a `reset()` like Next).
|
|
11
13
|
*/
|
|
12
|
-
export
|
|
13
|
-
error
|
|
14
|
-
reset,
|
|
15
|
-
}: {
|
|
16
|
-
error: Error & { digest?: string }
|
|
17
|
-
reset: () => void
|
|
18
|
-
}) {
|
|
14
|
+
export function RouteError() {
|
|
15
|
+
const error = useRouteError() as Error & { digest?: string }
|
|
19
16
|
const chunkStale = isChunkLoadError(error)
|
|
20
17
|
|
|
21
18
|
React.useEffect(() => {
|
|
22
|
-
if (
|
|
19
|
+
if (import.meta.env.DEV) {
|
|
23
20
|
console.error(error)
|
|
24
21
|
}
|
|
25
22
|
}, [error])
|
|
@@ -35,23 +32,14 @@ export default function AppRouteError({
|
|
|
35
32
|
<p className="max-w-md text-sm text-muted-foreground">
|
|
36
33
|
{chunkStale
|
|
37
34
|
? "The app loaded an outdated script bundle (common after a dev-server rebuild). Reload the page to fetch the latest chunks."
|
|
38
|
-
:
|
|
39
|
-
? error
|
|
35
|
+
: import.meta.env.DEV
|
|
36
|
+
? error?.message
|
|
40
37
|
: "Please try again. If the problem continues, contact support."}
|
|
41
38
|
</p>
|
|
42
39
|
</div>
|
|
43
40
|
<div className="flex flex-wrap items-center justify-center gap-2">
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
Reload page
|
|
47
|
-
</Button>
|
|
48
|
-
) : null}
|
|
49
|
-
<Button
|
|
50
|
-
type="button"
|
|
51
|
-
variant={chunkStale ? "outline" : "default"}
|
|
52
|
-
onClick={() => reset()}
|
|
53
|
-
>
|
|
54
|
-
Try again
|
|
41
|
+
<Button type="button" onClick={() => window.location.reload()}>
|
|
42
|
+
{chunkStale ? "Reload page" : "Try again"}
|
|
55
43
|
</Button>
|
|
56
44
|
</div>
|
|
57
45
|
</div>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Default loading
|
|
4
|
+
* Default loading fallback — sidebar chrome stays mounted; main column
|
|
5
|
+
* shows skeleton while a route's lazy chunk resolves. Mirrors the Next
|
|
6
|
+
* `app/(app)/loading.tsx` behaviour.
|
|
5
7
|
*/
|
|
6
|
-
export
|
|
8
|
+
export function LoadingFallback() {
|
|
7
9
|
return (
|
|
8
10
|
<div
|
|
9
11
|
className="flex flex-col gap-4 p-6 md:p-8"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Link } from "react-router-dom"
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button"
|
|
4
|
+
|
|
5
|
+
export default function NotFound() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="flex min-h-[60vh] flex-col items-center justify-center gap-4 px-4 py-12 text-center">
|
|
8
|
+
<h1 className="text-2xl font-semibold text-foreground">Page not found</h1>
|
|
9
|
+
<p className="max-w-md text-sm text-muted-foreground">
|
|
10
|
+
The page you’re looking for doesn’t exist or was moved.
|
|
11
|
+
</p>
|
|
12
|
+
<Button asChild>
|
|
13
|
+
<Link to="/dashboard">Back to dashboard</Link>
|
|
14
|
+
</Button>
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { lazy, Suspense } from "react"
|
|
2
|
+
|
|
3
|
+
import { PrimaryPageTemplate } from "@/components/templates/primary-page-template"
|
|
4
|
+
import { Skeleton } from "@/components/ui/skeleton"
|
|
5
|
+
import { DASHBOARD_METRICS, DASHBOARD_INSIGHT } from "@/lib/mock/dashboard"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `next/dynamic` → `React.lazy`. The skeleton fallback below mirrors the
|
|
9
|
+
* one the Next page used.
|
|
10
|
+
*/
|
|
11
|
+
const DashboardTabs = lazy(() =>
|
|
12
|
+
import("@/components/dashboard-tabs").then(m => ({ default: m.DashboardTabs })),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
function DashboardSkeleton() {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className="flex flex-col gap-4 p-4 md:p-6"
|
|
19
|
+
aria-busy="true"
|
|
20
|
+
aria-label="Loading dashboard"
|
|
21
|
+
>
|
|
22
|
+
<Skeleton className="h-9 w-56 max-w-full" />
|
|
23
|
+
<Skeleton className="h-11 w-full max-w-xl" />
|
|
24
|
+
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
25
|
+
<Skeleton className="h-24 rounded-xl" />
|
|
26
|
+
<Skeleton className="h-24 rounded-xl" />
|
|
27
|
+
<Skeleton className="h-24 rounded-xl" />
|
|
28
|
+
<Skeleton className="h-24 rounded-xl" />
|
|
29
|
+
</div>
|
|
30
|
+
<Skeleton className="min-h-[320px] w-full rounded-xl" />
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default function DashboardPage() {
|
|
36
|
+
return (
|
|
37
|
+
<PrimaryPageTemplate siteHeader={{ title: "Dashboard" }}>
|
|
38
|
+
<Suspense fallback={<DashboardSkeleton />}>
|
|
39
|
+
<DashboardTabs
|
|
40
|
+
title="Dashboard"
|
|
41
|
+
subtitle="Design system shell · sample metrics and charts"
|
|
42
|
+
metrics={DASHBOARD_METRICS}
|
|
43
|
+
insight={DASHBOARD_INSIGHT}
|
|
44
|
+
/>
|
|
45
|
+
</Suspense>
|
|
46
|
+
</PrimaryPageTemplate>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import Link from "
|
|
1
|
+
import { Link } from "react-router-dom"
|
|
2
|
+
|
|
2
3
|
import { PrimaryPageTemplate } from "@/components/templates/primary-page-template"
|
|
3
4
|
import { Button } from "@/components/ui/button"
|
|
4
5
|
|
|
@@ -25,7 +26,7 @@ export default function HelpPage() {
|
|
|
25
26
|
</a>
|
|
26
27
|
</Button>
|
|
27
28
|
<Button variant="outline" asChild>
|
|
28
|
-
<Link
|
|
29
|
+
<Link to="/settings#appearance">App settings</Link>
|
|
29
30
|
</Button>
|
|
30
31
|
</div>
|
|
31
32
|
<section id="more" className="scroll-mt-20 mt-10">
|