@exxatdesignux/ui 0.2.19 → 0.4.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 (716) hide show
  1. package/CHANGELOG.md +662 -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 +43 -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-library-hub-header.mdc +28 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  23. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  24. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  25. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  26. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  27. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  28. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  29. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -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 +3 -3
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +5 -16
  36. package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
  37. package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
  38. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +19 -34
  39. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  40. package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
  41. package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
  42. package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
  43. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +10 -12
  44. package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
  45. package/consumer-extras/handbook/HANDBOOK.md +187 -0
  46. package/consumer-extras/handbook/glossary.md +58 -0
  47. package/consumer-extras/handbook/reference-implementations.md +153 -0
  48. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  49. package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
  50. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  51. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  52. package/consumer-extras/patterns/data-views-pattern.md +31 -66
  53. package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
  54. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  55. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  56. package/dist/components/data-table/filter-date-calendar.js +280 -0
  57. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  58. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  59. package/dist/components/data-table/filter-text-value-input.js +561 -0
  60. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  61. package/dist/components/data-table/index.d.ts +45 -0
  62. package/dist/components/data-table/index.js +3085 -0
  63. package/dist/components/data-table/index.js.map +1 -0
  64. package/dist/components/data-table/pagination.d.ts +28 -0
  65. package/dist/components/data-table/pagination.js +3264 -0
  66. package/dist/components/data-table/pagination.js.map +1 -0
  67. package/dist/components/data-table/types.d.ts +84 -0
  68. package/dist/components/data-table/types.js +3 -0
  69. package/dist/components/data-table/types.js.map +1 -0
  70. package/dist/components/data-table/use-table-state.d.ts +116 -0
  71. package/dist/components/data-table/use-table-state.js +670 -0
  72. package/dist/components/data-table/use-table-state.js.map +1 -0
  73. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  74. package/dist/components/data-views/board-card-primitives.js +84 -0
  75. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  76. package/dist/components/data-views/data-row-list.d.ts +33 -0
  77. package/dist/components/data-views/data-row-list.js +106 -0
  78. package/dist/components/data-views/data-row-list.js.map +1 -0
  79. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  80. package/dist/components/data-views/finder-panel-view.js +388 -0
  81. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  82. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  83. package/dist/components/data-views/folder-grid-view.js +58 -0
  84. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  85. package/dist/components/data-views/hub-table.d.ts +173 -0
  86. package/dist/components/data-views/hub-table.js +5783 -0
  87. package/dist/components/data-views/hub-table.js.map +1 -0
  88. package/dist/components/data-views/index.d.ts +27 -0
  89. package/dist/components/data-views/index.js +6797 -0
  90. package/dist/components/data-views/index.js.map +1 -0
  91. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  92. package/dist/components/data-views/list-page-board-card.js +264 -0
  93. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  94. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  95. package/dist/components/data-views/list-page-board-template.js +137 -0
  96. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  97. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  98. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  99. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  100. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  101. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  102. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  103. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  104. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  105. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  106. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  107. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  108. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  109. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  110. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  111. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  112. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  113. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  114. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  115. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  116. package/dist/components/data-views/os-folder-glyph.js +104 -0
  117. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  118. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  119. package/dist/components/data-views/outline-tree-menu.js +131 -0
  120. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  121. package/dist/components/table-properties/column-row.d.ts +22 -0
  122. package/dist/components/table-properties/column-row.js +153 -0
  123. package/dist/components/table-properties/column-row.js.map +1 -0
  124. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  125. package/dist/components/table-properties/draggable-list.js +53 -0
  126. package/dist/components/table-properties/draggable-list.js.map +1 -0
  127. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  128. package/dist/components/table-properties/drawer-button.js +2748 -0
  129. package/dist/components/table-properties/drawer-button.js.map +1 -0
  130. package/dist/components/table-properties/drawer.d.ts +100 -0
  131. package/dist/components/table-properties/drawer.js +2595 -0
  132. package/dist/components/table-properties/drawer.js.map +1 -0
  133. package/dist/components/table-properties/filter-card.d.ts +24 -0
  134. package/dist/components/table-properties/filter-card.js +854 -0
  135. package/dist/components/table-properties/filter-card.js.map +1 -0
  136. package/dist/components/table-properties/index.d.ts +14 -0
  137. package/dist/components/table-properties/index.js +2768 -0
  138. package/dist/components/table-properties/index.js.map +1 -0
  139. package/dist/components/table-properties/sort-card.d.ts +20 -0
  140. package/dist/components/table-properties/sort-card.js +102 -0
  141. package/dist/components/table-properties/sort-card.js.map +1 -0
  142. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  143. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  144. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  145. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  146. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  147. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  148. package/dist/components/templates/index.d.ts +9 -0
  149. package/dist/components/templates/index.js +2720 -0
  150. package/dist/components/templates/index.js.map +1 -0
  151. package/dist/components/templates/list-page.d.ts +83 -0
  152. package/dist/components/templates/list-page.js +2433 -0
  153. package/dist/components/templates/list-page.js.map +1 -0
  154. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  155. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  156. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  157. package/dist/components/ui/accordion.d.ts +10 -0
  158. package/dist/components/ui/accordion.js +74 -0
  159. package/dist/components/ui/accordion.js.map +1 -0
  160. package/dist/components/ui/alert-dialog.d.ts +37 -0
  161. package/dist/components/ui/alert-dialog.js +201 -0
  162. package/dist/components/ui/alert-dialog.js.map +1 -0
  163. package/dist/components/ui/avatar.d.ts +84 -0
  164. package/dist/components/ui/avatar.js +328 -0
  165. package/dist/components/ui/avatar.js.map +1 -0
  166. package/dist/components/ui/badge.d.ts +13 -0
  167. package/dist/components/ui/badge.js +49 -0
  168. package/dist/components/ui/badge.js.map +1 -0
  169. package/dist/components/ui/banner.d.ts +62 -0
  170. package/dist/components/ui/banner.js +364 -0
  171. package/dist/components/ui/banner.js.map +1 -0
  172. package/dist/components/ui/breadcrumb.d.ts +14 -0
  173. package/dist/components/ui/breadcrumb.js +114 -0
  174. package/dist/components/ui/breadcrumb.js.map +1 -0
  175. package/dist/components/ui/button.d.ts +16 -0
  176. package/dist/components/ui/button.js +59 -0
  177. package/dist/components/ui/button.js.map +1 -0
  178. package/dist/components/ui/calendar.d.ts +13 -0
  179. package/dist/components/ui/calendar.js +238 -0
  180. package/dist/components/ui/calendar.js.map +1 -0
  181. package/dist/components/ui/card.d.ts +14 -0
  182. package/dist/components/ui/card.js +102 -0
  183. package/dist/components/ui/card.js.map +1 -0
  184. package/dist/components/ui/chart.d.ts +58 -0
  185. package/dist/components/ui/chart.js +292 -0
  186. package/dist/components/ui/chart.js.map +1 -0
  187. package/dist/components/ui/checkbox.d.ts +23 -0
  188. package/dist/components/ui/checkbox.js +155 -0
  189. package/dist/components/ui/checkbox.js.map +1 -0
  190. package/dist/components/ui/coach-mark.d.ts +27 -0
  191. package/dist/components/ui/coach-mark.js +306 -0
  192. package/dist/components/ui/coach-mark.js.map +1 -0
  193. package/dist/components/ui/collapsible.d.ts +8 -0
  194. package/dist/components/ui/collapsible.js +35 -0
  195. package/dist/components/ui/collapsible.js.map +1 -0
  196. package/dist/components/ui/command.d.ts +36 -0
  197. package/dist/components/ui/command.js +274 -0
  198. package/dist/components/ui/command.js.map +1 -0
  199. package/dist/components/ui/context-menu.d.ts +32 -0
  200. package/dist/components/ui/context-menu.js +245 -0
  201. package/dist/components/ui/context-menu.js.map +1 -0
  202. package/dist/components/ui/date-picker-field.d.ts +38 -0
  203. package/dist/components/ui/date-picker-field.js +550 -0
  204. package/dist/components/ui/date-picker-field.js.map +1 -0
  205. package/dist/components/ui/dialog.d.ts +22 -0
  206. package/dist/components/ui/dialog.js +200 -0
  207. package/dist/components/ui/dialog.js.map +1 -0
  208. package/dist/components/ui/dot-pattern.d.ts +21 -0
  209. package/dist/components/ui/dot-pattern.js +139 -0
  210. package/dist/components/ui/dot-pattern.js.map +1 -0
  211. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  212. package/dist/components/ui/drag-handle-grip.js +15 -0
  213. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  214. package/dist/components/ui/drawer.d.ts +16 -0
  215. package/dist/components/ui/drawer.js +125 -0
  216. package/dist/components/ui/drawer.js.map +1 -0
  217. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  218. package/dist/components/ui/dropdown-menu.js +353 -0
  219. package/dist/components/ui/dropdown-menu.js.map +1 -0
  220. package/dist/components/ui/export-drawer.d.ts +11 -0
  221. package/dist/components/ui/export-drawer.js +1658 -0
  222. package/dist/components/ui/export-drawer.js.map +1 -0
  223. package/dist/components/ui/field.d.ts +30 -0
  224. package/dist/components/ui/field.js +249 -0
  225. package/dist/components/ui/field.js.map +1 -0
  226. package/dist/components/ui/form.d.ts +28 -0
  227. package/dist/components/ui/form.js +110 -0
  228. package/dist/components/ui/form.js.map +1 -0
  229. package/dist/components/ui/hover-card.d.ts +9 -0
  230. package/dist/components/ui/hover-card.js +43 -0
  231. package/dist/components/ui/hover-card.js.map +1 -0
  232. package/dist/components/ui/input-group.d.ts +20 -0
  233. package/dist/components/ui/input-group.js +219 -0
  234. package/dist/components/ui/input-group.js.map +1 -0
  235. package/dist/components/ui/input-mask.d.ts +39 -0
  236. package/dist/components/ui/input-mask.js +118 -0
  237. package/dist/components/ui/input-mask.js.map +1 -0
  238. package/dist/components/ui/input.d.ts +5 -0
  239. package/dist/components/ui/input.js +30 -0
  240. package/dist/components/ui/input.js.map +1 -0
  241. package/dist/components/ui/kbd.d.ts +20 -0
  242. package/dist/components/ui/kbd.js +45 -0
  243. package/dist/components/ui/kbd.js.map +1 -0
  244. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  245. package/dist/components/ui/key-metrics-context.js +26 -0
  246. package/dist/components/ui/key-metrics-context.js.map +1 -0
  247. package/dist/components/ui/key-metrics.d.ts +131 -0
  248. package/dist/components/ui/key-metrics.js +1015 -0
  249. package/dist/components/ui/key-metrics.js.map +1 -0
  250. package/dist/components/ui/label.d.ts +6 -0
  251. package/dist/components/ui/label.js +28 -0
  252. package/dist/components/ui/label.js.map +1 -0
  253. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  254. package/dist/components/ui/list-page-view-frame.js +24 -0
  255. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  256. package/dist/components/ui/page-header.d.ts +51 -0
  257. package/dist/components/ui/page-header.js +372 -0
  258. package/dist/components/ui/page-header.js.map +1 -0
  259. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  260. package/dist/components/ui/payment-card-fields.js +80 -0
  261. package/dist/components/ui/payment-card-fields.js.map +1 -0
  262. package/dist/components/ui/popover.d.ts +10 -0
  263. package/dist/components/ui/popover.js +47 -0
  264. package/dist/components/ui/popover.js.map +1 -0
  265. package/dist/components/ui/radio-group.d.ts +29 -0
  266. package/dist/components/ui/radio-group.js +190 -0
  267. package/dist/components/ui/radio-group.js.map +1 -0
  268. package/dist/components/ui/resizable.d.ts +16 -0
  269. package/dist/components/ui/resizable.js +51 -0
  270. package/dist/components/ui/resizable.js.map +1 -0
  271. package/dist/components/ui/scroll-area.d.ts +8 -0
  272. package/dist/components/ui/scroll-area.js +66 -0
  273. package/dist/components/ui/scroll-area.js.map +1 -0
  274. package/dist/components/ui/select.d.ts +18 -0
  275. package/dist/components/ui/select.js +186 -0
  276. package/dist/components/ui/select.js.map +1 -0
  277. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  278. package/dist/components/ui/selection-tile-grid.js +347 -0
  279. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  280. package/dist/components/ui/separator.d.ts +7 -0
  281. package/dist/components/ui/separator.js +33 -0
  282. package/dist/components/ui/separator.js.map +1 -0
  283. package/dist/components/ui/sheet.d.ts +18 -0
  284. package/dist/components/ui/sheet.js +181 -0
  285. package/dist/components/ui/sheet.js.map +1 -0
  286. package/dist/components/ui/sidebar.d.ts +94 -0
  287. package/dist/components/ui/sidebar.js +805 -0
  288. package/dist/components/ui/sidebar.js.map +1 -0
  289. package/dist/components/ui/skeleton.d.ts +5 -0
  290. package/dist/components/ui/skeleton.js +22 -0
  291. package/dist/components/ui/skeleton.js.map +1 -0
  292. package/dist/components/ui/slider.d.ts +7 -0
  293. package/dist/components/ui/slider.js +66 -0
  294. package/dist/components/ui/slider.js.map +1 -0
  295. package/dist/components/ui/sonner.d.ts +6 -0
  296. package/dist/components/ui/sonner.js +38 -0
  297. package/dist/components/ui/sonner.js.map +1 -0
  298. package/dist/components/ui/status-badge.d.ts +38 -0
  299. package/dist/components/ui/status-badge.js +77 -0
  300. package/dist/components/ui/status-badge.js.map +1 -0
  301. package/dist/components/ui/table.d.ts +13 -0
  302. package/dist/components/ui/table.js +115 -0
  303. package/dist/components/ui/table.js.map +1 -0
  304. package/dist/components/ui/tabs.d.ts +15 -0
  305. package/dist/components/ui/tabs.js +93 -0
  306. package/dist/components/ui/tabs.js.map +1 -0
  307. package/dist/components/ui/textarea.d.ts +6 -0
  308. package/dist/components/ui/textarea.js +25 -0
  309. package/dist/components/ui/textarea.js.map +1 -0
  310. package/dist/components/ui/tip.d.ts +12 -0
  311. package/dist/components/ui/tip.js +61 -0
  312. package/dist/components/ui/tip.js.map +1 -0
  313. package/dist/components/ui/toggle-group.d.ts +14 -0
  314. package/dist/components/ui/toggle-group.js +104 -0
  315. package/dist/components/ui/toggle-group.js.map +1 -0
  316. package/dist/components/ui/toggle-switch.d.ts +10 -0
  317. package/dist/components/ui/toggle-switch.js +33 -0
  318. package/dist/components/ui/toggle-switch.js.map +1 -0
  319. package/dist/components/ui/toggle.d.ts +13 -0
  320. package/dist/components/ui/toggle.js +51 -0
  321. package/dist/components/ui/toggle.js.map +1 -0
  322. package/dist/components/ui/tooltip.d.ts +10 -0
  323. package/dist/components/ui/tooltip.js +68 -0
  324. package/dist/components/ui/tooltip.js.map +1 -0
  325. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  326. package/dist/components/ui/view-segmented-control.js +167 -0
  327. package/dist/components/ui/view-segmented-control.js.map +1 -0
  328. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  329. package/dist/hooks/use-app-theme.d.ts +24 -0
  330. package/dist/hooks/use-app-theme.js +286 -0
  331. package/dist/hooks/use-app-theme.js.map +1 -0
  332. package/dist/hooks/use-coach-mark.d.ts +86 -0
  333. package/dist/hooks/use-coach-mark.js +218 -0
  334. package/dist/hooks/use-coach-mark.js.map +1 -0
  335. package/dist/hooks/use-mobile.d.ts +3 -0
  336. package/dist/hooks/use-mobile.js +29 -0
  337. package/dist/hooks/use-mobile.js.map +1 -0
  338. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  339. package/dist/hooks/use-mod-key-label.js +25 -0
  340. package/dist/hooks/use-mod-key-label.js.map +1 -0
  341. package/dist/index.d.ts +120 -0
  342. package/dist/index.js +13421 -0
  343. package/dist/index.js.map +1 -0
  344. package/dist/lib/compose-refs.d.ts +6 -0
  345. package/dist/lib/compose-refs.js +17 -0
  346. package/dist/lib/compose-refs.js.map +1 -0
  347. package/dist/lib/conditional-rule-match.d.ts +30 -0
  348. package/dist/lib/conditional-rule-match.js +66 -0
  349. package/dist/lib/conditional-rule-match.js.map +1 -0
  350. package/dist/lib/data-list-display-options.d.ts +26 -0
  351. package/dist/lib/data-list-display-options.js +14 -0
  352. package/dist/lib/data-list-display-options.js.map +1 -0
  353. package/dist/lib/data-list-view-registry.d.ts +2 -0
  354. package/dist/lib/data-list-view-registry.js +102 -0
  355. package/dist/lib/data-list-view-registry.js.map +1 -0
  356. package/dist/lib/data-list-view-surface.d.ts +2 -0
  357. package/dist/lib/data-list-view-surface.js +80 -0
  358. package/dist/lib/data-list-view-surface.js.map +1 -0
  359. package/dist/lib/data-list-view.d.ts +21 -0
  360. package/dist/lib/data-list-view.js +25 -0
  361. package/dist/lib/data-list-view.js.map +1 -0
  362. package/dist/lib/date-filter.d.ts +22 -0
  363. package/dist/lib/date-filter.js +61 -0
  364. package/dist/lib/date-filter.js.map +1 -0
  365. package/dist/lib/dev-log.d.ts +8 -0
  366. package/dist/lib/dev-log.js +10 -0
  367. package/dist/lib/dev-log.js.map +1 -0
  368. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  369. package/dist/lib/dropdown-menu-surface.js +6 -0
  370. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  371. package/dist/lib/editable-target.d.ts +12 -0
  372. package/dist/lib/editable-target.js +12 -0
  373. package/dist/lib/editable-target.js.map +1 -0
  374. package/dist/lib/list-page-table-properties.d.ts +35 -0
  375. package/dist/lib/list-page-table-properties.js +81 -0
  376. package/dist/lib/list-page-table-properties.js.map +1 -0
  377. package/dist/lib/raf-throttle.d.ts +23 -0
  378. package/dist/lib/raf-throttle.js +27 -0
  379. package/dist/lib/raf-throttle.js.map +1 -0
  380. package/dist/lib/row-height.d.ts +16 -0
  381. package/dist/lib/row-height.js +10 -0
  382. package/dist/lib/row-height.js.map +1 -0
  383. package/dist/lib/table-properties-types.d.ts +83 -0
  384. package/dist/lib/table-properties-types.js +19 -0
  385. package/dist/lib/table-properties-types.js.map +1 -0
  386. package/dist/lib/utils.d.ts +5 -0
  387. package/dist/lib/utils.js +11 -0
  388. package/dist/lib/utils.js.map +1 -0
  389. package/package.json +83 -19
  390. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  391. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  392. package/src/components/data-table/index.tsx +1678 -0
  393. package/src/components/data-table/pagination.tsx +259 -0
  394. package/src/components/data-table/types.ts +96 -0
  395. package/src/components/data-table/use-table-state.ts +767 -0
  396. package/src/components/data-views/board-card-primitives.tsx +93 -0
  397. package/src/components/data-views/data-row-list.tsx +183 -0
  398. package/src/components/data-views/finder-panel-view.tsx +405 -0
  399. package/src/components/data-views/folder-grid-view.tsx +86 -0
  400. package/src/components/data-views/hub-table.tsx +606 -0
  401. package/src/components/data-views/index.ts +28 -0
  402. package/src/components/data-views/list-page-board-card.tsx +192 -0
  403. package/src/components/data-views/list-page-board-template.tsx +122 -0
  404. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  405. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  406. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  407. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  408. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  409. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  410. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  411. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  412. package/src/components/table-properties/column-row.tsx +90 -0
  413. package/src/components/table-properties/draggable-list.ts +54 -0
  414. package/src/components/table-properties/drawer-button.tsx +300 -0
  415. package/src/components/table-properties/drawer.tsx +1148 -0
  416. package/src/components/table-properties/filter-card.tsx +251 -0
  417. package/src/components/table-properties/index.ts +36 -0
  418. package/src/components/table-properties/sort-card.tsx +63 -0
  419. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  420. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  421. package/src/components/templates/index.ts +33 -0
  422. package/src/components/templates/list-page.tsx +602 -0
  423. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  424. package/src/components/ui/accordion.tsx +92 -0
  425. package/src/components/ui/alert-dialog.tsx +221 -0
  426. package/src/components/ui/avatar.tsx +13 -2
  427. package/src/components/ui/banner.tsx +2 -2
  428. package/src/components/ui/button.tsx +4 -4
  429. package/src/components/ui/calendar.tsx +1 -1
  430. package/src/components/ui/coach-mark.tsx +1 -1
  431. package/src/components/ui/context-menu.tsx +291 -0
  432. package/src/components/ui/date-picker-field.tsx +2 -2
  433. package/src/components/ui/dot-pattern.tsx +183 -0
  434. package/src/components/ui/export-drawer.tsx +375 -0
  435. package/src/components/ui/hover-card.tsx +66 -0
  436. package/src/components/ui/key-metrics-context.tsx +78 -0
  437. package/src/components/ui/key-metrics.tsx +1133 -0
  438. package/src/components/ui/list-page-view-frame.tsx +64 -0
  439. package/src/components/ui/page-header.tsx +244 -0
  440. package/src/components/ui/payment-card-fields.tsx +2 -2
  441. package/src/components/ui/resizable.tsx +68 -0
  442. package/src/components/ui/scroll-area.tsx +72 -0
  443. package/src/components/ui/selection-tile-grid.tsx +9 -2
  444. package/src/components/ui/sidebar.tsx +84 -12
  445. package/src/components/ui/slider.tsx +83 -0
  446. package/src/globals.css +2201 -7
  447. package/src/globals.d.ts +20 -0
  448. package/src/index.ts +68 -1
  449. package/src/lib/conditional-rule-match.ts +119 -0
  450. package/src/lib/data-list-display-options.ts +35 -0
  451. package/src/lib/data-list-view-registry.ts +104 -0
  452. package/src/lib/data-list-view-surface.ts +83 -0
  453. package/src/lib/data-list-view.ts +47 -0
  454. package/src/lib/dev-log.ts +10 -0
  455. package/src/lib/editable-target.ts +20 -0
  456. package/src/lib/list-page-table-properties.ts +48 -0
  457. package/src/lib/raf-throttle.ts +45 -0
  458. package/src/lib/row-height.ts +19 -0
  459. package/src/lib/table-properties-types.ts +98 -0
  460. package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
  461. package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
  462. package/template/.cursor/rules/exxat-command-menu.mdc +2 -2
  463. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +7 -7
  464. package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
  465. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  466. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +7 -7
  467. package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
  468. package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
  469. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  470. package/template/AGENTS.md +135 -103
  471. package/template/app/(app)/columns/page.tsx +11 -0
  472. package/template/app/(app)/dashboard/loading.tsx +15 -3
  473. package/template/app/(app)/dashboard/page.tsx +14 -2
  474. package/template/app/(app)/layout.tsx +17 -4
  475. package/template/app/(app)/library/all/page.tsx +11 -0
  476. package/template/app/(app)/library/find/page.tsx +12 -0
  477. package/template/app/(app)/{question-bank → library}/layout.tsx +17 -17
  478. package/template/app/(app)/library/list/page.tsx +12 -0
  479. package/template/app/(app)/library/new/page.tsx +45 -0
  480. package/template/app/(app)/library/page.tsx +11 -0
  481. package/template/app/(app)/loading.tsx +18 -1
  482. package/template/app/(app)/settings/page.tsx +5 -4
  483. package/template/app/(app)/tokens-themes/page.tsx +11 -0
  484. package/template/app/globals.css +14 -16
  485. package/template/components/ask-leo-composer.tsx +2 -2
  486. package/template/components/ask-leo-sidebar.tsx +5 -1
  487. package/template/components/brand-color-picker.tsx +2 -2
  488. package/template/components/charts-overview.tsx +1 -1
  489. package/template/components/columns-client.tsx +158 -0
  490. package/template/components/columns-showcase.tsx +541 -0
  491. package/template/components/dashboard-report-charts.tsx +1 -1
  492. package/template/components/dashboard-tabs.tsx +1 -1
  493. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  494. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  495. package/template/components/data-table/index.tsx +1 -1634
  496. package/template/components/data-table/pagination.tsx +1 -255
  497. package/template/components/data-table/types.ts +1 -94
  498. package/template/components/data-table/use-table-state.test.ts +420 -0
  499. package/template/components/data-table/use-table-state.ts +1 -758
  500. package/template/components/data-views/board-card-primitives.tsx +1 -93
  501. package/template/components/data-views/data-row-list.tsx +1 -183
  502. package/template/components/data-views/finder-panel-view.tsx +1 -405
  503. package/template/components/data-views/folder-grid-view.tsx +1 -86
  504. package/template/components/data-views/hub-table.tsx +1 -0
  505. package/template/components/data-views/index.ts +77 -38
  506. package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
  507. package/template/components/data-views/list-page-board-card.tsx +1 -192
  508. package/template/components/data-views/list-page-board-template.tsx +1 -122
  509. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  510. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  511. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  512. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  513. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  514. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  515. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  516. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  517. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  518. package/template/components/data-views/table-cells.tsx +673 -0
  519. package/template/components/export-drawer.test.tsx +71 -0
  520. package/template/components/export-drawer.tsx +1 -375
  521. package/template/components/exxat-product-logo.tsx +5 -5
  522. package/template/components/folder-details-shell.tsx +11 -11
  523. package/template/components/hub-tree-panel-view.tsx +26 -26
  524. package/template/components/invite-collaborators-drawer.tsx +3 -3
  525. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  526. package/template/components/key-metrics.tsx +1 -1063
  527. package/template/components/leo-insight-indicator.tsx +2 -2
  528. package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
  529. package/template/components/{question-bank-client.tsx → library-client.tsx} +83 -83
  530. package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
  531. package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
  532. package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +44 -44
  533. package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +16 -16
  534. package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
  535. package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
  536. package/template/components/library-panel-activator.tsx +8 -0
  537. package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +63 -63
  538. package/template/components/library-table.tsx +839 -0
  539. package/template/components/list-hub-status-badge.tsx +2 -2
  540. package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +489 -441
  541. package/template/components/onboarding/index.ts +9 -0
  542. package/template/components/onboarding/onboarding-01.tsx +1 -1
  543. package/template/components/onboarding/onboarding-02.tsx +1 -1
  544. package/template/components/onboarding/onboarding-03.tsx +1 -1
  545. package/template/components/onboarding/onboarding-04.tsx +1 -1
  546. package/template/components/page-header.tsx +8 -226
  547. package/template/components/product-switcher.tsx +3 -4
  548. package/template/components/product-wordmark.tsx +2 -1
  549. package/template/components/settings-appearance-card.tsx +3 -4
  550. package/template/components/settings-client.tsx +15 -59
  551. package/template/components/settings-form-row.tsx +4 -9
  552. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  553. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +114 -73
  554. package/template/components/sidebar/index.ts +16 -0
  555. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  556. package/template/components/sidebar/secondary-panel.tsx +316 -0
  557. package/template/components/sidebar/sidebar-auto-collapse.tsx +27 -0
  558. package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +2 -1
  559. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  560. package/template/components/site-header.tsx +1 -1
  561. package/template/components/table-properties/column-row.tsx +1 -90
  562. package/template/components/table-properties/draggable-list.ts +1 -49
  563. package/template/components/table-properties/drawer-button.tsx +1 -262
  564. package/template/components/table-properties/drawer.tsx +1 -1166
  565. package/template/components/table-properties/filter-card.tsx +1 -251
  566. package/template/components/table-properties/sort-card.tsx +1 -59
  567. package/template/components/table-properties/types.ts +28 -71
  568. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  569. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  570. package/template/components/templates/discovery-hub-template.tsx +1 -1
  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 +2 -2
  575. package/template/components/tokens-secondary-nav.tsx +192 -0
  576. package/template/components/tokens-themes-client.tsx +476 -0
  577. package/template/components/tokens-themes-section.tsx +386 -0
  578. package/template/components/ui/accordion.tsx +1 -0
  579. package/template/components/ui/alert-dialog.tsx +1 -0
  580. package/template/components/ui/context-menu.tsx +1 -0
  581. package/template/components/ui/dot-pattern.tsx +1 -183
  582. package/template/components/ui/hover-card.tsx +1 -0
  583. package/template/components/ui/resizable.tsx +1 -68
  584. package/template/components/ui/scroll-area.tsx +1 -0
  585. package/template/components/ui/slider.tsx +1 -0
  586. package/template/docs/HANDBOOK.md +187 -0
  587. package/template/docs/blueprints/README.md +86 -0
  588. package/template/docs/blueprints/_template.md +91 -0
  589. package/template/docs/blueprints/board-card.md +123 -0
  590. package/template/docs/blueprints/data-table.md +139 -0
  591. package/template/docs/blueprints/key-metrics.md +128 -0
  592. package/template/docs/blueprints/list-page-template.md +123 -0
  593. package/template/docs/blueprints/page-header.md +130 -0
  594. package/template/docs/collaboration-access-pattern.md +7 -7
  595. package/template/docs/command-menu-pattern.md +1 -1
  596. package/template/docs/component-selection-guide.md +224 -0
  597. package/template/docs/components-audit-2026-05.md +158 -0
  598. package/template/docs/data-views-pattern.md +31 -66
  599. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  600. package/template/docs/glossary.md +58 -0
  601. package/template/docs/kpi-flat-band-pattern.md +3 -3
  602. package/template/docs/kpi-trend-pattern.md +18 -3
  603. package/template/docs/large-dataset-strategy.md +155 -0
  604. package/template/docs/library-hub-header-pattern.md +25 -0
  605. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  606. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  607. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  608. package/template/docs/migrations/README.md +100 -0
  609. package/template/docs/migrations/_template.md +64 -0
  610. package/template/docs/reference-implementations.md +151 -0
  611. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  612. package/template/docs/token-taxonomy.md +416 -0
  613. package/template/docs/voice-and-tone.md +262 -0
  614. package/template/eslint.config.mjs +27 -0
  615. package/template/hooks/use-secondary-panel-hub-nav.ts +11 -11
  616. package/template/lib/ask-leo-route-context.ts +6 -18
  617. package/template/lib/coach-mark-registry.ts +0 -16
  618. package/template/lib/command-menu-config.ts +5 -13
  619. package/template/lib/command-menu-search-data.ts +8 -23
  620. package/template/lib/conditional-rule-match.ts +6 -97
  621. package/template/lib/data-list-display-options.ts +1 -49
  622. package/template/lib/data-list-view-registry.ts +1 -104
  623. package/template/lib/data-list-view-surface.ts +1 -83
  624. package/template/lib/data-list-view.ts +1 -47
  625. package/template/lib/data-view-dashboard-storage.ts +35 -38
  626. package/template/lib/dev-log.ts +1 -8
  627. package/template/lib/editable-target.ts +1 -10
  628. package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
  629. package/template/lib/library-dedicated-search.ts +19 -0
  630. package/template/lib/library-hub-search.ts +90 -0
  631. package/template/lib/library-nav.ts +477 -0
  632. package/template/lib/library-recent-searches.ts +22 -0
  633. package/template/lib/{question-bank-supported-views.ts → library-supported-views.ts} +2 -3
  634. package/template/lib/list-page-table-properties.ts +1 -48
  635. package/template/lib/list-status-badges.ts +16 -11
  636. package/template/lib/mock/dashboard.ts +1 -1
  637. package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
  638. package/template/lib/mock/library-header-collaborators.ts +54 -0
  639. package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
  640. package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
  641. package/template/lib/mock/library.ts +249 -0
  642. package/template/lib/mock/navigation.tsx +32 -35
  643. package/template/lib/raf-throttle.ts +1 -45
  644. package/template/lib/row-height.ts +4 -10
  645. package/template/lib/sidebar-state-cookie.ts +11 -2
  646. package/template/lib/table-state-lifecycle.ts +3 -3
  647. package/template/next.config.mjs +7 -4
  648. package/template/package.json +1 -0
  649. package/template/tests/setup.ts +25 -0
  650. package/consumer-extras/AGENTS.md +0 -76
  651. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  652. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  653. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  654. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  655. package/src/components/ui/button-group.tsx +0 -81
  656. package/src/theme.css +0 -16
  657. package/src/tokens/README.md +0 -15
  658. package/src/tokens/base.css +0 -337
  659. package/src/tokens/high-contrast.css +0 -1195
  660. package/src/tokens/layers.css +0 -224
  661. package/src/tokens/tailwind-bridge.css +0 -118
  662. package/src/tokens/themes.css +0 -201
  663. package/template/app/(app)/data-list/layout.tsx +0 -43
  664. package/template/app/(app)/data-list/page.tsx +0 -10
  665. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  666. package/template/app/(app)/examples/page.tsx +0 -43
  667. package/template/app/(app)/question-bank/find/page.tsx +0 -13
  668. package/template/app/(app)/question-bank/library/page.tsx +0 -12
  669. package/template/app/(app)/question-bank/list/page.tsx +0 -13
  670. package/template/app/(app)/question-bank/new/page.tsx +0 -50
  671. package/template/app/(app)/question-bank/page.tsx +0 -12
  672. package/template/components/app-route-loading.tsx +0 -14
  673. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  674. package/template/components/dashboard-onboarding.tsx +0 -21
  675. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  676. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  677. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  678. package/template/components/list-hub-board-view.tsx +0 -68
  679. package/template/components/list-hub-client.tsx +0 -186
  680. package/template/components/list-hub-list-view.tsx +0 -36
  681. package/template/components/list-hub-panel-activator.tsx +0 -8
  682. package/template/components/list-hub-secondary-nav.tsx +0 -121
  683. package/template/components/list-hub-table.tsx +0 -336
  684. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  685. package/template/components/question-bank-list-view.tsx +0 -53
  686. package/template/components/question-bank-panel-activator.tsx +0 -8
  687. package/template/components/question-bank-table.tsx +0 -729
  688. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  689. package/template/components/secondary-panel.tsx +0 -220
  690. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  691. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  692. package/template/components/secondary-panels/registry.tsx +0 -15
  693. package/template/components/section-cards.tsx +0 -106
  694. package/template/components/sidebar-auto-collapse.tsx +0 -23
  695. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  696. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  697. package/template/components/templates/page-loading-shell.tsx +0 -262
  698. package/template/components/ui/button-group.tsx +0 -1
  699. package/template/docs/consumer-app-pattern.md +0 -39
  700. package/template/docs/focused-workflow-page-pattern.md +0 -84
  701. package/template/docs/question-bank-hub-header-pattern.md +0 -25
  702. package/template/lib/list-hub-nav.ts +0 -121
  703. package/template/lib/mock/list-hub-directory.ts +0 -27
  704. package/template/lib/mock/list-hub-kpi.ts +0 -27
  705. package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
  706. package/template/lib/mock/question-bank.ts +0 -249
  707. package/template/lib/page-loading-variant.ts +0 -40
  708. package/template/lib/question-bank-dedicated-search.ts +0 -19
  709. package/template/lib/question-bank-hub-search.ts +0 -90
  710. package/template/lib/question-bank-nav.ts +0 -477
  711. package/template/lib/question-bank-recent-searches.ts +0 -22
  712. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  713. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  714. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  715. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  716. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,594 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ### Build and distribution overhaul
8
+
9
+ The package now ships a real compiled `dist/` (ESM + `.d.ts` + source
10
+ maps) produced by `tsup`, replacing the previous shadcn-style "ship raw
11
+ `.tsx` source" approach. Non-Next consumers (Vite, Remix, plain Node
12
+ tooling) can now install and import without configuring a TS/JSX
13
+ transform for `node_modules`.
14
+ - `exports`, `main`, `module`, `types` point at `./dist/*`.
15
+ - `"use client"` directives are preserved on emit via a post-build pass
16
+ in `tsup.config.ts`.
17
+ - `prepack` builds before publish so `dist/` is always current.
18
+ - Per-component subpath imports
19
+ (`@exxatdesignux/ui/components/<name>`) continue to work — they now
20
+ resolve to `dist/components/ui/<name>.js`.
21
+
22
+ ### New primitives
23
+ - **`AlertDialog`** — blocking confirm dialog backed by Radix
24
+ `AlertDialog`. Ships `AlertDialogAction` + `AlertDialogCancel` that
25
+ wrap `Button` so consumers can pair destructive verbs without
26
+ re-styling. Read the new
27
+ `.cursor/rules/exxat-drawer-vs-dialog.mdc` for when to choose this
28
+ over the generic `Dialog`.
29
+ - **`Accordion`** — Radix-backed expandable section list with
30
+ chevron-flipping triggers. Use for FAQ-style or settings-grouping
31
+ surfaces where each panel toggles independently (`type="multiple"`)
32
+ or as a single-open group (`type="single"`).
33
+ - **`ContextMenu`** — right-click + long-press menu mirroring the
34
+ `DropdownMenu` surface (same item heights, tints, separators,
35
+ sub-menu chevron, checkbox / radio item indicators). Pair with a
36
+ visible `…` overflow `DropdownMenu` so keyboard-only users can reach
37
+ the same actions.
38
+ - **`HoverCard`** — richer hover surface for content too large or
39
+ interactive for a `Tooltip` (avatars, link previews, glossary
40
+ entries). Comes with the same animation tokens as `Popover`.
41
+ - **`ScrollArea`** — explicitly-bounded scroll container with
42
+ always-visible-on-hover scrollbars that respect platform conventions;
43
+ for sidebar trees, popover lists, long inspector panels.
44
+ - **`Slider`** — single- and dual-thumb numeric range backed by Radix
45
+ `Slider`. Thumbs render automatically based on `value` / `defaultValue`
46
+ cardinality.
47
+
48
+ Each primitive is exported from both the umbrella entry
49
+ (`@exxatdesignux/ui`) and a subpath
50
+ (`@exxatdesignux/ui/components/<name>`); matching `apps/web`
51
+ re-export shims live at `apps/web/components/ui/<name>.tsx`.
52
+
53
+ ### Promoted patterns (no longer leaf-only)
54
+
55
+ The package now ships product patterns alongside primitives — the same
56
+ shape as SLDS, Adobe Spectrum, Primer, MUI, Chakra.
57
+ - **`PageHeader`** — full hub header (h1, subtitle, optional
58
+ collaboration variant with face row + access info). Moved from
59
+ `apps/web/components/page-header.tsx`. `apps/web` keeps a 1-line
60
+ re-export shim at the original path; every existing
61
+ `import … from "@/components/page-header"` site continues to work.
62
+ - **`ListPageViewFrame`** — shared horizontal gutter + optional
63
+ centered max-width for non-`DataTable` list-hub view bodies (folder
64
+ icon grid, finder panel, OS-style explorer). Moved from
65
+ `apps/web/components/data-views/list-page-view-frame.tsx`.
66
+ - **`KeyMetrics`** (with `KeyMetricsContent`, `MetricItem`,
67
+ `MetricInsight`, `metricTrendTone`, `metricTrendAriaQualifier`) —
68
+ the full ~1.1 k LOC KPI strip moved from
69
+ `apps/web/components/key-metrics.tsx`. Hard-wired references to the
70
+ host app's `useAskLeo()` hook and `<AskLeoShortcutKbds />` component
71
+ are gone; both flow through a new injectable context.
72
+
73
+ Consumers wire their assistant by mounting `KeyMetricsProvider`
74
+ near the root and passing two optional values:
75
+ - **`defaultInsightAction: () => void`** — fires when the user
76
+ clicks the default "Ask Leo about these metrics" header CTA.
77
+ When omitted, the CTA is hidden entirely so the strip stays
78
+ useful in apps without an AI surface.
79
+ - **`shortcutHint: React.ReactNode`** — inline kbd chord (or any
80
+ node) rendered next to the action label inside the tooltip.
81
+ When omitted, the tooltip shows just the label.
82
+ - **`defaultActionLabel: string`** — visible + accessible name
83
+ for the header CTA. Defaults to "Ask Leo".
84
+
85
+ This is the same injection shape Adobe Spectrum (`Provider`-based
86
+ services) and Material UI (`Theme` context) use, so design-system
87
+ patterns can ship without taking a hard dependency on the host
88
+ app's AI / shortcut wiring.
89
+
90
+ `apps/web` keeps a 1-line `key-metrics.tsx` re-export shim plus a
91
+ new `key-metrics-ask-leo-bridge.tsx` adapter that's mounted in
92
+ `(app)/layout.tsx` just inside `AskLeoProvider`. All 20 existing
93
+ `<KeyMetrics />` consumers continue to work with no source
94
+ changes.
95
+
96
+ ### New shared utilities (`@exxatdesignux/ui/lib/*`)
97
+
98
+ Foundation modules promoted from `apps/web` so the upcoming
99
+ `DataTable`, `useTableState`, and `TablePropertiesDrawer` promotions
100
+ have a stable shared contract.
101
+ - **`row-height`** — `RowHeight` type + `ROW_HEIGHT_TILES` density
102
+ presets (compact / default / comfortable). Shared by the Properties
103
+ drawer tiles and `useTableState`.
104
+ - **`raf-throttle`** — coalesces high-frequency event handlers
105
+ (scroll, resize, ResizeObserver) into one call per animation frame
106
+ with a `.cancel()` for effect cleanup.
107
+ - **`editable-target`** — `isEditableTarget()` guard used by global
108
+ keyboard-shortcut handlers (Export `⌘⇧E`, rename `F2`, …) so
109
+ hotkeys don't steal keystrokes from text inputs / `contenteditable`
110
+ surfaces.
111
+ - **`conditional-rule-match`** — pure matchers
112
+ (`conditionalRuleMatchesRow`, `getConditionalRowBackground`,
113
+ `getConditionalCellBackground`) shared by `DataTable` cells,
114
+ `data-row-list` rows, and board card row tints so all three views
115
+ paint conditional formatting identically.
116
+ - **`table-properties-types`** — generic filter / sort /
117
+ conditional-rule type contracts (`FilterOperator`,
118
+ `FilterTextMask`, `FilterFieldDef`, `ActiveFilter`, `SortRule`,
119
+ `ColDef`, `ConditionalRule`) plus the design-system
120
+ `OPERATOR_LABELS` and `RULE_COLORS` palette. Product-specific seed
121
+ data (Placements `FILTER_FIELDS` + `COLUMNS` arrays) intentionally
122
+ stays in `apps/web/components/table-properties/types.ts`, which
123
+ now re-exports the types from the package.
124
+
125
+ `apps/web` keeps 1-line shims at the original `@/lib/*` paths
126
+ (`row-height.ts`, `raf-throttle.ts`, `editable-target.ts`,
127
+ `conditional-rule-match.ts`) so every existing import site continues
128
+ to work with no source change. The 12 files that import from
129
+ `@/components/table-properties/types` also keep working because the
130
+ file now re-exports the package types alongside the Placements
131
+ defaults.
132
+
133
+ ### Promoted DataTable (the biggest one)
134
+
135
+ The full generic `DataTable<TData>` family moved into the package as
136
+ `@exxatdesignux/ui/components/data-table` — ~3 k LOC across six files:
137
+ - **`./components/data-table`** (the umbrella) — `DataTable`,
138
+ `DataTableExtendedProps`, the column header context menu, resizing,
139
+ drag-to-reorder, per-column quick search, pinned columns,
140
+ group-by + collapsible groups, hidden columns, bulk-action bar,
141
+ conditional cell tints, sticky group headers, the column auto-fit
142
+ algorithm, and the inline filter popovers. Imports from
143
+ `next-themes` (light/dark column resizers) and `react-dom`
144
+ (`createPortal` for the bulk-action bar) are passed through; everything
145
+ else routes to DS primitives or DS lib utilities.
146
+ - **`./components/data-table/use-table-state`** — the 758-LOC hook
147
+ that owns filtering, sorting, search, density, pinning, hidden
148
+ columns, group-by, and column ordering for any consumer table.
149
+ No app-specific coupling; takes a generic `TData[]` + column defs.
150
+ - **`./components/data-table/pagination`** — `PaginationBar`,
151
+ `DataTablePaginated`, and `CountSyncer`. Wraps the umbrella
152
+ `DataTable` with a page-size selector + page navigation.
153
+ - **`./components/data-table/types`** — `ColumnDef`, `CellContext`,
154
+ `DataTableProps`, `PaginationConfig`, `SortDir`. Re-exports
155
+ `ConditionalRule` and `FilterTextMask` from the package
156
+ `table-properties-types` so column-def authors only need one import.
157
+ - **`./components/data-table/filter-date-calendar`** — single-date
158
+ YYYY-MM-DD filter calendar shared by the inline filter popover and
159
+ the Properties drawer date inputs.
160
+ - **`./components/data-table/filter-text-value-input`** — masked /
161
+ unmasked text input router for filter values (`phone`, `zip`,
162
+ `dateMDY`, free text). Falls back to the package `Input` when no
163
+ mask is requested.
164
+
165
+ The promotion required **no decoupling work** — Wave 7's `KeyMetrics`
166
+ context refactor and Wave 8's lib promotions had already moved every
167
+ shared dependency into the package. The DataTable suite has no
168
+ `useAskLeo`-style app-runtime coupling; every `@/` import the original
169
+ files used now resolves inside `packages/ui`.
170
+
171
+ Package `exports` map adds two new entries so the umbrella + subpath
172
+ imports both work:
173
+ - `./components/data-table` → `dist/components/data-table/index.js`
174
+ - `./components/data-table/*` →
175
+ `dist/components/data-table/*.{js,d.ts}`
176
+
177
+ These are declared **before** the generic `./components/*` rule so
178
+ the literal key and longer pattern win specificity resolution.
179
+
180
+ `apps/web/components/data-table/*.{ts,tsx}` (all 6 files) become 1-line
181
+ re-export shims so every existing
182
+ `import { DataTable } from "@/components/data-table"` site (~12 hubs
183
+ plus `useTableState` consumers) continues to work with no source
184
+ change.
185
+
186
+ The package now publishes `dist/components/data-table/{index,
187
+ pagination, use-table-state, filter-date-calendar,
188
+ filter-text-value-input, types}.{js,d.ts,js.map}` with the leading
189
+ `"use client"` directive preserved on every client module.
190
+
191
+ ### Linting
192
+ - Add `eslint-plugin-react-hooks` to `packages/ui` and register
193
+ `react-hooks/rules-of-hooks` (error) + `react-hooks/exhaustive-deps`
194
+ (warn). Required so the promoted `DataTable` and `useTableState`
195
+ files keep working — both carry targeted `eslint-disable-next-line
196
+ react-hooks/exhaustive-deps` comments that previously errored out
197
+ with "Definition for rule '…' was not found".
198
+
199
+ ### Promoted Table Properties drawer + data-list view registry
200
+
201
+ The full Table Properties drawer family moved into the package as
202
+ `@exxatdesignux/ui/components/table-properties` — ~1.6 k LOC across six
203
+ files plus the five data-list-view lib modules that the drawer (and
204
+ `ListPageTemplate` view tabs) read for label / icon / render-kind
205
+ metadata.
206
+ - **`./components/table-properties`** (the umbrella):
207
+ - `drawer.tsx` (~1.1 k LOC) — Properties sheet with View type tiles,
208
+ Filters / Sort / Group / Columns panels, Conditional formatting
209
+ rules, and the Display sub-sheet (gridlines, row height,
210
+ pagination, board swimlane field, line count). Sheet uses `z-[90]`
211
+ so portaled menus from inside it stack on top of `z-50` dropdowns.
212
+ - `drawer-button.tsx` (~280 LOC) — Reusable Properties button + drawer
213
+ combo. Accepts any `useTableState<T>` return value as `state`
214
+ (structural typing reads only display-agnostic fields, so it works
215
+ for any row shape). Mutators are read via `stateRef.current.X`
216
+ inside the Sheet portal, so handler identities stay stable
217
+ across re-renders.
218
+ - `filter-card.tsx` (~250 LOC) — One filter row inside the drawer
219
+ (operator dropdown, value picker, remove button). Used by both
220
+ filter rules and conditional-formatting rules.
221
+ - `sort-card.tsx` (~60 LOC) — One sort rule in the Sort panel (label,
222
+ direction toggle, drag handle, remove).
223
+ - `column-row.tsx` (~90 LOC) — One row in the Columns panel
224
+ (visibility toggle, drag handle).
225
+ - `draggable-list.ts` (~50 LOC) — `useDraggableList` pointer-driven
226
+ reorder hook shared by sort cards, column rows, and conditional
227
+ rule lists.
228
+
229
+ Both `drawer.tsx` and `drawer-button.tsx` get cleaner contracts as
230
+ part of the move: **`fieldDefinitions` and `filterFields` are now
231
+ required props**, replacing the silent fallback to the Placements
232
+ `COLUMNS` / `FILTER_FIELDS` constants. Every real consumer was
233
+ already passing both through `drawerToolbarProps` from
234
+ `HubTable` (built once via `columnsToFieldDefinitions` /
235
+ `columnsToFilterFields`); the fallback path was unreachable and
236
+ leaked Placements column shapes into the design-system package.
237
+ `DrawerSortCard` similarly drops its `COLUMNS.find(…).label`
238
+ fallback — the drawer always passes a `fieldLabel`
239
+ (`resolveColumnLabel(rule.fieldKey)`).
240
+
241
+ - **`./lib/data-list-view`** — `DataListViewType` vocabulary
242
+ (`table | list | board | dashboard | calendar | folder | panel |
243
+ tree-panel`), `DATA_LIST_VIEW_TILES`, `dataListViewLabel`,
244
+ `dataListViewIcon`, `dataListViewAddShortcut`.
245
+ - **`./lib/data-list-view-registry`** — Registry that maps each view
246
+ type to its render kind + chrome rules (`hubMetricsStrip`,
247
+ `dataListViewTilesForHub`, `dataListViewSelectionTilesForHub`,
248
+ `DATA_LIST_SURFACE_VIEW_TYPES`, `isDataListSurfaceViewType`,
249
+ `isDataListViewTypeSupported`).
250
+ - **`./lib/data-list-view-surface`** — `DataListViewRenderKind` enum
251
+ - `getDataListViewRenderKind`, `usesDataTableComponent`,
252
+ `usesDashboardSurface`, `usesToolbarWithFilteredRows` predicates so
253
+ `view === "dashboard"` is never mistaken for `view === "board"` in
254
+ switch chains.
255
+ - **`./lib/data-list-display-options`** — `DataListDisplayOptions`
256
+ (board line count, board swimlane key, show titles / column labels /
257
+ search) + `DEFAULT_DATA_LIST_DISPLAY_OPTIONS`.
258
+ - **`./lib/list-page-table-properties`** —
259
+ `createListPageEditViewHandler` + `OpenTablePropertiesHandle` so
260
+ `ListPageTemplate`'s "View → Edit" callback opens the drawer (after
261
+ coercing the tab to `table` when the active view does not host
262
+ Properties).
263
+
264
+ Package `exports` map adds:
265
+ - `./components/table-properties` →
266
+ `dist/components/table-properties/index.js` (umbrella)
267
+ - `./components/table-properties/*` →
268
+ `dist/components/table-properties/*.{js,d.ts}` (subpath)
269
+
270
+ `apps/web` keeps 1-line shims at all the original paths:
271
+ - 6 drawer-family files at `apps/web/components/table-properties/*`
272
+ (`drawer`, `drawer-button`, `filter-card`, `sort-card`, `column-row`,
273
+ `draggable-list`) — all re-export from
274
+ `@exxatdesignux/ui/components/table-properties/*`.
275
+ - 5 lib files at `apps/web/lib/*` (`data-list-view`,
276
+ `data-list-view-registry`, `data-list-view-surface`,
277
+ `data-list-display-options`, `list-page-table-properties`).
278
+
279
+ `apps/web/components/table-properties/types.ts` keeps the
280
+ Placements-specific `FILTER_FIELDS` + `COLUMNS` seed data (those are
281
+ **product data**, not design-system primitives) and continues to
282
+ re-export the generic types from `@exxatdesignux/ui/lib/table-properties-types`,
283
+ so every existing `import … from "@/components/table-properties"`
284
+ site keeps working unchanged.
285
+
286
+ The package now ships
287
+ `dist/components/table-properties/{drawer, drawer-button, filter-card,
288
+ sort-card, column-row, draggable-list, index}.{js,d.ts,js.map}` with
289
+ the leading `"use client"` directive preserved on the 5 client modules
290
+ (`draggable-list` is a pure hook so the inheriting consumer's `"use
291
+ client"` boundary covers it).
292
+
293
+ ### Promoted Data views — list-page binding layer
294
+
295
+ The list-page binding layer moved into the package as
296
+ `@exxatdesignux/ui/components/data-views` — ~1.15 k LOC across 9
297
+ files. `HubTable<TRow>` is now the canonical composition that ties
298
+ `DataTable` + `useTableState` + `TablePropertiesDrawerButton` + view
299
+ tabs into one generic component:
300
+ - **`./components/data-views/hub-table`** (~497 LOC) — `HubTable<TRow>`
301
+ - `columnsToFilterFields` + `columnsToFieldDefinitions` helpers +
302
+ `HubTableProps<TRow>` / `HubTableRendererArgs<TRow>` /
303
+ `HubDrawerToolbarProps`. Pass columns, rows, supported view types,
304
+ and a `renderers: { [renderKind]: ReactNode | () => ReactNode }` map.
305
+ The component owns `useTableState`, builds
306
+ `filterFields`/`fieldDefinitions` from your columns, mounts the
307
+ Properties button, and routes the active view tab through
308
+ `ListPageConnectedViewBody`.
309
+ - **`./components/data-views/list-page-connected-view-body`** —
310
+ `ListPageConnectedViewBody` + `ListPageViewNotConfigured` + the
311
+ `ListPageConnectedViewRenderers` type. Switches view bodies by
312
+ `DataListViewRenderKind` and shows a clear empty state when a
313
+ registered view is missing a renderer (never silently falls through
314
+ to dashboard).
315
+ - **`./components/data-views/data-row-list`** — virtualized list-view
316
+ body backed by `@tanstack/react-virtual` (new package dependency,
317
+ declared in `peerDependencies` shape; tree-shaken when only board
318
+ consumers import).
319
+ - **`./components/data-views/list-page-board-template`** — Reusable
320
+ kanban shell where columns are defined by predicates over each row.
321
+ - **`./components/data-views/list-page-board-card`** —
322
+ `ListPageBoardCard` shell with `stack` and `row` layouts, optional
323
+ `ListPageBoardCardAvatar`, `ListPageBoardCardTitleRow`,
324
+ `ListPageBoardCardBadgeRow`, `ListPageBoardCardBody`,
325
+ `ListPageBoardCardSecondary` slots. Matches placement-board card
326
+ visuals one-to-one.
327
+ - **`./components/data-views/board-card-primitives`** —
328
+ `BoardCardTwoLineBlock`, `BoardCardIconRow`,
329
+ `BoardNewCardPlaceholder` primitives shared between
330
+ `list-page-board-template` and consumer-built board cards. Reads
331
+ `BoardLineCount` from `data-list-display-options` to clamp text
332
+ lines.
333
+ - **`./components/data-views/list-page-tree-column-header`** /
334
+ **`list-page-split-details-placeholder`** /
335
+ **`list-page-split-hub-chrome`** — Pure-CSS shells used by the
336
+ finder / tree-panel / multi-column explorer views (centered card
337
+ - fixed viewport height; composes `ListPageViewFrame`).
338
+
339
+ Package `exports` map adds:
340
+ - `./components/data-views` →
341
+ `dist/components/data-views/index.js` (umbrella)
342
+ - `./components/data-views/*` →
343
+ `dist/components/data-views/*.{js,d.ts}` (subpath)
344
+
345
+ All 9 modules are exported from the main `@exxatdesignux/ui` barrel
346
+ and `apps/web/components/data-views/{hub-table, data-row-list,
347
+ list-page-connected-view-body, board-card-primitives,
348
+ list-page-board-card, list-page-board-template,
349
+ list-page-tree-column-header, list-page-split-details-placeholder,
350
+ list-page-split-hub-chrome}.tsx` are all 1-line re-export shims, so
351
+ every existing consumer (Placements, Team, Compliance, Question Bank,
352
+ plus every `HubTableRendererArgs<TRow>`-typed table renderer) keeps
353
+ working with no source change.
354
+
355
+ ### Tooling
356
+ - Add `@tanstack/react-virtual` to `packages/ui` `dependencies` (the
357
+ virtualized `DataRowList` body needs it). External in `tsup` so the
358
+ consumer bundle dedupes against any pre-existing `apps/web` copy.
359
+ - Add `packages/ui/src/globals.d.ts` declaring a minimal
360
+ `process.env.NODE_ENV` ambient so `HubTable`'s dev-time
361
+ missing-renderer `console.warn` typechecks without taking on a
362
+ `@types/node` dependency. Both bundlers and Next.js's RSC compiler
363
+ statically replace `process.env.NODE_ENV` at build time, so the
364
+ declaration only affects type-checking.
365
+ - Clean up `useImperativeHandle` deps in `HubTable` to extract the
366
+ stable `setSheetOpen` setter from `useTableState` before the hook
367
+ call, removing the misplaced
368
+ `eslint-disable-next-line react-hooks/exhaustive-deps` comment.
369
+
370
+ ### Promoted ExportDrawer + ListPageTemplate + small templates
371
+
372
+ The page-scale list-hub composition moved into the package as
373
+ `@exxatdesignux/ui/components/templates` so non-Next consumers (Vite,
374
+ Remix, plain CRA) can mount a complete hub without copying app source.
375
+ - **`./components/export-drawer`** — `ExportDrawer` (format + date range
376
+ - columns + active-filter toggle), single-file component composed from
377
+ in-package primitives only. App-specific `devLog` came along as
378
+ `./lib/dev-log` (`process.env.NODE_ENV` gated — bundlers strip the
379
+ call site in production).
380
+ - **`./components/templates/list-page`** — `ListPageTemplate` +
381
+ `ViewTab` / `ViewType` / `FilterOption` types + the canonical
382
+ `VIEW_TYPES` array derived from `DATA_LIST_VIEW_TILES`. The template
383
+ composes `PageHeader` slots (`header`, `metrics`,
384
+ `beforeSiteHeader`), the view-segmented control, and the now-promoted
385
+ `ExportDrawer` directly.
386
+ - **`./components/templates/nested-secondary-panel-shell`** — Single
387
+ responsive shell pairing a primary sidebar with a nested secondary
388
+ panel (used by Question bank).
389
+ - **`./components/templates/dedicated-search-landing-template`** —
390
+ Empty-`?q=` landing surface (`DotPattern` + lens + suggestions
391
+ slot) composed on `ListPageViewFrame`.
392
+ - **`./components/templates/dedicated-search-results-template`** —
393
+ `DedicatedSearchResultsHeaderChrome` + the
394
+ `DEDICATED_SEARCH_RESULTS_OUTER_CONTENT_CLASSNAME` shared classname
395
+ for the populated `?q=` branch.
396
+
397
+ App-side compositions that wrap product-specific shells
398
+ (`PrimaryPageTemplate`, `SecondaryPanelHubTemplate`,
399
+ `DiscoveryHubTemplate`, `NewFocusTemplate`) stay in
400
+ `apps/web/components/templates/` because they pull in `SiteHeader`,
401
+ `useAskLeo`, or per-route mock data — those will graduate when their
402
+ respective shells are decoupled.
403
+
404
+ Package `exports` map adds:
405
+ - `./components/templates` → `dist/components/templates/index.js`
406
+ - `./components/templates/*` →
407
+ `dist/components/templates/*.{js,d.ts}`
408
+
409
+ `apps/web` ships 1-line re-export shims at
410
+ `apps/web/components/export-drawer.tsx`,
411
+ `apps/web/lib/dev-log.ts`, and
412
+ `apps/web/components/templates/{list-page,
413
+ nested-secondary-panel-shell, dedicated-search-landing-template,
414
+ dedicated-search-results-template}.tsx` so every existing consumer
415
+ keeps working unchanged. All 15 Next.js routes still compile.
416
+
417
+ ### Promoted Data view bodies — finder / folder grid / outline tree / tree-panel shell + folder glyph
418
+
419
+ Six view-body modules moved into
420
+ `@exxatdesignux/ui/components/data-views/`, finishing the data-views
421
+ surface graduation that started with `HubTable`:
422
+ - **`./components/data-views/list-page-split-hub-tokens`** — Shared
423
+ layout classnames (`LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS`,
424
+ `LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS`,
425
+ `LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS`) so finder / tree-panel /
426
+ multi-column hubs stay visually aligned.
427
+ - **`./components/data-views/outline-tree-menu`** — VS Code–style
428
+ outline chrome (`OutlineTreeMenu`, `OutlineTreeMenuItem`,
429
+ `OutlineTreeLeafButton`, `OutlineTreeSub`, `OutlineTreeSubItem`,
430
+ `OutlineTreeCollapsibleContentRail`) with the guide-spacer + sub-row
431
+ shift classnames consumers compose for inset rails.
432
+ - **`./components/data-views/folder-grid-view`** — Generic icon-grid
433
+ layout with empty state, `aria-label`-named list, `renderTile`
434
+ render-prop, and optional centered max-width (icon-grid frame).
435
+ - **`./components/data-views/finder-panel-view`** — Miller-style
436
+ 3-column split for list hubs (`FinderPanelView`) reusing the split
437
+ hub tokens + `ListPageTreeColumnHeader` +
438
+ `ListPageSplitDetailsPlaceholder`.
439
+ - **`./components/data-views/list-page-tree-panel-shell`** — Generic
440
+ two-pane layout (tree column + details column) with persisted
441
+ `react-resizable-panels` group id and shared
442
+ `ListPageSplitHubChrome` chrome.
443
+ - **`./components/data-views/os-folder-glyph`** — Windows-11-style
444
+ folder art (Icons8) + FA glyph overlay, with a generic
445
+ `FolderGlyphColorKey` palette type. Product `QuestionBankFolderColorKey`
446
+ stays in app mock data (same string union — structurally compatible
447
+ with `FolderGlyphColorKey`, no source changes required at call sites).
448
+
449
+ Package `exports` map continues to route
450
+ `./components/data-views/*` to the new modules. The package barrel
451
+ re-exports them all. App-side 1-line shims continue to provide the
452
+ `@/components/data-views/<file>` import paths.
453
+
454
+ `apps/web/components/data-views/question-bank-folder-tree-branch.tsx`
455
+ stays in the app — it pulls product mock data
456
+ (`QuestionBankFolder` / `QUESTION_BANK_FOLDER_ICON_COLORS`) and is the
457
+ right boundary between "design-system primitive" and "product
458
+ composition".
459
+
460
+ ### Tailwind L0 token namespace — verified
461
+
462
+ The `--exxat-color-*` / `--exxat-radius-*` / `--exxat-spacing-*` L0
463
+ canonical namespace (migration `0002-exxat-token-namespace.md`) is live
464
+ in the package's `src/globals.css` with Tailwind bridges (`bg-surface-1`,
465
+ `text-ink-1`, `rounded-2`, …) wired through `@theme inline`. The hooks
466
+ index (`packages/ui/tokens/hooks-index.json`) is regenerated to 197
467
+ tokens and passes `tokens:check`. `apps/web/app/globals.css` imports
468
+ the package CSS, so consumers inherit every L0 alias automatically. No
469
+ existing token was renamed; opportunistic per-file migration to L0
470
+ forms is non-breaking and continues as devs touch the code.
471
+
472
+ ### Documentation — three new blueprints
473
+
474
+ Added SLDS-style spec docs for the most-touched compositions, completing
475
+ the patterns the blueprints README itself flagged as "future":
476
+ - **`apps/web/docs/blueprints/list-page-template.md`** — view tabs +
477
+ metrics slot + properties drawer wiring, with WCAG mapping and
478
+ Do / Don't table.
479
+ - **`apps/web/docs/blueprints/board-card.md`** — `ListPageBoardCard`
480
+ shell + status badge + body primitives, including the list-row
481
+ counterpart (`layout="row"`).
482
+ - **`apps/web/docs/blueprints/key-metrics.md`** — flat vs card
483
+ variant, KPI count cap, trend polarity, and the service-injection
484
+ bridge for app-specific actions like Ask Leo.
485
+
486
+ The blueprints README links each new doc to its narrative + cursor
487
+ rules + React component. (Storybook / Ladle catalog is intentionally
488
+ not adopted in this pass: the Next.js demo routes plus blueprints
489
+ already cover the documentation surface, and adopting Storybook would
490
+ add infra without immediate signal for this DS.)
491
+
492
+ ### Hygiene
493
+ - Add `license: "UNLICENSED"` + `author` fields to `package.json`.
494
+ - Add `--exxat-color-wordmark-ink-light` / `-dark` tokens (used by the
495
+ Exxat product logo SVG + HTML wordmark prefix; replaces five `[#273441](https://github.com/ExxatDesign/Exxat-DS-Workspace/issues/273441)`
496
+ / `#A8B2BA` literals in `apps/web/components/exxat-product-logo.tsx`
497
+ - `product-wordmark.tsx`).
498
+ - ESLint config landed alongside source. Runs in PR CI with the
499
+ workspace `@exxatdesignux/eslint-plugin` rules (no hex literals, no
500
+ deprecated tokens, no SLDS / Lightning leakage, no Sonner toasts).
501
+ - `npm publish` runs with Sigstore `--provenance` from the
502
+ `.github/workflows/publish-ui.yml` workflow + creates an automated
503
+ GitHub Release.
504
+ - New PR-time CI workflow gates every PR on install → lint → typecheck
505
+ → tokens drift check → vitest → build, plus the Changesets release
506
+ flow on `main`.
507
+ - Scope the `brace-expansion` security override (GHSA-v6h2-p8h4-qcjw)
508
+ to per-major lines so `minimatch@3.1.5` keeps its compatible 1.x
509
+ branch and ESLint config loading no longer crashes with
510
+ `expand is not a function`.
511
+ - Prune unused mutator destructures in
512
+ `apps/web/components/table-properties/drawer-button.tsx` (left behind
513
+ by the earlier `react-hooks/refs` refactor). Setters are now read
514
+ exclusively via `stateRef.current.X` so handler identities stay
515
+ stable while the Sheet is portaled.
516
+
517
+ - ### Demo / template hub renamed from "Question bank" → "Library"
518
+
519
+ The reference hub that ships in `packages/ui/template/**` and the
520
+ consumer-side mirrors in `packages/ui/consumer-extras/**` were renamed
521
+ from a domain-specific "Question bank" to a generic, placeholder-labeled
522
+ **Library** hub. This affects three surfaces consumers see:
523
+ 1. **Template route + components** (used by `exxat-ui scaffold-app`):
524
+ - `app/(app)/question-bank/**` → `app/(app)/library/**`. The
525
+ `library/library` sub-route was simultaneously renamed to
526
+ `library/all` so the canonical "list everything" path reads
527
+ `/library/all`.
528
+ - `components/question-bank-*.tsx` (13 files) →
529
+ `components/library-*.tsx`. `components/new-question-composer.tsx`
530
+ → `components/new-library-item-form.tsx`.
531
+ - `components/data-views/question-bank-folder-tree-branch.tsx` →
532
+ `components/data-views/library-folder-tree-branch.tsx`.
533
+ - `lib/mock/question-bank{,-folders,-inspector,-kpi,-header-collaborators}.ts`
534
+ → `lib/mock/library-*.ts`.
535
+ - `lib/question-bank-{nav,supported-views,authoring,recent-searches,hub-search,dedicated-search}.ts`
536
+ → `lib/library-*.ts`.
537
+ 2. **TypeScript surface (template only — package itself ships
538
+ generic shells):** `QuestionBankItem` → `LibraryItem`,
539
+ `QuestionBankFolder` → `LibraryFolder`, `QuestionBankNavState` →
540
+ `LibraryNavState`, `QuestionBankTable` → `LibraryTable`, etc. The
541
+ nested secondary-panel id flipped from `"question-bank"` to
542
+ `"library"`; consumers wiring `useAutoPanel` or the `secondaryPanel`
543
+ prop on a nav row must update the literal.
544
+ 3. **Consumer docs + agent rules** (`packages/ui/consumer-extras/`):
545
+ `cursor-rules/exxat-question-bank-hub-header.mdc` →
546
+ `cursor-rules/exxat-library-hub-header.mdc`. The skill and
547
+ handbook entries that cited "Question bank" as the reference
548
+ implementation now cite the **Library** hub instead.
549
+
550
+ Mock content was also abstracted from clinical/medical strings (Bloom
551
+ taxonomy, NBME, anatomy, clinical decks) to neutral placeholders:
552
+ `Item 01..12`, `Owner A..E`, `Category 1..4`, `Type 1..3`,
553
+ `Low / Normal / High`, `Tier 1..6`, `Folder 1..6`, `LIB-2026-###` ids.
554
+ This makes the template usable as a starter for any domain — clinical,
555
+ education, retail, ops, etc. — without rewriting demo data first.
556
+
557
+ ### Migration for consumer apps
558
+
559
+ Run `pnpm exxat-ui sync-extras` (or whatever wrapper your repo uses)
560
+ to refresh `cursor-rules/`, `cursor-skills/`, `patterns/`, and
561
+ `handbook/` from the new mirror. The two breaking edges to check
562
+ manually inside your own app code:
563
+ - Any nav row that pinned `secondaryPanel: "question-bank"` →
564
+ `secondaryPanel: "library"`.
565
+ - Any direct import from
566
+ `@/components/question-bank-*` / `@/lib/question-bank-*` /
567
+ `@/lib/mock/question-bank-*` (likely only if you forked the demo
568
+ hub) → rename to the matching `library-*` path.
569
+
570
+ The `DataTable`, `useTableState`, `HubTable`, `ListPageTemplate`,
571
+ `TablePropertiesDrawer`, `KeyMetrics`, and `PageHeader` APIs are
572
+ unchanged — only the demo hub naming flipped.
573
+
574
+ ### Pagination chrome regression fixed
575
+
576
+ Independent of the rename, `HubTable.defaultTableRenderer` and the
577
+ `list-with-toolbar` default block now embed `<PaginationBar>` inside
578
+ the table card with `sticky bottom-0` instead of floating it below the
579
+ border. The new layout passes `hasFooter` through to `<DataTable>` so
580
+ the table's top corners stay `rounded-t-lg` and the bottom corners go
581
+ square, then anchors the pagination slab to the page scroll container
582
+ (`PrimaryPageTemplate.bodyClassName`). The shipped `PaginationBar`
583
+ component itself is unchanged.
584
+
585
+ ### Docs
586
+ - `apps/web/docs/large-dataset-strategy.md` — new doc covering today's
587
+ client-mode behavior, when to enable pagination, the server-mode
588
+ upgrade path via `paginationOverride`, and the row-virtualization
589
+ follow-up. Cross-linked from `apps/web/AGENTS.md` and
590
+ `apps/web/docs/data-views-pattern.md`.
591
+
3
592
  All notable changes to `@exxatdesignux/ui` are documented here. The file ships in the npm tarball at `node_modules/@exxatdesignux/ui/CHANGELOG.md`.
4
593
 
5
594
  ## For AI assistants (upgrade handoff)
@@ -15,25 +604,91 @@ After the user bumps `@exxatdesignux/ui`, do this in order:
15
604
 
16
605
  ---
17
606
 
18
- ## [0.2.19] - 2026-05-19
607
+ ## [Unreleased]
608
+
609
+ ## [0.3.1] – 2026-05-21
610
+
611
+ ### Fixed
612
+
613
+ - **Customer demo `template/` was stale.** Re-ran `sync-template-from-web` and confirmed the npm `template/` payload now matches what the monorepo runs (`/columns`, `/tokens-themes`, `/question-bank`, `/dashboard`, settings) byte-for-byte. Previously the published `template/` still carried deleted entity-domain files (`placements-*`, `sites-*`, `team-*`, `compliance-*`, `rotation-*`) — they're gone now.
614
+
615
+ ### Changed
616
+
617
+ - **`prepack` now auto-syncs template + consumer-extras before `tsup`.** New chain: `sync-template-from-web && vendor-consumer-extras && tsup`. Every `npm publish` (and every `npm pack`) guarantees the shipped `template/` mirrors `apps/web` and the AI bundle under `consumer-extras/` mirrors the latest skills + patterns. No more "I bumped the version but the template is stale" mode — drift is now impossible at publish time.
618
+ - **Handbook + skills refreshed for the post-cleanup canonical refs.** `apps/web/AGENTS.md`, `apps/web/docs/HANDBOOK.md`, `apps/web/docs/data-views-pattern.md`, `apps/web/docs/glossary.md`, `apps/web/docs/reference-implementations.md`, `apps/web/docs/blueprints/{data-table,page-header}.md`, `apps/web/docs/kpi-flat-band-pattern.md`, and `apps/web/docs/component-selection-guide.md` (and the matching `.cursor/skills/exxat-ds-skill/SKILL.md`) all stop citing the deleted Placements / Sites / Team / Compliance components. New canonical references: `columns-showcase.tsx` (smallest single-view hub), `tokens-themes-client.tsx` (smallest secondary-panel + URL-driven scope hub with built-in pagination chrome), `question-bank-table.tsx` + `question-bank-hub-client.tsx` (full multi-view hub: table, board, dashboard).
619
+
620
+ ## [0.3.0] – 2026-05-21
19
621
 
20
622
  ### Added
21
623
 
22
- - **Design tokens (CSS modules):** Split theme surface into `src/tokens/` (`base.css`, `themes.css`, `high-contrast.css`, `layers.css`, `tailwind-bridge.css`). Entry points `globals.css` / `theme.css` re-export only **no token value changes**.
23
- - **Package export:** `@exxatdesignux/ui/tokens/*` for consumers that import token partials alongside Tailwind v4.
624
+ - **`exxat-token-economy` skill** (`.cursor/skills/exxat-token-economy/SKILL.md` + Claude mirror) the new "read this first" entry for any AI working with the design system. Targets **~50% fewer input tokens per design turn** by giving the assistant: a task → minimum-file-set table (so it doesn't reflexively open `AGENTS.md`), a five-question pre-flight that catches the top rule violations before generation, canonical primitive aliases (no `grep` needed), tiny copy-verbatim scaffolds for hub client / column def / KPI item, a deny-list of expensive files, an ask-vs-assume heuristic, and an output-discipline section that keeps the assistant's own response lean. `HANDBOOK.md` now opens with a callout pointing to it.
625
+ - **Importable cell primitives** — every SaaS-grid cell pattern demoed in `columns-showcase.tsx` (progress, currency, numeric, rating, signal bars, boolean toggle, attachment count, external link, relative time, face rail with `+N`, type pill, tag list with `+N`, generic `RowActionsCell<TRow>`) is now a named export from `@/components/data-views` (`apps/web/components/data-views/table-cells.tsx`). The showcase becomes a thin orchestrator that imports these — proving they're production-ready, not demo-only. The token-economy skill's §3 ("primitive aliases") and §4 ("`ColumnDef` scaffolds") both name the cells so the AI imports them on the first try instead of re-deriving `Intl.NumberFormat`, star loops, or `<a target="_blank">` inline. `.cursor/rules/exxat-data-tables.mdc` adds a MUST-USE clause; `reference-implementations.md` gains a "Cell primitives (importable)" table; `glossary.md` adds a "Cell primitive" entry.
626
+ - **`exxat-ui sync-extras` now installs the full AI bundle in one command.** Previously the CLI shipped only Cursor skills + pattern docs; consumers had to `degit` Cursor rules and handbook tier docs separately. The CLI now writes, in one pass:
627
+ 1. **Skills to both clients** — `.cursor/skills/exxat-*/` **and** `.claude/skills/exxat-*/` (16 folders including the new **`exxat-token-economy`**; same `SKILL.md` shape, two readers, one source of truth — no more `ln -s` step).
628
+ 2. **Cursor rules** — `.cursor/rules/exxat-*.mdc` (29 binding `MUST` / `MUST NOT` files: data-tables, accessibility, kbd shortcuts, KPI trends/flat-band/max-four, board cards, list-page-view-shells, centralized-list-dataset, reuse-before-custom, no-toast, drawer-vs-dialog, page-vs-drawer, no-slds-leakage, token-discipline, mono-ids, fontawesome-icons, dashboard-view-charts, …).
629
+ 3. **Handbook tier** — `docs/exxat-ds/handbook/{HANDBOOK,glossary,voice-and-tone,reference-implementations}.md`. These are stage-rewritten copies of `apps/web/docs/*.md` — links to shipped patterns use `../`, links to unshipped neighbours (blueprints, token-taxonomy, root `AGENTS.md`, `lib/*`) are rewritten to absolute GitHub URLs at bundle time so every link in the consumer's repo resolves.
630
+ 4. **Patterns + checklist** — unchanged from prior releases (`docs/exxat-ds/*-pattern.md`, `consumer-upgrade-checklist.md`).
631
+
632
+ The CLI is **namespaced** — it only writes files starting with `exxat-` (skills + rules), so a consumer's own non-Exxat rules / skills survive an upgrade untouched. Product code under `app/`, `pages/`, `src/`, plus the consumer's own `AGENTS.md`, are never modified. Bundle source lives at `packages/ui/consumer-extras/{cursor-skills,cursor-rules,patterns,handbook}/`.
633
+
634
+ - **Single centralized `<HubTable<TRow>>`** — `components/data-views/hub-table.tsx` is now the one table surface every list-page hub renders. It owns the previously per-hub scaffolding that drifted across five files: `useTableState`, `displayOptions` (controlled or internal), `conditionalRules` add/remove/update, `filterFields` + `fieldDefinitions` + `resolveColumnLabel` memos, `TablePropertiesDrawerButton` wiring with `supportedViewTypes`, the imperative `openPropertiesDrawer()` handle (`HubTableHandle`), the default `DataTable` for `view === "table"`, and `ListPageConnectedViewBody` routing for every other view. Hubs now pass only **what's different**: column defs, a typed `renderers: HubTableRenderers<TRow>` map for non-table views, and entity-specific labels/sorts/empties. The renderer args (`state`, `toolbar`, `toolbarShell`, `drawerToolbarProps`, `displayOptions`, `patchDisplay`) cover both the common "wrap a body in the shared toolbar" case (`toolbarShell(<MyView rows={state.rows} />)`) and the escape-hatch case (dashboards that own their own toolbar with extra layout-edit actions splat `drawerToolbarProps` back into a custom `<TablePropertiesDrawerButton>`). Hub-specific helpers (`columnsToFilterFields`, `columnsToFieldDefinitions`) are exported from the same module so column defs become the single source of truth for filters + drawer field options. Mirrored to `packages/ui/template/components/data-views/hub-table.tsx`.
635
+ - **Per-hub `supportedViewTypes` allowlists** — `lib/team-supported-views.ts`, `lib/compliance-supported-views.ts`, `lib/placements-supported-views.ts`, `lib/sites-supported-views.ts` (matching the existing `question-bank-supported-views.ts` and `list-hub-supported-views.ts`). Each hub passes its allowlist into `<HubTable>` so `TablePropertiesDrawerButton` filters the view-type tile grid to the hub's implemented views — Sites cannot pick Calendar, Placements cannot pick Calendar, Team cannot pick Folder/Tree, etc. Pair these with `ListPageTemplate.supportedViewTypes` on the hub client to filter the Add-view menu + ⌘1–9 shortcuts in tandem.
24
636
 
25
637
  ### Changed
26
638
 
27
- - **Starter `template/`** and **consumer extras:** List hub shell, secondary panel registry, route-aware loading skeletons, focused-workflow settings layout, KPI flat band + shell elevation docs/skills synced from `apps/web`.
639
+ - **Every hub table migrated to `<HubTable>` + `ListPageConnectedViewBody`** the previous "single centralized list dataset" rule is now structurally enforced (one `useTableState` per hub, one row bag every view body reads). Net code: hub `*-table.tsx` files dropped from **4,402** → **2,984** lines (-32%) by removing duplicated scaffolding; the new `hub-table.tsx` adds ~350 lines once. Per-hub deltas:
640
+ 1. **`placements-table.tsx`** 1,642 → 955 (-42%). Six bespoke `DataList*Shell` sub-components (board / list / dashboard / folder / tree-panel / panel) deleted — each one was a separate copy of `<DataTableToolbar … toolbarSlot={s => <TablePropertiesDrawerButton …/>}>` wrapped around a different view body. Replaced by per-view renderer entries that call `toolbarShell(<body />)`. Pagination chrome (`CountSyncer` + `PaginationBar`) moves into a custom `tableRenderer` + the `list-with-toolbar` renderer; `HubTable.paginationOverride` is forwarded into `useTableState`. The dashboard's layout-edit + coach-mark + persistence state lives in an internal `<PlacementsDashboardBody>` component (renderers can't host hooks — `ListPageConnectedViewBody` calls them inline).
641
+ 2. **`question-bank-table.tsx`** 1,073 → 823 (-23%). The custom `<HubFolderColumnsPanel>` miller-view + `<HubTreePanelView>` stay (genuinely entity-specific); every shell/toolbar wrapper around them is gone. The `QuestionBankNewFolderSheet` modal state (shared by panel + tree-panel) moves to the hub's top scope, so both renderers share one sheet instance instead of duplicating it. URL search sync is now `HubTable.syncedSearchFromUrl={searchLanding ? undefined : urlListSearch}` (was a 5th positional argument to `useTableState`).
642
+ 3. **`team-table.tsx`** 693 → 534 (-23%). Dashboard layout + coach-mark + persistence state extracted into a `<TeamDashboardBody>` internal component, same pattern as Placements. `TeamFinderListRow` + `TeamFinderDetail` panel helpers unchanged.
643
+ 4. **`compliance-table.tsx`** 612 → 448 (-27%). Same dashboard-body extraction; panel groups builder unchanged.
644
+ 5. **`sites-table.tsx`** 382 → 224 (-41%). Inline panel + dashboard renderers; sites has no custom dashboard-layout state.
645
+ - **`HubTable` API additions** (back-compat — all new props optional) — `displayOptions` + `onDisplayOptionsChange` (controlled mode for hubs that persist display state at the page level, e.g. Placements; otherwise `HubTable` owns the state internally), `pagination` + `onPaginationChange` (forwarded to `TablePropertiesDrawerButton` so the drawer's Display panel can offer "Show pagination"), `paginationOverride` (forwarded to `useTableState` for server-style paged tables), `syncedSearchFromUrl` (forwarded to `useTableState` for `?q=`-bound toolbar search), `onRowClick`, and `tableRenderer` (override for the `data-table` view when the hub needs pagination chrome or a custom wrapper around `<DataTable>`).
646
+ - **`OpenTablePropertiesHandle` aliases** — each `*-table.tsx` now exports `*TableHandle = HubTableHandle` instead of `= OpenTablePropertiesHandle` directly. Both resolve to the same shape (`{ openPropertiesDrawer(): void }`), so existing `tablePropertiesRef` consumers continue to work without changes.
28
647
 
29
- ### Chore (monorepo)
648
+ ### Added (continued, from earlier in this Unreleased section)
649
+
650
+ - **View registry + per-hub `supportedViewTypes` plumbing** — single source of truth for list-page view types and their render kinds, with per-hub allowlists so Properties, Add view, and ⌘1–9 shortcuts never offer a view the hub does not render.
651
+ 1. **`lib/data-list-view-registry.ts`** — `DATA_LIST_VIEW_REGISTRY` (one `DataListViewDefinition` per `DataListViewType`), `dataListViewDefinition`, `dataListViewTilesForHub` / `dataListViewSelectionTilesForHub` (filtered tiles for a hub's `supportedViewTypes`), `isDataListSurfaceViewType` (now derived from the registry — the previous local `SURFACE_VIEW_TYPES` literal in `lib/list-page-table-properties.ts` is gone), `showsListPageHubMetricsStrip` (false for `calendar` and `dashboard`).
652
+ 2. **`components/data-views/list-page-connected-view-body.tsx`** — `<ListPageConnectedViewBody view renderers hubLabel />` switches list-hub view bodies by render kind. Missing kinds render a clear `<ListPageViewNotConfigured>` empty state — never silently fall through to dashboard. Renderers can be `React.ReactNode` or `() => ReactNode` (the latter for lazy / heavy bodies).
653
+ 3. **`lib/hub-connected-view-renderers.ts`** — typed `defineHubViewRenderers(supported, renderers)` builder; the `Supported` generic constrains the renderer keys to the hub's actual render kinds, and dev builds emit a console warning when a supported view has no body.
654
+ 4. **`lib/question-bank-supported-views.ts`** + **`lib/list-hub-supported-views.ts`** — per-hub allowlists (e.g. Question bank supports `table | list | board | dashboard | folder | panel | tree-panel`; List hub supports `table | list | board | calendar | panel`). Hubs pass these into `ListPageTemplate.supportedViewTypes` and `TablePropertiesDrawerButton.supportedViewTypes`.
655
+ 5. **`DataListViewType` gains `"calendar"`** — and `data-list-view-surface.ts` adds the matching `calendar-with-toolbar` render kind. Existing hubs are unaffected (no hub claims `calendar` in its supported set yet); the type is now forward-compatible with a calendar body.
656
+
657
+ ### Changed
658
+
659
+ - **`TablePropertiesDrawer` + `TablePropertiesDrawerButton`** accept optional `supportedViewTypes?: readonly DataListViewType[]`. When set, the view-type tile grid in Properties is filtered to that hub's implemented views (via `dataListViewTilesForHub`) so users cannot switch a hub into a view it does not render. Default behavior (omitting the prop) is unchanged — all registered tiles are shown.
660
+ - **`ListPageTemplate`** accepts the same `supportedViewTypes` prop and filters **both** the Add view dropdown menu and the ⌘1–9 shortcut bindings to the hub's actual views. Previously, `VIEW_TYPES.slice(0, 9)` bound every registered view globally even on hubs that only implement a subset, so a user could ⌘4 → Dashboard into a hub that had no dashboard renderer (it would fall through to the not-configured empty state).
661
+ - **Question bank** (`question-bank-client.tsx`, `question-bank-table.tsx`) now passes `QUESTION_BANK_SUPPORTED_VIEWS` into `ListPageTemplate.supportedViewTypes` and `TablePropertiesDrawerButton.supportedViewTypes` end-to-end. Other hubs (Placements, Team, Compliance, Sites) are unchanged for this release — they still expose every registered view; their `supportedViewTypes` props are opt-in.
662
+ - **`lib/list-page-table-properties.ts`** no longer maintains its own `SURFACE_VIEW_TYPES` literal. `isDataListSurfaceViewType` is re-exported from `lib/data-list-view-registry.ts` so adding a new `DataListViewType` no longer requires editing three files.
663
+
664
+ ### Promoted into `@exxatdesignux/ui` (shared primitives)
665
+
666
+ - **`components/resizable`** + **`components/dot-pattern`** moved from `apps/web/components/ui/` to `packages/ui/src/components/ui/`. App imports continue to work through `apps/web/components/ui/{resizable,dot-pattern}.tsx`, which are now one-line re-exports from `@exxatdesignux/ui/components/{resizable,dot-pattern}`. Added `motion@^12.38.0` and `react-resizable-panels@^4.10.0` to `packages/ui/package.json` `dependencies`.
667
+
668
+ ### Removed
669
+
670
+ - **`components/section-cards.tsx`** (dead since the shadcn starter — zero imports across `apps/web` and `packages/ui/template/`).
671
+
672
+ ### Renamed
30
673
 
31
- - Package **`version`** **0.2.19** publish with tag **`ui-v0.2.19`**.
674
+ - **`components/sites-all-client.tsx`** → **`components/sites-client.tsx`**; `SitesAllClient` export → `SitesClient`. The hub is currently unmounted (no `app/(app)/sites/` route), but the file is kept as a reference Sites hub composition and renamed for consistency with `placements-client`, `team-client`, `compliance-client`. Mirrored in `packages/ui/template/`.
32
675
 
33
676
  ## [0.2.18] - 2026-05-19
34
677
 
35
678
  ### Fixed
36
679
 
680
+ - **Dark mode surface elevation ladder — popover / card split, secondary panel nestled** (`globals.css`):
681
+ 1. **`--popover` lifted to L=0.275** (was 0.225). Sharing the card's subtle 0.225 value made floating dropdowns blend straight into the canvas (only +0.025 above L=0.20) — the dropdown chrome lost its boundary. Popover now sits +0.075 above canvas with a slightly elevated chroma (built-ins 0.022 / custom `max(0.018, c·0.16)`), giving dropdowns and menus the visible lift they need over content. `--card` stays at 0.225 — it's an _inline_ surface, not a floating one, and the earlier "subtle wash" reading was correct for it.
682
+ 2. **`--secondary-panel-bg` rewired** from `var(--brand-tint)` (which resolved to L=0.30) down to **L=0.22**. The old value made the secondary nav panel _brighter_ than the surrounding sidebar (L=0.245), so the Library / question-bank rail popped out as a bright tile instead of nesting in. The new value wedges it between sidebar (0.245) and canvas (0.20). Per-theme overrides carry the brand hue + chroma (Exxat One 0.025, Prism 0.030, Assessment 0.025, custom `max(0.020, c·0.20)`).
683
+ 3. **Dark surface ladder is now** `--background` 0.20 → `--secondary-panel-bg` 0.22 → `--card` 0.225 → `--sidebar` / `--input-background` 0.245 → `--popover` 0.275 — clear, monotonic stepping with floating elements lifting further than inline ones.
684
+ - **Dark mode card / popover / input-background — softened to a subtle brand wash, not a tinted panel** (`globals.css`): The previous pass at `L=0.255 C=0.030` made cards read as a _separate tinted surface_ floating above canvas. Pulled lightness down to `L=0.225` (only 0.025 above `--background` at L=0.20) and chroma down to `C=0.017` (built-ins) / `max(0.015, calc(c*0.13))` (custom). Cards now read as the same surface family as canvas with a small elevation step and a whisper of brand hue — the saturated brand expression remains on `--brand-tint` and `--sidebar` where it belongs. Input background follows the same shift (L 0.245 / C 0.010). Foreground contrast unchanged (≥ 12:1).
685
+ - **Hydration warnings from the Cursor IDE browser preview** (`app/(app)/layout.tsx`, `components/templates/nested-secondary-panel-shell.tsx`, `components/ask-leo-sidebar.tsx`): The in-IDE browser MCP injects a `data-cursor-ref` attribute on top-level layout chrome _before_ React hydrates so it can target those nodes for click automation. React then warned about an attribute it didn't render. Added `suppressHydrationWarning` on just the three SSR-rendered shell roots that the MCP tags. The flag is scoped to _each element's own attributes only_ — children still hydrate normally and any real mismatch inside the panel still surfaces. Has zero effect outside the Cursor IDE preview.
686
+ - **Dark mode brand surfaces — every product chrome surface now reads as the brand per product** (`globals.css`):
687
+ 1. **`--brand-tint`** was never overridden in `.dark` or any `.theme-*.dark` block, so it cascaded down from the light-mode pale value (e.g. `oklch(0.97 0.02 343)` for Prism). Because the dark `--secondary-panel-bg` formula derived it as `color-mix(--card 32%, --brand-tint 68%)`, the question-bank Library secondary panel rendered as a pale rose / lavender pastel on dark canvas. Fixed by adding `--brand-tint` / `--brand-tint-light` / `--brand-tint-subtle` overrides at dark-mode lightness inside `.dark`, `.theme-one.dark`, `.theme-prism.dark`, `.theme-assessment.dark`, and `.theme-custom.dark`.
688
+ 2. **`--secondary-panel-bg` formula in `.dark`** rewritten from `color-mix(--card 32%, --brand-tint 68%)` to plain `var(--brand-tint)`. The old mix folded in `--card`'s neutral hue 270 — never overridden per theme in dark mode — so every product's secondary panel was pulled toward the same purple-neutral. Now the panel renders as a fully brand-tinted dark surface that varies clearly per product: Exxat One `#2c2a46` (navy-lavender), Prism `#402235` (wine), Assessment `#143525` (forest green).
689
+ 3. **`--brand-tint` / `--sidebar` chroma** raised from `0.014–0.015` to `0.04–0.055` at their dark-mode lightnesses. At L≈0.245–0.30 the OKLCH hue-perception threshold is much higher than at L≈0.97 (Helmholtz–Kohlrausch effect), so the previous chroma was below the perception floor — products looked identical even though their hues were set correctly. The new chroma is well within WCAG contrast bounds (foreground stays ≥ 11:1 on every variant).
690
+ 4. **`--card` / `--popover` / `--input-background`** were only set in base `.dark` at neutral hue 270, never overridden per theme. KPI tiles, popovers, and outlined surfaces therefore stayed dead grey no matter which product was active — directly visible on the dashboard's six KPI tiles in the custom-orange theme. Added per-theme overrides at L≈0.255 with chroma 0.03 (built-ins) or `max(0.022, calc(c * 0.22))` (custom) at brand hue. Cards now render as a "darker version of the brand color" per product: Exxat One `#212131`, Prism `#2d1d27`, Assessment `#15271e`, custom-orange `#2f1e16`.
691
+ - **Dark canvas brand cohesion** (`globals.css`): `--background` chroma in every `.theme-*.dark` block bumped from `0.008` to `0.014`. At L 0.20 the previous chroma sat below the OKLCH hue-perception threshold, so the canvas read as dead-neutral grey regardless of the brand hue. The new value gives the canvas a perceptible whisper of brand chroma without affecting text contrast (foreground stays ≥ 12:1 against background).
37
692
  - **`Sidebar`**: Read `sidebar_state` on the server for `defaultOpen` so the documents **Resources** heading and rail chrome match the first client paint (fixes hydration warnings). Skip redundant cookie restore when state already matches.
38
693
  - **`TablePropertiesDrawer`**: Portaled **Add filter / sort / rule** menus use `z-[90]` above the properties sheet (`z-[80]`); `Sheet` and dropdowns use `modal={false}`; filter updates apply synchronously (no `startTransition` deferral). Drawer button routes column/display handlers through refs for the portaled sheet.
39
694
 
@@ -60,7 +715,7 @@ After the user bumps `@exxatdesignux/ui`, do this in order:
60
715
 
61
716
  ### Changed
62
717
 
63
- - **Tokens**: `globals.css` / `theme.css` refinements and starter **`template/`** parity with the web app (layout, Question bank hub chrome, navigation).
718
+ - **Tokens**: `globals.css` refinements and starter **`template/`** parity with the web app (layout, Question bank hub chrome, navigation). _(Note: `theme.css` was a duplicate of `globals.css` and has been removed — see [`0003-globals-css-canonical.md`](../../apps/web/docs/migrations/0003-globals-css-canonical.md).)_
64
719
  - **Consumer extras**: Cursor skills + pattern docs refreshed for collaboration / Question bank hub header.
65
720
 
66
721
  ### Chore (monorepo)