@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.
Files changed (478) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/bin/cli.mjs +70 -1
  3. package/bin/init.mjs +18 -4
  4. package/bin/sync-extras.mjs +28 -4
  5. package/consumer-extras/README.md +41 -5
  6. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
  7. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
  8. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
  9. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
  10. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
  11. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
  12. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
  13. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
  14. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
  15. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
  16. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +13 -2
  17. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
  18. package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
  19. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
  20. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
  21. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
  22. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
  23. package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
  24. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
  25. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
  26. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
  27. package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
  28. package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
  29. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
  30. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
  31. package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
  32. package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
  33. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
  34. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
  35. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
  36. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
  37. package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
  38. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
  39. package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
  40. package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
  41. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
  42. package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +92 -12
  43. package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
  44. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
  45. package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
  46. package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +70 -17
  47. package/consumer-extras/patterns/command-menu-pattern.md +2 -2
  48. package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
  49. package/consumer-extras/patterns/jobs/README.md +1 -1
  50. package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
  51. package/consumer-extras/scripts/dev-guard.mjs +156 -0
  52. package/consumer-extras/templates/README.md +23 -0
  53. package/consumer-extras/templates/handoff.md +190 -0
  54. package/dist/hooks/use-app-theme.d.ts +1 -1
  55. package/package.json +2 -2
  56. package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
  57. package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
  58. package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
  59. package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
  60. package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
  61. package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
  62. package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
  63. package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
  64. package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
  65. package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
  66. package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
  67. package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
  68. package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
  69. package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
  70. package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
  71. package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
  72. package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
  73. package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
  74. package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
  75. package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
  76. package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
  77. package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
  78. package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
  79. package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
  80. package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
  81. package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
  82. package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
  83. package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
  84. package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
  85. package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
  86. package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
  87. package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
  88. package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
  89. package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
  90. package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
  91. package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
  92. package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
  93. package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
  94. package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
  95. package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
  96. package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
  97. package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
  98. package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
  99. package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
  100. package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
  101. package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
  102. package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
  103. package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
  104. package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
  105. package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
  106. package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
  107. package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
  108. package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
  109. package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
  110. package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
  111. package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
  112. package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
  113. package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
  114. package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
  115. package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
  116. package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
  117. package/{template → template-vite}/components/command-menu.tsx +1 -1
  118. package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
  119. package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
  120. package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
  121. package/{template → template-vite}/components/library-client.tsx +1 -1
  122. package/{template → template-vite}/components/library-hub-client.tsx +2 -2
  123. package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
  124. package/{template → template-vite}/components/library-table.tsx +35 -27
  125. package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
  126. package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
  127. package/{template → template-vite}/components/settings-client.tsx +1 -1
  128. package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
  129. package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
  130. package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
  131. package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
  132. package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
  133. package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
  134. package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
  135. package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
  136. package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
  137. package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
  138. package/template-vite/index.html +49 -0
  139. package/template-vite/lib/next-compat.tsx +98 -0
  140. package/{template → template-vite}/package.json +15 -27
  141. package/template-vite/scripts/port-next-imports.mjs +70 -0
  142. package/template-vite/src/App.tsx +103 -0
  143. package/template-vite/src/main.tsx +50 -0
  144. package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
  145. package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
  146. package/template-vite/src/pages/_not-found.tsx +17 -0
  147. package/template-vite/src/pages/dashboard.tsx +48 -0
  148. package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
  149. package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
  150. package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
  151. package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
  152. package/template-vite/src/routes.tsx +72 -0
  153. package/{template/app → template-vite/src/styles}/globals.css +6 -2
  154. package/{template → template-vite}/tsconfig.json +5 -14
  155. package/template-vite/vite.config.ts +52 -0
  156. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
  157. package/template/.agents/skills/shadcn/SKILL.md +0 -242
  158. package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
  159. package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  160. package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
  161. package/template/.agents/skills/shadcn/cli.md +0 -257
  162. package/template/.agents/skills/shadcn/customization.md +0 -202
  163. package/template/.agents/skills/shadcn/evals/evals.json +0 -47
  164. package/template/.agents/skills/shadcn/mcp.md +0 -94
  165. package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
  166. package/template/.agents/skills/shadcn/rules/composition.md +0 -195
  167. package/template/.agents/skills/shadcn/rules/forms.md +0 -192
  168. package/template/.agents/skills/shadcn/rules/icons.md +0 -101
  169. package/template/.agents/skills/shadcn/rules/styling.md +0 -162
  170. package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
  171. package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
  172. package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
  173. package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
  174. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
  175. package/template/.nvmrc +0 -1
  176. package/template/.prettierignore +0 -7
  177. package/template/Logo/Exxat_Prism.svg +0 -39
  178. package/template/Logo/Exxat_one.svg +0 -36
  179. package/template/app/(app)/dashboard/loading.tsx +0 -18
  180. package/template/app/(app)/dashboard/page.tsx +0 -36
  181. package/template/app/(app)/layout.tsx +0 -77
  182. package/template/app/global-error.tsx +0 -63
  183. package/template/app/layout.tsx +0 -133
  184. package/template/app/page.tsx +0 -9
  185. package/template/docs/HANDBOOK.md +0 -187
  186. package/template/docs/blueprints/README.md +0 -86
  187. package/template/docs/blueprints/_template.md +0 -91
  188. package/template/docs/blueprints/board-card.md +0 -123
  189. package/template/docs/blueprints/data-table.md +0 -139
  190. package/template/docs/blueprints/key-metrics.md +0 -128
  191. package/template/docs/blueprints/list-page-template.md +0 -123
  192. package/template/docs/blueprints/page-header.md +0 -130
  193. package/template/docs/card-vs-rows-pattern.md +0 -36
  194. package/template/docs/collaboration-access-pattern.md +0 -116
  195. package/template/docs/command-menu-pattern.md +0 -45
  196. package/template/docs/component-selection-guide.md +0 -224
  197. package/template/docs/components-audit-2026-05.md +0 -158
  198. package/template/docs/consumer-upgrade-checklist.md +0 -52
  199. package/template/docs/data-views-pattern.md +0 -185
  200. package/template/docs/drawer-vs-dialog-pattern.md +0 -50
  201. package/template/docs/glossary.md +0 -59
  202. package/template/docs/hub-supported-views-pattern.md +0 -53
  203. package/template/docs/jobs/README.md +0 -59
  204. package/template/docs/jobs/record-detail.md +0 -177
  205. package/template/docs/kpi-flat-band-pattern.md +0 -57
  206. package/template/docs/kpi-strip-max-four-pattern.md +0 -30
  207. package/template/docs/kpi-trend-pattern.md +0 -58
  208. package/template/docs/large-dataset-strategy.md +0 -155
  209. package/template/docs/library-hub-header-pattern.md +0 -25
  210. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
  211. package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
  212. package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
  213. package/template/docs/migrations/README.md +0 -100
  214. package/template/docs/migrations/_template.md +0 -64
  215. package/template/docs/modern-saas-patterns.md +0 -165
  216. package/template/docs/perf-memory-pattern.md +0 -206
  217. package/template/docs/reference-implementations.md +0 -153
  218. package/template/docs/shell-surface-elevation-pattern.md +0 -52
  219. package/template/docs/token-taxonomy.md +0 -416
  220. package/template/docs/voice-and-tone.md +0 -262
  221. package/template/ecosystem.config.cjs +0 -32
  222. package/template/next.config.mjs +0 -216
  223. package/template/postcss.config.mjs +0 -8
  224. package/template/public/favicon/favicon.ico +0 -0
  225. package/template/tests/setup.ts +0 -26
  226. package/template/vitest.config.ts +0 -18
  227. /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
  228. /package/{template → template-vite}/.prettierrc +0 -0
  229. /package/{template → template-vite}/AGENTS.md +0 -0
  230. /package/{template → template-vite}/README.md +0 -0
  231. /package/{template → template-vite}/components/.gitkeep +0 -0
  232. /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
  233. /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
  234. /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
  235. /package/{template → template-vite}/components/charts-overview.tsx +0 -0
  236. /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
  237. /package/{template → template-vite}/components/columns-client.tsx +0 -0
  238. /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
  239. /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
  240. /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
  241. /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
  242. /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
  243. /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
  244. /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
  245. /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
  246. /package/{template → template-vite}/components/data-table/index.tsx +0 -0
  247. /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
  248. /package/{template → template-vite}/components/data-table/types.ts +0 -0
  249. /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
  250. /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
  251. /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
  252. /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
  253. /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
  254. /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
  255. /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
  256. /package/{template → template-vite}/components/data-views/index.ts +0 -0
  257. /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
  258. /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
  259. /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
  260. /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
  261. /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
  262. /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
  263. /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
  264. /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
  265. /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
  266. /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
  267. /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
  268. /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
  269. /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
  270. /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
  271. /package/{template → template-vite}/components/export-drawer.tsx +0 -0
  272. /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
  273. /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
  274. /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
  275. /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
  276. /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
  277. /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
  278. /package/{template → template-vite}/components/key-metrics.tsx +0 -0
  279. /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
  280. /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
  281. /package/{template → template-vite}/components/library-board-view.tsx +0 -0
  282. /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
  283. /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
  284. /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
  285. /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
  286. /package/{template → template-vite}/components/library-page-header.tsx +0 -0
  287. /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
  288. /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
  289. /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
  290. /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
  291. /package/{template → template-vite}/components/onboarding/index.ts +0 -0
  292. /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
  293. /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
  294. /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
  295. /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
  296. /package/{template → template-vite}/components/page-header.tsx +0 -0
  297. /package/{template → template-vite}/components/product-switcher.tsx +0 -0
  298. /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
  299. /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
  300. /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
  301. /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
  302. /package/{template → template-vite}/components/sidebar/index.ts +0 -0
  303. /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
  304. /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
  305. /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
  306. /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
  307. /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
  308. /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
  309. /package/{template → template-vite}/components/site-header.tsx +0 -0
  310. /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
  311. /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
  312. /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
  313. /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
  314. /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
  315. /package/{template → template-vite}/components/table-properties/index.ts +0 -0
  316. /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
  317. /package/{template → template-vite}/components/table-properties/types.ts +0 -0
  318. /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
  319. /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
  320. /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
  321. /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
  322. /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
  323. /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
  324. /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
  325. /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
  326. /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
  327. /package/{template → template-vite}/components/theme-provider.tsx +0 -0
  328. /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
  329. /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
  330. /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
  331. /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
  332. /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
  333. /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
  334. /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
  335. /package/{template → template-vite}/components/ui/badge.tsx +0 -0
  336. /package/{template → template-vite}/components/ui/banner.tsx +0 -0
  337. /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
  338. /package/{template → template-vite}/components/ui/button.tsx +0 -0
  339. /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
  340. /package/{template → template-vite}/components/ui/card.tsx +0 -0
  341. /package/{template → template-vite}/components/ui/chart.tsx +0 -0
  342. /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
  343. /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
  344. /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
  345. /package/{template → template-vite}/components/ui/command.tsx +0 -0
  346. /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
  347. /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
  348. /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
  349. /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
  350. /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
  351. /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
  352. /package/{template → template-vite}/components/ui/field.tsx +0 -0
  353. /package/{template → template-vite}/components/ui/form.tsx +0 -0
  354. /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
  355. /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
  356. /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
  357. /package/{template → template-vite}/components/ui/input.tsx +0 -0
  358. /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
  359. /package/{template → template-vite}/components/ui/label.tsx +0 -0
  360. /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
  361. /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
  362. /package/{template → template-vite}/components/ui/popover.tsx +0 -0
  363. /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
  364. /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
  365. /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
  366. /package/{template → template-vite}/components/ui/select.tsx +0 -0
  367. /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
  368. /package/{template → template-vite}/components/ui/separator.tsx +0 -0
  369. /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
  370. /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
  371. /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
  372. /package/{template → template-vite}/components/ui/slider.tsx +0 -0
  373. /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
  374. /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
  375. /package/{template → template-vite}/components/ui/table.tsx +0 -0
  376. /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
  377. /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
  378. /package/{template → template-vite}/components/ui/tip.tsx +0 -0
  379. /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
  380. /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
  381. /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
  382. /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
  383. /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
  384. /package/{template → template-vite}/components.json +0 -0
  385. /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
  386. /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
  387. /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
  388. /package/{template → template-vite}/contexts/product-context.tsx +0 -0
  389. /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
  390. /package/{template → template-vite}/eslint.config.mjs +0 -0
  391. /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
  392. /package/{template → template-vite}/hooks/.gitkeep +0 -0
  393. /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
  394. /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
  395. /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
  396. /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
  397. /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
  398. /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
  399. /package/{template → template-vite}/lib/.gitkeep +0 -0
  400. /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
  401. /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
  402. /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
  403. /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
  404. /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
  405. /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
  406. /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
  407. /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
  408. /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
  409. /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
  410. /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
  411. /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
  412. /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
  413. /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
  414. /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
  415. /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
  416. /package/{template → template-vite}/lib/data-list-view.ts +0 -0
  417. /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
  418. /package/{template → template-vite}/lib/date-filter.ts +0 -0
  419. /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
  420. /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
  421. /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
  422. /package/{template → template-vite}/lib/dev-log.ts +0 -0
  423. /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
  424. /package/{template → template-vite}/lib/editable-target.ts +0 -0
  425. /package/{template → template-vite}/lib/exxat-palette.json +0 -0
  426. /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
  427. /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
  428. /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
  429. /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
  430. /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
  431. /package/{template → template-vite}/lib/library-authoring.ts +0 -0
  432. /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
  433. /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
  434. /package/{template → template-vite}/lib/library-nav.ts +0 -0
  435. /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
  436. /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
  437. /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
  438. /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
  439. /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
  440. /package/{template → template-vite}/lib/logo-dev.ts +0 -0
  441. /package/{template → template-vite}/lib/mailto.ts +0 -0
  442. /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
  443. /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
  444. /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
  445. /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
  446. /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
  447. /package/{template → template-vite}/lib/mock/library.ts +0 -0
  448. /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
  449. /package/{template → template-vite}/lib/motion-ui.ts +0 -0
  450. /package/{template → template-vite}/lib/product-brand.ts +0 -0
  451. /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
  452. /package/{template → template-vite}/lib/row-height.ts +0 -0
  453. /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
  454. /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
  455. /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
  456. /package/{template → template-vite}/lib/utils.test.ts +0 -0
  457. /package/{template → template-vite}/lib/utils.ts +0 -0
  458. /package/{template → template-vite}/public/.gitkeep +0 -0
  459. /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
  460. /package/{template → template-vite}/public/avatars/user.svg +0 -0
  461. /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
  462. /package/{template/app → template-vite/public}/favicon.ico +0 -0
  463. /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
  464. /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
  465. /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
  466. /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
  467. /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
  468. /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
  469. /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
  470. /package/{template → template-vite}/skills-lock.json +0 -0
  471. /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
  472. /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
  473. /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
  474. /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
  475. /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
  476. /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
  477. /package/{template → template-vite}/stores/app-store.ts +0 -0
  478. /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": ">=24.0.0"
8
+ "node": ">=20.0.0"
9
9
  },
10
10
  "scripts": {
11
- "dev": "NODE_OPTIONS='--max-old-space-size=6144 --max-semi-space-size=64' NEXT_TELEMETRY_DISABLED=1 next dev --turbopack",
12
- "dev:webpack": "NODE_OPTIONS='--max-old-space-size=6144 --max-semi-space-size=64' NEXT_TELEMETRY_DISABLED=1 next dev",
13
- "dev:3001": "NODE_OPTIONS='--max-old-space-size=6144 --max-semi-space-size=64' NEXT_TELEMETRY_DISABLED=1 next dev --turbopack -p 3001",
14
- "dev:3005": "NODE_OPTIONS='--max-old-space-size=6144 --max-semi-space-size=64' NEXT_TELEMETRY_DISABLED=1 next dev --turbopack -p 3005",
15
- "dev:profile": "NODE_OPTIONS='--max-old-space-size=6144 --heap-prof --heap-prof-interval=512000 --diagnostic-dir=./.next/diagnostics' NEXT_TELEMETRY_DISABLED=1 next dev --turbopack",
16
- "dev:fresh": "pnpm clean:cache && pnpm dev",
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
- "@next/bundle-analyzer": "16.2.6",
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-config-next": "16.2.6",
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 for the signed-in app shell. Lets users retry without a full reload.
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 default function AppRouteError({
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 (process.env.NODE_ENV === "development") {
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
- : process.env.NODE_ENV === "development"
39
- ? error.message
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
- {chunkStale ? (
45
- <Button type="button" onClick={() => window.location.reload()}>
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 UI for app routes (sidebar chrome stays; main column shows this fallback).
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 default function AppRouteLoading() {
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 "next/link"
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 href="/settings#appearance">App settings</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">