@exxatdesignux/ui 0.2.19 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/CHANGELOG.md +60 -7
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +42 -7
  4. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
  5. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
  6. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
  7. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
  8. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
  9. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
  10. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
  11. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
  12. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
  13. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
  14. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
  15. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
  16. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
  17. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
  18. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
  19. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
  20. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
  21. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  23. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  24. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  25. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  26. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  27. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  28. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
  29. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
  30. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
  31. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
  32. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
  33. package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
  34. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +4 -15
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
  39. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  40. package/consumer-extras/handbook/glossary.md +57 -0
  41. package/consumer-extras/handbook/reference-implementations.md +126 -0
  42. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  43. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  44. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  45. package/consumer-extras/patterns/data-views-pattern.md +17 -54
  46. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  47. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  48. package/dist/components/data-table/filter-date-calendar.js +280 -0
  49. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  50. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  51. package/dist/components/data-table/filter-text-value-input.js +561 -0
  52. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  53. package/dist/components/data-table/index.d.ts +45 -0
  54. package/dist/components/data-table/index.js +3085 -0
  55. package/dist/components/data-table/index.js.map +1 -0
  56. package/dist/components/data-table/pagination.d.ts +28 -0
  57. package/dist/components/data-table/pagination.js +3264 -0
  58. package/dist/components/data-table/pagination.js.map +1 -0
  59. package/dist/components/data-table/types.d.ts +84 -0
  60. package/dist/components/data-table/types.js +3 -0
  61. package/dist/components/data-table/types.js.map +1 -0
  62. package/dist/components/data-table/use-table-state.d.ts +116 -0
  63. package/dist/components/data-table/use-table-state.js +670 -0
  64. package/dist/components/data-table/use-table-state.js.map +1 -0
  65. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  66. package/dist/components/data-views/board-card-primitives.js +84 -0
  67. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  68. package/dist/components/data-views/data-row-list.d.ts +33 -0
  69. package/dist/components/data-views/data-row-list.js +106 -0
  70. package/dist/components/data-views/data-row-list.js.map +1 -0
  71. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  72. package/dist/components/data-views/finder-panel-view.js +388 -0
  73. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  74. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  75. package/dist/components/data-views/folder-grid-view.js +58 -0
  76. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  77. package/dist/components/data-views/hub-table.d.ts +167 -0
  78. package/dist/components/data-views/hub-table.js +5561 -0
  79. package/dist/components/data-views/hub-table.js.map +1 -0
  80. package/dist/components/data-views/index.d.ts +27 -0
  81. package/dist/components/data-views/index.js +6575 -0
  82. package/dist/components/data-views/index.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  84. package/dist/components/data-views/list-page-board-card.js +264 -0
  85. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  86. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  87. package/dist/components/data-views/list-page-board-template.js +137 -0
  88. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  89. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  90. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  91. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  93. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  94. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  96. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  97. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  98. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  99. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  100. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  102. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  103. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  104. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  105. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  106. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  107. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  108. package/dist/components/data-views/os-folder-glyph.js +104 -0
  109. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  110. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  111. package/dist/components/data-views/outline-tree-menu.js +131 -0
  112. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  113. package/dist/components/table-properties/column-row.d.ts +22 -0
  114. package/dist/components/table-properties/column-row.js +153 -0
  115. package/dist/components/table-properties/column-row.js.map +1 -0
  116. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  117. package/dist/components/table-properties/draggable-list.js +53 -0
  118. package/dist/components/table-properties/draggable-list.js.map +1 -0
  119. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  120. package/dist/components/table-properties/drawer-button.js +2748 -0
  121. package/dist/components/table-properties/drawer-button.js.map +1 -0
  122. package/dist/components/table-properties/drawer.d.ts +100 -0
  123. package/dist/components/table-properties/drawer.js +2595 -0
  124. package/dist/components/table-properties/drawer.js.map +1 -0
  125. package/dist/components/table-properties/filter-card.d.ts +24 -0
  126. package/dist/components/table-properties/filter-card.js +854 -0
  127. package/dist/components/table-properties/filter-card.js.map +1 -0
  128. package/dist/components/table-properties/index.d.ts +14 -0
  129. package/dist/components/table-properties/index.js +2768 -0
  130. package/dist/components/table-properties/index.js.map +1 -0
  131. package/dist/components/table-properties/sort-card.d.ts +20 -0
  132. package/dist/components/table-properties/sort-card.js +102 -0
  133. package/dist/components/table-properties/sort-card.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  135. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  136. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  137. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  138. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  139. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  140. package/dist/components/templates/index.d.ts +9 -0
  141. package/dist/components/templates/index.js +2720 -0
  142. package/dist/components/templates/index.js.map +1 -0
  143. package/dist/components/templates/list-page.d.ts +83 -0
  144. package/dist/components/templates/list-page.js +2433 -0
  145. package/dist/components/templates/list-page.js.map +1 -0
  146. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  147. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  148. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  149. package/dist/components/ui/accordion.d.ts +10 -0
  150. package/dist/components/ui/accordion.js +74 -0
  151. package/dist/components/ui/accordion.js.map +1 -0
  152. package/dist/components/ui/alert-dialog.d.ts +37 -0
  153. package/dist/components/ui/alert-dialog.js +201 -0
  154. package/dist/components/ui/alert-dialog.js.map +1 -0
  155. package/dist/components/ui/avatar.d.ts +84 -0
  156. package/dist/components/ui/avatar.js +328 -0
  157. package/dist/components/ui/avatar.js.map +1 -0
  158. package/dist/components/ui/badge.d.ts +13 -0
  159. package/dist/components/ui/badge.js +49 -0
  160. package/dist/components/ui/badge.js.map +1 -0
  161. package/dist/components/ui/banner.d.ts +62 -0
  162. package/dist/components/ui/banner.js +364 -0
  163. package/dist/components/ui/banner.js.map +1 -0
  164. package/dist/components/ui/breadcrumb.d.ts +14 -0
  165. package/dist/components/ui/breadcrumb.js +114 -0
  166. package/dist/components/ui/breadcrumb.js.map +1 -0
  167. package/dist/components/ui/button.d.ts +16 -0
  168. package/dist/components/ui/button.js +59 -0
  169. package/dist/components/ui/button.js.map +1 -0
  170. package/dist/components/ui/calendar.d.ts +13 -0
  171. package/dist/components/ui/calendar.js +238 -0
  172. package/dist/components/ui/calendar.js.map +1 -0
  173. package/dist/components/ui/card.d.ts +14 -0
  174. package/dist/components/ui/card.js +102 -0
  175. package/dist/components/ui/card.js.map +1 -0
  176. package/dist/components/ui/chart.d.ts +58 -0
  177. package/dist/components/ui/chart.js +292 -0
  178. package/dist/components/ui/chart.js.map +1 -0
  179. package/dist/components/ui/checkbox.d.ts +23 -0
  180. package/dist/components/ui/checkbox.js +155 -0
  181. package/dist/components/ui/checkbox.js.map +1 -0
  182. package/dist/components/ui/coach-mark.d.ts +27 -0
  183. package/dist/components/ui/coach-mark.js +306 -0
  184. package/dist/components/ui/coach-mark.js.map +1 -0
  185. package/dist/components/ui/collapsible.d.ts +8 -0
  186. package/dist/components/ui/collapsible.js +35 -0
  187. package/dist/components/ui/collapsible.js.map +1 -0
  188. package/dist/components/ui/command.d.ts +36 -0
  189. package/dist/components/ui/command.js +274 -0
  190. package/dist/components/ui/command.js.map +1 -0
  191. package/dist/components/ui/context-menu.d.ts +32 -0
  192. package/dist/components/ui/context-menu.js +245 -0
  193. package/dist/components/ui/context-menu.js.map +1 -0
  194. package/dist/components/ui/date-picker-field.d.ts +38 -0
  195. package/dist/components/ui/date-picker-field.js +550 -0
  196. package/dist/components/ui/date-picker-field.js.map +1 -0
  197. package/dist/components/ui/dialog.d.ts +22 -0
  198. package/dist/components/ui/dialog.js +200 -0
  199. package/dist/components/ui/dialog.js.map +1 -0
  200. package/dist/components/ui/dot-pattern.d.ts +21 -0
  201. package/dist/components/ui/dot-pattern.js +139 -0
  202. package/dist/components/ui/dot-pattern.js.map +1 -0
  203. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  204. package/dist/components/ui/drag-handle-grip.js +15 -0
  205. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  206. package/dist/components/ui/drawer.d.ts +16 -0
  207. package/dist/components/ui/drawer.js +125 -0
  208. package/dist/components/ui/drawer.js.map +1 -0
  209. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  210. package/dist/components/ui/dropdown-menu.js +353 -0
  211. package/dist/components/ui/dropdown-menu.js.map +1 -0
  212. package/dist/components/ui/export-drawer.d.ts +11 -0
  213. package/dist/components/ui/export-drawer.js +1658 -0
  214. package/dist/components/ui/export-drawer.js.map +1 -0
  215. package/dist/components/ui/field.d.ts +30 -0
  216. package/dist/components/ui/field.js +249 -0
  217. package/dist/components/ui/field.js.map +1 -0
  218. package/dist/components/ui/form.d.ts +28 -0
  219. package/dist/components/ui/form.js +110 -0
  220. package/dist/components/ui/form.js.map +1 -0
  221. package/dist/components/ui/hover-card.d.ts +9 -0
  222. package/dist/components/ui/hover-card.js +43 -0
  223. package/dist/components/ui/hover-card.js.map +1 -0
  224. package/dist/components/ui/input-group.d.ts +20 -0
  225. package/dist/components/ui/input-group.js +219 -0
  226. package/dist/components/ui/input-group.js.map +1 -0
  227. package/dist/components/ui/input-mask.d.ts +39 -0
  228. package/dist/components/ui/input-mask.js +118 -0
  229. package/dist/components/ui/input-mask.js.map +1 -0
  230. package/dist/components/ui/input.d.ts +5 -0
  231. package/dist/components/ui/input.js +30 -0
  232. package/dist/components/ui/input.js.map +1 -0
  233. package/dist/components/ui/kbd.d.ts +20 -0
  234. package/dist/components/ui/kbd.js +45 -0
  235. package/dist/components/ui/kbd.js.map +1 -0
  236. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  237. package/dist/components/ui/key-metrics-context.js +26 -0
  238. package/dist/components/ui/key-metrics-context.js.map +1 -0
  239. package/dist/components/ui/key-metrics.d.ts +131 -0
  240. package/dist/components/ui/key-metrics.js +1015 -0
  241. package/dist/components/ui/key-metrics.js.map +1 -0
  242. package/dist/components/ui/label.d.ts +6 -0
  243. package/dist/components/ui/label.js +28 -0
  244. package/dist/components/ui/label.js.map +1 -0
  245. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  246. package/dist/components/ui/list-page-view-frame.js +24 -0
  247. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  248. package/dist/components/ui/page-header.d.ts +51 -0
  249. package/dist/components/ui/page-header.js +372 -0
  250. package/dist/components/ui/page-header.js.map +1 -0
  251. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  252. package/dist/components/ui/payment-card-fields.js +80 -0
  253. package/dist/components/ui/payment-card-fields.js.map +1 -0
  254. package/dist/components/ui/popover.d.ts +10 -0
  255. package/dist/components/ui/popover.js +47 -0
  256. package/dist/components/ui/popover.js.map +1 -0
  257. package/dist/components/ui/radio-group.d.ts +29 -0
  258. package/dist/components/ui/radio-group.js +190 -0
  259. package/dist/components/ui/radio-group.js.map +1 -0
  260. package/dist/components/ui/resizable.d.ts +16 -0
  261. package/dist/components/ui/resizable.js +51 -0
  262. package/dist/components/ui/resizable.js.map +1 -0
  263. package/dist/components/ui/scroll-area.d.ts +8 -0
  264. package/dist/components/ui/scroll-area.js +66 -0
  265. package/dist/components/ui/scroll-area.js.map +1 -0
  266. package/dist/components/ui/select.d.ts +18 -0
  267. package/dist/components/ui/select.js +186 -0
  268. package/dist/components/ui/select.js.map +1 -0
  269. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  270. package/dist/components/ui/selection-tile-grid.js +347 -0
  271. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  272. package/dist/components/ui/separator.d.ts +7 -0
  273. package/dist/components/ui/separator.js +33 -0
  274. package/dist/components/ui/separator.js.map +1 -0
  275. package/dist/components/ui/sheet.d.ts +18 -0
  276. package/dist/components/ui/sheet.js +181 -0
  277. package/dist/components/ui/sheet.js.map +1 -0
  278. package/dist/components/ui/sidebar.d.ts +94 -0
  279. package/dist/components/ui/sidebar.js +805 -0
  280. package/dist/components/ui/sidebar.js.map +1 -0
  281. package/dist/components/ui/skeleton.d.ts +5 -0
  282. package/dist/components/ui/skeleton.js +22 -0
  283. package/dist/components/ui/skeleton.js.map +1 -0
  284. package/dist/components/ui/slider.d.ts +7 -0
  285. package/dist/components/ui/slider.js +66 -0
  286. package/dist/components/ui/slider.js.map +1 -0
  287. package/dist/components/ui/sonner.d.ts +6 -0
  288. package/dist/components/ui/sonner.js +38 -0
  289. package/dist/components/ui/sonner.js.map +1 -0
  290. package/dist/components/ui/status-badge.d.ts +38 -0
  291. package/dist/components/ui/status-badge.js +77 -0
  292. package/dist/components/ui/status-badge.js.map +1 -0
  293. package/dist/components/ui/table.d.ts +13 -0
  294. package/dist/components/ui/table.js +115 -0
  295. package/dist/components/ui/table.js.map +1 -0
  296. package/dist/components/ui/tabs.d.ts +15 -0
  297. package/dist/components/ui/tabs.js +93 -0
  298. package/dist/components/ui/tabs.js.map +1 -0
  299. package/dist/components/ui/textarea.d.ts +6 -0
  300. package/dist/components/ui/textarea.js +25 -0
  301. package/dist/components/ui/textarea.js.map +1 -0
  302. package/dist/components/ui/tip.d.ts +12 -0
  303. package/dist/components/ui/tip.js +61 -0
  304. package/dist/components/ui/tip.js.map +1 -0
  305. package/dist/components/ui/toggle-group.d.ts +14 -0
  306. package/dist/components/ui/toggle-group.js +104 -0
  307. package/dist/components/ui/toggle-group.js.map +1 -0
  308. package/dist/components/ui/toggle-switch.d.ts +10 -0
  309. package/dist/components/ui/toggle-switch.js +33 -0
  310. package/dist/components/ui/toggle-switch.js.map +1 -0
  311. package/dist/components/ui/toggle.d.ts +13 -0
  312. package/dist/components/ui/toggle.js +51 -0
  313. package/dist/components/ui/toggle.js.map +1 -0
  314. package/dist/components/ui/tooltip.d.ts +10 -0
  315. package/dist/components/ui/tooltip.js +68 -0
  316. package/dist/components/ui/tooltip.js.map +1 -0
  317. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  318. package/dist/components/ui/view-segmented-control.js +167 -0
  319. package/dist/components/ui/view-segmented-control.js.map +1 -0
  320. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  321. package/dist/hooks/use-app-theme.d.ts +24 -0
  322. package/dist/hooks/use-app-theme.js +286 -0
  323. package/dist/hooks/use-app-theme.js.map +1 -0
  324. package/dist/hooks/use-coach-mark.d.ts +86 -0
  325. package/dist/hooks/use-coach-mark.js +218 -0
  326. package/dist/hooks/use-coach-mark.js.map +1 -0
  327. package/dist/hooks/use-mobile.d.ts +3 -0
  328. package/dist/hooks/use-mobile.js +29 -0
  329. package/dist/hooks/use-mobile.js.map +1 -0
  330. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  331. package/dist/hooks/use-mod-key-label.js +25 -0
  332. package/dist/hooks/use-mod-key-label.js.map +1 -0
  333. package/dist/index.d.ts +120 -0
  334. package/dist/index.js +13324 -0
  335. package/dist/index.js.map +1 -0
  336. package/dist/lib/compose-refs.d.ts +6 -0
  337. package/dist/lib/compose-refs.js +17 -0
  338. package/dist/lib/compose-refs.js.map +1 -0
  339. package/dist/lib/conditional-rule-match.d.ts +30 -0
  340. package/dist/lib/conditional-rule-match.js +66 -0
  341. package/dist/lib/conditional-rule-match.js.map +1 -0
  342. package/dist/lib/data-list-display-options.d.ts +26 -0
  343. package/dist/lib/data-list-display-options.js +14 -0
  344. package/dist/lib/data-list-display-options.js.map +1 -0
  345. package/dist/lib/data-list-view-registry.d.ts +2 -0
  346. package/dist/lib/data-list-view-registry.js +102 -0
  347. package/dist/lib/data-list-view-registry.js.map +1 -0
  348. package/dist/lib/data-list-view-surface.d.ts +2 -0
  349. package/dist/lib/data-list-view-surface.js +80 -0
  350. package/dist/lib/data-list-view-surface.js.map +1 -0
  351. package/dist/lib/data-list-view.d.ts +21 -0
  352. package/dist/lib/data-list-view.js +25 -0
  353. package/dist/lib/data-list-view.js.map +1 -0
  354. package/dist/lib/date-filter.d.ts +22 -0
  355. package/dist/lib/date-filter.js +61 -0
  356. package/dist/lib/date-filter.js.map +1 -0
  357. package/dist/lib/dev-log.d.ts +8 -0
  358. package/dist/lib/dev-log.js +10 -0
  359. package/dist/lib/dev-log.js.map +1 -0
  360. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  361. package/dist/lib/dropdown-menu-surface.js +6 -0
  362. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  363. package/dist/lib/editable-target.d.ts +12 -0
  364. package/dist/lib/editable-target.js +12 -0
  365. package/dist/lib/editable-target.js.map +1 -0
  366. package/dist/lib/list-page-table-properties.d.ts +35 -0
  367. package/dist/lib/list-page-table-properties.js +81 -0
  368. package/dist/lib/list-page-table-properties.js.map +1 -0
  369. package/dist/lib/raf-throttle.d.ts +23 -0
  370. package/dist/lib/raf-throttle.js +27 -0
  371. package/dist/lib/raf-throttle.js.map +1 -0
  372. package/dist/lib/row-height.d.ts +16 -0
  373. package/dist/lib/row-height.js +10 -0
  374. package/dist/lib/row-height.js.map +1 -0
  375. package/dist/lib/table-properties-types.d.ts +83 -0
  376. package/dist/lib/table-properties-types.js +19 -0
  377. package/dist/lib/table-properties-types.js.map +1 -0
  378. package/dist/lib/utils.d.ts +5 -0
  379. package/dist/lib/utils.js +11 -0
  380. package/dist/lib/utils.js.map +1 -0
  381. package/package.json +83 -19
  382. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  383. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  384. package/src/components/data-table/index.tsx +1678 -0
  385. package/src/components/data-table/pagination.tsx +255 -0
  386. package/src/components/data-table/types.ts +96 -0
  387. package/src/components/data-table/use-table-state.ts +767 -0
  388. package/src/components/data-views/board-card-primitives.tsx +93 -0
  389. package/src/components/data-views/data-row-list.tsx +183 -0
  390. package/src/components/data-views/finder-panel-view.tsx +405 -0
  391. package/src/components/data-views/folder-grid-view.tsx +86 -0
  392. package/src/components/data-views/hub-table.tsx +498 -0
  393. package/src/components/data-views/index.ts +28 -0
  394. package/src/components/data-views/list-page-board-card.tsx +192 -0
  395. package/src/components/data-views/list-page-board-template.tsx +122 -0
  396. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  397. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  398. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  399. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  400. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  401. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  402. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  403. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  404. package/src/components/table-properties/column-row.tsx +90 -0
  405. package/src/components/table-properties/draggable-list.ts +54 -0
  406. package/src/components/table-properties/drawer-button.tsx +300 -0
  407. package/src/components/table-properties/drawer.tsx +1148 -0
  408. package/src/components/table-properties/filter-card.tsx +251 -0
  409. package/src/components/table-properties/index.ts +36 -0
  410. package/src/components/table-properties/sort-card.tsx +63 -0
  411. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  412. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  413. package/src/components/templates/index.ts +33 -0
  414. package/src/components/templates/list-page.tsx +602 -0
  415. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  416. package/src/components/ui/accordion.tsx +92 -0
  417. package/src/components/ui/alert-dialog.tsx +221 -0
  418. package/src/components/ui/avatar.tsx +13 -2
  419. package/src/components/ui/banner.tsx +2 -2
  420. package/src/components/ui/button.tsx +4 -4
  421. package/src/components/ui/calendar.tsx +1 -1
  422. package/src/components/ui/coach-mark.tsx +1 -1
  423. package/src/components/ui/context-menu.tsx +291 -0
  424. package/src/components/ui/date-picker-field.tsx +2 -2
  425. package/src/components/ui/dot-pattern.tsx +183 -0
  426. package/src/components/ui/export-drawer.tsx +375 -0
  427. package/src/components/ui/hover-card.tsx +66 -0
  428. package/src/components/ui/key-metrics-context.tsx +78 -0
  429. package/src/components/ui/key-metrics.tsx +1133 -0
  430. package/src/components/ui/list-page-view-frame.tsx +64 -0
  431. package/src/components/ui/page-header.tsx +244 -0
  432. package/src/components/ui/payment-card-fields.tsx +2 -2
  433. package/src/components/ui/resizable.tsx +68 -0
  434. package/src/components/ui/scroll-area.tsx +72 -0
  435. package/src/components/ui/selection-tile-grid.tsx +9 -2
  436. package/src/components/ui/sidebar.tsx +84 -12
  437. package/src/components/ui/slider.tsx +83 -0
  438. package/src/globals.css +2201 -7
  439. package/src/globals.d.ts +20 -0
  440. package/src/index.ts +68 -1
  441. package/src/lib/conditional-rule-match.ts +119 -0
  442. package/src/lib/data-list-display-options.ts +35 -0
  443. package/src/lib/data-list-view-registry.ts +104 -0
  444. package/src/lib/data-list-view-surface.ts +83 -0
  445. package/src/lib/data-list-view.ts +47 -0
  446. package/src/lib/dev-log.ts +10 -0
  447. package/src/lib/editable-target.ts +20 -0
  448. package/src/lib/list-page-table-properties.ts +48 -0
  449. package/src/lib/raf-throttle.ts +45 -0
  450. package/src/lib/row-height.ts +19 -0
  451. package/src/lib/table-properties-types.ts +98 -0
  452. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  453. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  454. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  455. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  456. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  457. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  458. package/template/AGENTS.md +104 -78
  459. package/template/app/(app)/dashboard/loading.tsx +15 -3
  460. package/template/app/(app)/dashboard/page.tsx +14 -2
  461. package/template/app/(app)/examples/page.tsx +0 -2
  462. package/template/app/(app)/layout.tsx +17 -4
  463. package/template/app/(app)/loading.tsx +18 -1
  464. package/template/app/(app)/question-bank/find/page.tsx +1 -2
  465. package/template/app/(app)/question-bank/layout.tsx +1 -1
  466. package/template/app/(app)/question-bank/library/page.tsx +1 -2
  467. package/template/app/(app)/question-bank/list/page.tsx +1 -2
  468. package/template/app/(app)/question-bank/new/page.tsx +15 -20
  469. package/template/app/(app)/question-bank/page.tsx +1 -2
  470. package/template/app/(app)/settings/page.tsx +5 -4
  471. package/template/app/globals.css +14 -16
  472. package/template/components/ask-leo-sidebar.tsx +5 -1
  473. package/template/components/brand-color-picker.tsx +2 -2
  474. package/template/components/charts-overview.tsx +1 -1
  475. package/template/components/compliance-board-view.tsx +142 -0
  476. package/template/components/compliance-client.tsx +92 -0
  477. package/template/components/compliance-page-header.tsx +89 -0
  478. package/template/components/compliance-table.tsx +468 -0
  479. package/template/components/dashboard-report-charts.tsx +1 -1
  480. package/template/components/dashboard-tabs.tsx +1 -1
  481. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  482. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  483. package/template/components/data-table/index.tsx +1 -1634
  484. package/template/components/data-table/pagination.tsx +1 -255
  485. package/template/components/data-table/types.ts +1 -94
  486. package/template/components/data-table/use-table-state.test.ts +420 -0
  487. package/template/components/data-table/use-table-state.ts +1 -758
  488. package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
  489. package/template/components/data-view-dashboard-charts-team.tsx +971 -0
  490. package/template/components/data-view-dashboard-charts.tsx +1503 -0
  491. package/template/components/data-views/board-card-primitives.tsx +1 -93
  492. package/template/components/data-views/data-row-list.tsx +1 -183
  493. package/template/components/data-views/finder-panel-view.tsx +1 -405
  494. package/template/components/data-views/folder-grid-view.tsx +1 -86
  495. package/template/components/data-views/hub-table.tsx +1 -0
  496. package/template/components/data-views/index.ts +50 -37
  497. package/template/components/data-views/list-page-board-card.tsx +1 -192
  498. package/template/components/data-views/list-page-board-template.tsx +1 -122
  499. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  500. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  501. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  502. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  503. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  504. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  505. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  506. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  507. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  508. package/template/components/export-drawer.test.tsx +71 -0
  509. package/template/components/export-drawer.tsx +1 -375
  510. package/template/components/exxat-product-logo.tsx +5 -5
  511. package/template/components/hub-tree-panel-view.tsx +2 -2
  512. package/template/components/invite-collaborators-drawer.tsx +3 -3
  513. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  514. package/template/components/key-metrics.tsx +1 -1063
  515. package/template/components/leo-insight-indicator.tsx +2 -2
  516. package/template/components/new-placement-back-btn.tsx +28 -0
  517. package/template/components/new-placement-form.tsx +942 -0
  518. package/template/components/new-question-composer.tsx +456 -408
  519. package/template/components/onboarding/index.ts +9 -0
  520. package/template/components/onboarding/onboarding-01.tsx +1 -1
  521. package/template/components/onboarding/onboarding-02.tsx +1 -1
  522. package/template/components/onboarding/onboarding-03.tsx +1 -1
  523. package/template/components/onboarding/onboarding-04.tsx +1 -1
  524. package/template/components/page-header.tsx +8 -226
  525. package/template/components/placement-board-card.tsx +250 -0
  526. package/template/components/placement-detail.tsx +438 -0
  527. package/template/components/placements-board-view.tsx +397 -0
  528. package/template/components/placements-client.tsx +220 -0
  529. package/template/components/placements-list-view.tsx +124 -0
  530. package/template/components/placements-page-header.tsx +166 -0
  531. package/template/components/placements-table-cells.test.tsx +22 -0
  532. package/template/components/placements-table-cells.tsx +173 -0
  533. package/template/components/placements-table-columns.tsx +210 -0
  534. package/template/components/placements-table.tsx +934 -0
  535. package/template/components/product-switcher.tsx +3 -4
  536. package/template/components/product-wordmark.tsx +2 -1
  537. package/template/components/question-bank-client.tsx +5 -5
  538. package/template/components/question-bank-hub-client.tsx +1 -1
  539. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  540. package/template/components/question-bank-secondary-nav.tsx +3 -3
  541. package/template/components/question-bank-table.tsx +541 -431
  542. package/template/components/rotations-empty-state.tsx +50 -0
  543. package/template/components/rotations-panel-activator.tsx +8 -0
  544. package/template/components/settings-appearance-card.tsx +3 -4
  545. package/template/components/settings-client.tsx +15 -59
  546. package/template/components/settings-form-row.tsx +4 -9
  547. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  548. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
  549. package/template/components/sidebar/index.ts +16 -0
  550. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  551. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
  552. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  553. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  554. package/template/components/site-header.tsx +1 -1
  555. package/template/components/sites-board-view.tsx +67 -0
  556. package/template/components/sites-client.tsx +154 -0
  557. package/template/components/sites-table.tsx +249 -0
  558. package/template/components/table-properties/column-row.tsx +1 -90
  559. package/template/components/table-properties/draggable-list.ts +1 -49
  560. package/template/components/table-properties/drawer-button.tsx +1 -262
  561. package/template/components/table-properties/drawer.tsx +1 -1166
  562. package/template/components/table-properties/filter-card.tsx +1 -251
  563. package/template/components/table-properties/sort-card.tsx +1 -59
  564. package/template/components/table-properties/types.ts +28 -71
  565. package/template/components/team-board-view.tsx +122 -0
  566. package/template/components/team-client.tsx +100 -0
  567. package/template/components/team-page-header.tsx +92 -0
  568. package/template/components/team-table.tsx +553 -0
  569. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  570. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  571. package/template/components/templates/list-page.tsx +1 -608
  572. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
  573. package/template/components/templates/new-focus-template.tsx +659 -0
  574. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  575. package/template/components/ui/accordion.tsx +1 -0
  576. package/template/components/ui/alert-dialog.tsx +1 -0
  577. package/template/components/ui/context-menu.tsx +1 -0
  578. package/template/components/ui/dot-pattern.tsx +1 -183
  579. package/template/components/ui/hover-card.tsx +1 -0
  580. package/template/components/ui/resizable.tsx +1 -68
  581. package/template/components/ui/scroll-area.tsx +1 -0
  582. package/template/components/ui/slider.tsx +1 -0
  583. package/template/docs/blueprints/README.md +86 -0
  584. package/template/docs/blueprints/_template.md +91 -0
  585. package/template/docs/blueprints/board-card.md +123 -0
  586. package/template/docs/blueprints/data-table.md +139 -0
  587. package/template/docs/blueprints/key-metrics.md +128 -0
  588. package/template/docs/blueprints/list-page-template.md +123 -0
  589. package/template/docs/blueprints/page-header.md +130 -0
  590. package/template/docs/command-menu-pattern.md +1 -1
  591. package/template/docs/component-selection-guide.md +224 -0
  592. package/template/docs/components-audit-2026-05.md +158 -0
  593. package/template/docs/data-views-pattern.md +17 -54
  594. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  595. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  596. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  597. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  598. package/template/docs/migrations/README.md +100 -0
  599. package/template/docs/migrations/_template.md +64 -0
  600. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  601. package/template/docs/token-taxonomy.md +416 -0
  602. package/template/eslint.config.mjs +27 -0
  603. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  604. package/template/lib/command-menu-config.ts +0 -1
  605. package/template/lib/command-menu-search-data.ts +27 -11
  606. package/template/lib/compliance-supported-views.ts +10 -0
  607. package/template/lib/conditional-rule-match.ts +6 -97
  608. package/template/lib/data-list-display-options.ts +1 -49
  609. package/template/lib/data-list-view-registry.ts +1 -104
  610. package/template/lib/data-list-view-surface.ts +1 -83
  611. package/template/lib/data-list-view.ts +1 -47
  612. package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
  613. package/template/lib/data-view-dashboard-storage.ts +35 -38
  614. package/template/lib/dev-log.ts +1 -8
  615. package/template/lib/editable-target.ts +1 -10
  616. package/template/lib/list-page-table-properties.ts +1 -48
  617. package/template/lib/list-status-badges.ts +97 -4
  618. package/template/lib/mock/compliance-kpi.ts +61 -0
  619. package/template/lib/mock/compliance.ts +146 -0
  620. package/template/lib/mock/navigation.tsx +0 -9
  621. package/template/lib/mock/placements-kpi.ts +134 -0
  622. package/template/lib/mock/placements.ts +176 -0
  623. package/template/lib/mock/sites-directory.ts +16 -0
  624. package/template/lib/mock/sites-kpi.ts +25 -0
  625. package/template/lib/mock/team-kpi.ts +60 -0
  626. package/template/lib/mock/team.ts +118 -0
  627. package/template/lib/placement-board-card-layout.ts +79 -0
  628. package/template/lib/placements-supported-views.ts +12 -0
  629. package/template/lib/question-bank-supported-views.ts +0 -1
  630. package/template/lib/raf-throttle.ts +1 -45
  631. package/template/lib/row-height.ts +4 -10
  632. package/template/lib/sidebar-state-cookie.ts +11 -2
  633. package/template/lib/sites-supported-views.ts +10 -0
  634. package/template/lib/table-state-lifecycle.ts +2 -2
  635. package/template/lib/team-supported-views.ts +10 -0
  636. package/template/package.json +1 -0
  637. package/template/tests/setup.ts +25 -0
  638. package/consumer-extras/AGENTS.md +0 -76
  639. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  640. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  641. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  642. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  643. package/src/components/ui/button-group.tsx +0 -81
  644. package/src/theme.css +0 -16
  645. package/src/tokens/README.md +0 -15
  646. package/src/tokens/base.css +0 -337
  647. package/src/tokens/high-contrast.css +0 -1195
  648. package/src/tokens/layers.css +0 -224
  649. package/src/tokens/tailwind-bridge.css +0 -118
  650. package/src/tokens/themes.css +0 -201
  651. package/template/app/(app)/data-list/layout.tsx +0 -43
  652. package/template/app/(app)/data-list/page.tsx +0 -10
  653. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  654. package/template/components/app-route-loading.tsx +0 -14
  655. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  656. package/template/components/dashboard-onboarding.tsx +0 -21
  657. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  658. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  659. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  660. package/template/components/list-hub-board-view.tsx +0 -68
  661. package/template/components/list-hub-client.tsx +0 -186
  662. package/template/components/list-hub-list-view.tsx +0 -36
  663. package/template/components/list-hub-panel-activator.tsx +0 -8
  664. package/template/components/list-hub-secondary-nav.tsx +0 -121
  665. package/template/components/list-hub-table.tsx +0 -336
  666. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  667. package/template/components/question-bank-list-view.tsx +0 -53
  668. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  669. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  670. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  671. package/template/components/secondary-panels/registry.tsx +0 -15
  672. package/template/components/section-cards.tsx +0 -106
  673. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  674. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  675. package/template/components/templates/page-loading-shell.tsx +0 -262
  676. package/template/components/ui/button-group.tsx +0 -1
  677. package/template/docs/consumer-app-pattern.md +0 -39
  678. package/template/docs/focused-workflow-page-pattern.md +0 -84
  679. package/template/lib/list-hub-nav.ts +0 -121
  680. package/template/lib/mock/list-hub-directory.ts +0 -27
  681. package/template/lib/mock/list-hub-kpi.ts +0 -27
  682. package/template/lib/page-loading-variant.ts +0 -40
  683. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  684. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  685. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  686. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  687. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  688. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
@@ -0,0 +1,388 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { GripVertical } from 'lucide-react';
6
+ import { Panel, Group, Separator } from 'react-resizable-panels';
7
+ import { jsxs, jsx } from 'react/jsx-runtime';
8
+
9
+ function cn(...inputs) {
10
+ return twMerge(clsx(inputs));
11
+ }
12
+ function ResizablePanelGroup({
13
+ direction = "horizontal",
14
+ className,
15
+ ...props
16
+ }) {
17
+ return /* @__PURE__ */ jsx(
18
+ Group,
19
+ {
20
+ orientation: direction,
21
+ className: cn(
22
+ "flex h-full w-full",
23
+ direction === "vertical" && "flex-col",
24
+ className
25
+ ),
26
+ ...props
27
+ }
28
+ );
29
+ }
30
+ var ResizablePanel = Panel;
31
+ function ResizableHandle({ withHandle, className, ...props }) {
32
+ return /* @__PURE__ */ jsx(
33
+ Separator,
34
+ {
35
+ className: cn(
36
+ // Base — horizontal handle (between side-by-side panels)
37
+ "relative flex w-1 shrink-0 cursor-col-resize items-center justify-center bg-border/60",
38
+ "transition-colors hover:bg-border active:bg-primary/30",
39
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
40
+ // Vertical handle (between stacked panels)
41
+ "data-[orientation=vertical]:h-1 data-[orientation=vertical]:w-full data-[orientation=vertical]:cursor-row-resize data-[orientation=vertical]:flex-row",
42
+ className
43
+ ),
44
+ ...props,
45
+ children: withHandle && /* @__PURE__ */ jsx("div", { className: "z-10 flex h-5 w-3.5 items-center justify-center rounded-sm border border-border bg-background shadow-sm", children: /* @__PURE__ */ jsx(GripVertical, { className: "h-3 w-3 text-muted-foreground" }) })
46
+ }
47
+ );
48
+ }
49
+ function ListPageTreeColumnHeader({
50
+ title,
51
+ trailing,
52
+ className
53
+ }) {
54
+ return /* @__PURE__ */ jsx("div", { className: cn("shrink-0 border-b border-border/50 bg-card px-3 py-2", className), children: /* @__PURE__ */ jsxs("div", { className: "flex h-9 items-center justify-between gap-2", children: [
55
+ /* @__PURE__ */ jsx("h3", { className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground", children: title }),
56
+ trailing ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-0.5", children: trailing }) : null
57
+ ] }) });
58
+ }
59
+ function ListPageSplitDetailsPlaceholder({
60
+ title = "Nothing selected",
61
+ description,
62
+ className
63
+ }) {
64
+ return /* @__PURE__ */ jsxs(
65
+ "div",
66
+ {
67
+ className: cn(
68
+ "flex h-full min-h-0 flex-col items-center justify-center bg-card px-6 py-10 text-center",
69
+ className
70
+ ),
71
+ children: [
72
+ /* @__PURE__ */ jsx("div", { className: "mb-4 flex size-14 items-center justify-center rounded-2xl border border-dashed border-border/70 bg-card", children: /* @__PURE__ */ jsx(
73
+ "i",
74
+ {
75
+ className: "fa-light fa-sidebar text-[1.65rem] leading-none text-muted-foreground/70",
76
+ "aria-hidden": "true"
77
+ }
78
+ ) }),
79
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: title }),
80
+ description ? /* @__PURE__ */ jsx("div", { className: "mt-1.5 max-w-[16rem] text-xs leading-relaxed text-muted-foreground", children: description }) : null
81
+ ]
82
+ }
83
+ );
84
+ }
85
+
86
+ // src/components/data-views/list-page-split-hub-tokens.ts
87
+ var LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS = "w-1 bg-border/40 hover:bg-brand/20 transition-colors";
88
+ var LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS = "flex min-h-0 min-w-0 flex-col bg-card";
89
+ var LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS = "flex min-h-0 min-w-0 flex-col bg-card";
90
+ function GroupsColumn({
91
+ groups,
92
+ selectedGroupId,
93
+ onSelect,
94
+ columnTitle
95
+ }) {
96
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
97
+ /* @__PURE__ */ jsx(ListPageTreeColumnHeader, { title: columnTitle }),
98
+ /* @__PURE__ */ jsx(
99
+ "div",
100
+ {
101
+ className: "min-h-0 flex-1 overflow-y-auto py-1",
102
+ role: "listbox",
103
+ "aria-label": "Group navigation",
104
+ "aria-multiselectable": "false",
105
+ children: groups.map((group) => {
106
+ const isSelected = group.id === selectedGroupId;
107
+ return /* @__PURE__ */ jsx("div", { className: "group flex items-center hover:bg-muted/50", children: /* @__PURE__ */ jsxs(
108
+ "button",
109
+ {
110
+ type: "button",
111
+ role: "option",
112
+ "aria-selected": isSelected,
113
+ onClick: () => onSelect(group.id),
114
+ className: cn(
115
+ "flex w-full flex-1 items-center gap-2 px-3 py-2 text-start text-sm transition-colors duration-75",
116
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
117
+ isSelected ? "bg-accent font-medium text-accent-foreground" : "text-foreground"
118
+ ),
119
+ children: [
120
+ group.accent ? /* @__PURE__ */ jsx("span", { className: cn("size-2 shrink-0 rounded-full", group.accent), "aria-hidden": "true" }) : group.icon ? /* @__PURE__ */ jsx(
121
+ "i",
122
+ {
123
+ className: cn(
124
+ "fa-light shrink-0 text-xs",
125
+ group.icon,
126
+ isSelected ? "text-accent-foreground" : "text-muted-foreground"
127
+ ),
128
+ "aria-hidden": "true"
129
+ }
130
+ ) : null,
131
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate leading-tight", children: group.label }),
132
+ /* @__PURE__ */ jsx(
133
+ "span",
134
+ {
135
+ className: cn(
136
+ "shrink-0 tabular-nums text-xs",
137
+ isSelected ? "text-accent-foreground/80" : "text-muted-foreground"
138
+ ),
139
+ children: group.count
140
+ }
141
+ )
142
+ ]
143
+ }
144
+ ) }, group.id);
145
+ })
146
+ }
147
+ )
148
+ ] });
149
+ }
150
+ function FinderGroupStrip({
151
+ groups,
152
+ selectedGroupId,
153
+ onSelect,
154
+ ariaLabel = "Scope"
155
+ }) {
156
+ return /* @__PURE__ */ jsx(
157
+ "div",
158
+ {
159
+ role: "toolbar",
160
+ "aria-label": ariaLabel,
161
+ className: "flex min-h-10 flex-wrap items-center gap-1.5 border-b border-border bg-card px-2 py-2",
162
+ children: groups.map((group) => {
163
+ const isSelected = group.id === selectedGroupId;
164
+ return /* @__PURE__ */ jsxs(
165
+ "button",
166
+ {
167
+ type: "button",
168
+ "aria-pressed": isSelected,
169
+ onClick: () => onSelect(group.id),
170
+ className: cn(
171
+ "inline-flex h-8 max-w-full min-w-0 shrink-0 items-center gap-1.5 rounded-lg border px-2.5 text-xs font-medium transition-colors",
172
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
173
+ isSelected ? "border-brand/40 bg-accent text-accent-foreground" : "border-transparent bg-background/80 text-foreground hover:bg-muted"
174
+ ),
175
+ children: [
176
+ group.accent ? /* @__PURE__ */ jsx("span", { className: cn("size-2 shrink-0 rounded-full", group.accent), "aria-hidden": "true" }) : group.icon ? /* @__PURE__ */ jsx(
177
+ "i",
178
+ {
179
+ className: cn(
180
+ "fa-light shrink-0 text-[11px]",
181
+ group.icon,
182
+ isSelected ? "text-accent-foreground" : "text-muted-foreground"
183
+ ),
184
+ "aria-hidden": "true"
185
+ }
186
+ ) : null,
187
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: group.label }),
188
+ /* @__PURE__ */ jsx(
189
+ "span",
190
+ {
191
+ className: cn(
192
+ "shrink-0 tabular-nums text-[11px]",
193
+ isSelected ? "text-accent-foreground/85" : "text-muted-foreground"
194
+ ),
195
+ children: group.count
196
+ }
197
+ )
198
+ ]
199
+ },
200
+ group.id
201
+ );
202
+ })
203
+ }
204
+ );
205
+ }
206
+ function ListColumn({
207
+ rows,
208
+ getRowId,
209
+ selectedId,
210
+ renderListRow,
211
+ onSelect,
212
+ emptyList,
213
+ groupLabel,
214
+ columnTitle,
215
+ onAddItem
216
+ }) {
217
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
218
+ /* @__PURE__ */ jsx(ListPageTreeColumnHeader, { title: columnTitle }),
219
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
220
+ /* @__PURE__ */ jsx(
221
+ "div",
222
+ {
223
+ className: "min-h-0 flex-1 overflow-y-auto py-1",
224
+ role: "listbox",
225
+ "aria-label": `${groupLabel} items`,
226
+ "aria-multiselectable": "false",
227
+ children: rows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center justify-center px-4 py-12 text-center text-sm text-muted-foreground", children: emptyList ?? /* @__PURE__ */ jsx("p", { children: "No items in this group." }) }) : rows.map((row) => {
228
+ const id = getRowId(row);
229
+ const isSelected = id === selectedId;
230
+ return /* @__PURE__ */ jsx("div", { className: "group flex items-center hover:bg-muted/50", children: /* @__PURE__ */ jsx(
231
+ "button",
232
+ {
233
+ type: "button",
234
+ role: "option",
235
+ "aria-selected": isSelected,
236
+ onClick: () => onSelect(id),
237
+ className: cn(
238
+ "flex w-full flex-1 items-center gap-3 px-3 py-2 text-start text-sm transition-colors duration-75",
239
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset",
240
+ isSelected ? "bg-accent font-medium text-accent-foreground" : "text-foreground"
241
+ ),
242
+ children: renderListRow(row, isSelected)
243
+ }
244
+ ) }, id);
245
+ })
246
+ }
247
+ ),
248
+ onAddItem ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center justify-center border-t border-border/50 px-2 py-1.5", children: /* @__PURE__ */ jsx(
249
+ "button",
250
+ {
251
+ type: "button",
252
+ onClick: onAddItem,
253
+ className: "flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
254
+ "aria-label": `Add item to ${groupLabel}`,
255
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-plus text-xs", "aria-hidden": "true" })
256
+ }
257
+ ) }) : null
258
+ ] })
259
+ ] });
260
+ }
261
+ function DetailColumn({ children }) {
262
+ return /* @__PURE__ */ jsxs("div", { className: cn(LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS, "overflow-hidden"), children: [
263
+ /* @__PURE__ */ jsx(ListPageTreeColumnHeader, { title: "Details" }),
264
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children })
265
+ ] });
266
+ }
267
+ function DefaultEmptyDetail() {
268
+ return /* @__PURE__ */ jsx(ListPageSplitDetailsPlaceholder, { title: "Nothing selected" });
269
+ }
270
+ function FinderPanelView({
271
+ groups,
272
+ rows,
273
+ getRowId,
274
+ getRowGroupId,
275
+ renderListRow,
276
+ renderDetail,
277
+ emptyDetail,
278
+ emptyList,
279
+ defaultGroupId,
280
+ ariaLabel = "List and details",
281
+ autoSaveId = "finder-panel-view",
282
+ className,
283
+ style,
284
+ onAddItem,
285
+ embedded = false,
286
+ groupsColumnTitle = "Categories",
287
+ getListColumnTitle = (g) => g?.label ?? "Items"
288
+ }) {
289
+ const mergedStyle = React.useMemo(() => {
290
+ if (embedded) {
291
+ return { height: "100%", minHeight: 0, ...style };
292
+ }
293
+ return {
294
+ height: "calc(100vh - 280px)",
295
+ minHeight: 420,
296
+ ...style
297
+ };
298
+ }, [embedded, style]);
299
+ const firstGroupId = defaultGroupId ?? groups[0]?.id ?? "all";
300
+ const [selectedGroupId, setSelectedGroupId] = React.useState(firstGroupId);
301
+ const [selectedRowId, setSelectedRowId] = React.useState(null);
302
+ const visibleRows = React.useMemo(() => {
303
+ if (selectedGroupId === "all") return rows;
304
+ return rows.filter((r) => getRowGroupId(r) === selectedGroupId);
305
+ }, [rows, selectedGroupId, getRowGroupId]);
306
+ React.useEffect(() => {
307
+ setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null);
308
+ }, [selectedGroupId, visibleRows, getRowId]);
309
+ React.useEffect(() => {
310
+ if (selectedRowId !== null && !visibleRows.find((r) => getRowId(r) === selectedRowId)) {
311
+ setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null);
312
+ }
313
+ }, [visibleRows, selectedRowId, getRowId]);
314
+ const selectedRow = selectedRowId !== null ? visibleRows.find((r) => getRowId(r) === selectedRowId) ?? null : null;
315
+ const selectedGroup = groups.find((g) => g.id === selectedGroupId);
316
+ const listColumnTitle = getListColumnTitle(selectedGroup);
317
+ return /* @__PURE__ */ jsx(
318
+ "div",
319
+ {
320
+ className: cn(
321
+ embedded ? "flex h-full min-h-0 flex-col overflow-hidden" : "mx-4 mb-6 overflow-hidden rounded-xl border border-border bg-card lg:mx-6",
322
+ className
323
+ ),
324
+ style: mergedStyle,
325
+ "aria-label": ariaLabel,
326
+ children: /* @__PURE__ */ jsxs(
327
+ ResizablePanelGroup,
328
+ {
329
+ id: String(autoSaveId),
330
+ direction: "horizontal",
331
+ className: "h-full min-h-0 w-full flex-1",
332
+ children: [
333
+ /* @__PURE__ */ jsx(
334
+ ResizablePanel,
335
+ {
336
+ id: "groups",
337
+ defaultSize: "22%",
338
+ minSize: "16%",
339
+ maxSize: "32%",
340
+ className: LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,
341
+ children: /* @__PURE__ */ jsx(
342
+ GroupsColumn,
343
+ {
344
+ columnTitle: groupsColumnTitle,
345
+ groups,
346
+ selectedGroupId,
347
+ onSelect: (id) => setSelectedGroupId(id)
348
+ }
349
+ )
350
+ }
351
+ ),
352
+ /* @__PURE__ */ jsx(ResizableHandle, { withHandle: true, className: LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS }),
353
+ /* @__PURE__ */ jsx(
354
+ ResizablePanel,
355
+ {
356
+ id: "list",
357
+ defaultSize: "34%",
358
+ minSize: "22%",
359
+ maxSize: "48%",
360
+ className: LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,
361
+ children: /* @__PURE__ */ jsx(
362
+ ListColumn,
363
+ {
364
+ columnTitle: listColumnTitle,
365
+ rows: visibleRows,
366
+ getRowId,
367
+ selectedId: selectedRowId,
368
+ renderListRow,
369
+ onSelect: (id) => setSelectedRowId(id),
370
+ emptyList,
371
+ groupLabel: selectedGroup?.label ?? "All",
372
+ onAddItem
373
+ }
374
+ )
375
+ }
376
+ ),
377
+ /* @__PURE__ */ jsx(ResizableHandle, { withHandle: true, className: LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS }),
378
+ /* @__PURE__ */ jsx(ResizablePanel, { id: "detail", defaultSize: "44%", minSize: "30%", className: LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS, children: /* @__PURE__ */ jsx(DetailColumn, { children: selectedRow ? renderDetail(selectedRow) : emptyDetail ?? /* @__PURE__ */ jsx(DefaultEmptyDetail, {}) }) })
379
+ ]
380
+ }
381
+ )
382
+ }
383
+ );
384
+ }
385
+
386
+ export { FinderGroupStrip, FinderPanelView, GroupsColumn };
387
+ //# sourceMappingURL=finder-panel-view.js.map
388
+ //# sourceMappingURL=finder-panel-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/resizable.tsx","../../../src/components/data-views/list-page-tree-column-header.tsx","../../../src/components/data-views/list-page-split-details-placeholder.tsx","../../../src/components/data-views/list-page-split-hub-tokens.ts","../../../src/components/data-views/finder-panel-view.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"finder-panel-view.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { GripVertical } from \"lucide-react\"\nimport { Group, Panel, Separator } from \"react-resizable-panels\"\nimport type { GroupProps, PanelProps, SeparatorProps } from \"react-resizable-panels\"\n\nimport { cn } from \"../../lib/utils\"\n\n// ─── ResizablePanelGroup ──────────────────────────────────────────────────────\n\nexport type ResizablePanelGroupProps = Omit<GroupProps, \"orientation\"> & {\n direction?: \"horizontal\" | \"vertical\"\n}\n\nexport function ResizablePanelGroup({\n direction = \"horizontal\",\n className,\n ...props\n}: ResizablePanelGroupProps) {\n return (\n <Group\n orientation={direction}\n className={cn(\n \"flex h-full w-full\",\n direction === \"vertical\" && \"flex-col\",\n className,\n )}\n {...props}\n />\n )\n}\n\n// ─── ResizablePanel ───────────────────────────────────────────────────────────\n\nexport type ResizablePanelProps = PanelProps\n\nexport const ResizablePanel = Panel\n\n// ─── ResizableHandle ──────────────────────────────────────────────────────────\n\nexport type ResizableHandleProps = Omit<SeparatorProps, \"children\"> & {\n /** Render a visible grip icon on the handle. */\n withHandle?: boolean\n}\n\nexport function ResizableHandle({ withHandle, className, ...props }: ResizableHandleProps) {\n return (\n <Separator\n className={cn(\n // Base — horizontal handle (between side-by-side panels)\n \"relative flex w-1 shrink-0 cursor-col-resize items-center justify-center bg-border/60\",\n \"transition-colors hover:bg-border active:bg-primary/30\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n // Vertical handle (between stacked panels)\n \"data-[orientation=vertical]:h-1 data-[orientation=vertical]:w-full data-[orientation=vertical]:cursor-row-resize data-[orientation=vertical]:flex-row\",\n className,\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"z-10 flex h-5 w-3.5 items-center justify-center rounded-sm border border-border bg-background shadow-sm\">\n <GripVertical className=\"h-3 w-3 text-muted-foreground\" />\n </div>\n )}\n </Separator>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageTreeColumnHeaderProps {\n title: string\n /** Right side (e.g. icon buttons) — keep touch targets ≥ 24px */\n trailing?: React.ReactNode\n className?: string\n}\n\n/**\n * Shared left-column header for tree / outline surfaces — matches Question bank “Questions” bar.\n */\nexport function ListPageTreeColumnHeader({\n title,\n trailing,\n className,\n}: ListPageTreeColumnHeaderProps) {\n return (\n <div className={cn(\"shrink-0 border-b border-border/50 bg-card px-3 py-2\", className)}>\n <div className=\"flex h-9 items-center justify-between gap-2\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\">{title}</h3>\n {trailing ? (\n <div className=\"flex shrink-0 items-center gap-0.5\">{trailing}</div>\n ) : null}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageSplitDetailsPlaceholderProps {\n title?: string\n description?: React.ReactNode\n className?: string\n}\n\n/**\n * Empty right pane for split hubs — flat `bg-card` to match Miller / tree columns.\n */\nexport function ListPageSplitDetailsPlaceholder({\n title = \"Nothing selected\",\n description,\n className,\n}: ListPageSplitDetailsPlaceholderProps) {\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 flex-col items-center justify-center bg-card px-6 py-10 text-center\",\n className,\n )}\n >\n <div className=\"mb-4 flex size-14 items-center justify-center rounded-2xl border border-dashed border-border/70 bg-card\">\n <i\n className=\"fa-light fa-sidebar text-[1.65rem] leading-none text-muted-foreground/70\"\n aria-hidden=\"true\"\n />\n </div>\n <p className=\"text-sm font-medium text-foreground\">{title}</p>\n {description ? (\n <div className=\"mt-1.5 max-w-[16rem] text-xs leading-relaxed text-muted-foreground\">{description}</div>\n ) : null}\n </div>\n )\n}\n","/**\n * Shared layout tokens for list-hub split surfaces (Miller columns, tree + details).\n * Keeps Question bank panel / tree and generic `FinderPanelView` visually aligned.\n */\n\n/** `ResizableHandle` between miller / tree columns — matches Question bank panel. */\nexport const LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS =\n \"w-1 bg-border/40 hover:bg-brand/20 transition-colors\"\n\n/** Primary column stack (scope list, folder list, record list, …). */\nexport const LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n\n/** Right-hand inspector / detail column shell. */\nexport const LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n","\"use client\"\n\n/**\n * FinderPanelView — Miller-style 3-column split for list-page hubs.\n *\n * Visual shell matches Question bank panel (`ListPageTreeColumnHeader`, `LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS`,\n * shared resizable handles) — see `list-page-split-hub-tokens.ts`.\n */\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"../ui/resizable\"\nimport { ListPageTreeColumnHeader } from \"./list-page-tree-column-header\"\nimport { ListPageSplitDetailsPlaceholder } from \"./list-page-split-details-placeholder\"\nimport {\n LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,\n LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS,\n LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS,\n} from \"./list-page-split-hub-tokens\"\n\nexport interface FinderGroup {\n id: string\n label: string\n icon?: string\n accent?: string\n count: number\n}\n\nexport interface FinderPanelViewProps<T> {\n groups: FinderGroup[]\n rows: T[]\n getRowId: (row: T) => string | number\n getRowGroupId: (row: T) => string\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n renderDetail: (row: T) => React.ReactNode\n emptyDetail?: React.ReactNode\n emptyList?: React.ReactNode\n defaultGroupId?: string\n ariaLabel?: string\n autoSaveId?: string\n className?: string\n style?: React.CSSProperties\n onAddItem?: () => void\n /**\n * When true, omit outer margin, border, and card fill so the grid fits inside\n * `ListPageSplitHubChrome` (shared split surface across hubs).\n */\n embedded?: boolean\n /** Left column title (Question bank: “Categories”). */\n groupsColumnTitle?: string\n /** Middle column title; defaults from the active group label. */\n getListColumnTitle?: (activeGroup: FinderGroup | undefined) => string\n}\n\nexport function GroupsColumn({\n groups,\n selectedGroupId,\n onSelect,\n columnTitle,\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n columnTitle: string\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label=\"Group navigation\"\n aria-multiselectable=\"false\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <div key={group.id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-2 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-xs\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 flex-1 truncate leading-tight\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-xs\",\n isSelected ? \"text-accent-foreground/80\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\n/**\n * Horizontal scope strip (toolbar toggles). Optional: place above a hub body when you need\n * status scope without consuming a Finder column.\n */\nexport function FinderGroupStrip({\n groups,\n selectedGroupId,\n onSelect,\n ariaLabel = \"Scope\",\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n ariaLabel?: string\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label={ariaLabel}\n className=\"flex min-h-10 flex-wrap items-center gap-1.5 border-b border-border bg-card px-2 py-2\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <button\n key={group.id}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"inline-flex h-8 max-w-full min-w-0 shrink-0 items-center gap-1.5 rounded-lg border px-2.5 text-xs font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n isSelected\n ? \"border-brand/40 bg-accent text-accent-foreground\"\n : \"border-transparent bg-background/80 text-foreground hover:bg-muted\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-[11px]\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 truncate\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-[11px]\",\n isSelected ? \"text-accent-foreground/85\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n\nfunction ListColumn<T>({\n rows,\n getRowId,\n selectedId,\n renderListRow,\n onSelect,\n emptyList,\n groupLabel,\n columnTitle,\n onAddItem,\n}: {\n rows: T[]\n getRowId: (row: T) => string | number\n selectedId: string | number | null\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n onSelect: (id: string | number) => void\n emptyList?: React.ReactNode\n groupLabel: string\n columnTitle: string\n onAddItem?: () => void\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label={`${groupLabel} items`}\n aria-multiselectable=\"false\"\n >\n {rows.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center text-sm text-muted-foreground\">\n {emptyList ?? <p>No items in this group.</p>}\n </div>\n ) : (\n rows.map(row => {\n const id = getRowId(row)\n const isSelected = id === selectedId\n return (\n <div key={id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-3 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {renderListRow(row, isSelected)}\n </button>\n </div>\n )\n })\n )}\n </div>\n {onAddItem ? (\n <div className=\"flex shrink-0 items-center justify-center border-t border-border/50 px-2 py-1.5\">\n <button\n type=\"button\"\n onClick={onAddItem}\n className=\"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={`Add item to ${groupLabel}`}\n >\n <i className=\"fa-light fa-plus text-xs\" aria-hidden=\"true\" />\n </button>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction DetailColumn({ children }: { children: React.ReactNode }) {\n return (\n <div className={cn(LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS, \"overflow-hidden\")}>\n <ListPageTreeColumnHeader title=\"Details\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">{children}</div>\n </div>\n )\n}\n\nfunction DefaultEmptyDetail() {\n return (\n <ListPageSplitDetailsPlaceholder title=\"Nothing selected\" />\n )\n}\n\nexport function FinderPanelView<T>({\n groups,\n rows,\n getRowId,\n getRowGroupId,\n renderListRow,\n renderDetail,\n emptyDetail,\n emptyList,\n defaultGroupId,\n ariaLabel = \"List and details\",\n autoSaveId = \"finder-panel-view\",\n className,\n style,\n onAddItem,\n embedded = false,\n groupsColumnTitle = \"Categories\",\n getListColumnTitle = g => g?.label ?? \"Items\",\n}: FinderPanelViewProps<T>) {\n const mergedStyle = React.useMemo<React.CSSProperties>(() => {\n if (embedded) {\n return { height: \"100%\", minHeight: 0, ...style }\n }\n return {\n height: \"calc(100vh - 280px)\",\n minHeight: 420,\n ...style,\n }\n }, [embedded, style])\n const firstGroupId = defaultGroupId ?? groups[0]?.id ?? \"all\"\n const [selectedGroupId, setSelectedGroupId] = React.useState(firstGroupId)\n const [selectedRowId, setSelectedRowId] = React.useState<string | number | null>(null)\n\n const visibleRows = React.useMemo(() => {\n if (selectedGroupId === \"all\") return rows\n return rows.filter(r => getRowGroupId(r) === selectedGroupId)\n }, [rows, selectedGroupId, getRowGroupId])\n\n React.useEffect(() => {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }, [selectedGroupId, visibleRows, getRowId])\n\n React.useEffect(() => {\n if (selectedRowId !== null && !visibleRows.find(r => getRowId(r) === selectedRowId)) {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }\n }, [visibleRows, selectedRowId, getRowId])\n\n const selectedRow =\n selectedRowId !== null\n ? (visibleRows.find(r => getRowId(r) === selectedRowId) ?? null)\n : null\n\n const selectedGroup = groups.find(g => g.id === selectedGroupId)\n const listColumnTitle = getListColumnTitle(selectedGroup)\n\n return (\n <div\n className={cn(\n embedded\n ? \"flex h-full min-h-0 flex-col overflow-hidden\"\n : \"mx-4 mb-6 overflow-hidden rounded-xl border border-border bg-card lg:mx-6\",\n className,\n )}\n style={mergedStyle}\n aria-label={ariaLabel}\n >\n <ResizablePanelGroup\n id={String(autoSaveId)}\n direction=\"horizontal\"\n className=\"h-full min-h-0 w-full flex-1\"\n >\n <ResizablePanel\n id=\"groups\"\n defaultSize=\"22%\"\n minSize=\"16%\"\n maxSize=\"32%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <GroupsColumn\n columnTitle={groupsColumnTitle}\n groups={groups}\n selectedGroupId={selectedGroupId}\n onSelect={id => setSelectedGroupId(id)}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel\n id=\"list\"\n defaultSize=\"34%\"\n minSize=\"22%\"\n maxSize=\"48%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <ListColumn\n columnTitle={listColumnTitle}\n rows={visibleRows}\n getRowId={getRowId}\n selectedId={selectedRowId}\n renderListRow={renderListRow}\n onSelect={id => setSelectedRowId(id)}\n emptyList={emptyList}\n groupLabel={selectedGroup?.label ?? \"All\"}\n onAddItem={onAddItem}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel id=\"detail\" defaultSize=\"44%\" minSize=\"30%\" className={LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS}>\n <DetailColumn>\n {selectedRow\n ? renderDetail(selectedRow)\n : (emptyDetail ?? <DefaultEmptyDetail />)}\n </DetailColumn>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n )\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ interface FolderGridViewProps<T> {
5
+ rows: T[];
6
+ getRowId: (row: T) => string | number;
7
+ /** Render one tile — receives the row, returns a React node (typically a `<button>`). */
8
+ renderTile: (row: T) => React.ReactNode;
9
+ /** Shown when `rows` is empty. */
10
+ emptyContent?: React.ReactNode;
11
+ /** `aria-label` on the grid list. */
12
+ ariaLabel?: string;
13
+ className?: string;
14
+ /**
15
+ * When true, constrains the grid to a centered max width so folder tiles don’t stretch
16
+ * edge-to-edge on very wide viewports.
17
+ */
18
+ constrainWidth?: boolean;
19
+ }
20
+ declare function FolderGridView<T>({ rows, getRowId, renderTile, emptyContent, ariaLabel, className, constrainWidth, }: FolderGridViewProps<T>): react_jsx_runtime.JSX.Element;
21
+
22
+ export { FolderGridView, type FolderGridViewProps };
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function cn(...inputs) {
7
+ return twMerge(clsx(inputs));
8
+ }
9
+ var LIST_PAGE_VIEW_FRAME_GUTTER = "mx-4 mb-6 lg:mx-6";
10
+ var LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID = "max-w-6xl";
11
+ function ListPageViewFrame({
12
+ children,
13
+ className,
14
+ maxWidthClassName,
15
+ gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,
16
+ ...rest
17
+ }) {
18
+ return /* @__PURE__ */ jsx("div", { className: cn(gutterClassName, className), ...rest, children: maxWidthClassName ? /* @__PURE__ */ jsx("div", { className: cn("mx-auto w-full min-w-0", maxWidthClassName), children }) : children });
19
+ }
20
+ function FolderGridView({
21
+ rows,
22
+ getRowId,
23
+ renderTile,
24
+ emptyContent,
25
+ ariaLabel = "Folder view",
26
+ className,
27
+ constrainWidth = false
28
+ }) {
29
+ if (rows.length === 0) {
30
+ return /* @__PURE__ */ jsx(
31
+ ListPageViewFrame,
32
+ {
33
+ maxWidthClassName: constrainWidth ? LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID : void 0,
34
+ className: cn(className),
35
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center rounded-xl border border-dashed border-border py-16 text-sm text-muted-foreground", children: [
36
+ /* @__PURE__ */ jsx("i", { className: "fa-solid fa-grid-2 mb-3 text-3xl opacity-40", "aria-hidden": "true" }),
37
+ emptyContent ?? /* @__PURE__ */ jsx("p", { children: "No records found." })
38
+ ] })
39
+ }
40
+ );
41
+ }
42
+ return /* @__PURE__ */ jsx(ListPageViewFrame, { className: cn(className), children: /* @__PURE__ */ jsx(
43
+ "div",
44
+ {
45
+ className: cn(
46
+ "grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8",
47
+ constrainWidth && "mx-auto max-w-6xl"
48
+ ),
49
+ role: "list",
50
+ "aria-label": ariaLabel,
51
+ children: rows.map((row) => /* @__PURE__ */ jsx("div", { role: "listitem", children: renderTile(row) }, getRowId(row)))
52
+ }
53
+ ) });
54
+ }
55
+
56
+ export { FolderGridView };
57
+ //# sourceMappingURL=folder-grid-view.js.map
58
+ //# sourceMappingURL=folder-grid-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/list-page-view-frame.tsx","../../../src/components/data-views/folder-grid-view.tsx"],"names":["jsx"],"mappings":";;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACuBO,IAAM,2BAAA,GAA8B,mBAAA;AAGpC,IAAM,kCAAA,GAAqC,WAAA;AAgB3C,SAAS,iBAAA,CAAkB;AAAA,EAChC,QAAA;AAAA,EACA,SAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA,GAAkB,2BAAA;AAAA,EAClB,GAAG;AACL,CAAA,EAA2B;AACzB,EAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,eAAA,EAAiB,SAAS,GAAI,GAAG,IAAA,EACjD,8CACC,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,wBAAA,EAA0B,iBAAiB,CAAA,EAAI,QAAA,EAAS,IAE3E,QAAA,EAEJ,CAAA;AAEJ;ACnBO,SAAS,cAAA,CAAkB;AAAA,EAChC,IAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA,GAAY,aAAA;AAAA,EACZ,SAAA;AAAA,EACA,cAAA,GAAiB;AACnB,CAAA,EAA2B;AACzB,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,uBACEA,GAAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,iBAAA,EAAmB,iBAAiB,kCAAA,GAAqC,MAAA;AAAA,QACzE,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,QAEvB,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6HAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6CAAA,EAA8C,eAAY,MAAA,EAAO,CAAA;AAAA,UAC7E,YAAA,oBAAgBA,GAAAA,CAAC,GAAA,EAAA,EAAE,QAAA,EAAA,mBAAA,EAAiB;AAAA,SAAA,EACvC;AAAA;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,uBACEA,GAAAA,CAAC,iBAAA,EAAA,EAAkB,WAAW,EAAA,CAAG,SAAS,GACxC,QAAA,kBAAAA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,oGAAA;AAAA,QACA,cAAA,IAAkB;AAAA,OACpB;AAAA,MACA,IAAA,EAAK,MAAA;AAAA,MACL,YAAA,EAAY,SAAA;AAAA,MAEX,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,qBACRA,IAAC,KAAA,EAAA,EAAwB,IAAA,EAAK,UAAA,EAC3B,QAAA,EAAA,UAAA,CAAW,GAAG,CAAA,EAAA,EADP,QAAA,CAAS,GAAG,CAEtB,CACD;AAAA;AAAA,GACH,EACF,CAAA;AAEJ","file":"folder-grid-view.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\n/**\n * ListPageViewFrame — shared horizontal gutter + optional centered max-width\n * for list-hub **view bodies** (folder icon grid, finder panel chrome,\n * OS-style folder explorer, dashboard slices, etc.).\n *\n * MUST be used instead of ad-hoc `mx-4 lg:mx-6` + `mx-auto max-w-*` pairs on\n * each page — see `apps/web/AGENTS.md` §4.5 and\n * `.cursor/rules/exxat-list-page-view-shells.mdc`.\n *\n * MUST NOT wrap `DataTable` when its toolbar already applies the same inset\n * (avoid double gutter); use this for **non-table** view branches or\n * **sections below** the shared toolbar.\n *\n * Promotion note: this file lived at\n * `apps/web/components/data-views/list-page-view-frame.tsx` until\n * 2026-05-20. It moved into `@exxatdesignux/ui` because the gutter / max-\n * width contract is entity-agnostic and other consumers (a future docs\n * site, partner apps) need the same rhythm without dragging in the whole\n * `data-views/` family.\n */\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/** Default horizontal rhythm for view bodies under `ListPageTemplate` (matches `FolderGridView`). */\nexport const LIST_PAGE_VIEW_FRAME_GUTTER = \"mx-4 mb-6 lg:mx-6\"\n\n/** Typical max width for icon grids / dense tile views on ultra-wide monitors. */\nexport const LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID = \"max-w-6xl\"\n\n/** Slightly wider shell when a view includes toolbar + breadcrumbs + grid (e.g. OS folder explorer). */\nexport const LIST_PAGE_VIEW_FRAME_MAX_WIDE = \"max-w-7xl\"\n\nexport interface ListPageViewFrameProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n /**\n * When set, children are wrapped in `mx-auto w-full min-w-0` + this\n * max-width so the block stays centered inside the primary page column.\n */\n maxWidthClassName?: string\n /** Override outer gutter; default `LIST_PAGE_VIEW_FRAME_GUTTER`. */\n gutterClassName?: string\n}\n\nexport function ListPageViewFrame({\n children,\n className,\n maxWidthClassName,\n gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,\n ...rest\n}: ListPageViewFrameProps) {\n return (\n <div className={cn(gutterClassName, className)} {...rest}>\n {maxWidthClassName ? (\n <div className={cn(\"mx-auto w-full min-w-0\", maxWidthClassName)}>{children}</div>\n ) : (\n children\n )}\n </div>\n )\n}\n","\"use client\"\n\n/**\n * FolderGridView — generic icon-grid layout for any list-page hub.\n *\n * Handles the responsive CSS grid shell, empty state, and accessibility list role.\n * Pass a `renderTile` render-prop for domain-specific tile content\n * (Placements, Team, Rotations, etc.).\n *\n * Usage:\n * ```tsx\n * <FolderGridView\n * rows={placements}\n * getRowId={r => r.id}\n * renderTile={row => <PlacementFolderTile row={row} onClick={…} />}\n * ariaLabel=\"Placements folder view\"\n * />\n * ```\n */\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ListPageViewFrame,\n LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID,\n} from \"../ui/list-page-view-frame\"\n\nexport interface FolderGridViewProps<T> {\n rows: T[]\n getRowId: (row: T) => string | number\n /** Render one tile — receives the row, returns a React node (typically a `<button>`). */\n renderTile: (row: T) => React.ReactNode\n /** Shown when `rows` is empty. */\n emptyContent?: React.ReactNode\n /** `aria-label` on the grid list. */\n ariaLabel?: string\n className?: string\n /**\n * When true, constrains the grid to a centered max width so folder tiles don’t stretch\n * edge-to-edge on very wide viewports.\n */\n constrainWidth?: boolean\n}\n\nexport function FolderGridView<T>({\n rows,\n getRowId,\n renderTile,\n emptyContent,\n ariaLabel = \"Folder view\",\n className,\n constrainWidth = false,\n}: FolderGridViewProps<T>) {\n if (rows.length === 0) {\n return (\n <ListPageViewFrame\n maxWidthClassName={constrainWidth ? LIST_PAGE_VIEW_FRAME_MAX_ICON_GRID : undefined}\n className={cn(className)}\n >\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed border-border py-16 text-sm text-muted-foreground\">\n <i className=\"fa-solid fa-grid-2 mb-3 text-3xl opacity-40\" aria-hidden=\"true\" />\n {emptyContent ?? <p>No records found.</p>}\n </div>\n </ListPageViewFrame>\n )\n }\n\n return (\n <ListPageViewFrame className={cn(className)}>\n <div\n className={cn(\n \"grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8\",\n constrainWidth && \"mx-auto max-w-6xl\",\n )}\n role=\"list\"\n aria-label={ariaLabel}\n >\n {rows.map(row => (\n <div key={getRowId(row)} role=\"listitem\">\n {renderTile(row)}\n </div>\n ))}\n </div>\n </ListPageViewFrame>\n )\n}\n"]}