@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
@@ -1,36 +0,0 @@
1
- # Cards vs table rows vs list rows
2
-
3
- > **Related:** **`AGENTS.md` §4–§5**, **`.cursor/rules/exxat-data-tables.mdc`**, **`.cursor/rules/exxat-board-cards.mdc`**, **`docs/data-views-pattern.md`**.
4
-
5
- ## When to use **rows** (table or dense list)
6
-
7
- - **Many similar records** (roughly **10+**) where users **scan**, **sort**, **filter**, and **compare columns**.
8
- - **Same fields** across entities — columns align; export and **TablePropertiesDrawer** apply.
9
- - **Primary hub** pattern — **`DataTable`** + **`ListPageTemplate`** per **`exxat-data-tables`**.
10
-
11
- **Use:** `DataTable`, shared toolbar, row actions, pinned columns.
12
-
13
- ## When to use **cards** (tile / board / marketing)
14
-
15
- - **Lower cardinality** or **visual-first** browsing — folders, dashboards, “pick a template”, hero metrics beside a chart.
16
- - **Heterogeneous content** — each card has a different layout (title, badge, avatar, two-line body) where a rigid grid of columns would fight the design.
17
- - **Kanban** — **`ListPageBoardCard`** + column model; still fed by **`tableState.rows`**.
18
-
19
- **Use:** `ListPageBoardCard`, `ChartCard`, icon grids under **`ListPageViewFrame`**, dashboard chart tiles.
20
-
21
- ## When to use **list rows** (not full DataTable)
22
-
23
- - **Medium density** — fewer columns than a grid; reading order is **vertical** (timeline, activity, simple roster without heavy operators).
24
- - Still wire **search** when the list is the main surface and item count grows.
25
-
26
- **Prefer** graduating to **`DataTable`** once the hub needs filters, column hide, density, or export parity with other list hubs.
27
-
28
- ## Anti-patterns
29
-
30
- - **Cards for 50+ homogeneous records** when the product expects sort/filter/compare — that belongs in **`DataTable`**.
31
- - **A second bespoke “table”** alongside **`DataTable`** for the same dataset — extend the table stack instead (**`exxat-centralized-list-dataset`**).
32
- - **Raw `<table>`** for product data lists — forbidden (**`exxat-data-tables`**).
33
-
34
- ## See also
35
-
36
- - **`.cursor/rules/exxat-card-vs-list-rows.mdc`**, **`.cursor/skills/exxat-card-vs-list-rows/SKILL.md`**
@@ -1,116 +0,0 @@
1
- # Collaboration & access pattern
2
-
3
- Shared UI for **who can access a hub** (face stack in the header) and **inviting people** (floating sheet). **Reference:** Library — `LibraryPageHeader`, `LibraryClient`, `InviteCollaboratorsDrawer`.
4
-
5
- **Folder-scoped library:** When the library URL selects a folder (`?scope=folder&folderId=`), the same header **⋯ More** menu also exposes **Customize folder** (name / color / icon) via **`LibraryNewFolderSheet`** mounted on **`LibraryClient`** so it works on every view tab. See **`docs/library-hub-header-pattern.md`** and **`.cursor/rules/exxat-library-hub-header.mdc`**.
6
-
7
- ## When to use
8
-
9
- - A list hub or library is **shared** across people (not a private directory).
10
- - Users need to see **who has access**, **invite by email**, and assign **library access** (Owner / Editor / Commenter / Viewer).
11
- - The hub already uses **`ListPageTemplate`** + **`PageHeader`** (or an entity header built on it).
12
-
13
- **Do not** use this for org-wide **role** administration (Faculty, Program coordinator, Director) as the only story — those are **directory role tags** on people, not library access.
14
-
15
- ## Vocabulary
16
-
17
- | Concept | Meaning | Source |
18
- |--------|---------|--------|
19
- | **Library access** | What someone can do **in this hub** (Owner, Editor, Commenter, Viewer) | `lib/collaborator-access.ts` |
20
- | **Directory roles** | Org/job tags on a person (Faculty, Program coordinator, Director) | `PageHeaderCollaborator.roles` |
21
- | **Face rail** | Overlapping avatars in the header when the roster is non-empty | `PageHeader` `variant="collaboration"` |
22
- | **Empty roster CTA** | Outline **Add collaborator** in the header when `collaborators` is empty | `PageHeader` + `COLLABORATION_HEADER_ADD_LABEL` |
23
- | **Invite sheet** | Floating right **`Sheet`** for roster + invite form | `InviteCollaboratorsDrawer` |
24
- | **Hub wiring** | Roster state + invite sheet in one render-prop shell | `CollaborationAccessFlow` |
25
-
26
- ## Header (`PageHeader`)
27
-
28
- - Set **`variant="collaboration"`**.
29
- - Pass **`collaborators`** (`PageHeaderCollaborator[]`) and optional **`accessInfo`**.
30
- - **Non-empty roster** — overlapping **face rail** only; each face and **`+N`** open the invite sheet via **`onCollaboratorsOpen`**.
31
- - **Empty roster** — outline **`Add collaborator`** (`addCollaboratorLabel`, default **`COLLABORATION_HEADER_ADD_LABEL`**) opens the same sheet.
32
- - **Invite** also lives under **⋯ More** on the entity page header (first item when `variant="collaboration"`).
33
-
34
- ```tsx
35
- <CollaborationAccessFlow
36
- initialCollaborators={LIBRARY_HEADER_COLLABORATORS}
37
- resourceLabel={hubHeader.title}
38
- >
39
- {({ collaborators, openInvite }) => (
40
- <LibraryPageHeader
41
- variant="collaboration"
42
- title={hubHeader.title}
43
- questionCount={count}
44
- collaborators={collaborators}
45
- onAddCollaborator={openInvite}
46
- onCollaboratorsOpen={openInvite}
47
- onExport={() => setExportOpen(true)}
48
- showMetrics={showMetrics}
49
- onToggleMetrics={() => setShowMetrics(v => !v)}
50
- />
51
- )}
52
- </CollaborationAccessFlow>
53
- ```
54
-
55
- ## Hub client state
56
-
57
- - Prefer **`CollaborationAccessFlow`** — owns **`collaborators`**, **`openInvite`**, and **`InviteCollaboratorsDrawer`**; pass **`openInvite`** to **`onAddCollaborator`** / **`onCollaboratorsOpen`**.
58
- - Without the flow: **`collaborators`** — `useState` seeded from `lib/mock/<entity>-header-collaborators.ts` (or API later); **`inviteOpen`** — boolean; mount **`InviteCollaboratorsDrawer`** beside **`ListPageTemplate`**.
59
- - On invite success, append to **`collaborators`** so the **face rail** and sheet roster stay aligned.
60
- - **Change access** — roster menu updates **`collaborators`** via **`onCollaboratorAccessChange`** ( **`CollaborationAccessFlow`** default).
61
- - **Remove access** — confirm dialog then **`onCollaboratorRemove`**; blocked for the only **Owner**.
62
-
63
- ## `PageHeaderCollaborator`
64
-
65
- | Field | Use |
66
- |-------|-----|
67
- | `id`, `name`, `imageUrl`, `initials` | Face rail + roster row |
68
- | `email` | Roster (below name); invite form |
69
- | `access` | Library access badge (Owner … Viewer) |
70
- | `roles` | Optional **outline** chips (Faculty, Program coordinator, Director) |
71
-
72
- ## Invite sheet (`InviteCollaboratorsDrawer`)
73
-
74
- Mirror **`ExportDrawer`** chrome: floating **`Sheet`**, no overlay, **`showCloseButton={false}`**, footer **Cancel** / **Send invite** with inline **`Kbd`** (**Esc** / **⏎**), **`Shortcut`** for Enter on the open surface.
75
-
76
- **Invite field:** one bordered row — email input + **access** menu on the right.
77
-
78
- - Use **`Select`** with **`SelectGroup`** for access (invite row in **`InputGroupAddon`**, roster row standalone); **`position="popper"`** inside the sheet; **no** toast on success (**§6.5**).
79
-
80
- **People with access:** one **`rounded-lg border`** list with **`divide-y`** — **not** one card per person.
81
-
82
- Row order:
83
-
84
- 1. **Name** (`text-sm font-medium`)
85
- 2. **Email** (`text-xs text-muted-foreground`)
86
- 3. **Role tags** (`Badge variant="outline"`) when `roles` is set
87
- 4. Trailing **library access** **`Select`** when the hub wires **`onCollaboratorAccessChange`**; **Remove access** (trash) opens a confirm **`Dialog`** when **`onCollaboratorRemove`** is set. The sole **Owner** cannot be removed or demoted until another owner exists.
88
-
89
- ## Library access constants
90
-
91
- - Types and invite options: **`lib/collaborator-access.ts`**
92
- - **`INVITE_COLLABORATOR_ACCESS_OPTIONS`** — Editor / Commenter / Viewer (no Owner on invite)
93
- - Customize option **descriptions** per hub; keep **values** stable for forms/API
94
-
95
- ## File map
96
-
97
- | Piece | Path |
98
- |-------|------|
99
- | Access types | `lib/collaborator-access.ts` |
100
- | Hub flow | `components/collaboration-access-flow.tsx` |
101
- | Collaborator type | `components/page-header.tsx` (`PageHeaderCollaborator`) |
102
- | Invite sheet | `components/invite-collaborators-drawer.tsx` |
103
- | Entity header | `components/library-page-header.tsx` |
104
- | Hub wiring | `components/library-client.tsx` |
105
- | Demo roster | `lib/mock/library-header-collaborators.ts` |
106
-
107
- ## Checklist (new hub)
108
-
109
- - [ ] `PageHeader` / entity header uses **`variant="collaboration"`** when the product is shared.
110
- - [ ] **Empty roster** shows **Add collaborator**; **non-empty** shows face rail; both open the invite sheet.
111
- - [ ] **Invite people** under **⋯ More**; **`CollaborationAccessFlow`** (or equivalent) owns roster + sheet.
112
- - [ ] Roster: single bordered list; **name → email → role tags**; access badge on the right.
113
- - [ ] Invite row: email + access menu; **`FormDescription`** for format; **no** toast.
114
- - [ ] Labels from **`collaborator-access.ts`**; mock/API rows extend **`PageHeaderCollaborator`** once.
115
-
116
- **Handbook:** `AGENTS.md` §4.7 · **Rule:** `.cursor/rules/exxat-collaboration-access.mdc` · **Skill:** `.cursor/skills/exxat-collaboration-access/SKILL.md`
@@ -1,45 +0,0 @@
1
- # Global command palette (⌘K)
2
-
3
- **Code:** `components/command-menu.tsx`, config **`buildCommandMenuConfig()`** in **`lib/command-menu-config.ts`**, wired in **`app/(app)/layout.tsx`** via **`CommandMenuProvider`**. Searchable row data is built in **`lib/command-menu-search-data.ts`** (not inside the shell component).
4
-
5
- ## Role
6
-
7
- The command menu is the app’s **global search and AI entry**—one place to jump to routes, library pages, patterns, and AI starters. It is **not** a duplicate of the left sidebar; it **indexes** product surfaces for fast discovery.
8
-
9
- ## User model
10
-
11
- | Need | Where it lives |
12
- |------|----------------|
13
- | **Find a page, component, or pattern** | Palette — filterable list, **Enter** to navigate. |
14
- | **Quick AI / natural language** | Prefer **short answers or “research” snippets inside the palette** when the product can return compact, citeable results without leaving the flow. |
15
- | **Long or complex answers** | **Ask Leo** right sidebar — multi-step reasoning, long-form help, or anything that does not fit a small results surface. |
16
-
17
- **Design rule:** Treat the palette as **progressive disclosure**—lightweight results first in-menu; **escalate** to Ask Leo when the answer is too large or needs a dedicated conversation surface.
18
-
19
- ## Keyboard
20
-
21
- - **⌘K / Ctrl+K** — open / toggle the palette (global listener in `CommandMenu`).
22
- - **Ask Leo** remains **⌘⌥K / Ctrl+Alt+K** (see `.cursor/rules/exxat-kbd-shortcuts.mdc`) so it does not collide with table search where both exist.
23
-
24
- ## Configuration
25
-
26
- - **Static groups** (AI suggestions, Navigation, Components, Patterns) live in **`lib/command-menu-config.ts`**.
27
- - Optional **`dataGroups`** are passed to **`buildCommandMenuConfig({ dataGroups })`** from the app shell. **Implementation:** **`getCommandMenuSearchDataGroups()`** in **`lib/command-menu-search-data.ts`** maps mock/API rows (e.g. placements with student names) to **`CommandMenuItem`** rows with **`label`**, **`href`**, and **`keywords`** for cmdk filtering. The layout uses **`buildCommandMenuConfig({ dataGroups: getCommandMenuSearchDataGroups() })`**. Keep domain mapping **outside** `command-menu.tsx` so data sources can change without editing the shell.
28
- - **`searchOnly` on `CommandMenuGroup`:** cmdk shows **every** mounted item when the search box is empty. For large indexes (hundreds of placements), set **`searchOnly: true`** on that group so **`command-menu.tsx`** does not render it until the user has typed a non-empty query. Static groups (AI, Navigation, …) stay visible on open; the data group appears once the user searches.
29
-
30
- ## Files (quick reference)
31
-
32
- | Piece | Location |
33
- |-------|----------|
34
- | Palette UI | `components/command-menu.tsx` |
35
- | Static groups + `buildCommandMenuConfig` | `lib/command-menu-config.ts` (`CommandMenuGroup.searchOnly`) |
36
- | Row → menu items (placements, etc.) | `lib/command-menu-search-data.ts` |
37
- | Provider + `dataGroups` | `app/(app)/layout.tsx` |
38
-
39
- ## Sidebar
40
-
41
- **“Search or ask Leo”** in the sidebar opens the same palette; shortcuts and copy should stay aligned with **`AGENTS.md` §7.1**.
42
-
43
- ---
44
-
45
- Keep this document aligned with **`apps/web/AGENTS.md` §7.1** when behavior or copy changes.
@@ -1,224 +0,0 @@
1
- # Exxat DS — Component Selection Guide
2
-
3
- **Audience:** humans + AI agents. **Companion to:** [`token-taxonomy.md`](./token-taxonomy.md), [`blueprints/`](./blueprints/).
4
-
5
- When you're about to build a UI, **start here**. Follow the decision tree
6
- to find the right composition before you write any markup. The rule is
7
- always: **compose existing components first**; only create a new shared
8
- primitive after asking the user
9
- ([`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc)).
10
-
11
- ---
12
-
13
- ## 0. Quick chart
14
-
15
- ```
16
- ┌─────────────────────────────────────┐
17
- │ What is the surface? │
18
- └──┬──────────────────────────────────┘
19
-
20
- ┌───────────┴────────────────────────────┐
21
- │ │
22
- PRIMARY HUB OVERLAY / SECONDARY
23
- (route w/ many records, (on top of a hub,
24
- filters, properties) modal task, side panel)
25
- │ │
26
- │ ▼
27
- │ See § 3
28
-
29
- See § 1
30
- ```
31
-
32
- ---
33
-
34
- ## 1. Building a primary hub (route with records)
35
-
36
- ```
37
- Q: Is the data > ~10 comparable records?
38
- ─────────────────────────────────────────
39
- │ yes ──────────────────────────────► DataTable inside ListPageTemplate (§1.1)
40
- │ no ──┬─ all rows shown at once?
41
- │ │ yes ── simple `<dl>` / card list (no Properties / Filters needed)
42
- │ │ no ── still use DataTable — future growth is expected
43
- └─────►
44
- ```
45
-
46
- ### 1.1 DataTable hub (canonical)
47
-
48
- | Need | Use |
49
- |---|---|
50
- | Browsable grid | **`DataTable`** + **`useTableState`** ([blueprint](./blueprints/data-table.md)) |
51
- | View tabs (table/list/board/dashboard) | **`ListPageTemplate`** + connected views ([`exxat-list-page-connected-views.mdc`](../../.cursor/rules/exxat-list-page-connected-views.mdc)) |
52
- | Column/density/properties | **`TablePropertiesDrawer`** (pass `currentView` + `onViewChange`) |
53
- | Filters | Shared `FilterFieldDef` chips |
54
- | Find-in-list | Toolbar search (`⌘K`) |
55
- | Metrics strip | **`KeyMetrics`** `variant="flat"` ([`kpi-flat-band-pattern.md`](./kpi-flat-band-pattern.md)) — **max 4 tiles** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)) |
56
- | Export | Filled primary CTA + `⋯` → `ExportDrawer` |
57
- | Kanban view body | **`ListPageBoardCard`** + `ListPageBoardTemplate` ([`exxat-board-cards.mdc`](../../.cursor/rules/exxat-board-cards.mdc)) |
58
- | Folder / panel view body | **`FolderGridView`** / **`FinderPanelView`** wrapped in **`ListPageViewFrame`** ([`exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc)) |
59
- | Dashboard view body | **`KeyMetrics variant="card"`** + a hub-specific chart section (reference: `library-dashboard-charts.tsx`) |
60
- | Nested scope nav (All / Mine / tree) | **`secondaryPanel`** + `PANELS` + `useAutoPanel` ([`exxat-primary-nav-secondary-panel.mdc`](../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc)) |
61
- | Shared hub w/ invite | **`PageHeader` `variant="collaboration"`** + `InviteCollaboratorsDrawer` |
62
- | Dedicated search (empty `?q=` vs results) | **`DedicatedSearchLandingTemplate`** + **`DedicatedSearchResultsHeaderChrome`** |
63
-
64
- **Reference:** `PlacementsClient` (Placements) is the most complete example.
65
-
66
- ### 1.2 Visual-browse hub (kanban / gallery)
67
-
68
- If the product wants a **kanban-first** experience and the table is the
69
- fallback rather than primary:
70
-
71
- ```
72
- ListPageTemplate
73
- ├── PageHeader
74
- ├── KeyMetrics (optional, ≤4)
75
- └── viewType="board" → ListPageBoardTemplate + ListPageBoardCard
76
- ```
77
-
78
- Even here, **back the board with `useTableState`** so switching to the table
79
- tab is consistent. Don't fork the data.
80
-
81
- ---
82
-
83
- ## 2. Naming a card / row / list
84
-
85
- | Pattern | What to reach for |
86
- |---|---|
87
- | Dense comparable rows | `DataTable` row (don't card-wall it — see [`card-vs-rows-pattern.md`](./card-vs-rows-pattern.md)) |
88
- | Kanban column card | `ListPageBoardCard` + `BoardCardTwoLineBlock` + `BoardCardIconRow` |
89
- | OS-folder grid | `FolderGridView` in `ListPageViewFrame` |
90
- | Finder split (list + preview) | `FinderPanelView` |
91
- | Sidebar nav row | `SidebarMenuButton` (do not roll your own) |
92
- | KPI tile | `KeyMetrics` `MetricItem` — never a custom `Card` w/ number |
93
- | Coach mark tile | `CoachMark` step — never an ad-hoc onboarding popover |
94
-
95
- ---
96
-
97
- ## 3. Same-route overlay vs new route
98
-
99
- Always ask: **does the user need the hub visible behind them?**
100
-
101
- ```
102
- ┌────────────────────────────┐
103
- │ Does the user need the hub │
104
- │ visible behind them? │
105
- └─────────────┬──────────────┘
106
-
107
- ┌───── YES ─────┴───── NO ─────┐
108
- ▼ ▼
109
- Same route New route
110
- (overlay) (own URL)
111
- │ │
112
- ┌─────┴──────┐ │
113
- │ Is the task│ │
114
- │ short + │ │
115
- │ blocking? │ │
116
- └─────┬──────┘ │
117
- │ │
118
- ┌─ YES ┴ NO ──┐ │
119
- ▼ ▼ ▼
120
- Dialog Sheet panel Page route
121
- (AlertDialog, (TablePropertiesDrawer, (full create/edit
122
- delete confirm) ExportDrawer, wizard, deep detail)
123
- InviteCollaboratorsDrawer)
124
- ```
125
-
126
- See [`drawer-vs-dialog-pattern.md`](./drawer-vs-dialog-pattern.md) and
127
- [`exxat-page-vs-drawer.mdc`](../../.cursor/rules/exxat-page-vs-drawer.mdc).
128
-
129
- ---
130
-
131
- ## 4. Search / Find / Command
132
-
133
- | Need | Use | Shortcut |
134
- |---|---|---|
135
- | Find inside a table | `DataTableToolbar` search | `⌘K` / `Ctrl K` (no Alt) |
136
- | Find inside a hub (across tabs/views) | Same `⌘K` while focus is on the hub | `⌘K` |
137
- | Global navigation + AI starter | `CommandMenu` ([`command-menu-pattern.md`](./command-menu-pattern.md)) | `⌘K` while no input has focus |
138
- | Long AI / chat | `AskLeoSidebar` | `⌘⌥K` |
139
- | Dedicated search page (results view) | `DedicatedSearchLandingTemplate` + `DedicatedSearchResultsHeaderChrome` | — |
140
-
141
- ---
142
-
143
- ## 5. Feedback / messaging
144
-
145
- | Need | Use |
146
- |---|---|
147
- | Persistent banner ("system maintenance") | `SystemBanner` |
148
- | Per-page contextual info | `LocalBanner` |
149
- | Per-control success/error | Inline text next to the field |
150
- | Confirm a destructive action | `AlertDialog` |
151
- | **Never** | `toast()` / Sonner / snackbars ([`exxat-no-toast.mdc`](../../.cursor/rules/exxat-no-toast.mdc)) |
152
-
153
- ---
154
-
155
- ## 6. Icons
156
-
157
- | Use case | Pattern |
158
- |---|---|
159
- | Icon next to a label | FA glyph + `aria-hidden` (Case A) |
160
- | Icon standing alone (meaning-bearing) | `<span role="img" aria-label="…" tabIndex={0}>` + `Tooltip` (Case B) |
161
- | Icon-only button / link | `<button aria-label="…">` wrapped in `Tooltip` (Case C) |
162
- | Product mark | `ExxatProductLogo` |
163
- | School / org mark | `logoDevUrl()` |
164
-
165
- Source: `apps/web/AGENTS.md` §8.6.
166
-
167
- ---
168
-
169
- ## 7. KPIs / metrics
170
-
171
- | Need | Use |
172
- |---|---|
173
- | Hub metric strip on top of `ListPageTemplate` | `KeyMetrics variant="flat"` |
174
- | Dashboard view tab key-metrics card | `KeyMetrics variant="card"` (1–4 tiles) |
175
- | Chart + mini-metric next to it | `ChartCard` + chart's own KPI helpers |
176
- | Trend arrow on a metric | Set `MetricItem.trend` to match delta sign; set `trendPolarity` when "up" is bad |
177
-
178
- Cap visible KPIs at **4** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)).
179
-
180
- ---
181
-
182
- ## 8. Identifiers and typography
183
-
184
- | Carries | Use |
185
- |---|---|
186
- | System ID (`questionId`, record key) | `font-mono tabular-nums` ([`exxat-mono-ids.mdc`](../../.cursor/rules/exxat-mono-ids.mdc)) |
187
- | Page title | `<h1>` with `font-heading` (Ivy Presto) inside `PageHeader` |
188
- | Body | Default Inter, ≥ 11px (`text-xs` minimum) |
189
- | Status label | `ListHubStatusBadge` from `lib/list-status-badges.ts` — never raw text |
190
- | Currency / counts | `tabular-nums` (no `font-mono`) |
191
-
192
- ---
193
-
194
- ## 9. When NOTHING here fits
195
-
196
- You are now in the territory covered by
197
- [`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc):
198
-
199
- 1. Re-scan `apps/web/components/`, `packages/ui/src/components/`, and `apps/web/components/data-views/`.
200
- 2. Check `AGENTS.md` §9 architecture table.
201
- 3. If still no fit, **ask the user** with a short option list:
202
- - extend an existing primitive (preferred),
203
- - add a new component under `components/data-views/` or `components/templates/`,
204
- - or open a packaged shared primitive in `packages/ui`.
205
-
206
- ---
207
-
208
- ## 10. Cheat sheet — one-line rules
209
-
210
- - **Data list, > 10 rows** → `DataTable` + `ListPageTemplate`.
211
- - **Visual browse / kanban** → `ListPageBoardCard`.
212
- - **Folder / panel / OS-folder view** → `data-views/` primitive in `ListPageViewFrame`.
213
- - **Quick auxiliary task with hub behind** → drawer.
214
- - **Blocking short confirm** → dialog.
215
- - **Primary / long / own-URL flow** → new route.
216
- - **Global ⌘K** → `CommandMenu` (search + quick AI).
217
- - **Long AI** → Ask Leo (`⌘⌥K`).
218
- - **Feedback** → banner / inline / dialog — **never** toast.
219
- - **Icon-only button** → `aria-label` + `Tooltip` (Case C).
220
- - **System ID** → `font-mono tabular-nums`.
221
- - **KPI strip** → ≤ 4 tiles, `variant="flat"` on hubs.
222
- - **Hex color in code** → no. Use a token.
223
-
224
- See also: [`AGENTS.md` §13 checklist](../AGENTS.md) — run it before shipping a hub.
@@ -1,158 +0,0 @@
1
- # `apps/web/components/` audit — 2026-05
2
-
3
- **Author:** Exxat DS hardening sweep · **Scope:** observation only — no code moved.
4
-
5
- This audit was triggered by formalizing the design system (token taxonomy +
6
- blueprints + selection guide + ESLint guardrails) so that any future
7
- component refactor has a clear target structure. **No file is moved or
8
- deleted by this audit itself.** Treat each finding as a follow-up PR
9
- candidate; bundle them as you like.
10
-
11
- ## 1. Sizes & shape
12
-
13
- | Bucket | Count | Notes |
14
- |---|---|---|
15
- | Top-level `components/*.tsx` | **99** | Mix of hub clients, hub tables, hub views, page headers, dashboard charts, sidebar bits, leaf primitives |
16
- | `components/data-table/` | 5 | Correct — base table stack |
17
- | `components/data-views/` | 14 | Correct — generic view primitives + board card |
18
- | `components/onboarding/` | 5 (4 demos + index) | Demo variants of `GettingStarted` |
19
- | `components/table-properties/` | (drawer + parts) | Correct |
20
- | `components/templates/` | 7 | Correct — page-level templates |
21
- | `components/ui/` | 40+ | Reserved for shadcn primitives bridged from `packages/ui` |
22
-
23
- ## 2. Findings
24
-
25
- ### 2.1 Dead components (zero importers found)
26
-
27
- > **Resolved 2026-05-19.** A re-verification scan confirmed that
28
- > `form-layout-01.tsx` and `section-cards.tsx` are **not present** in either
29
- > `apps/web/components/` or `packages/ui/template/components/` — the audit's
30
- > initial finding was based on a stale snapshot. No action needed.
31
-
32
- ### 2.2 Onboarding components split between two locations
33
-
34
- > **Resolved 2026-05-19.** Option A landed:
35
- > - `getting-started.tsx` moved into `components/onboarding/getting-started.tsx`
36
- > (both `apps/web/` and `packages/ui/template/`).
37
- > - Deprecated shims `dashboard-onboarding.tsx` and
38
- > `dashboard-onboarding-gallery.tsx` deleted in both locations
39
- > (no consumers outside themselves).
40
- > - `components/onboarding/index.ts` now re-exports `GettingStarted`,
41
- > `GettingStartedProgressCard`, `GettingStartedVariantView`,
42
- > `renderGettingStartedVariant`, `GETTING_STARTED_STORAGE_KEY`, and
43
- > the `Onboarding01`–`Onboarding04` variant cards.
44
- > - Dashboard consumers (`dashboard-tabs.tsx`, `dashboard-report-charts.tsx`)
45
- > import via `@/components/onboarding/getting-started`; intra-folder
46
- > variants use the relative `./getting-started` path.
47
-
48
- ### 2.3 Sidebar shell — high top-level density
49
-
50
- > **Resolved 2026-05-19.** All 11 sidebar files relocated into
51
- > `components/sidebar/` (both `apps/web/` and `packages/ui/template/`):
52
- >
53
- > ```
54
- > components/sidebar/
55
- > ├── index.ts ← barrel re-export
56
- > ├── app-sidebar.tsx
57
- > ├── app-sidebar-dynamic.tsx
58
- > ├── sidebar-shell.tsx
59
- > ├── sidebar-auto-collapse.tsx
60
- > ├── sidebar-auto-open.tsx
61
- > ├── nav-main.tsx
62
- > ├── nav-secondary.tsx
63
- > ├── nav-documents.tsx
64
- > ├── nav-user.tsx
65
- > ├── secondary-nav.tsx
66
- > └── secondary-panel.tsx
67
- > ```
68
- >
69
- > **External consumers** now import via the barrel:
70
- > `import { AppSidebar, SidebarShell, useSecondaryPanel } from "@/components/sidebar"`.
71
- > Per-file paths still resolve (escape hatch), e.g.
72
- > `@/components/sidebar/secondary-panel`.
73
- >
74
- > **Intra-folder** imports use relative paths (`./nav-user`, `./secondary-panel`)
75
- > so internal restructure does not ripple out.
76
- >
77
- > Dead-import audit at completion: zero references to `@/components/<sidebar-file>"`
78
- > remain outside the new folder.
79
- >
80
- > `nav-main`, `nav-secondary`, `nav-documents`, `sidebar-auto-open` are
81
- > currently zero-import (only mentioned in docs/skills). They were moved for
82
- > directory consistency; pruning truly dead files is a separate concern.
83
-
84
- ### 2.4 Dedicated-search files — naming consistent
85
-
86
- `dedicated-search-recents.tsx`, `dedicated-search-url-composer.tsx`,
87
- `components/templates/dedicated-search-{landing,results}-template.tsx` —
88
- generic family already lives across `templates/` + top-level. **No action.**
89
-
90
- ### 2.5 Entity-bound views — correctly at top level
91
-
92
- `*-list-view.tsx`, `*-board-view.tsx`, `*-page-header.tsx`, `*-client.tsx`,
93
- `*-table.tsx`, `*-dashboard-charts*.tsx`, `*-os-folder-view.tsx`,
94
- `*-panel-activator.tsx` — these are entity-specific compositions that
95
- **must** stay co-located with the hub they serve. **No action.**
96
-
97
- ### 2.6 Possibly generic — re-evaluate during reuse work
98
-
99
- - `tinted-icon-disc.tsx` — used in KPI/empty states. If the API has stabilized,
100
- consider moving to `components/data-views/` or `packages/ui/src/components/ui/`.
101
- - `task-list-panel.tsx`, `task-priority-badge.tsx` — generic-sounding but
102
- bound to a Task entity. Confirm scope before any move.
103
- - `tree-panel-view.tsx`-style: `hub-tree-panel-view.tsx`,
104
- `folder-details-shell.tsx` — already generic-sounding. If imported by
105
- ≥ 2 hubs, move under `data-views/`.
106
-
107
- A quick rule of thumb:
108
-
109
- > If a component is imported by **only one** hub, it stays at the top level
110
- > next to that hub.
111
- > If it is (or could be) imported by **≥ 2** hubs, promote it into
112
- > `components/data-views/` (record-bearing) or `components/templates/`
113
- > (page chrome).
114
-
115
- ### 2.7 `packages/ui/template/` parity
116
-
117
- Most top-level files are mirrored under `packages/ui/template/components/`
118
- (starter scaffold for `create-exxat-app`). When a file moves in
119
- `apps/web/components/`, `pnpm --filter @exxatdesignux/ui sync-template`
120
- will also move it under `template/`. **Always run `sync-template` after any
121
- refactor under §2.3 / §2.6** so the published starter stays buildable.
122
-
123
- ## 3. Non-findings — what's already healthy
124
-
125
- - **`components/ui/`** is reserved for shadcn-aligned primitives; no
126
- duplicates appear at the top level (e.g. no rogue `button.tsx` next to the
127
- one in `ui/`).
128
- - **`components/data-views/`** is the right home for generic record-bearing
129
- surfaces (`FolderGridView`, `FinderPanelView`, `ListPageBoardCard`).
130
- Entity-specific board cards (`placement-board-card.tsx`) correctly stay
131
- at top level.
132
- - **`components/templates/`** is the right home for page-level wrappers
133
- (`ListPageTemplate`, `DedicatedSearch*Template`,
134
- `SecondaryPanelHubTemplate`, `DiscoveryHubTemplate`). No drift.
135
- - **No `components/lightning/`** folder anywhere — `exxat-no-slds-leakage`
136
- rule already passes.
137
- - **No second toast surface** — only `components/ui/sonner.tsx` exists, and
138
- it's gated by `exxat-no-toast` + the new `exxat-ds/no-sonner-toast` lint.
139
-
140
- ## 4. Suggested follow-up PRs
141
-
142
- | # | Title | Scope | Risk |
143
- |---|---|---|---|
144
- | 1 | Remove dead `form-layout-01.tsx` + `section-cards.tsx` from `apps/web/` and `packages/ui/template/` | Trivial | Low |
145
- | 2 | Consolidate `getting-started.tsx` + `dashboard-onboarding*.tsx` under `components/onboarding/` | Small | Low (import rename) |
146
- | 3 | ~~Move sidebar files into `components/sidebar/`~~ — **done 2026-05-19** (§2.3) | Medium | — |
147
- | 4 | Promote `tinted-icon-disc.tsx`, `hub-tree-panel-view.tsx`, `folder-details-shell.tsx` to `data-views/` if used by ≥ 2 hubs | Small per file | Low |
148
- | 5 | Run `sync-template` after each of 1–4 to keep `packages/ui/template/` aligned | Single command | Low |
149
-
150
- None of these is urgent. They become valuable when the top-level file count
151
- exceeds ~110 or when a new hub joins the codebase.
152
-
153
- ## 5. References
154
-
155
- - [`apps/web/AGENTS.md`](../AGENTS.md) §9 — architecture pointers
156
- - [`apps/web/docs/component-selection-guide.md`](./component-selection-guide.md)
157
- - [`.cursor/rules/exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc) — ask before adding new primitives
158
- - [`.cursor/rules/exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc) — when to extract to `data-views/`
@@ -1,52 +0,0 @@
1
- # Upgrading `@exxatdesignux/ui` (human + AI checklist)
2
-
3
- Use this after **`npm install @exxatdesignux/ui@…`** / **`pnpm add @exxatdesignux/ui@…`**. It is copied into **`docs/exxat-ds/`** when you run **`exxat-ui sync-extras`**, so Cursor and other tools can find it beside other DS pattern docs.
4
-
5
- ## 1. See what changed
6
-
7
- | Source | Purpose |
8
- |--------|---------|
9
- | **`node_modules/@exxatdesignux/ui/CHANGELOG.md`** | Release notes for the installed version (and peers). |
10
- | **`npx --package=@exxatdesignux/ui@latest exxat-ui changelog`** | Print the changelog from the package on disk / npx extract. |
11
-
12
- ## 2. Refresh AI / pattern docs (optional but recommended)
13
-
14
- ```bash
15
- npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras
16
- ```
17
-
18
- Overwrites only **`.cursor/skills/exxat-*`** and **`docs/exxat-ds/*.md`** (including this file). Does **not** change your app routes or product code.
19
-
20
- ## 3. Align app code with the reference template
21
-
22
- The npm package includes a full Next.js reference under:
23
-
24
- **`node_modules/@exxatdesignux/ui/template/`**
25
-
26
- Use it when you need to know **what files exist**, **how shims re-export** `@exxatdesignux/ui`, or **what AGENTS / layout** patterns look like for the current release. Porting is manual: diff template vs your repo and apply intentional changes (imports, new components, CSS entrypoints).
27
-
28
- ## 4. Dependency and Node
29
-
30
- - Keep **`@exxatdesignux/ui`** on the same semver your team tested; prefer explicit **`^x.y.z`** or pinned **`x.y.z`**.
31
- - Match **`engines.node`** in your app to the value declared in **`node_modules/@exxatdesignux/ui/package.json`** (see CHANGELOG if it changed).
32
- - **≥ 0.5.3:** Remove **`vaul`** from your app `package.json` and delete any `components/ui/drawer.tsx` shim — side panels use **`Sheet`** only (**`.cursor/rules/exxat-no-vaul.mdc`**).
33
-
34
- ## 5. Consumer UI audit (after sync-extras)
35
-
36
- If the app was built before current agent rules, verify:
37
-
38
- | Symptom | Fix |
39
- |---------|-----|
40
- | Full-width tab bar on list hub | Use **`ListPageTemplate`** view toolbar — **`exxat-tabs-chrome.mdc`** |
41
- | Full-width Overview / Academics tabs | **`TabsList`** must stay **`w-fit`** — no `w-full` / `flex-1` stretch |
42
- | Grey custom header buttons | **`PageHeader`** + **`Button`** variants — **`exxat-page-header-actions.mdc`** |
43
- | Bespoke student popover in table | **`HoverCard`** + shared cells/badges — **`exxat-table-row-preview.mdc`** |
44
- | Custom hub table / trimmed Add view | **`HubTable`** + **`FULL_HUB_SUPPORTED_VIEWS`** — **`exxat-hub-supported-views.mdc`** |
45
- | Agent copied uploaded screenshots pixel-for-pixel | **`exxat-no-image-pixel-copy.mdc`** — images = IA only; map to blueprints + reference hubs |
46
-
47
- ## 6. Still stuck?
48
-
49
- - **`npx --package=@exxatdesignux/ui@latest exxat-ui doctor`** — compares local CLI version vs npm **`latest`**.
50
- - **`npx --package=@exxatdesignux/ui@latest exxat-ui update`** — install commands and reminders.
51
-
52
- Maintainers publish from the design-system monorepo with git tags **`ui-v<version>`**; registry **`latest`** follows those tags.