@exxatdesignux/ui 0.2.19 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/CHANGELOG.md +60 -7
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +42 -7
  4. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
  5. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
  6. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
  7. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
  8. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
  9. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
  10. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
  11. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
  12. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
  13. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
  14. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
  15. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
  16. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
  17. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
  18. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
  19. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
  20. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
  21. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  23. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  24. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  25. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  26. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  27. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  28. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
  29. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
  30. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
  31. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
  32. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
  33. package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
  34. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +4 -15
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
  39. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  40. package/consumer-extras/handbook/glossary.md +57 -0
  41. package/consumer-extras/handbook/reference-implementations.md +126 -0
  42. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  43. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  44. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  45. package/consumer-extras/patterns/data-views-pattern.md +17 -54
  46. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  47. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  48. package/dist/components/data-table/filter-date-calendar.js +280 -0
  49. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  50. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  51. package/dist/components/data-table/filter-text-value-input.js +561 -0
  52. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  53. package/dist/components/data-table/index.d.ts +45 -0
  54. package/dist/components/data-table/index.js +3085 -0
  55. package/dist/components/data-table/index.js.map +1 -0
  56. package/dist/components/data-table/pagination.d.ts +28 -0
  57. package/dist/components/data-table/pagination.js +3264 -0
  58. package/dist/components/data-table/pagination.js.map +1 -0
  59. package/dist/components/data-table/types.d.ts +84 -0
  60. package/dist/components/data-table/types.js +3 -0
  61. package/dist/components/data-table/types.js.map +1 -0
  62. package/dist/components/data-table/use-table-state.d.ts +116 -0
  63. package/dist/components/data-table/use-table-state.js +670 -0
  64. package/dist/components/data-table/use-table-state.js.map +1 -0
  65. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  66. package/dist/components/data-views/board-card-primitives.js +84 -0
  67. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  68. package/dist/components/data-views/data-row-list.d.ts +33 -0
  69. package/dist/components/data-views/data-row-list.js +106 -0
  70. package/dist/components/data-views/data-row-list.js.map +1 -0
  71. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  72. package/dist/components/data-views/finder-panel-view.js +388 -0
  73. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  74. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  75. package/dist/components/data-views/folder-grid-view.js +58 -0
  76. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  77. package/dist/components/data-views/hub-table.d.ts +167 -0
  78. package/dist/components/data-views/hub-table.js +5561 -0
  79. package/dist/components/data-views/hub-table.js.map +1 -0
  80. package/dist/components/data-views/index.d.ts +27 -0
  81. package/dist/components/data-views/index.js +6575 -0
  82. package/dist/components/data-views/index.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  84. package/dist/components/data-views/list-page-board-card.js +264 -0
  85. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  86. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  87. package/dist/components/data-views/list-page-board-template.js +137 -0
  88. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  89. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  90. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  91. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  93. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  94. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  96. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  97. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  98. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  99. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  100. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  102. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  103. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  104. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  105. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  106. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  107. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  108. package/dist/components/data-views/os-folder-glyph.js +104 -0
  109. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  110. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  111. package/dist/components/data-views/outline-tree-menu.js +131 -0
  112. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  113. package/dist/components/table-properties/column-row.d.ts +22 -0
  114. package/dist/components/table-properties/column-row.js +153 -0
  115. package/dist/components/table-properties/column-row.js.map +1 -0
  116. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  117. package/dist/components/table-properties/draggable-list.js +53 -0
  118. package/dist/components/table-properties/draggable-list.js.map +1 -0
  119. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  120. package/dist/components/table-properties/drawer-button.js +2748 -0
  121. package/dist/components/table-properties/drawer-button.js.map +1 -0
  122. package/dist/components/table-properties/drawer.d.ts +100 -0
  123. package/dist/components/table-properties/drawer.js +2595 -0
  124. package/dist/components/table-properties/drawer.js.map +1 -0
  125. package/dist/components/table-properties/filter-card.d.ts +24 -0
  126. package/dist/components/table-properties/filter-card.js +854 -0
  127. package/dist/components/table-properties/filter-card.js.map +1 -0
  128. package/dist/components/table-properties/index.d.ts +14 -0
  129. package/dist/components/table-properties/index.js +2768 -0
  130. package/dist/components/table-properties/index.js.map +1 -0
  131. package/dist/components/table-properties/sort-card.d.ts +20 -0
  132. package/dist/components/table-properties/sort-card.js +102 -0
  133. package/dist/components/table-properties/sort-card.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  135. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  136. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  137. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  138. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  139. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  140. package/dist/components/templates/index.d.ts +9 -0
  141. package/dist/components/templates/index.js +2720 -0
  142. package/dist/components/templates/index.js.map +1 -0
  143. package/dist/components/templates/list-page.d.ts +83 -0
  144. package/dist/components/templates/list-page.js +2433 -0
  145. package/dist/components/templates/list-page.js.map +1 -0
  146. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  147. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  148. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  149. package/dist/components/ui/accordion.d.ts +10 -0
  150. package/dist/components/ui/accordion.js +74 -0
  151. package/dist/components/ui/accordion.js.map +1 -0
  152. package/dist/components/ui/alert-dialog.d.ts +37 -0
  153. package/dist/components/ui/alert-dialog.js +201 -0
  154. package/dist/components/ui/alert-dialog.js.map +1 -0
  155. package/dist/components/ui/avatar.d.ts +84 -0
  156. package/dist/components/ui/avatar.js +328 -0
  157. package/dist/components/ui/avatar.js.map +1 -0
  158. package/dist/components/ui/badge.d.ts +13 -0
  159. package/dist/components/ui/badge.js +49 -0
  160. package/dist/components/ui/badge.js.map +1 -0
  161. package/dist/components/ui/banner.d.ts +62 -0
  162. package/dist/components/ui/banner.js +364 -0
  163. package/dist/components/ui/banner.js.map +1 -0
  164. package/dist/components/ui/breadcrumb.d.ts +14 -0
  165. package/dist/components/ui/breadcrumb.js +114 -0
  166. package/dist/components/ui/breadcrumb.js.map +1 -0
  167. package/dist/components/ui/button.d.ts +16 -0
  168. package/dist/components/ui/button.js +59 -0
  169. package/dist/components/ui/button.js.map +1 -0
  170. package/dist/components/ui/calendar.d.ts +13 -0
  171. package/dist/components/ui/calendar.js +238 -0
  172. package/dist/components/ui/calendar.js.map +1 -0
  173. package/dist/components/ui/card.d.ts +14 -0
  174. package/dist/components/ui/card.js +102 -0
  175. package/dist/components/ui/card.js.map +1 -0
  176. package/dist/components/ui/chart.d.ts +58 -0
  177. package/dist/components/ui/chart.js +292 -0
  178. package/dist/components/ui/chart.js.map +1 -0
  179. package/dist/components/ui/checkbox.d.ts +23 -0
  180. package/dist/components/ui/checkbox.js +155 -0
  181. package/dist/components/ui/checkbox.js.map +1 -0
  182. package/dist/components/ui/coach-mark.d.ts +27 -0
  183. package/dist/components/ui/coach-mark.js +306 -0
  184. package/dist/components/ui/coach-mark.js.map +1 -0
  185. package/dist/components/ui/collapsible.d.ts +8 -0
  186. package/dist/components/ui/collapsible.js +35 -0
  187. package/dist/components/ui/collapsible.js.map +1 -0
  188. package/dist/components/ui/command.d.ts +36 -0
  189. package/dist/components/ui/command.js +274 -0
  190. package/dist/components/ui/command.js.map +1 -0
  191. package/dist/components/ui/context-menu.d.ts +32 -0
  192. package/dist/components/ui/context-menu.js +245 -0
  193. package/dist/components/ui/context-menu.js.map +1 -0
  194. package/dist/components/ui/date-picker-field.d.ts +38 -0
  195. package/dist/components/ui/date-picker-field.js +550 -0
  196. package/dist/components/ui/date-picker-field.js.map +1 -0
  197. package/dist/components/ui/dialog.d.ts +22 -0
  198. package/dist/components/ui/dialog.js +200 -0
  199. package/dist/components/ui/dialog.js.map +1 -0
  200. package/dist/components/ui/dot-pattern.d.ts +21 -0
  201. package/dist/components/ui/dot-pattern.js +139 -0
  202. package/dist/components/ui/dot-pattern.js.map +1 -0
  203. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  204. package/dist/components/ui/drag-handle-grip.js +15 -0
  205. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  206. package/dist/components/ui/drawer.d.ts +16 -0
  207. package/dist/components/ui/drawer.js +125 -0
  208. package/dist/components/ui/drawer.js.map +1 -0
  209. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  210. package/dist/components/ui/dropdown-menu.js +353 -0
  211. package/dist/components/ui/dropdown-menu.js.map +1 -0
  212. package/dist/components/ui/export-drawer.d.ts +11 -0
  213. package/dist/components/ui/export-drawer.js +1658 -0
  214. package/dist/components/ui/export-drawer.js.map +1 -0
  215. package/dist/components/ui/field.d.ts +30 -0
  216. package/dist/components/ui/field.js +249 -0
  217. package/dist/components/ui/field.js.map +1 -0
  218. package/dist/components/ui/form.d.ts +28 -0
  219. package/dist/components/ui/form.js +110 -0
  220. package/dist/components/ui/form.js.map +1 -0
  221. package/dist/components/ui/hover-card.d.ts +9 -0
  222. package/dist/components/ui/hover-card.js +43 -0
  223. package/dist/components/ui/hover-card.js.map +1 -0
  224. package/dist/components/ui/input-group.d.ts +20 -0
  225. package/dist/components/ui/input-group.js +219 -0
  226. package/dist/components/ui/input-group.js.map +1 -0
  227. package/dist/components/ui/input-mask.d.ts +39 -0
  228. package/dist/components/ui/input-mask.js +118 -0
  229. package/dist/components/ui/input-mask.js.map +1 -0
  230. package/dist/components/ui/input.d.ts +5 -0
  231. package/dist/components/ui/input.js +30 -0
  232. package/dist/components/ui/input.js.map +1 -0
  233. package/dist/components/ui/kbd.d.ts +20 -0
  234. package/dist/components/ui/kbd.js +45 -0
  235. package/dist/components/ui/kbd.js.map +1 -0
  236. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  237. package/dist/components/ui/key-metrics-context.js +26 -0
  238. package/dist/components/ui/key-metrics-context.js.map +1 -0
  239. package/dist/components/ui/key-metrics.d.ts +131 -0
  240. package/dist/components/ui/key-metrics.js +1015 -0
  241. package/dist/components/ui/key-metrics.js.map +1 -0
  242. package/dist/components/ui/label.d.ts +6 -0
  243. package/dist/components/ui/label.js +28 -0
  244. package/dist/components/ui/label.js.map +1 -0
  245. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  246. package/dist/components/ui/list-page-view-frame.js +24 -0
  247. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  248. package/dist/components/ui/page-header.d.ts +51 -0
  249. package/dist/components/ui/page-header.js +372 -0
  250. package/dist/components/ui/page-header.js.map +1 -0
  251. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  252. package/dist/components/ui/payment-card-fields.js +80 -0
  253. package/dist/components/ui/payment-card-fields.js.map +1 -0
  254. package/dist/components/ui/popover.d.ts +10 -0
  255. package/dist/components/ui/popover.js +47 -0
  256. package/dist/components/ui/popover.js.map +1 -0
  257. package/dist/components/ui/radio-group.d.ts +29 -0
  258. package/dist/components/ui/radio-group.js +190 -0
  259. package/dist/components/ui/radio-group.js.map +1 -0
  260. package/dist/components/ui/resizable.d.ts +16 -0
  261. package/dist/components/ui/resizable.js +51 -0
  262. package/dist/components/ui/resizable.js.map +1 -0
  263. package/dist/components/ui/scroll-area.d.ts +8 -0
  264. package/dist/components/ui/scroll-area.js +66 -0
  265. package/dist/components/ui/scroll-area.js.map +1 -0
  266. package/dist/components/ui/select.d.ts +18 -0
  267. package/dist/components/ui/select.js +186 -0
  268. package/dist/components/ui/select.js.map +1 -0
  269. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  270. package/dist/components/ui/selection-tile-grid.js +347 -0
  271. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  272. package/dist/components/ui/separator.d.ts +7 -0
  273. package/dist/components/ui/separator.js +33 -0
  274. package/dist/components/ui/separator.js.map +1 -0
  275. package/dist/components/ui/sheet.d.ts +18 -0
  276. package/dist/components/ui/sheet.js +181 -0
  277. package/dist/components/ui/sheet.js.map +1 -0
  278. package/dist/components/ui/sidebar.d.ts +94 -0
  279. package/dist/components/ui/sidebar.js +805 -0
  280. package/dist/components/ui/sidebar.js.map +1 -0
  281. package/dist/components/ui/skeleton.d.ts +5 -0
  282. package/dist/components/ui/skeleton.js +22 -0
  283. package/dist/components/ui/skeleton.js.map +1 -0
  284. package/dist/components/ui/slider.d.ts +7 -0
  285. package/dist/components/ui/slider.js +66 -0
  286. package/dist/components/ui/slider.js.map +1 -0
  287. package/dist/components/ui/sonner.d.ts +6 -0
  288. package/dist/components/ui/sonner.js +38 -0
  289. package/dist/components/ui/sonner.js.map +1 -0
  290. package/dist/components/ui/status-badge.d.ts +38 -0
  291. package/dist/components/ui/status-badge.js +77 -0
  292. package/dist/components/ui/status-badge.js.map +1 -0
  293. package/dist/components/ui/table.d.ts +13 -0
  294. package/dist/components/ui/table.js +115 -0
  295. package/dist/components/ui/table.js.map +1 -0
  296. package/dist/components/ui/tabs.d.ts +15 -0
  297. package/dist/components/ui/tabs.js +93 -0
  298. package/dist/components/ui/tabs.js.map +1 -0
  299. package/dist/components/ui/textarea.d.ts +6 -0
  300. package/dist/components/ui/textarea.js +25 -0
  301. package/dist/components/ui/textarea.js.map +1 -0
  302. package/dist/components/ui/tip.d.ts +12 -0
  303. package/dist/components/ui/tip.js +61 -0
  304. package/dist/components/ui/tip.js.map +1 -0
  305. package/dist/components/ui/toggle-group.d.ts +14 -0
  306. package/dist/components/ui/toggle-group.js +104 -0
  307. package/dist/components/ui/toggle-group.js.map +1 -0
  308. package/dist/components/ui/toggle-switch.d.ts +10 -0
  309. package/dist/components/ui/toggle-switch.js +33 -0
  310. package/dist/components/ui/toggle-switch.js.map +1 -0
  311. package/dist/components/ui/toggle.d.ts +13 -0
  312. package/dist/components/ui/toggle.js +51 -0
  313. package/dist/components/ui/toggle.js.map +1 -0
  314. package/dist/components/ui/tooltip.d.ts +10 -0
  315. package/dist/components/ui/tooltip.js +68 -0
  316. package/dist/components/ui/tooltip.js.map +1 -0
  317. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  318. package/dist/components/ui/view-segmented-control.js +167 -0
  319. package/dist/components/ui/view-segmented-control.js.map +1 -0
  320. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  321. package/dist/hooks/use-app-theme.d.ts +24 -0
  322. package/dist/hooks/use-app-theme.js +286 -0
  323. package/dist/hooks/use-app-theme.js.map +1 -0
  324. package/dist/hooks/use-coach-mark.d.ts +86 -0
  325. package/dist/hooks/use-coach-mark.js +218 -0
  326. package/dist/hooks/use-coach-mark.js.map +1 -0
  327. package/dist/hooks/use-mobile.d.ts +3 -0
  328. package/dist/hooks/use-mobile.js +29 -0
  329. package/dist/hooks/use-mobile.js.map +1 -0
  330. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  331. package/dist/hooks/use-mod-key-label.js +25 -0
  332. package/dist/hooks/use-mod-key-label.js.map +1 -0
  333. package/dist/index.d.ts +120 -0
  334. package/dist/index.js +13324 -0
  335. package/dist/index.js.map +1 -0
  336. package/dist/lib/compose-refs.d.ts +6 -0
  337. package/dist/lib/compose-refs.js +17 -0
  338. package/dist/lib/compose-refs.js.map +1 -0
  339. package/dist/lib/conditional-rule-match.d.ts +30 -0
  340. package/dist/lib/conditional-rule-match.js +66 -0
  341. package/dist/lib/conditional-rule-match.js.map +1 -0
  342. package/dist/lib/data-list-display-options.d.ts +26 -0
  343. package/dist/lib/data-list-display-options.js +14 -0
  344. package/dist/lib/data-list-display-options.js.map +1 -0
  345. package/dist/lib/data-list-view-registry.d.ts +2 -0
  346. package/dist/lib/data-list-view-registry.js +102 -0
  347. package/dist/lib/data-list-view-registry.js.map +1 -0
  348. package/dist/lib/data-list-view-surface.d.ts +2 -0
  349. package/dist/lib/data-list-view-surface.js +80 -0
  350. package/dist/lib/data-list-view-surface.js.map +1 -0
  351. package/dist/lib/data-list-view.d.ts +21 -0
  352. package/dist/lib/data-list-view.js +25 -0
  353. package/dist/lib/data-list-view.js.map +1 -0
  354. package/dist/lib/date-filter.d.ts +22 -0
  355. package/dist/lib/date-filter.js +61 -0
  356. package/dist/lib/date-filter.js.map +1 -0
  357. package/dist/lib/dev-log.d.ts +8 -0
  358. package/dist/lib/dev-log.js +10 -0
  359. package/dist/lib/dev-log.js.map +1 -0
  360. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  361. package/dist/lib/dropdown-menu-surface.js +6 -0
  362. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  363. package/dist/lib/editable-target.d.ts +12 -0
  364. package/dist/lib/editable-target.js +12 -0
  365. package/dist/lib/editable-target.js.map +1 -0
  366. package/dist/lib/list-page-table-properties.d.ts +35 -0
  367. package/dist/lib/list-page-table-properties.js +81 -0
  368. package/dist/lib/list-page-table-properties.js.map +1 -0
  369. package/dist/lib/raf-throttle.d.ts +23 -0
  370. package/dist/lib/raf-throttle.js +27 -0
  371. package/dist/lib/raf-throttle.js.map +1 -0
  372. package/dist/lib/row-height.d.ts +16 -0
  373. package/dist/lib/row-height.js +10 -0
  374. package/dist/lib/row-height.js.map +1 -0
  375. package/dist/lib/table-properties-types.d.ts +83 -0
  376. package/dist/lib/table-properties-types.js +19 -0
  377. package/dist/lib/table-properties-types.js.map +1 -0
  378. package/dist/lib/utils.d.ts +5 -0
  379. package/dist/lib/utils.js +11 -0
  380. package/dist/lib/utils.js.map +1 -0
  381. package/package.json +83 -19
  382. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  383. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  384. package/src/components/data-table/index.tsx +1678 -0
  385. package/src/components/data-table/pagination.tsx +255 -0
  386. package/src/components/data-table/types.ts +96 -0
  387. package/src/components/data-table/use-table-state.ts +767 -0
  388. package/src/components/data-views/board-card-primitives.tsx +93 -0
  389. package/src/components/data-views/data-row-list.tsx +183 -0
  390. package/src/components/data-views/finder-panel-view.tsx +405 -0
  391. package/src/components/data-views/folder-grid-view.tsx +86 -0
  392. package/src/components/data-views/hub-table.tsx +498 -0
  393. package/src/components/data-views/index.ts +28 -0
  394. package/src/components/data-views/list-page-board-card.tsx +192 -0
  395. package/src/components/data-views/list-page-board-template.tsx +122 -0
  396. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  397. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  398. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  399. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  400. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  401. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  402. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  403. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  404. package/src/components/table-properties/column-row.tsx +90 -0
  405. package/src/components/table-properties/draggable-list.ts +54 -0
  406. package/src/components/table-properties/drawer-button.tsx +300 -0
  407. package/src/components/table-properties/drawer.tsx +1148 -0
  408. package/src/components/table-properties/filter-card.tsx +251 -0
  409. package/src/components/table-properties/index.ts +36 -0
  410. package/src/components/table-properties/sort-card.tsx +63 -0
  411. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  412. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  413. package/src/components/templates/index.ts +33 -0
  414. package/src/components/templates/list-page.tsx +602 -0
  415. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  416. package/src/components/ui/accordion.tsx +92 -0
  417. package/src/components/ui/alert-dialog.tsx +221 -0
  418. package/src/components/ui/avatar.tsx +13 -2
  419. package/src/components/ui/banner.tsx +2 -2
  420. package/src/components/ui/button.tsx +4 -4
  421. package/src/components/ui/calendar.tsx +1 -1
  422. package/src/components/ui/coach-mark.tsx +1 -1
  423. package/src/components/ui/context-menu.tsx +291 -0
  424. package/src/components/ui/date-picker-field.tsx +2 -2
  425. package/src/components/ui/dot-pattern.tsx +183 -0
  426. package/src/components/ui/export-drawer.tsx +375 -0
  427. package/src/components/ui/hover-card.tsx +66 -0
  428. package/src/components/ui/key-metrics-context.tsx +78 -0
  429. package/src/components/ui/key-metrics.tsx +1133 -0
  430. package/src/components/ui/list-page-view-frame.tsx +64 -0
  431. package/src/components/ui/page-header.tsx +244 -0
  432. package/src/components/ui/payment-card-fields.tsx +2 -2
  433. package/src/components/ui/resizable.tsx +68 -0
  434. package/src/components/ui/scroll-area.tsx +72 -0
  435. package/src/components/ui/selection-tile-grid.tsx +9 -2
  436. package/src/components/ui/sidebar.tsx +84 -12
  437. package/src/components/ui/slider.tsx +83 -0
  438. package/src/globals.css +2201 -7
  439. package/src/globals.d.ts +20 -0
  440. package/src/index.ts +68 -1
  441. package/src/lib/conditional-rule-match.ts +119 -0
  442. package/src/lib/data-list-display-options.ts +35 -0
  443. package/src/lib/data-list-view-registry.ts +104 -0
  444. package/src/lib/data-list-view-surface.ts +83 -0
  445. package/src/lib/data-list-view.ts +47 -0
  446. package/src/lib/dev-log.ts +10 -0
  447. package/src/lib/editable-target.ts +20 -0
  448. package/src/lib/list-page-table-properties.ts +48 -0
  449. package/src/lib/raf-throttle.ts +45 -0
  450. package/src/lib/row-height.ts +19 -0
  451. package/src/lib/table-properties-types.ts +98 -0
  452. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  453. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  454. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  455. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  456. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  457. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  458. package/template/AGENTS.md +104 -78
  459. package/template/app/(app)/dashboard/loading.tsx +15 -3
  460. package/template/app/(app)/dashboard/page.tsx +14 -2
  461. package/template/app/(app)/examples/page.tsx +0 -2
  462. package/template/app/(app)/layout.tsx +17 -4
  463. package/template/app/(app)/loading.tsx +18 -1
  464. package/template/app/(app)/question-bank/find/page.tsx +1 -2
  465. package/template/app/(app)/question-bank/layout.tsx +1 -1
  466. package/template/app/(app)/question-bank/library/page.tsx +1 -2
  467. package/template/app/(app)/question-bank/list/page.tsx +1 -2
  468. package/template/app/(app)/question-bank/new/page.tsx +15 -20
  469. package/template/app/(app)/question-bank/page.tsx +1 -2
  470. package/template/app/(app)/settings/page.tsx +5 -4
  471. package/template/app/globals.css +14 -16
  472. package/template/components/ask-leo-sidebar.tsx +5 -1
  473. package/template/components/brand-color-picker.tsx +2 -2
  474. package/template/components/charts-overview.tsx +1 -1
  475. package/template/components/compliance-board-view.tsx +142 -0
  476. package/template/components/compliance-client.tsx +92 -0
  477. package/template/components/compliance-page-header.tsx +89 -0
  478. package/template/components/compliance-table.tsx +468 -0
  479. package/template/components/dashboard-report-charts.tsx +1 -1
  480. package/template/components/dashboard-tabs.tsx +1 -1
  481. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  482. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  483. package/template/components/data-table/index.tsx +1 -1634
  484. package/template/components/data-table/pagination.tsx +1 -255
  485. package/template/components/data-table/types.ts +1 -94
  486. package/template/components/data-table/use-table-state.test.ts +420 -0
  487. package/template/components/data-table/use-table-state.ts +1 -758
  488. package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
  489. package/template/components/data-view-dashboard-charts-team.tsx +971 -0
  490. package/template/components/data-view-dashboard-charts.tsx +1503 -0
  491. package/template/components/data-views/board-card-primitives.tsx +1 -93
  492. package/template/components/data-views/data-row-list.tsx +1 -183
  493. package/template/components/data-views/finder-panel-view.tsx +1 -405
  494. package/template/components/data-views/folder-grid-view.tsx +1 -86
  495. package/template/components/data-views/hub-table.tsx +1 -0
  496. package/template/components/data-views/index.ts +50 -37
  497. package/template/components/data-views/list-page-board-card.tsx +1 -192
  498. package/template/components/data-views/list-page-board-template.tsx +1 -122
  499. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  500. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  501. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  502. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  503. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  504. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  505. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  506. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  507. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  508. package/template/components/export-drawer.test.tsx +71 -0
  509. package/template/components/export-drawer.tsx +1 -375
  510. package/template/components/exxat-product-logo.tsx +5 -5
  511. package/template/components/hub-tree-panel-view.tsx +2 -2
  512. package/template/components/invite-collaborators-drawer.tsx +3 -3
  513. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  514. package/template/components/key-metrics.tsx +1 -1063
  515. package/template/components/leo-insight-indicator.tsx +2 -2
  516. package/template/components/new-placement-back-btn.tsx +28 -0
  517. package/template/components/new-placement-form.tsx +942 -0
  518. package/template/components/new-question-composer.tsx +456 -408
  519. package/template/components/onboarding/index.ts +9 -0
  520. package/template/components/onboarding/onboarding-01.tsx +1 -1
  521. package/template/components/onboarding/onboarding-02.tsx +1 -1
  522. package/template/components/onboarding/onboarding-03.tsx +1 -1
  523. package/template/components/onboarding/onboarding-04.tsx +1 -1
  524. package/template/components/page-header.tsx +8 -226
  525. package/template/components/placement-board-card.tsx +250 -0
  526. package/template/components/placement-detail.tsx +438 -0
  527. package/template/components/placements-board-view.tsx +397 -0
  528. package/template/components/placements-client.tsx +220 -0
  529. package/template/components/placements-list-view.tsx +124 -0
  530. package/template/components/placements-page-header.tsx +166 -0
  531. package/template/components/placements-table-cells.test.tsx +22 -0
  532. package/template/components/placements-table-cells.tsx +173 -0
  533. package/template/components/placements-table-columns.tsx +210 -0
  534. package/template/components/placements-table.tsx +934 -0
  535. package/template/components/product-switcher.tsx +3 -4
  536. package/template/components/product-wordmark.tsx +2 -1
  537. package/template/components/question-bank-client.tsx +5 -5
  538. package/template/components/question-bank-hub-client.tsx +1 -1
  539. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  540. package/template/components/question-bank-secondary-nav.tsx +3 -3
  541. package/template/components/question-bank-table.tsx +541 -431
  542. package/template/components/rotations-empty-state.tsx +50 -0
  543. package/template/components/rotations-panel-activator.tsx +8 -0
  544. package/template/components/settings-appearance-card.tsx +3 -4
  545. package/template/components/settings-client.tsx +15 -59
  546. package/template/components/settings-form-row.tsx +4 -9
  547. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  548. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
  549. package/template/components/sidebar/index.ts +16 -0
  550. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  551. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
  552. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  553. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  554. package/template/components/site-header.tsx +1 -1
  555. package/template/components/sites-board-view.tsx +67 -0
  556. package/template/components/sites-client.tsx +154 -0
  557. package/template/components/sites-table.tsx +249 -0
  558. package/template/components/table-properties/column-row.tsx +1 -90
  559. package/template/components/table-properties/draggable-list.ts +1 -49
  560. package/template/components/table-properties/drawer-button.tsx +1 -262
  561. package/template/components/table-properties/drawer.tsx +1 -1166
  562. package/template/components/table-properties/filter-card.tsx +1 -251
  563. package/template/components/table-properties/sort-card.tsx +1 -59
  564. package/template/components/table-properties/types.ts +28 -71
  565. package/template/components/team-board-view.tsx +122 -0
  566. package/template/components/team-client.tsx +100 -0
  567. package/template/components/team-page-header.tsx +92 -0
  568. package/template/components/team-table.tsx +553 -0
  569. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  570. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  571. package/template/components/templates/list-page.tsx +1 -608
  572. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
  573. package/template/components/templates/new-focus-template.tsx +659 -0
  574. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  575. package/template/components/ui/accordion.tsx +1 -0
  576. package/template/components/ui/alert-dialog.tsx +1 -0
  577. package/template/components/ui/context-menu.tsx +1 -0
  578. package/template/components/ui/dot-pattern.tsx +1 -183
  579. package/template/components/ui/hover-card.tsx +1 -0
  580. package/template/components/ui/resizable.tsx +1 -68
  581. package/template/components/ui/scroll-area.tsx +1 -0
  582. package/template/components/ui/slider.tsx +1 -0
  583. package/template/docs/blueprints/README.md +86 -0
  584. package/template/docs/blueprints/_template.md +91 -0
  585. package/template/docs/blueprints/board-card.md +123 -0
  586. package/template/docs/blueprints/data-table.md +139 -0
  587. package/template/docs/blueprints/key-metrics.md +128 -0
  588. package/template/docs/blueprints/list-page-template.md +123 -0
  589. package/template/docs/blueprints/page-header.md +130 -0
  590. package/template/docs/command-menu-pattern.md +1 -1
  591. package/template/docs/component-selection-guide.md +224 -0
  592. package/template/docs/components-audit-2026-05.md +158 -0
  593. package/template/docs/data-views-pattern.md +17 -54
  594. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  595. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  596. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  597. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  598. package/template/docs/migrations/README.md +100 -0
  599. package/template/docs/migrations/_template.md +64 -0
  600. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  601. package/template/docs/token-taxonomy.md +416 -0
  602. package/template/eslint.config.mjs +27 -0
  603. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  604. package/template/lib/command-menu-config.ts +0 -1
  605. package/template/lib/command-menu-search-data.ts +27 -11
  606. package/template/lib/compliance-supported-views.ts +10 -0
  607. package/template/lib/conditional-rule-match.ts +6 -97
  608. package/template/lib/data-list-display-options.ts +1 -49
  609. package/template/lib/data-list-view-registry.ts +1 -104
  610. package/template/lib/data-list-view-surface.ts +1 -83
  611. package/template/lib/data-list-view.ts +1 -47
  612. package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
  613. package/template/lib/data-view-dashboard-storage.ts +35 -38
  614. package/template/lib/dev-log.ts +1 -8
  615. package/template/lib/editable-target.ts +1 -10
  616. package/template/lib/list-page-table-properties.ts +1 -48
  617. package/template/lib/list-status-badges.ts +97 -4
  618. package/template/lib/mock/compliance-kpi.ts +61 -0
  619. package/template/lib/mock/compliance.ts +146 -0
  620. package/template/lib/mock/navigation.tsx +0 -9
  621. package/template/lib/mock/placements-kpi.ts +134 -0
  622. package/template/lib/mock/placements.ts +176 -0
  623. package/template/lib/mock/sites-directory.ts +16 -0
  624. package/template/lib/mock/sites-kpi.ts +25 -0
  625. package/template/lib/mock/team-kpi.ts +60 -0
  626. package/template/lib/mock/team.ts +118 -0
  627. package/template/lib/placement-board-card-layout.ts +79 -0
  628. package/template/lib/placements-supported-views.ts +12 -0
  629. package/template/lib/question-bank-supported-views.ts +0 -1
  630. package/template/lib/raf-throttle.ts +1 -45
  631. package/template/lib/row-height.ts +4 -10
  632. package/template/lib/sidebar-state-cookie.ts +11 -2
  633. package/template/lib/sites-supported-views.ts +10 -0
  634. package/template/lib/table-state-lifecycle.ts +2 -2
  635. package/template/lib/team-supported-views.ts +10 -0
  636. package/template/package.json +1 -0
  637. package/template/tests/setup.ts +25 -0
  638. package/consumer-extras/AGENTS.md +0 -76
  639. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  640. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  641. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  642. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  643. package/src/components/ui/button-group.tsx +0 -81
  644. package/src/theme.css +0 -16
  645. package/src/tokens/README.md +0 -15
  646. package/src/tokens/base.css +0 -337
  647. package/src/tokens/high-contrast.css +0 -1195
  648. package/src/tokens/layers.css +0 -224
  649. package/src/tokens/tailwind-bridge.css +0 -118
  650. package/src/tokens/themes.css +0 -201
  651. package/template/app/(app)/data-list/layout.tsx +0 -43
  652. package/template/app/(app)/data-list/page.tsx +0 -10
  653. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  654. package/template/components/app-route-loading.tsx +0 -14
  655. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  656. package/template/components/dashboard-onboarding.tsx +0 -21
  657. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  658. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  659. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  660. package/template/components/list-hub-board-view.tsx +0 -68
  661. package/template/components/list-hub-client.tsx +0 -186
  662. package/template/components/list-hub-list-view.tsx +0 -36
  663. package/template/components/list-hub-panel-activator.tsx +0 -8
  664. package/template/components/list-hub-secondary-nav.tsx +0 -121
  665. package/template/components/list-hub-table.tsx +0 -336
  666. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  667. package/template/components/question-bank-list-view.tsx +0 -53
  668. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  669. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  670. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  671. package/template/components/secondary-panels/registry.tsx +0 -15
  672. package/template/components/section-cards.tsx +0 -106
  673. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  674. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  675. package/template/components/templates/page-loading-shell.tsx +0 -262
  676. package/template/components/ui/button-group.tsx +0 -1
  677. package/template/docs/consumer-app-pattern.md +0 -39
  678. package/template/docs/focused-workflow-page-pattern.md +0 -84
  679. package/template/lib/list-hub-nav.ts +0 -121
  680. package/template/lib/mock/list-hub-directory.ts +0 -27
  681. package/template/lib/mock/list-hub-kpi.ts +0 -27
  682. package/template/lib/page-loading-variant.ts +0 -40
  683. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  684. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  685. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  686. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  687. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  688. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
@@ -0,0 +1,224 @@
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"`** + chart sections from `data-view-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 Drawer / Sheet 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.
@@ -0,0 +1,158 @@
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/`
@@ -10,17 +10,17 @@ This document describes how list pages combine **views**, **toolbar** behavior,
10
10
 
11
11
  | Need | Reuse | Where Placements uses it |
12
12
  | --- | --- | --- |
13
- | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/data-list-client.tsx` + `components/templates/list-page.tsx` |
14
- | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/data-list-table.tsx` |
15
- | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `data-list-table.tsx` |
16
- | **Board / list** | `PlacementsBoardView`, `PlacementsListView` + same `useTableState` | `DataListTable` |
13
+ | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/placements-client.tsx` + `components/templates/list-page.tsx` |
14
+ | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/placements-table.tsx` |
15
+ | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `placements-table.tsx` |
16
+ | **Board / list** | `PlacementsBoardView`, `PlacementListRowContent` (wrapped by `HubTable.renderListRow` → `DataRowList`) + same `useTableState` | `PlacementsTable` |
17
17
  | **Page header** (primary CTA + More ⋯ + export) | `PlacementsPageHeader` or `TeamPageHeader` | `components/placements-page-header.tsx`, `components/team-page-header.tsx` |
18
- | **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `DataListClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
18
+ | **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `PlacementsClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
19
19
  | **Team roster** | `TeamTable` — `DataTable` + `useTableState` + `TablePropertiesDrawer`; list/board/dashboard read **`tableState.rows`** | `components/team-table.tsx` |
20
20
  | **Dashboard view (list tab)** | **`KeyMetrics`** (`variant="flat"` or `"card"`) — same KPI system as the template metrics strip; **do not** add ad-hoc `Card` grids for entity summaries | `TeamTable` dashboard branch, `lib/mock/team-kpi.ts` |
21
21
  | **List hub metrics strip** | **`KeyMetrics variant="flat"`** — transparent cells, OKLCH brand glow only, border hairlines (**no** grey panel) | **`docs/kpi-flat-band-pattern.md`**, Placements / Team / Question bank clients |
22
22
  | **Secondary panel chrome** | **`--secondary-panel-bg`** on **`NestedSecondaryPanelShell`** (lighter than sidebar, follows active product) | **`docs/shell-surface-elevation-pattern.md`**, Question bank |
23
- | **Export** | `ExportDrawer` | `ListPageTemplate` export props; `DataListClient` |
23
+ | **Export** | `ExportDrawer` | `ListPageTemplate` export props; `PlacementsClient` |
24
24
  | **View body layout** (gutter + centered max-width for folder / icon / panel-style content) | **`ListPageViewFrame`** (`components/data-views/list-page-view-frame.tsx`, re-exported from `components/data-views`) | **`FolderGridView`** (uses the frame); **`QuestionBankOsFolderView`** — see **`AGENTS.md` §4.5** |
25
25
 
26
26
  **Rules:** (1) Import and compose these components; pass **props** and **column defs** for your entity. (2) If something is missing, **extend the shared component** under `components/` (e.g. a new optional slot on `DataTableToolbar`) rather than copying markup into a single page. (3) Card-only or lightweight pages may use a smaller **Properties** sheet only when there is **no** table—otherwise use `TablePropertiesDrawer` with `DataTable` (see Team).
@@ -29,7 +29,7 @@ This document describes how list pages combine **views**, **toolbar** behavior,
29
29
 
30
30
  If the page uses a **`DataTable`** (or equivalent data grid) as the main surface, it **must** sit under **`ListPageTemplate`** so users get the **views toolbar** (tabs, add view, per-tab settings). The default `ViewTab` entries should include at least one tab whose `viewType` is **`table`** when the primary experience is tabular data. **Do not** render a `DataTable` alone under only `PageHeader` + body.
31
31
 
32
- - **Reference:** `DataListClient` (Placements) and `TeamClient` (Team).
32
+ - **Reference:** `PlacementsClient` (Placements) and `TeamClient` (Team).
33
33
  - **Rationale:** Consistent navigation, saved views, per-tab view type (table / list / board), and export at the template level.
34
34
 
35
35
  ## View layout frame (centered, reusable)
@@ -38,45 +38,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
38
38
 
39
39
  **Handbook:** **`AGENTS.md` §4.5**. **Cursor:** **`.cursor/rules/exxat-list-page-view-shells.mdc`**. **Skill:** **`.cursor/skills/exxat-list-page-view-shells/SKILL.md`**. **Do not** wrap **`DataTable`** in the frame if that stacks padding with the table toolbar (**`AGENTS.md` §5**).
40
40
 
41
- ## View registry and connected bodies (extensibility)
42
-
43
- To add a **new view type** without breaking existing hubs:
44
-
45
- 1. **Register once** — Add a tile in `lib/data-list-view.ts` (`DATA_LIST_VIEW_TILES`). Capabilities (hub KPI strip, render kind) derive automatically in `lib/data-list-view-registry.ts`.
46
- 2. **Build the body once** — Add or extend a generic surface under `components/data-views/` (e.g. `ListPageCalendarView`). Entity-specific wiring stays in props (`getEventDate`, board `renderCard`), not a second calendar implementation per hub.
47
- 3. **Declare what each hub supports** — `lib/<hub>-supported-views.ts` exports a `const` array; pass the same array to **`ListPageTemplate`** (`supportedViewTypes`), the hub table (`supportedViewTypes` → `TablePropertiesDrawerButton`), and rely on defaults if omitted. **Add view**, **⌘1–9** shortcuts, and **Properties → View type** tiles all use `dataListViewTilesForHub` / `dataListViewSelectionTilesForHub` so users cannot pick a view the hub never implemented.
48
- 4. **Route in the hub table with `ListPageConnectedViewBody`** — Switch on **`getDataListViewRenderKind(view)`**, not raw `view === "…"` chains. Pass one renderer per kind the hub supports via **`defineHubViewRenderers(MY_HUB_SUPPORTED_VIEWS, { … })`** (`lib/hub-connected-view-renderers.ts`) so dev builds warn when a supported view has no body. **Do not** use a default branch that renders dashboard/KPIs; missing renderers show `ListPageViewNotConfigured`.
49
- 5. **Let the template own hub chrome** — `ListPageTemplate` hides the metrics strip on calendar/dashboard via `showsListPageHubMetricsStrip(activeTab.viewType)`. Hub clients pass `showMetrics` only; they do not reimplement per-tab KPI visibility.
50
- 6. **Panel / Miller columns** — Reuse **`ListPageFolderColumnsPanel`** (`components/data-views/list-page-folder-columns-panel.tsx`) for folder + record columns; hub-specific chrome (folder colors, actions) lives in a thin wrapper (e.g. `QuestionBankFolderColumnsPanel`). **Do not** export question-bank-only tree/folder nav from the generic `data-views` barrel.
51
-
52
- ```tsx
53
- // lib/my-hub-supported-views.ts
54
- export const MY_HUB_SUPPORTED_VIEWS = ["table", "list", "calendar"] as const satisfies readonly DataListViewType[]
55
-
56
- // my-hub-client.tsx
57
- <ListPageTemplate supportedViewTypes={MY_HUB_SUPPORTED_VIEWS} showMetrics={showMetrics} … />
58
-
59
- // my-hub-table.tsx
60
- import { defineHubViewRenderers } from "@/lib/hub-connected-view-renderers"
61
-
62
- return (
63
- <ListPageConnectedViewBody
64
- view={view}
65
- hubLabel="My hub"
66
- renderers={defineHubViewRenderers(MY_HUB_SUPPORTED_VIEWS, {
67
- "data-table": <DataTable … />,
68
- "calendar-with-toolbar": toolbarShell(<ListPageCalendarView rows={tableState.rows} getEventDate={…} />),
69
- })}
70
- />
71
- )
72
- ```
73
-
74
- **Checklist for a new view type:** registry tile → `data-views/` component → update each `*-supported-views.ts` that should expose it → add renderer in each `*-table.tsx` (via `defineHubViewRenderers`) → Properties drawer copy in `table-properties/drawer.tsx` if needed → `table-state-lifecycle` picks up types via `DATA_LIST_VIEW_TILES` (no separate allowlist).
75
-
76
41
  ## Architecture
77
42
 
78
43
  - **Page shell** — `ListPageTemplate` owns the views toolbar (tabs), optional metrics, and export drawer. Content for the active tab is rendered via `renderContent`.
79
- - **Per–lifecycle (or category) data** — `DataListTable` swaps **columns** and **row sets** based on `lifecycleTabId` (e.g. All / Upcoming / Ongoing / Completed). Each lifecycle tab gets its **own** `DataListTable` instance (`key={tab.filterId}`) so `useTableState` resets correctly when columns change.
44
+ - **Per–lifecycle (or category) data** — `PlacementsTable` swaps **columns** and **row sets** based on `lifecycleTabId` (e.g. All / Upcoming / Ongoing / Completed). Each lifecycle tab gets its **own** `PlacementsTable` instance (`key={tab.filterId}`) so `useTableState` resets correctly when columns change.
80
45
  - **Shared table state** — `useTableState` holds sort, search, filters, grouping, column order/visibility/pins/widths, row height, gridlines, and pagination flags. **Table**, **list**, **board**, and **dashboard** all read the same state so switching view type keeps behavior aligned.
81
46
 
82
47
  ## Mock data and connected views
@@ -94,10 +59,10 @@ return (
94
59
 
95
60
  | Concern | Table | List | Board | Dashboard (view tab) |
96
61
  | --- | --- | --- | --- | --- |
97
- | Primary surface | `DataTable` | `PlacementsListView` / entity list | `PlacementsBoardView` / entity board | **`KeyMetrics`** (+ optional charts via shared dashboard components) |
62
+ | Primary surface | `DataTable` | `DataRowList` + entity row body (e.g. `PlacementListRowContent`) wired via `HubTable.renderListRow` | `PlacementsBoardView` / entity board | **`KeyMetrics`** (+ optional charts via shared dashboard components) |
98
63
  | Data source | `useTableState` | **`tableState.rows`** | **`tableState.rows`** | **`tableState.rows`** via KPI helpers |
99
64
  | Column headers / labels | `showColumnLabels` | Same source columns, list layout | Phase columns + optional board column menu | N/A (metrics from same columns/filters) |
100
- | Row click / navigation | From `DataListTable` | From list shell | Card `onOpen` | N/A |
65
+ | Row click / navigation | From `PlacementsTable` | From list shell | Card `onOpen` | N/A |
101
66
  | Pagination | Optional `PaginationBar` + `CountSyncer` | Same pattern | N/A (board uses phase columns) | N/A |
102
67
 
103
68
  ## Toolbar and properties
@@ -134,10 +99,10 @@ return (
134
99
 
135
100
  ## Persistence
136
101
 
137
- - **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `DataListClient` with `useLayoutEffect`, saved debounced on change. `ListPageTemplate` runs in **controlled** mode when `tabs` / `onTabsChange` / `activeTabId` / `onActiveTabChange` are passed.
138
- - **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `DataListTable` with `useLayoutEffect`; saved debounced when those fields change.
102
+ - **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `PlacementsClient` with `useLayoutEffect`, saved debounced on change. `ListPageTemplate` runs in **controlled** mode when `tabs` / `onTabsChange` / `activeTabId` / `onActiveTabChange` are passed.
103
+ - **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `PlacementsTable` with `useLayoutEffect`; saved debounced when those fields change.
139
104
 
140
- To add a new page: copy the `DataListClient` pattern (controlled `ListPageTemplate` + storage key namespace) or call `schedulePageSave` / `scheduleLifecycleSave` with your own keys.
105
+ To add a new page: copy the `PlacementsClient` pattern (controlled `ListPageTemplate` + storage key namespace) or call `schedulePageSave` / `scheduleLifecycleSave` with your own keys.
141
106
 
142
107
  ## Rules of thumb
143
108
 
@@ -181,13 +146,11 @@ Reference: `components/placements-page-header.tsx`, `components/team-page-header
181
146
 
182
147
  **When to use a new page (route):** The flow is **primary**, **long-form**, **multi-step**, or should have its **own URL** / bookmark / history **without** the parent page behind it — e.g. full create/edit, wizards, or detail that *is* the task.
183
148
 
184
- **Focused workflow shell:** For dedicated create/edit, wizards, and sectioned settings, use **`FocusedWorkflowPageTemplate`** + layouts in **`focused-workflow-layouts.tsx`** see **`docs/focused-workflow-page-pattern.md`** and **`AGENTS.md` §14**. **Not** for list hubs (**`ListPageTemplate`**) or Miller-column explorers.
185
-
186
- **Rule of thumb:** **Context + quick** → **drawer**; **blocking short choice** → **dialog**; **primary / long / wizard / settings** → **focused workflow route** (or other dedicated page).
149
+ **Rule of thumb:** **Context + quick** **drawer**; **blocking short choice** **dialog**; **otherwise** **new page**.
187
150
 
188
151
  **Modal vs side panel (same route):** When the overlay stays on the same URL, prefer **`docs/drawer-vs-dialog-pattern.md`** and **`.cursor/rules/exxat-drawer-vs-dialog.mdc`** — drawers keep the hub visible; dialogs trap focus for confirms.
189
152
 
190
- Canonical rules: **`AGENTS.md` §6.4**, **§14**, root **`.cursor/rules/exxat-page-vs-drawer.mdc`**, **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**, **`.cursor/rules/exxat-focused-workflow-page.mdc`**.
153
+ Canonical rules: **`AGENTS.md` §6.4**, root **`.cursor/rules/exxat-page-vs-drawer.mdc`**, **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**.
191
154
 
192
155
  ---
193
156
 
@@ -195,7 +158,7 @@ Canonical rules: **`AGENTS.md` §6.4**, **§14**, root **`.cursor/rules/exxat-pa
195
158
 
196
159
  When a route is a **primary** destination in nav (main hub for an entity) **and** the dataset is **large** or **highly interactive**:
197
160
 
198
- - Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`DataListClient`** / **`DataListTable`** — not a minimal `PageHeader`-only layout.
161
+ - Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`PlacementsClient`** / **`PlacementsTable`** — not a minimal `PageHeader`-only layout.
199
162
  - Smaller satellite pages may use **`PageHeader` + section content**; once the dataset grows past the dense-list threshold, add the toolbar rules above and consider promoting to the full template if the page becomes a main hub.
200
163
 
201
164
  ---
@@ -207,7 +170,7 @@ When a route is a **primary** destination in nav (main hub for an entity) **and*
207
170
  - [ ] **>10 items** → search, filter, sort, properties (per surface type above).
208
171
  - [ ] **Has data to export** → **More** menu with **Export** + shared `ExportDrawer` pattern.
209
172
  - [ ] **Primary + large / main hub** → `ListPageTemplate`-style shell where applicable.
210
- - [ ] **Page vs drawer vs dialog (§6.4)** — Quick with parent **context** → drawer/sheet; **blocking** confirm → **dialog**; primary or long flows → **focused workflow route** (`docs/focused-workflow-page-pattern.md`, **§14**) or other dedicated page (`docs/drawer-vs-dialog-pattern.md`).
173
+ - [ ] **Page vs drawer vs dialog (§6.4)** — Quick with parent **context** → drawer/sheet; **blocking** confirm → **dialog**; primary or long flows → **new route** (`docs/drawer-vs-dialog-pattern.md`).
211
174
  - [ ] **Primary button** → `Button` default variant (`size="lg"` for parity with Placements), not outline.
212
175
  - [ ] **Dashboard view tab** → `KeyMetrics` + shared KPI helpers from **`tableState.rows`**; no duplicate one-off metric cards.
213
176
  - [ ] **Data view charts** → `ChartFigure` + `chart-keyboard-selection`; layout persistence via **`data-view-dashboard-storage`** (see `AGENTS.md` §4.3).
@@ -30,15 +30,13 @@
30
30
 
31
31
  Use when the work is **primary**, **long**, **multi-step**, or deserves its **own URL** — see **`exxat-page-vs-drawer.mdc`** and **`AGENTS.md` §6.4**.
32
32
 
33
- For **large forms, wizards, and sectioned settings**, use **`FocusedWorkflowPageTemplate`** and body layouts — **`docs/focused-workflow-page-pattern.md`**, **`AGENTS.md` §14**, **`.cursor/skills/exxat-focused-workflow-page/SKILL.md`**.
34
-
35
33
  ## Quick matrix
36
34
 
37
35
  | Need | Drawer | Dialog | Route |
38
36
  | --- | --- | --- | --- |
39
37
  | Keep hub visible | Yes | No (blocks) | No |
40
38
  | Short confirm / alert | Rare | Yes | Overkill |
41
- | Long form / wizard | Cramped | No | Yes — **`FocusedWorkflowPageTemplate`** |
39
+ | Long form / wizard | Cramped | No | Yes |
42
40
  | Properties tied to a table | Yes | Too small | Optional |
43
41
 
44
42
  ## Accessibility
@@ -0,0 +1,95 @@
1
+ # Migration 0001 — `brand-deep` alias stabilization
2
+
3
+ > **Released in:** v0.2.18 · **Removed in:** — (no removal — alias is now official) · **Owner:** Exxat DS core
4
+ > **Type:** stabilization (clarifies an existing naming convention)
5
+
6
+ ## Why
7
+
8
+ `bg-brand-deep` / `text-brand-deep` Tailwind utilities are used throughout
9
+ `CoachMark` and several skill docs, but the **only** declared primitive is
10
+ `--brand-color-deep`. The bridge `--color-brand-deep: var(--brand-color-deep)`
11
+ in `theme.css @theme inline` made the utilities work — but contributors kept
12
+ asking "is `--brand-deep` a real token or a typo of `--brand-color-deep`?".
13
+
14
+ This migration **does not rename anything**. It documents the alias as
15
+ **official** and codifies the rule for similar future cases:
16
+
17
+ > A Tailwind utility may use a **short, semantic alias** at the L2 bridge,
18
+ > distinct from the L1 primitive name, **only when the alias prevents an
19
+ > awkward utility class** (e.g. `bg-brand-color-deep` is unwieldy; `bg-brand-deep`
20
+ > reads naturally). The alias MUST be listed in `docs/token-taxonomy.md` and
21
+ > in the generated `hooks-index.json`.
22
+
23
+ Without this migration entry, future contributors might "fix" `bg-brand-deep`
24
+ by renaming it to `bg-brand-color-deep`, breaking every coach mark.
25
+
26
+ ## Affected surface
27
+
28
+ | Surface | Was | Becomes |
29
+ |---|---|---|
30
+ | Tailwind utility | `bg-brand-deep`, `text-brand-deep` | **unchanged** (stabilized) |
31
+ | CSS custom prop (L2 bridge) | `--color-brand-deep` | **unchanged** (stabilized as alias) |
32
+ | CSS custom prop (L1 primitive) | `--brand-color-deep` | **unchanged** (canonical name) |
33
+ | Doc | _undocumented alias_ | Documented in `docs/token-taxonomy.md` §2.2 |
34
+
35
+ ## Before
36
+
37
+ ```css
38
+ /* packages/ui/src/theme.css */
39
+ @theme inline {
40
+ --color-brand-deep: var(--brand-color-deep); /* alias — was undocumented */
41
+ }
42
+
43
+ :root {
44
+ --brand-color-deep: oklch(0.28 0.085 286.1); /* L1 primitive */
45
+ }
46
+ ```
47
+
48
+ ```tsx
49
+ // packages/ui/src/components/ui/coach-mark.tsx — already correct
50
+ <div className="bg-brand-deep text-white">…</div>
51
+ ```
52
+
53
+ The risk was that someone would "tidy up" `--color-brand-deep` to
54
+ `--color-brand-color-deep`, breaking `bg-brand-deep`.
55
+
56
+ ## After
57
+
58
+ Same code; same tokens; **plus** an authoritative entry in
59
+ [`docs/token-taxonomy.md`](../token-taxonomy.md) §2.2 listing every L1 → L2
60
+ short-alias pair, and a regenerated [`packages/ui/tokens/hooks-index.json`](../../../packages/ui/tokens/hooks-index.json)
61
+ that exposes `--brand-color-deep` with `tailwindUtilities:
62
+ ["bg-brand-deep", "text-brand-deep", …]` so tooling can discover the link.
63
+
64
+ ## Migration recipe
65
+
66
+ ### Automatic
67
+
68
+ None needed — this migration changes documentation only.
69
+
70
+ ### Manual
71
+
72
+ For **future** short-alias additions, follow this pattern:
73
+
74
+ 1. Declare the L1 primitive: `--brand-<name>: oklch(...)` in `:root` and any
75
+ theme overrides in `.dark` / `.theme-prism` / etc.
76
+ 2. Declare the L2 alias in `@theme inline`: `--color-<short>: var(--brand-<name>)`.
77
+ 3. Add a row to `docs/token-taxonomy.md` §2.2 listing the alias.
78
+ 4. Run `pnpm --filter @exxatdesignux/ui tokens:index` and commit.
79
+ 5. Use the alias **only** for the case where the long name is awkward; do
80
+ **not** create aliases for ergonomics alone.
81
+
82
+ ## Verification
83
+
84
+ - [x] `pnpm --filter @exxatdesignux/ui tokens:index` runs and emits the alias
85
+ under `tailwindUtilities` for `--brand-color-deep`.
86
+ - [x] `docs/token-taxonomy.md` §2.2 lists `--brand-color-deep` and its alias.
87
+ - [x] `coach-mark.tsx` continues to render the deep-brand background.
88
+
89
+ ## References
90
+
91
+ - `packages/ui/src/theme.css` — lines declaring `--brand-color-deep` and the alias
92
+ - `packages/ui/src/components/ui/coach-mark.tsx`
93
+ - `apps/web/docs/token-taxonomy.md` §2.2 (Brand)
94
+ - `apps/web/docs/blueprints/page-header.md` (uses `--brand-color-*` family)
95
+ - `.cursor/rules/exxat-token-discipline.mdc` (codifies the alias rule)