@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
@@ -0,0 +1,2720 @@
1
+ import * as React12 from 'react';
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { Slot, Label as Label$1, Checkbox as Checkbox$1, RadioGroup as RadioGroup$1, DropdownMenu as DropdownMenu$1, Dialog as Dialog$1, Tooltip as Tooltip$1, Popover as Popover$1 } from 'radix-ui';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+ import { useForm, FormProvider, Controller, useFormContext } from 'react-hook-form';
7
+ import { z } from 'zod';
8
+ import { zodResolver } from '@hookform/resolvers/zod';
9
+ import { cva } from 'class-variance-authority';
10
+ import { XIcon, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from 'lucide-react';
11
+ import { getDefaultClassNames, DayPicker } from 'react-day-picker';
12
+ import { useMaskInput } from 'use-mask-input';
13
+ import { motion } from 'motion/react';
14
+
15
+ // src/components/templates/list-page.tsx
16
+ function cn(...inputs) {
17
+ return twMerge(clsx(inputs));
18
+ }
19
+ function Tooltip({
20
+ ...props
21
+ }) {
22
+ return /* @__PURE__ */ jsx(Tooltip$1.Root, { "data-slot": "tooltip", ...props });
23
+ }
24
+ function TooltipTrigger({
25
+ className,
26
+ ...props
27
+ }) {
28
+ return /* @__PURE__ */ jsx(
29
+ Tooltip$1.Trigger,
30
+ {
31
+ "data-slot": "tooltip-trigger",
32
+ suppressHydrationWarning: true,
33
+ className: cn("cursor-pointer", className),
34
+ ...props
35
+ }
36
+ );
37
+ }
38
+ function TooltipContent({
39
+ className,
40
+ sideOffset = 0,
41
+ children,
42
+ ...props
43
+ }) {
44
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsxs(
45
+ Tooltip$1.Content,
46
+ {
47
+ "data-slot": "tooltip-content",
48
+ sideOffset,
49
+ className: cn(
50
+ "z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pe-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
51
+ className
52
+ ),
53
+ ...props,
54
+ children: [
55
+ children,
56
+ /* @__PURE__ */ jsx(Tooltip$1.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })
57
+ ]
58
+ }
59
+ ) });
60
+ }
61
+ function Tip({ label, children, side = "top" }) {
62
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
63
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children }),
64
+ /* @__PURE__ */ jsx(TooltipContent, { side, className: "flex flex-wrap items-center gap-1.5", children: label })
65
+ ] });
66
+ }
67
+
68
+ // src/lib/dev-log.ts
69
+ function devLog(...args) {
70
+ if (process.env.NODE_ENV === "development") {
71
+ console.log(...args);
72
+ }
73
+ }
74
+ var buttonVariants = cva(
75
+ "group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
76
+ {
77
+ variants: {
78
+ variant: {
79
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
80
+ outline: "border-input bg-background hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:bg-input/15 dark:hover:bg-input/25",
81
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
82
+ ghost: "hover:bg-interactive-hover hover:text-interactive-hover-foreground aria-expanded:bg-interactive-hover aria-expanded:text-interactive-hover-foreground dark:hover:bg-interactive-hover-subtle",
83
+ destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
84
+ link: "text-primary underline-offset-4 hover:underline"
85
+ },
86
+ size: {
87
+ default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5",
88
+ xs: "h-6 gap-1 px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3",
89
+ sm: "h-8 gap-1 px-3 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 [&_svg:not([class*='size-'])]:size-3.5",
90
+ lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pe-3.5 has-data-[icon=inline-start]:ps-3.5",
91
+ icon: "size-9",
92
+ "icon-xs": "size-6 in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
93
+ "icon-sm": "size-8 in-data-[slot=button-group]:rounded-lg",
94
+ "icon-lg": "size-10"
95
+ }
96
+ },
97
+ defaultVariants: {
98
+ variant: "default",
99
+ size: "default"
100
+ }
101
+ }
102
+ );
103
+ var Button = React12.forwardRef(({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
104
+ const Comp = asChild ? Slot.Root : "button";
105
+ return /* @__PURE__ */ jsx(
106
+ Comp,
107
+ {
108
+ ref,
109
+ "data-slot": "button",
110
+ "data-variant": variant,
111
+ "data-size": size,
112
+ className: cn(buttonVariants({ variant, size }), className),
113
+ ...props
114
+ }
115
+ );
116
+ });
117
+ Button.displayName = "Button";
118
+ var Label = React12.forwardRef(function Label2({ className, ...props }, ref) {
119
+ return /* @__PURE__ */ jsx(
120
+ Label$1.Root,
121
+ {
122
+ ref,
123
+ "data-slot": "label",
124
+ className: cn(
125
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
126
+ className
127
+ ),
128
+ ...props
129
+ }
130
+ );
131
+ });
132
+ var checkboxVariants = cva(
133
+ [
134
+ "peer relative box-border flex shrink-0 items-center justify-center self-center rounded-[4px] border border-input",
135
+ "outline-none transition-[color,box-shadow,transform,background-color,border-color] duration-150",
136
+ "motion-reduce:transition-none",
137
+ "group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2",
138
+ "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
139
+ "disabled:cursor-not-allowed disabled:opacity-50",
140
+ "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary",
141
+ "dark:bg-input/15 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
142
+ ].join(" "),
143
+ {
144
+ variants: {
145
+ variant: {
146
+ default: [
147
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary",
148
+ "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground dark:data-[state=indeterminate]:bg-primary dark:data-[state=indeterminate]:text-primary-foreground"
149
+ ].join(" "),
150
+ outline: [
151
+ "bg-background",
152
+ "data-[state=checked]:border-primary data-[state=checked]:bg-background data-[state=checked]:text-primary data-[state=checked]:ring-2 data-[state=checked]:ring-primary/25",
153
+ "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-background data-[state=indeterminate]:text-primary data-[state=indeterminate]:ring-2 data-[state=indeterminate]:ring-primary/25"
154
+ ].join(" "),
155
+ secondary: [
156
+ "data-[state=checked]:border-secondary data-[state=checked]:bg-secondary data-[state=checked]:text-secondary-foreground",
157
+ "data-[state=indeterminate]:border-secondary data-[state=indeterminate]:bg-secondary data-[state=indeterminate]:text-secondary-foreground"
158
+ ].join(" "),
159
+ success: [
160
+ "data-[state=checked]:border-chart-2 data-[state=checked]:bg-chart-2 data-[state=checked]:text-primary-foreground",
161
+ "data-[state=indeterminate]:border-chart-2 data-[state=indeterminate]:bg-chart-2 data-[state=indeterminate]:text-primary-foreground"
162
+ ].join(" "),
163
+ destructive: [
164
+ "data-[state=checked]:border-destructive data-[state=checked]:bg-destructive data-[state=checked]:text-destructive-foreground",
165
+ "data-[state=indeterminate]:border-destructive data-[state=indeterminate]:bg-destructive data-[state=indeterminate]:text-destructive-foreground"
166
+ ].join(" "),
167
+ warning: [
168
+ "data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500 data-[state=checked]:text-amber-950",
169
+ "data-[state=indeterminate]:border-amber-500 data-[state=indeterminate]:bg-amber-500 data-[state=indeterminate]:text-amber-950"
170
+ ].join(" "),
171
+ muted: [
172
+ "data-[state=checked]:border-muted-foreground/50 data-[state=checked]:bg-muted data-[state=checked]:text-foreground",
173
+ "data-[state=indeterminate]:border-muted-foreground/50 data-[state=indeterminate]:bg-muted data-[state=indeterminate]:text-foreground"
174
+ ].join(" ")
175
+ },
176
+ size: {
177
+ sm: "size-3.5 max-h-3.5 max-w-3.5 min-h-3.5 min-w-3.5 rounded-[3px] [&_[data-slot=checkbox-indicator]_i]:text-[10px]",
178
+ default: "size-4 max-h-4 max-w-4 min-h-4 min-w-4 [&_[data-slot=checkbox-indicator]_i]:text-xs",
179
+ lg: "size-5 max-h-5 max-w-5 min-h-5 min-w-5 rounded-[5px] [&_[data-slot=checkbox-indicator]_i]:text-sm"
180
+ },
181
+ motion: {
182
+ none: "",
183
+ pop: [
184
+ "motion-safe:active:scale-95",
185
+ "data-[state=checked]:motion-safe:scale-[1.04] data-[state=indeterminate]:motion-safe:scale-[1.04]"
186
+ ].join(" "),
187
+ glow: [
188
+ "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35",
189
+ "data-[state=indeterminate]:shadow-[0_0_0_3px] data-[state=indeterminate]:shadow-primary/35"
190
+ ].join(" "),
191
+ "pop-glow": [
192
+ "motion-safe:active:scale-95",
193
+ "data-[state=checked]:motion-safe:scale-[1.04] data-[state=indeterminate]:motion-safe:scale-[1.04]",
194
+ "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35",
195
+ "data-[state=indeterminate]:shadow-[0_0_0_3px] data-[state=indeterminate]:shadow-primary/35"
196
+ ].join(" ")
197
+ }
198
+ },
199
+ defaultVariants: {
200
+ variant: "default",
201
+ size: "default",
202
+ motion: "none"
203
+ }
204
+ }
205
+ );
206
+ var checkboxIndicatorVariants = cva("grid place-content-center text-current", {
207
+ variants: {
208
+ motion: {
209
+ none: "transition-none",
210
+ pop: "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150",
211
+ glow: "",
212
+ "pop-glow": "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150"
213
+ }
214
+ },
215
+ defaultVariants: {
216
+ motion: "none"
217
+ }
218
+ });
219
+ var Checkbox = React12.forwardRef(
220
+ function Checkbox2({ className, variant, size, motion: motion2, checked, ...props }, ref) {
221
+ const m = motion2 ?? "none";
222
+ return /* @__PURE__ */ jsx(
223
+ Checkbox$1.Root,
224
+ {
225
+ ref,
226
+ "data-slot": "checkbox",
227
+ "data-variant": variant ?? "default",
228
+ "data-motion": m,
229
+ checked,
230
+ className: cn(checkboxVariants({ variant, size, motion: m }), className),
231
+ ...props,
232
+ children: /* @__PURE__ */ jsx(
233
+ Checkbox$1.Indicator,
234
+ {
235
+ "data-slot": "checkbox-indicator",
236
+ className: checkboxIndicatorVariants({ motion: m }),
237
+ children: checked === "indeterminate" ? /* @__PURE__ */ jsx("i", { className: "fa-solid fa-minus text-current", "aria-hidden": "true" }) : /* @__PURE__ */ jsx("i", { className: "fa-solid fa-check text-current", "aria-hidden": "true" })
238
+ }
239
+ )
240
+ }
241
+ );
242
+ }
243
+ );
244
+ function Kbd({
245
+ className,
246
+ variant = "tile",
247
+ "aria-hidden": ariaHidden,
248
+ ...props
249
+ }) {
250
+ const hidden = ariaHidden ?? (variant === "bare" ? true : void 0);
251
+ return /* @__PURE__ */ jsx(
252
+ "kbd",
253
+ {
254
+ "data-slot": "kbd",
255
+ "data-variant": variant,
256
+ "aria-hidden": hidden,
257
+ className: cn(
258
+ "pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 px-1 font-sans text-xs font-medium",
259
+ variant === "tile" && "bg-muted text-muted-foreground rounded-sm border",
260
+ variant === "bare" && "text-current/70 px-0",
261
+ className
262
+ ),
263
+ ...props
264
+ }
265
+ );
266
+ }
267
+ function KbdGroup({ className, ...props }) {
268
+ return /* @__PURE__ */ jsx(
269
+ "div",
270
+ {
271
+ "data-slot": "kbd-group",
272
+ className: cn("inline-flex items-center gap-1", className),
273
+ ...props
274
+ }
275
+ );
276
+ }
277
+
278
+ // src/lib/dropdown-menu-surface.ts
279
+ var DROPDOWN_MENU_CONTENT_SURFACE_CLASS = "min-w-52 w-max max-w-[min(24rem,calc(100vw-2rem))]";
280
+ function DropdownMenu({
281
+ ...props
282
+ }) {
283
+ return /* @__PURE__ */ jsx(DropdownMenu$1.Root, { "data-slot": "dropdown-menu", ...props });
284
+ }
285
+ function DropdownMenuTrigger({
286
+ className,
287
+ ...props
288
+ }) {
289
+ return /* @__PURE__ */ jsx(
290
+ DropdownMenu$1.Trigger,
291
+ {
292
+ "data-slot": "dropdown-menu-trigger",
293
+ suppressHydrationWarning: true,
294
+ className: cn("cursor-pointer", className),
295
+ ...props
296
+ }
297
+ );
298
+ }
299
+ function DropdownMenuContent({
300
+ className,
301
+ align = "start",
302
+ sideOffset = 4,
303
+ ...props
304
+ }) {
305
+ return /* @__PURE__ */ jsx(DropdownMenu$1.Portal, { children: /* @__PURE__ */ jsx(
306
+ DropdownMenu$1.Content,
307
+ {
308
+ "data-slot": "dropdown-menu-content",
309
+ sideOffset,
310
+ align,
311
+ className: cn(
312
+ "z-50 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
313
+ DROPDOWN_MENU_CONTENT_SURFACE_CLASS,
314
+ className
315
+ ),
316
+ ...props
317
+ }
318
+ ) });
319
+ }
320
+ function DropdownMenuItem({
321
+ className,
322
+ inset,
323
+ variant = "default",
324
+ shortcut,
325
+ children,
326
+ asChild,
327
+ ...props
328
+ }) {
329
+ return /* @__PURE__ */ jsx(
330
+ DropdownMenu$1.Item,
331
+ {
332
+ "data-slot": "dropdown-menu-item",
333
+ "data-inset": inset,
334
+ "data-variant": variant,
335
+ asChild,
336
+ className: cn(
337
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:ps-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_i]:pointer-events-none [&_svg]:shrink-0 [&_i]:shrink-0 [&_svg:not([data-product-logo]):not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
338
+ className
339
+ ),
340
+ ...props,
341
+ children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
342
+ children,
343
+ shortcut ? /* @__PURE__ */ jsx(DropdownMenuShortcut, { children: shortcut }) : null
344
+ ] })
345
+ }
346
+ );
347
+ }
348
+ function Shortcut({
349
+ keys,
350
+ onInvoke,
351
+ disabled
352
+ }) {
353
+ useShortcut(keys, onInvoke, disabled);
354
+ return null;
355
+ }
356
+ function useShortcut(keys, onInvoke, disabled) {
357
+ const ref = React12.useRef(onInvoke);
358
+ React12.useEffect(() => {
359
+ ref.current = onInvoke;
360
+ }, [onInvoke]);
361
+ React12.useEffect(() => {
362
+ if (disabled) return;
363
+ const parsed = parseShortcut(keys);
364
+ if (!parsed) return;
365
+ function handler(e) {
366
+ if (!matchesShortcut(e, parsed)) return;
367
+ const t = e.target;
368
+ if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) return;
369
+ if (t && (parsed.key === "enter" || parsed.key === " ")) {
370
+ const role = t.getAttribute("role");
371
+ if (t.tagName === "BUTTON" || t.tagName === "A" || t.tagName === "SELECT" || role === "button" || role === "link" || role === "menuitem" || role === "tab" || role === "option" || role === "checkbox" || role === "radio" || role === "switch" || t.closest('[role="button"], [role="link"], [role="menuitem"], [role="tab"], [role="option"]'))
372
+ return;
373
+ }
374
+ const openDialog = document.querySelector('[role="dialog"][data-state="open"], [role="alertdialog"][data-state="open"]');
375
+ if (openDialog && (!t || !openDialog.contains(t))) return;
376
+ e.preventDefault();
377
+ e.stopPropagation();
378
+ ref.current(e);
379
+ }
380
+ window.addEventListener("keydown", handler);
381
+ return () => window.removeEventListener("keydown", handler);
382
+ }, [keys, disabled]);
383
+ }
384
+ function mapKey(raw) {
385
+ const p = raw.toLowerCase();
386
+ if (raw === "\u232B") return "backspace";
387
+ if (raw === "\u2326") return "delete";
388
+ if (raw === "\u23CE" || p === "enter" || p === "return") return "enter";
389
+ if (raw === "\u2423" || p === "space") return " ";
390
+ if (p === "esc" || p === "escape") return "escape";
391
+ if (p === "tab") return "tab";
392
+ if (p === "up" || raw === "\u2191") return "arrowup";
393
+ if (p === "down" || raw === "\u2193") return "arrowdown";
394
+ if (p === "left" || raw === "\u2190") return "arrowleft";
395
+ if (p === "right" || raw === "\u2192") return "arrowright";
396
+ return p;
397
+ }
398
+ function parseShortcut(input) {
399
+ let s = input.trim();
400
+ if (!s) return null;
401
+ const out = { meta: false, ctrl: false, shift: false, alt: false, key: "" };
402
+ while (s.length) {
403
+ const c = s[0];
404
+ if (c === "\u2318") {
405
+ out.meta = true;
406
+ s = s.slice(1);
407
+ } else if (c === "\u2303") {
408
+ out.ctrl = true;
409
+ s = s.slice(1);
410
+ } else if (c === "\u21E7") {
411
+ out.shift = true;
412
+ s = s.slice(1);
413
+ } else if (c === "\u2325") {
414
+ out.alt = true;
415
+ s = s.slice(1);
416
+ } else break;
417
+ }
418
+ if (!s) return null;
419
+ if (/[+\s]/.test(s)) {
420
+ for (const raw of s.split(/[+\s]+/).filter(Boolean)) {
421
+ const p = raw.toLowerCase();
422
+ if (raw === "\u2318" || p === "cmd" || p === "meta" || p === "command") out.meta = true;
423
+ else if (raw === "\u2303" || p === "ctrl" || p === "control") out.ctrl = true;
424
+ else if (raw === "\u21E7" || p === "shift") out.shift = true;
425
+ else if (raw === "\u2325" || p === "alt" || p === "opt" || p === "option") out.alt = true;
426
+ else out.key = mapKey(raw);
427
+ }
428
+ } else {
429
+ out.key = mapKey(s);
430
+ }
431
+ return out.key ? out : null;
432
+ }
433
+ function matchesShortcut(e, s) {
434
+ if (e.metaKey !== s.meta) return false;
435
+ if (e.ctrlKey !== s.ctrl) return false;
436
+ if (e.altKey !== s.alt) return false;
437
+ if (e.shiftKey !== s.shift) return false;
438
+ return e.key.toLowerCase() === s.key;
439
+ }
440
+ function DropdownMenuLabel({
441
+ className,
442
+ inset,
443
+ ...props
444
+ }) {
445
+ return /* @__PURE__ */ jsx(
446
+ DropdownMenu$1.Label,
447
+ {
448
+ "data-slot": "dropdown-menu-label",
449
+ "data-inset": inset,
450
+ className: cn(
451
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:ps-7",
452
+ className
453
+ ),
454
+ ...props
455
+ }
456
+ );
457
+ }
458
+ function DropdownMenuSeparator({
459
+ className,
460
+ ...props
461
+ }) {
462
+ return /* @__PURE__ */ jsx(
463
+ DropdownMenu$1.Separator,
464
+ {
465
+ "data-slot": "dropdown-menu-separator",
466
+ className: cn("-mx-1 my-1 h-px bg-border", className),
467
+ ...props
468
+ }
469
+ );
470
+ }
471
+ function DropdownMenuShortcut({
472
+ className,
473
+ ...props
474
+ }) {
475
+ return /* @__PURE__ */ jsx(
476
+ "span",
477
+ {
478
+ "data-slot": "dropdown-menu-shortcut",
479
+ className: cn(
480
+ "ms-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
481
+ className
482
+ ),
483
+ ...props
484
+ }
485
+ );
486
+ }
487
+ var radioGroupItemVariants = cva(
488
+ [
489
+ "group/radio-group-item peer relative flex shrink-0 aspect-square rounded-full border border-input",
490
+ "outline-none transition-[color,box-shadow,transform,background-color,border-color] duration-150",
491
+ "motion-reduce:transition-none",
492
+ "group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2",
493
+ "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
494
+ "disabled:cursor-not-allowed disabled:opacity-50",
495
+ "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:data-[state=checked]:border-primary",
496
+ "dark:bg-input/15 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
497
+ ].join(" "),
498
+ {
499
+ variants: {
500
+ variant: {
501
+ default: [
502
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary"
503
+ ].join(" "),
504
+ outline: [
505
+ "bg-background",
506
+ "data-[state=checked]:border-primary data-[state=checked]:bg-background data-[state=checked]:text-primary data-[state=checked]:ring-2 data-[state=checked]:ring-primary/25"
507
+ ].join(" "),
508
+ secondary: [
509
+ "data-[state=checked]:border-secondary data-[state=checked]:bg-secondary data-[state=checked]:text-secondary-foreground"
510
+ ].join(" "),
511
+ success: [
512
+ "data-[state=checked]:border-chart-2 data-[state=checked]:bg-chart-2 data-[state=checked]:text-primary-foreground"
513
+ ].join(" "),
514
+ destructive: [
515
+ "data-[state=checked]:border-destructive data-[state=checked]:bg-destructive data-[state=checked]:text-destructive-foreground"
516
+ ].join(" "),
517
+ warning: [
518
+ "data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500 data-[state=checked]:text-amber-950"
519
+ ].join(" "),
520
+ muted: [
521
+ "data-[state=checked]:border-muted-foreground/50 data-[state=checked]:bg-muted data-[state=checked]:text-foreground"
522
+ ].join(" ")
523
+ },
524
+ size: {
525
+ sm: "size-3.5 min-h-3.5 min-w-3.5 max-h-3.5 max-w-3.5",
526
+ default: "size-4 min-h-4 min-w-4 max-h-4 max-w-4",
527
+ lg: "size-5 min-h-5 min-w-5 max-h-5 max-w-5"
528
+ },
529
+ motion: {
530
+ none: "",
531
+ pop: [
532
+ "motion-safe:active:scale-95",
533
+ "data-[state=checked]:motion-safe:scale-[1.04]"
534
+ ].join(" "),
535
+ glow: "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35",
536
+ "pop-glow": [
537
+ "motion-safe:active:scale-95",
538
+ "data-[state=checked]:motion-safe:scale-[1.04]",
539
+ "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35"
540
+ ].join(" ")
541
+ }
542
+ },
543
+ defaultVariants: {
544
+ variant: "default",
545
+ size: "default",
546
+ motion: "none"
547
+ }
548
+ }
549
+ );
550
+ var radioIndicatorDotVariants = cva(
551
+ "pointer-events-none absolute top-1/2 start-1/2 -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 rounded-full",
552
+ {
553
+ variants: {
554
+ variant: {
555
+ default: "bg-primary-foreground",
556
+ outline: "bg-primary",
557
+ secondary: "bg-secondary-foreground",
558
+ success: "bg-primary-foreground",
559
+ destructive: "bg-destructive-foreground",
560
+ warning: "bg-amber-950",
561
+ muted: "bg-foreground"
562
+ },
563
+ size: {
564
+ sm: "size-1.5",
565
+ default: "size-2",
566
+ lg: "size-2.5"
567
+ }
568
+ },
569
+ defaultVariants: {
570
+ variant: "default",
571
+ size: "default"
572
+ }
573
+ }
574
+ );
575
+ var radioIndicatorWrapperVariants = cva("relative flex size-full items-center justify-center", {
576
+ variants: {
577
+ motion: {
578
+ none: "",
579
+ pop: "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150",
580
+ glow: "",
581
+ "pop-glow": "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150"
582
+ }
583
+ },
584
+ defaultVariants: { motion: "none" }
585
+ });
586
+ var RadioGroupItemChromeContext = React12.createContext({});
587
+ function RadioGroup({
588
+ className,
589
+ itemVariant,
590
+ itemSize,
591
+ itemMotion,
592
+ ...props
593
+ }) {
594
+ const ctx = React12.useMemo(
595
+ () => ({ itemVariant, itemSize, itemMotion }),
596
+ [itemVariant, itemSize, itemMotion]
597
+ );
598
+ return /* @__PURE__ */ jsx(RadioGroupItemChromeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
599
+ RadioGroup$1.Root,
600
+ {
601
+ "data-slot": "radio-group",
602
+ className: cn("grid w-full gap-2", className),
603
+ ...props
604
+ }
605
+ ) });
606
+ }
607
+ var RadioGroupItem = React12.forwardRef(function RadioGroupItem2({ className, variant: variantProp, size: sizeProp, motion: motionProp, ...props }, ref) {
608
+ const ctx = React12.useContext(RadioGroupItemChromeContext);
609
+ const variant = variantProp ?? ctx.itemVariant;
610
+ const size = sizeProp ?? ctx.itemSize;
611
+ const motion2 = motionProp ?? ctx.itemMotion ?? "none";
612
+ const vResolved = variant ?? "default";
613
+ const sResolved = size ?? "default";
614
+ return /* @__PURE__ */ jsx(
615
+ RadioGroup$1.Item,
616
+ {
617
+ ref,
618
+ "data-slot": "radio-group-item",
619
+ "data-variant": vResolved,
620
+ "data-motion": motion2,
621
+ className: cn(radioGroupItemVariants({ variant, size, motion: motion2 }), className),
622
+ ...props,
623
+ children: /* @__PURE__ */ jsx(
624
+ RadioGroup$1.Indicator,
625
+ {
626
+ "data-slot": "radio-group-indicator",
627
+ className: radioIndicatorWrapperVariants({ motion: motion2 }),
628
+ children: /* @__PURE__ */ jsx("span", { className: radioIndicatorDotVariants({ variant: vResolved, size: sResolved }) })
629
+ }
630
+ )
631
+ }
632
+ );
633
+ });
634
+ function RadioGroupLabel({ className, ...props }) {
635
+ return /* @__PURE__ */ jsx(
636
+ Label,
637
+ {
638
+ "data-slot": "radio-group-label",
639
+ className: cn(
640
+ "inline-flex min-h-11 cursor-pointer select-none items-center gap-2 py-1 -my-1 text-sm font-medium leading-snug",
641
+ "peer-disabled:cursor-not-allowed peer-disabled:opacity-60",
642
+ className
643
+ ),
644
+ ...props
645
+ }
646
+ );
647
+ }
648
+ function selectionTileClassNames(selected) {
649
+ return cn(
650
+ "flex aspect-square flex-col items-center justify-center gap-1.5 rounded-lg border px-2 py-3 text-xs leading-tight transition-colors",
651
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
652
+ selected ? "border-brand bg-brand/5 text-foreground font-medium shadow-sm" : "border-border bg-background text-muted-foreground hover:border-border/80 hover:text-interactive-hover-foreground"
653
+ );
654
+ }
655
+ function selectionTilePreviewClassNames(selected) {
656
+ return cn(
657
+ "relative box-border flex aspect-square w-full max-w-full flex-col rounded-lg border p-1 transition-colors",
658
+ selected ? "border-brand bg-brand/5 shadow-sm" : "border-border bg-background hover:border-border/80"
659
+ );
660
+ }
661
+ function SelectionTileGraphic({
662
+ option,
663
+ selected
664
+ }) {
665
+ if (option.leading != null) {
666
+ return /* @__PURE__ */ jsx("span", { className: "flex h-full min-h-0 w-full min-w-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:block [&_svg]:h-full [&_svg]:w-auto [&_svg]:max-h-full [&_svg]:max-w-full [&_svg]:object-contain [&_svg]:object-center", children: option.leading });
667
+ }
668
+ if (option.icon) {
669
+ return /* @__PURE__ */ jsx(
670
+ "i",
671
+ {
672
+ className: cn(
673
+ "fa-light shrink-0 text-[18px] leading-none",
674
+ option.icon,
675
+ selected && "text-brand"
676
+ ),
677
+ "aria-hidden": "true"
678
+ }
679
+ );
680
+ }
681
+ return null;
682
+ }
683
+ function SelectionTileLabelText({
684
+ option
685
+ }) {
686
+ return /* @__PURE__ */ jsx("span", { className: "text-center leading-tight", children: option.label });
687
+ }
688
+ function SelectionTileCaptionBelow({
689
+ option,
690
+ selected,
691
+ ariaHidden = false
692
+ }) {
693
+ return /* @__PURE__ */ jsx(
694
+ "span",
695
+ {
696
+ className: cn(
697
+ "max-w-full px-0.5 text-center text-xs leading-tight",
698
+ selected ? "font-medium text-foreground" : "text-muted-foreground"
699
+ ),
700
+ ...ariaHidden ? { "aria-hidden": true } : {},
701
+ children: option.label
702
+ }
703
+ );
704
+ }
705
+ function SelectionTileGrid({
706
+ sectionLabel,
707
+ options,
708
+ columns = 4,
709
+ value,
710
+ onValueChange,
711
+ interaction,
712
+ idPrefix = "tile",
713
+ className,
714
+ labelPlacement = "inside",
715
+ itemVariant,
716
+ itemSize,
717
+ itemMotion
718
+ }) {
719
+ const gridClass = cn(
720
+ "gap-2",
721
+ columns === 2 && "grid grid-cols-2",
722
+ columns === 3 && "grid grid-cols-3",
723
+ columns === 4 && "grid grid-cols-4"
724
+ );
725
+ if (interaction === "radio") {
726
+ return /* @__PURE__ */ jsxs("div", { className, children: [
727
+ sectionLabel ? /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: sectionLabel }) : null,
728
+ /* @__PURE__ */ jsx(
729
+ RadioGroup,
730
+ {
731
+ value,
732
+ onValueChange: (v) => onValueChange(v),
733
+ className: gridClass,
734
+ itemVariant,
735
+ itemSize,
736
+ itemMotion,
737
+ children: options.map((opt) => {
738
+ const selected = value === opt.value;
739
+ const id = `${idPrefix}-${opt.value}`;
740
+ if (labelPlacement === "below") {
741
+ return /* @__PURE__ */ jsxs(
742
+ Label,
743
+ {
744
+ htmlFor: id,
745
+ className: cn(
746
+ "flex min-w-0 cursor-pointer flex-col items-center gap-1.5 rounded-lg focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background"
747
+ ),
748
+ children: [
749
+ /* @__PURE__ */ jsxs("span", { className: cn("flex w-full justify-center", selectionTilePreviewClassNames(selected)), children: [
750
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: opt.value, id, className: "sr-only" }),
751
+ /* @__PURE__ */ jsx("span", { className: "flex min-h-0 w-full min-w-0 flex-1 items-center justify-center", children: /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }) })
752
+ ] }),
753
+ /* @__PURE__ */ jsx(SelectionTileCaptionBelow, { option: opt, selected })
754
+ ]
755
+ },
756
+ opt.value
757
+ );
758
+ }
759
+ return /* @__PURE__ */ jsxs(
760
+ Label,
761
+ {
762
+ htmlFor: id,
763
+ className: cn(
764
+ "cursor-pointer rounded-lg focus-within:rounded-lg focus-within:ring-2 focus-within:ring-ring focus-within:outline-none",
765
+ selectionTileClassNames(selected)
766
+ ),
767
+ children: [
768
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: opt.value, id, className: "sr-only" }),
769
+ /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }),
770
+ /* @__PURE__ */ jsx(SelectionTileLabelText, { option: opt })
771
+ ]
772
+ },
773
+ opt.value
774
+ );
775
+ })
776
+ }
777
+ )
778
+ ] });
779
+ }
780
+ return /* @__PURE__ */ jsxs("div", { className, children: [
781
+ sectionLabel ? /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: sectionLabel }) : null,
782
+ /* @__PURE__ */ jsx("div", { className: gridClass, children: options.map((opt) => {
783
+ const selected = value === opt.value;
784
+ if (labelPlacement === "below") {
785
+ return /* @__PURE__ */ jsxs(
786
+ "button",
787
+ {
788
+ type: "button",
789
+ "aria-label": opt.label,
790
+ "aria-pressed": selected,
791
+ onClick: () => onValueChange(opt.value),
792
+ className: "flex min-w-0 flex-col items-center gap-1.5 rounded-lg border-0 bg-transparent p-0 text-inherit focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
793
+ children: [
794
+ /* @__PURE__ */ jsx("span", { className: cn("flex w-full justify-center", selectionTilePreviewClassNames(selected)), children: /* @__PURE__ */ jsx("span", { className: "flex min-h-0 w-full min-w-0 flex-1 items-center justify-center", children: /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }) }) }),
795
+ /* @__PURE__ */ jsx(SelectionTileCaptionBelow, { option: opt, selected, ariaHidden: true })
796
+ ]
797
+ },
798
+ opt.value
799
+ );
800
+ }
801
+ return /* @__PURE__ */ jsxs(
802
+ "button",
803
+ {
804
+ type: "button",
805
+ "aria-label": opt.label,
806
+ "aria-pressed": selected,
807
+ onClick: () => onValueChange(opt.value),
808
+ className: selectionTileClassNames(selected),
809
+ children: [
810
+ /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }),
811
+ /* @__PURE__ */ jsx(SelectionTileLabelText, { option: opt })
812
+ ]
813
+ },
814
+ opt.value
815
+ );
816
+ }) })
817
+ ] });
818
+ }
819
+ function Calendar({
820
+ className,
821
+ classNames,
822
+ showOutsideDays = true,
823
+ captionLayout = "label",
824
+ buttonVariant = "ghost",
825
+ formatters,
826
+ components,
827
+ ...props
828
+ }) {
829
+ const defaultClassNames = getDefaultClassNames();
830
+ return /* @__PURE__ */ jsx(
831
+ DayPicker,
832
+ {
833
+ showOutsideDays,
834
+ className: cn(
835
+ "group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
836
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
837
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
838
+ className
839
+ ),
840
+ captionLayout,
841
+ formatters: {
842
+ formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
843
+ ...formatters
844
+ },
845
+ classNames: {
846
+ root: cn("w-fit", defaultClassNames.root),
847
+ months: cn(
848
+ "relative flex flex-col gap-4 md:flex-row",
849
+ defaultClassNames.months
850
+ ),
851
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
852
+ nav: cn(
853
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
854
+ defaultClassNames.nav
855
+ ),
856
+ button_previous: cn(
857
+ buttonVariants({ variant: buttonVariant }),
858
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
859
+ defaultClassNames.button_previous
860
+ ),
861
+ button_next: cn(
862
+ buttonVariants({ variant: buttonVariant }),
863
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
864
+ defaultClassNames.button_next
865
+ ),
866
+ month_caption: cn(
867
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
868
+ defaultClassNames.month_caption
869
+ ),
870
+ dropdowns: cn(
871
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
872
+ defaultClassNames.dropdowns
873
+ ),
874
+ dropdown_root: cn(
875
+ "relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
876
+ defaultClassNames.dropdown_root
877
+ ),
878
+ dropdown: cn(
879
+ "absolute inset-0 bg-popover opacity-0",
880
+ defaultClassNames.dropdown
881
+ ),
882
+ caption_label: cn(
883
+ "font-medium select-none",
884
+ captionLayout === "label" ? "text-sm" : "flex h-8 items-center gap-1 rounded-md pe-1 ps-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
885
+ defaultClassNames.caption_label
886
+ ),
887
+ table: "w-full border-collapse",
888
+ weekdays: cn("flex", defaultClassNames.weekdays),
889
+ weekday: cn(
890
+ "flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
891
+ defaultClassNames.weekday
892
+ ),
893
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
894
+ week_number_header: cn(
895
+ "w-(--cell-size) select-none",
896
+ defaultClassNames.week_number_header
897
+ ),
898
+ week_number: cn(
899
+ "text-[0.8rem] text-muted-foreground select-none",
900
+ defaultClassNames.week_number
901
+ ),
902
+ day: cn(
903
+ "group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
904
+ props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md" : "[&:first-child[data-selected=true]_button]:rounded-l-md",
905
+ defaultClassNames.day
906
+ ),
907
+ range_start: cn(
908
+ "rounded-l-md bg-accent",
909
+ defaultClassNames.range_start
910
+ ),
911
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
912
+ range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
913
+ today: cn(
914
+ "rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
915
+ defaultClassNames.today
916
+ ),
917
+ outside: cn(
918
+ "text-muted-foreground aria-selected:text-muted-foreground",
919
+ defaultClassNames.outside
920
+ ),
921
+ disabled: cn(
922
+ "text-muted-foreground opacity-50",
923
+ defaultClassNames.disabled
924
+ ),
925
+ hidden: cn("invisible", defaultClassNames.hidden),
926
+ ...classNames
927
+ },
928
+ components: {
929
+ Root: ({ className: className2, rootRef, ...props2 }) => {
930
+ return /* @__PURE__ */ jsx(
931
+ "div",
932
+ {
933
+ "data-slot": "calendar",
934
+ ref: rootRef,
935
+ className: cn(className2),
936
+ ...props2
937
+ }
938
+ );
939
+ },
940
+ Chevron: ({ className: className2, orientation, ...props2 }) => {
941
+ if (orientation === "left") {
942
+ return /* @__PURE__ */ jsx(ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
943
+ }
944
+ if (orientation === "right") {
945
+ return /* @__PURE__ */ jsx(
946
+ ChevronRightIcon,
947
+ {
948
+ className: cn("size-4", className2),
949
+ ...props2
950
+ }
951
+ );
952
+ }
953
+ return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
954
+ },
955
+ DayButton: CalendarDayButton,
956
+ WeekNumber: ({ children, ...props2 }) => {
957
+ return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
958
+ },
959
+ ...components
960
+ },
961
+ ...props
962
+ }
963
+ );
964
+ }
965
+ function CalendarDayButton({
966
+ className,
967
+ day,
968
+ modifiers,
969
+ ...props
970
+ }) {
971
+ const defaultClassNames = getDefaultClassNames();
972
+ const ref = React12.useRef(null);
973
+ React12.useEffect(() => {
974
+ if (modifiers.focused) ref.current?.focus();
975
+ }, [modifiers.focused]);
976
+ return /* @__PURE__ */ jsx(
977
+ Button,
978
+ {
979
+ ref,
980
+ variant: "ghost",
981
+ size: "icon",
982
+ "data-day": day.date.toLocaleDateString(),
983
+ "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
984
+ "data-range-start": modifiers.range_start,
985
+ "data-range-end": modifiers.range_end,
986
+ "data-range-middle": modifiers.range_middle,
987
+ className: cn(
988
+ "flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70",
989
+ defaultClassNames.day,
990
+ className
991
+ ),
992
+ ...props
993
+ }
994
+ );
995
+ }
996
+ var Input = React12.forwardRef(
997
+ function Input2({ className, type, ...props }, ref) {
998
+ return /* @__PURE__ */ jsx(
999
+ "input",
1000
+ {
1001
+ ref,
1002
+ type,
1003
+ "data-slot": "input",
1004
+ className: cn(
1005
+ "h-8 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
1006
+ className
1007
+ ),
1008
+ ...props
1009
+ }
1010
+ );
1011
+ }
1012
+ );
1013
+ function InputGroup({ className, ...props }) {
1014
+ return /* @__PURE__ */ jsx(
1015
+ "div",
1016
+ {
1017
+ "data-slot": "input-group",
1018
+ role: "group",
1019
+ className: cn(
1020
+ "group/input-group relative flex h-8 w-full min-w-0 items-center rounded-md border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-1.5",
1021
+ className
1022
+ ),
1023
+ ...props
1024
+ }
1025
+ );
1026
+ }
1027
+ var inputGroupAddonVariants = cva(
1028
+ "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
1029
+ {
1030
+ variants: {
1031
+ align: {
1032
+ "inline-start": "order-first ps-2 has-[>button]:ms-[-0.3rem] has-[>kbd]:ms-[-0.15rem]",
1033
+ "inline-end": "order-last pe-2 has-[>button]:me-[-0.3rem] has-[>kbd]:me-[-0.15rem]",
1034
+ "block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
1035
+ "block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
1036
+ }
1037
+ },
1038
+ defaultVariants: {
1039
+ align: "inline-start"
1040
+ }
1041
+ }
1042
+ );
1043
+ function InputGroupAddon({
1044
+ className,
1045
+ align = "inline-start",
1046
+ ...props
1047
+ }) {
1048
+ return /* @__PURE__ */ jsx(
1049
+ "div",
1050
+ {
1051
+ role: "group",
1052
+ "data-slot": "input-group-addon",
1053
+ "data-align": align,
1054
+ className: cn(inputGroupAddonVariants({ align }), className),
1055
+ onClick: (e) => {
1056
+ if (e.target.closest("button")) {
1057
+ return;
1058
+ }
1059
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
1060
+ },
1061
+ ...props
1062
+ }
1063
+ );
1064
+ }
1065
+ var inputGroupButtonVariants = cva(
1066
+ "flex items-center gap-2 text-sm shadow-none",
1067
+ {
1068
+ variants: {
1069
+ size: {
1070
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
1071
+ sm: "",
1072
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
1073
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0"
1074
+ }
1075
+ },
1076
+ defaultVariants: {
1077
+ size: "xs"
1078
+ }
1079
+ }
1080
+ );
1081
+ function InputGroupButton({
1082
+ className,
1083
+ type = "button",
1084
+ variant = "ghost",
1085
+ size = "xs",
1086
+ ...props
1087
+ }) {
1088
+ return /* @__PURE__ */ jsx(
1089
+ Button,
1090
+ {
1091
+ type,
1092
+ "data-size": size,
1093
+ variant,
1094
+ className: cn(inputGroupButtonVariants({ size }), className),
1095
+ ...props
1096
+ }
1097
+ );
1098
+ }
1099
+
1100
+ // src/lib/compose-refs.ts
1101
+ function composeRefs(...refs) {
1102
+ return (node) => {
1103
+ for (const ref of refs) {
1104
+ if (ref == null) continue;
1105
+ if (typeof ref === "function") {
1106
+ ref(node);
1107
+ } else {
1108
+ ref.current = node;
1109
+ }
1110
+ }
1111
+ };
1112
+ }
1113
+ var exxatInputMaskDefaults = {
1114
+ placeholder: "_",
1115
+ showMaskOnHover: false
1116
+ };
1117
+ var exxatMaskPatterns = {
1118
+ /** US NANP 10-digit display */
1119
+ phoneUS: "(999) 999-9999",
1120
+ /** US ZIP or ZIP+4 */
1121
+ zipUS: "99999[-9999]",
1122
+ /** Calendar-style date (validate separately). */
1123
+ dateMDY: "99/99/9999"};
1124
+ var MaskedInput = React12.forwardRef(function MaskedInput2({ mask, maskOptions, className, type = "text", ...props }, ref) {
1125
+ const maskRef = useMaskInput({
1126
+ mask,
1127
+ options: { ...exxatInputMaskDefaults, ...maskOptions }
1128
+ });
1129
+ return /* @__PURE__ */ jsx(
1130
+ Input,
1131
+ {
1132
+ ref: composeRefs(ref, maskRef),
1133
+ type,
1134
+ className: cn(className),
1135
+ ...props
1136
+ }
1137
+ );
1138
+ });
1139
+ function Popover({ ...props }) {
1140
+ return /* @__PURE__ */ jsx(Popover$1.Root, { ...props });
1141
+ }
1142
+ function PopoverTrigger({ className, ...props }) {
1143
+ return /* @__PURE__ */ jsx(Popover$1.Trigger, { className: cn("cursor-pointer", className), ...props });
1144
+ }
1145
+ function PopoverContent({
1146
+ className,
1147
+ align = "start",
1148
+ sideOffset = 4,
1149
+ ...props
1150
+ }) {
1151
+ return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
1152
+ Popover$1.Content,
1153
+ {
1154
+ "data-slot": "popover-content",
1155
+ align,
1156
+ sideOffset,
1157
+ className: cn(
1158
+ "z-50 rounded-lg border border-border bg-popover shadow-md outline-none",
1159
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
1160
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
1161
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
1162
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
1163
+ "data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
1164
+ className
1165
+ ),
1166
+ ...props
1167
+ }
1168
+ ) });
1169
+ }
1170
+ var DATE_PICKER_ICON_CLASS = "fa-light fa-calendar";
1171
+ function parseMdyToLocalDate(raw) {
1172
+ const match = raw.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1173
+ if (!match) return void 0;
1174
+ const month = Number(match[1]);
1175
+ const day = Number(match[2]);
1176
+ const year = Number(match[3]);
1177
+ if (month < 1 || month > 12 || day < 1 || day > 31) return void 0;
1178
+ const date = new Date(year, month - 1, day, 12, 0, 0, 0);
1179
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) return void 0;
1180
+ return date;
1181
+ }
1182
+ function formatLocalDateToMdy(date) {
1183
+ const month = String(date.getMonth() + 1).padStart(2, "0");
1184
+ const day = String(date.getDate()).padStart(2, "0");
1185
+ const year = String(date.getFullYear());
1186
+ return `${month}/${day}/${year}`;
1187
+ }
1188
+ function DateTextInputField({
1189
+ value,
1190
+ onValueChange,
1191
+ "aria-label": ariaLabel,
1192
+ id,
1193
+ placeholder = "MM/DD/YYYY",
1194
+ className,
1195
+ inputClassName,
1196
+ autoFocus,
1197
+ disabled,
1198
+ fromYear = 2020,
1199
+ toYear = 2032,
1200
+ iconButtonVariant = "ghost",
1201
+ popoverAlign = "end",
1202
+ popoverClassName
1203
+ }) {
1204
+ return /* @__PURE__ */ jsxs(InputGroup, { className, children: [
1205
+ /* @__PURE__ */ jsx(
1206
+ MaskedInput,
1207
+ {
1208
+ "data-slot": "input-group-control",
1209
+ id,
1210
+ mask: exxatMaskPatterns.dateMDY,
1211
+ "aria-label": ariaLabel,
1212
+ placeholder,
1213
+ value,
1214
+ onChange: (event) => onValueChange(event.target.value),
1215
+ className: cn(
1216
+ "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
1217
+ inputClassName
1218
+ ),
1219
+ autoFocus,
1220
+ disabled
1221
+ }
1222
+ ),
1223
+ /* @__PURE__ */ jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxs(Popover, { children: [
1224
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1225
+ InputGroupButton,
1226
+ {
1227
+ type: "button",
1228
+ variant: iconButtonVariant,
1229
+ size: "icon-xs",
1230
+ disabled,
1231
+ "aria-label": `${ariaLabel} pick date`,
1232
+ children: /* @__PURE__ */ jsx("i", { className: DATE_PICKER_ICON_CLASS, "aria-hidden": "true" })
1233
+ }
1234
+ ) }),
1235
+ /* @__PURE__ */ jsx(
1236
+ PopoverContent,
1237
+ {
1238
+ className: cn("z-[80] w-auto p-0", popoverClassName),
1239
+ align: popoverAlign,
1240
+ sideOffset: 6,
1241
+ children: /* @__PURE__ */ jsx(
1242
+ Calendar,
1243
+ {
1244
+ mode: "single",
1245
+ selected: parseMdyToLocalDate(value),
1246
+ onSelect: (next) => onValueChange(next ? formatLocalDateToMdy(next) : ""),
1247
+ initialFocus: true,
1248
+ fromYear,
1249
+ toYear,
1250
+ captionLayout: "dropdown"
1251
+ }
1252
+ )
1253
+ }
1254
+ )
1255
+ ] }) })
1256
+ ] });
1257
+ }
1258
+ var MASK_BY_KIND = {
1259
+ phone: exxatMaskPatterns.phoneUS,
1260
+ zip: exxatMaskPatterns.zipUS,
1261
+ dateMDY: exxatMaskPatterns.dateMDY
1262
+ };
1263
+ function FilterTextValueInput({
1264
+ id,
1265
+ mask,
1266
+ value,
1267
+ onValueChange,
1268
+ "aria-label": ariaLabel,
1269
+ placeholder,
1270
+ className,
1271
+ autoFocus
1272
+ }) {
1273
+ if (mask === "dateMDY") {
1274
+ return /* @__PURE__ */ jsx(
1275
+ DateTextInputField,
1276
+ {
1277
+ id,
1278
+ value,
1279
+ onValueChange,
1280
+ "aria-label": ariaLabel,
1281
+ placeholder,
1282
+ inputClassName: className,
1283
+ autoFocus,
1284
+ iconButtonVariant: "ghost",
1285
+ popoverAlign: "end"
1286
+ }
1287
+ );
1288
+ }
1289
+ if (mask) {
1290
+ return /* @__PURE__ */ jsx(
1291
+ MaskedInput,
1292
+ {
1293
+ id,
1294
+ mask: MASK_BY_KIND[mask],
1295
+ "aria-label": ariaLabel,
1296
+ placeholder,
1297
+ value,
1298
+ onChange: (e) => onValueChange(e.target.value),
1299
+ className,
1300
+ autoFocus
1301
+ }
1302
+ );
1303
+ }
1304
+ return /* @__PURE__ */ jsx(
1305
+ Input,
1306
+ {
1307
+ id,
1308
+ type: "text",
1309
+ "aria-label": ariaLabel,
1310
+ placeholder,
1311
+ value,
1312
+ onChange: (e) => onValueChange(e.target.value),
1313
+ className,
1314
+ autoFocus
1315
+ }
1316
+ );
1317
+ }
1318
+ function Sheet({ ...props }) {
1319
+ return /* @__PURE__ */ jsx(Dialog$1.Root, { "data-slot": "sheet", ...props });
1320
+ }
1321
+ function SheetPortal({
1322
+ ...props
1323
+ }) {
1324
+ return /* @__PURE__ */ jsx(Dialog$1.Portal, { "data-slot": "sheet-portal", ...props });
1325
+ }
1326
+ function SheetOverlay({
1327
+ className,
1328
+ ...props
1329
+ }) {
1330
+ return /* @__PURE__ */ jsx(
1331
+ Dialog$1.Overlay,
1332
+ {
1333
+ "data-slot": "sheet-overlay",
1334
+ className: cn(
1335
+ "fixed inset-0 z-50 bg-overlay duration-300 ease-out supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
1336
+ className
1337
+ ),
1338
+ ...props
1339
+ }
1340
+ );
1341
+ }
1342
+ function SheetContent({
1343
+ className,
1344
+ children,
1345
+ side = "right",
1346
+ showCloseButton = true,
1347
+ showOverlay = true,
1348
+ ...props
1349
+ }) {
1350
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
1351
+ showOverlay && /* @__PURE__ */ jsx(SheetOverlay, {}),
1352
+ /* @__PURE__ */ jsxs(
1353
+ Dialog$1.Content,
1354
+ {
1355
+ "data-slot": "sheet-content",
1356
+ "data-side": side,
1357
+ className: cn(
1358
+ "fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg outline-none duration-300 ease-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-e data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-s data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-6 data-[side=left]:data-open:slide-in-from-left-6 data-[side=right]:data-open:slide-in-from-right-6 data-[side=top]:data-open:slide-in-from-top-6 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-6 data-[side=left]:data-closed:slide-out-to-left-6 data-[side=right]:data-closed:slide-out-to-right-6 data-[side=top]:data-closed:slide-out-to-top-6",
1359
+ className
1360
+ ),
1361
+ ...props,
1362
+ children: [
1363
+ children,
1364
+ showCloseButton && /* @__PURE__ */ jsx(Dialog$1.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ jsxs(
1365
+ Button,
1366
+ {
1367
+ variant: "ghost",
1368
+ className: "absolute top-3 end-3",
1369
+ size: "icon-sm",
1370
+ children: [
1371
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark", "aria-hidden": "true" }),
1372
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1373
+ ]
1374
+ }
1375
+ ) })
1376
+ ]
1377
+ }
1378
+ )
1379
+ ] });
1380
+ }
1381
+ function SheetTitle({
1382
+ className,
1383
+ ...props
1384
+ }) {
1385
+ return /* @__PURE__ */ jsx(
1386
+ Dialog$1.Title,
1387
+ {
1388
+ "data-slot": "sheet-title",
1389
+ className: cn(
1390
+ "text-base font-medium text-foreground",
1391
+ className
1392
+ ),
1393
+ ...props
1394
+ }
1395
+ );
1396
+ }
1397
+ var Form = FormProvider;
1398
+ var FormFieldContext = React12.createContext(
1399
+ {}
1400
+ );
1401
+ function FormField({ ...props }) {
1402
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
1403
+ }
1404
+ function useFormField() {
1405
+ const fieldContext = React12.useContext(FormFieldContext);
1406
+ const itemContext = React12.useContext(FormItemContext);
1407
+ const { getFieldState, formState } = useFormContext();
1408
+ const fieldState = getFieldState(fieldContext.name, formState);
1409
+ if (!fieldContext) throw new Error("useFormField must be used inside <FormField>");
1410
+ const { id } = itemContext;
1411
+ return {
1412
+ id,
1413
+ name: fieldContext.name,
1414
+ formItemId: `${id}-form-item`,
1415
+ formDescriptionId: `${id}-form-item-description`,
1416
+ formMessageId: `${id}-form-item-message`,
1417
+ ...fieldState
1418
+ };
1419
+ }
1420
+ var FormItemContext = React12.createContext({});
1421
+ function FormItem({ className, ...props }) {
1422
+ const id = React12.useId();
1423
+ return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("flex flex-col gap-1.5", className), ...props }) });
1424
+ }
1425
+ function FormLabel({ className, ...props }) {
1426
+ const { error, formItemId } = useFormField();
1427
+ return /* @__PURE__ */ jsx(
1428
+ Label,
1429
+ {
1430
+ "data-slot": "form-label",
1431
+ "data-error": !!error,
1432
+ className: cn("data-[error=true]:text-destructive", className),
1433
+ htmlFor: formItemId,
1434
+ ...props
1435
+ }
1436
+ );
1437
+ }
1438
+ function FormControl({ ...props }) {
1439
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
1440
+ return /* @__PURE__ */ jsx(
1441
+ Slot.Root,
1442
+ {
1443
+ "data-slot": "form-control",
1444
+ id: formItemId,
1445
+ "aria-describedby": !error ? formDescriptionId : `${formDescriptionId} ${formMessageId}`,
1446
+ "aria-invalid": !!error,
1447
+ ...props
1448
+ }
1449
+ );
1450
+ }
1451
+ function FormDescription({ className, ...props }) {
1452
+ const { formDescriptionId } = useFormField();
1453
+ return /* @__PURE__ */ jsx(
1454
+ "p",
1455
+ {
1456
+ "data-slot": "form-description",
1457
+ id: formDescriptionId,
1458
+ className: cn("text-muted-foreground text-sm", className),
1459
+ ...props
1460
+ }
1461
+ );
1462
+ }
1463
+ function FormMessage({ className, children, ...props }) {
1464
+ const { error, formMessageId } = useFormField();
1465
+ const body = error ? String(error?.message ?? "") : children;
1466
+ if (!body) return null;
1467
+ return /* @__PURE__ */ jsx(
1468
+ "p",
1469
+ {
1470
+ "data-slot": "form-message",
1471
+ id: formMessageId,
1472
+ className: cn("text-destructive text-sm", className),
1473
+ ...props,
1474
+ children: body
1475
+ }
1476
+ );
1477
+ }
1478
+ function parseMdyToDate(raw) {
1479
+ if (!raw?.trim()) return void 0;
1480
+ const m = raw.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1481
+ if (!m) return void 0;
1482
+ const month = Number(m[1]);
1483
+ const day = Number(m[2]);
1484
+ const year = Number(m[3]);
1485
+ if (month < 1 || month > 12 || day < 1 || day > 31) return void 0;
1486
+ const d = new Date(year, month - 1, day, 12, 0, 0, 0);
1487
+ if (d.getFullYear() !== year || d.getMonth() !== month - 1 || d.getDate() !== day) return void 0;
1488
+ return d;
1489
+ }
1490
+ var EXPORT_FORMAT_OPTIONS = [
1491
+ { value: "csv", label: "CSV", icon: "fa-file-csv" },
1492
+ { value: "excel", label: "Excel", icon: "fa-file-excel" },
1493
+ { value: "pdf", label: "PDF", icon: "fa-file-pdf" }
1494
+ ];
1495
+ var exportSchema = z.object({
1496
+ format: z.enum(["csv", "excel", "pdf"]),
1497
+ columns: z.enum(["all", "visible"]),
1498
+ dateFrom: z.string().optional(),
1499
+ dateTo: z.string().optional(),
1500
+ includeFilters: z.boolean()
1501
+ }).superRefine((data, ctx) => {
1502
+ const from = parseMdyToDate(data.dateFrom);
1503
+ const to = parseMdyToDate(data.dateTo);
1504
+ if (data.dateFrom?.trim() && !from) {
1505
+ ctx.addIssue({ code: "custom", message: "Enter a valid from date", path: ["dateFrom"] });
1506
+ }
1507
+ if (data.dateTo?.trim() && !to) {
1508
+ ctx.addIssue({ code: "custom", message: "Enter a valid to date", path: ["dateTo"] });
1509
+ }
1510
+ if (from && to && to < from) {
1511
+ ctx.addIssue({ code: "custom", message: "End date must be after start date", path: ["dateTo"] });
1512
+ }
1513
+ });
1514
+ function ExportDrawer({
1515
+ open,
1516
+ onOpenChange,
1517
+ totalRows = 0,
1518
+ visibleColumns
1519
+ }) {
1520
+ const form = useForm({
1521
+ resolver: zodResolver(exportSchema),
1522
+ defaultValues: {
1523
+ format: "csv",
1524
+ columns: "visible",
1525
+ dateFrom: "",
1526
+ dateTo: "",
1527
+ includeFilters: true
1528
+ }
1529
+ });
1530
+ const [isExporting, setIsExporting] = React12.useState(false);
1531
+ async function onSubmit(values) {
1532
+ setIsExporting(true);
1533
+ await new Promise((r) => setTimeout(r, 1200));
1534
+ devLog("Export:", {
1535
+ ...values,
1536
+ dateFrom: parseMdyToDate(values.dateFrom)?.toISOString(),
1537
+ dateTo: parseMdyToDate(values.dateTo)?.toISOString()
1538
+ });
1539
+ setIsExporting(false);
1540
+ onOpenChange(false);
1541
+ form.reset();
1542
+ }
1543
+ return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
1544
+ SheetContent,
1545
+ {
1546
+ "data-slot": "export-drawer",
1547
+ side: "right",
1548
+ showCloseButton: false,
1549
+ showOverlay: false,
1550
+ className: "z-[80] w-80 sm:max-w-80 p-0 gap-0 flex flex-col border border-border shadow-xl rounded-xl overflow-hidden",
1551
+ style: { top: "0.5rem", bottom: "0.5rem", right: "0.5rem", height: "calc(100vh - 1rem)" },
1552
+ children: [
1553
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 pt-5 pb-3", children: [
1554
+ /* @__PURE__ */ jsx(SheetTitle, { className: "text-base font-semibold leading-tight", children: "Export data" }),
1555
+ /* @__PURE__ */ jsx(Tip, { label: "Close", side: "bottom", children: /* @__PURE__ */ jsx(
1556
+ Button,
1557
+ {
1558
+ type: "button",
1559
+ variant: "ghost",
1560
+ size: "icon-sm",
1561
+ "aria-label": "Close",
1562
+ onClick: () => onOpenChange(false),
1563
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark text-[13px]", "aria-hidden": "true" })
1564
+ }
1565
+ ) })
1566
+ ] }),
1567
+ /* @__PURE__ */ jsxs("p", { className: "px-4 pb-3 text-sm text-muted-foreground -mt-1", children: [
1568
+ totalRows,
1569
+ " record",
1570
+ totalRows !== 1 ? "s" : "",
1571
+ " available for export."
1572
+ ] }),
1573
+ /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsx(
1574
+ "form",
1575
+ {
1576
+ id: "export-form",
1577
+ onSubmit: form.handleSubmit(onSubmit),
1578
+ className: "flex-1 overflow-y-auto",
1579
+ children: /* @__PURE__ */ jsxs("div", { className: "px-4 pb-4 space-y-5", children: [
1580
+ /* @__PURE__ */ jsx(
1581
+ FormField,
1582
+ {
1583
+ control: form.control,
1584
+ name: "format",
1585
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
1586
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
1587
+ SelectionTileGrid,
1588
+ {
1589
+ sectionLabel: "File format",
1590
+ options: EXPORT_FORMAT_OPTIONS,
1591
+ columns: 3,
1592
+ value: field.value,
1593
+ onValueChange: field.onChange,
1594
+ interaction: "radio",
1595
+ idPrefix: "export-fmt",
1596
+ itemVariant: "outline",
1597
+ itemMotion: "pop"
1598
+ }
1599
+ ) }),
1600
+ /* @__PURE__ */ jsx(FormMessage, {})
1601
+ ] })
1602
+ }
1603
+ ),
1604
+ /* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
1605
+ /* @__PURE__ */ jsxs("legend", { className: "text-sm font-medium leading-none mb-2", children: [
1606
+ "Date range",
1607
+ " ",
1608
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
1609
+ ] }),
1610
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
1611
+ /* @__PURE__ */ jsx(
1612
+ FormField,
1613
+ {
1614
+ control: form.control,
1615
+ name: "dateFrom",
1616
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "gap-1", children: [
1617
+ /* @__PURE__ */ jsx(FormLabel, { htmlFor: "export-date-from", className: "text-xs text-muted-foreground", children: "From" }),
1618
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
1619
+ FilterTextValueInput,
1620
+ {
1621
+ id: "export-date-from",
1622
+ mask: "dateMDY",
1623
+ "aria-label": "Export from date (optional)",
1624
+ placeholder: "MM/DD/YYYY",
1625
+ value: field.value ?? "",
1626
+ onValueChange: field.onChange,
1627
+ className: "h-8 text-sm"
1628
+ }
1629
+ ) }),
1630
+ /* @__PURE__ */ jsx(FormDescription, { className: "text-[11px]", children: "MM/DD/YYYY" }),
1631
+ /* @__PURE__ */ jsx(FormMessage, {})
1632
+ ] })
1633
+ }
1634
+ ),
1635
+ /* @__PURE__ */ jsx(
1636
+ FormField,
1637
+ {
1638
+ control: form.control,
1639
+ name: "dateTo",
1640
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "gap-1", children: [
1641
+ /* @__PURE__ */ jsx(FormLabel, { htmlFor: "export-date-to", className: "text-xs text-muted-foreground", children: "To" }),
1642
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
1643
+ FilterTextValueInput,
1644
+ {
1645
+ id: "export-date-to",
1646
+ mask: "dateMDY",
1647
+ "aria-label": "Export to date (optional)",
1648
+ placeholder: "MM/DD/YYYY",
1649
+ value: field.value ?? "",
1650
+ onValueChange: field.onChange,
1651
+ className: "h-8 text-sm"
1652
+ }
1653
+ ) }),
1654
+ /* @__PURE__ */ jsx(FormDescription, { className: "text-[11px]", children: "MM/DD/YYYY" }),
1655
+ /* @__PURE__ */ jsx(FormMessage, {})
1656
+ ] })
1657
+ }
1658
+ )
1659
+ ] })
1660
+ ] }),
1661
+ /* @__PURE__ */ jsx(
1662
+ FormField,
1663
+ {
1664
+ control: form.control,
1665
+ name: "columns",
1666
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
1667
+ /* @__PURE__ */ jsx(FormLabel, { className: "text-sm font-medium", children: "Columns" }),
1668
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
1669
+ RadioGroup,
1670
+ {
1671
+ value: field.value,
1672
+ onValueChange: field.onChange,
1673
+ className: "space-y-1.5 mt-1",
1674
+ itemVariant: "outline",
1675
+ itemMotion: "pop",
1676
+ children: [
1677
+ { value: "all", label: "All columns", sub: null },
1678
+ { value: "visible", label: "Visible columns only", sub: visibleColumns !== void 0 ? `${visibleColumns} columns` : null }
1679
+ ].map((opt) => /* @__PURE__ */ jsxs(
1680
+ "div",
1681
+ {
1682
+ className: "flex items-center gap-2.5 rounded-lg border border-border px-3 py-2.5 transition-colors hover:bg-interactive-hover has-[[data-state=checked]]:border-brand has-[[data-state=checked]]:bg-brand/10 cursor-pointer",
1683
+ children: [
1684
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: opt.value, id: `col-${opt.value}` }),
1685
+ /* @__PURE__ */ jsxs(
1686
+ RadioGroupLabel,
1687
+ {
1688
+ htmlFor: `col-${opt.value}`,
1689
+ className: "min-h-0 flex-1 cursor-pointer py-0 text-sm font-normal leading-none",
1690
+ children: [
1691
+ opt.label,
1692
+ opt.sub && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground ms-1.5 font-normal", children: [
1693
+ "(",
1694
+ opt.sub,
1695
+ ")"
1696
+ ] })
1697
+ ]
1698
+ }
1699
+ )
1700
+ ]
1701
+ },
1702
+ opt.value
1703
+ ))
1704
+ }
1705
+ ) }),
1706
+ /* @__PURE__ */ jsx(FormMessage, {})
1707
+ ] })
1708
+ }
1709
+ ),
1710
+ /* @__PURE__ */ jsx(
1711
+ FormField,
1712
+ {
1713
+ control: form.control,
1714
+ name: "includeFilters",
1715
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
1716
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-border px-3 py-2.5 transition-colors hover:bg-interactive-hover has-[[data-state=checked]]:border-primary", children: [
1717
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
1718
+ Checkbox,
1719
+ {
1720
+ id: "include-filters",
1721
+ checked: field.value,
1722
+ onCheckedChange: field.onChange,
1723
+ className: "mt-0.5 shrink-0"
1724
+ }
1725
+ ) }),
1726
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
1727
+ /* @__PURE__ */ jsx(Label, { htmlFor: "include-filters", className: "text-sm cursor-pointer font-medium leading-none", children: "Apply active filters" }),
1728
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Export only rows matching current filters" })
1729
+ ] })
1730
+ ] }),
1731
+ /* @__PURE__ */ jsx(FormMessage, {})
1732
+ ] })
1733
+ }
1734
+ )
1735
+ ] })
1736
+ }
1737
+ ) }),
1738
+ /* @__PURE__ */ jsx(Shortcut, { keys: "Enter", disabled: isExporting, onInvoke: () => form.handleSubmit(onSubmit)() }),
1739
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-3 border-t border-border", children: [
1740
+ /* @__PURE__ */ jsxs(
1741
+ Button,
1742
+ {
1743
+ type: "button",
1744
+ variant: "outline",
1745
+ className: "flex-1",
1746
+ onClick: () => onOpenChange(false),
1747
+ children: [
1748
+ "Cancel",
1749
+ /* @__PURE__ */ jsx(KbdGroup, { className: "ms-1.5", children: /* @__PURE__ */ jsx(Kbd, { variant: "bare", children: "Esc" }) })
1750
+ ]
1751
+ }
1752
+ ),
1753
+ /* @__PURE__ */ jsx(
1754
+ Button,
1755
+ {
1756
+ type: "submit",
1757
+ form: "export-form",
1758
+ className: "flex-1",
1759
+ disabled: isExporting,
1760
+ children: isExporting ? /* @__PURE__ */ jsxs(Fragment, { children: [
1761
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-spinner-third fa-spin text-[13px]", "aria-hidden": "true" }),
1762
+ "Exporting\u2026"
1763
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1764
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-arrow-down-to-line text-[13px]", "aria-hidden": "true" }),
1765
+ "Export",
1766
+ /* @__PURE__ */ jsx(KbdGroup, { className: "ms-1.5", children: /* @__PURE__ */ jsx(Kbd, { variant: "bare", children: "\u23CE" }) })
1767
+ ] })
1768
+ }
1769
+ )
1770
+ ] })
1771
+ ]
1772
+ }
1773
+ ) });
1774
+ }
1775
+ function Dialog({
1776
+ ...props
1777
+ }) {
1778
+ return /* @__PURE__ */ jsx(Dialog$1.Root, { "data-slot": "dialog", ...props });
1779
+ }
1780
+ function DialogPortal({
1781
+ ...props
1782
+ }) {
1783
+ return /* @__PURE__ */ jsx(Dialog$1.Portal, { "data-slot": "dialog-portal", ...props });
1784
+ }
1785
+ function DialogOverlay({
1786
+ className,
1787
+ ...props
1788
+ }) {
1789
+ return /* @__PURE__ */ jsx(
1790
+ Dialog$1.Overlay,
1791
+ {
1792
+ "data-slot": "dialog-overlay",
1793
+ className: cn(
1794
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
1795
+ className
1796
+ ),
1797
+ ...props
1798
+ }
1799
+ );
1800
+ }
1801
+ function DialogContent({
1802
+ className,
1803
+ children,
1804
+ showCloseButton = true,
1805
+ overlayClassName,
1806
+ ...props
1807
+ }) {
1808
+ return /* @__PURE__ */ jsxs(DialogPortal, { children: [
1809
+ /* @__PURE__ */ jsx(DialogOverlay, { className: overlayClassName ?? void 0 }),
1810
+ /* @__PURE__ */ jsxs(
1811
+ Dialog$1.Content,
1812
+ {
1813
+ "data-slot": "dialog-content",
1814
+ className: cn(
1815
+ "fixed top-1/2 start-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
1816
+ className
1817
+ ),
1818
+ ...props,
1819
+ children: [
1820
+ children,
1821
+ showCloseButton && /* @__PURE__ */ jsx(Dialog$1.Close, { "data-slot": "dialog-close", asChild: true, children: /* @__PURE__ */ jsxs(
1822
+ Button,
1823
+ {
1824
+ variant: "ghost",
1825
+ className: "absolute top-2 end-2",
1826
+ size: "icon-sm",
1827
+ children: [
1828
+ /* @__PURE__ */ jsx(
1829
+ XIcon,
1830
+ {}
1831
+ ),
1832
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1833
+ ]
1834
+ }
1835
+ ) })
1836
+ ]
1837
+ }
1838
+ )
1839
+ ] });
1840
+ }
1841
+ function DialogHeader({ className, ...props }) {
1842
+ return /* @__PURE__ */ jsx(
1843
+ "div",
1844
+ {
1845
+ "data-slot": "dialog-header",
1846
+ className: cn("flex flex-col gap-2", className),
1847
+ ...props
1848
+ }
1849
+ );
1850
+ }
1851
+ function DialogFooter({
1852
+ className,
1853
+ showCloseButton = false,
1854
+ children,
1855
+ ...props
1856
+ }) {
1857
+ return /* @__PURE__ */ jsxs(
1858
+ "div",
1859
+ {
1860
+ "data-slot": "dialog-footer",
1861
+ className: cn(
1862
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
1863
+ className
1864
+ ),
1865
+ ...props,
1866
+ children: [
1867
+ children,
1868
+ showCloseButton && /* @__PURE__ */ jsx(Dialog$1.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", children: "Close" }) })
1869
+ ]
1870
+ }
1871
+ );
1872
+ }
1873
+ function DialogTitle({
1874
+ className,
1875
+ ...props
1876
+ }) {
1877
+ return /* @__PURE__ */ jsx(
1878
+ Dialog$1.Title,
1879
+ {
1880
+ "data-slot": "dialog-title",
1881
+ className: cn(
1882
+ "font-heading text-base leading-none font-medium",
1883
+ className
1884
+ ),
1885
+ ...props
1886
+ }
1887
+ );
1888
+ }
1889
+ function DialogDescription({
1890
+ className,
1891
+ ...props
1892
+ }) {
1893
+ return /* @__PURE__ */ jsx(
1894
+ Dialog$1.Description,
1895
+ {
1896
+ "data-slot": "dialog-description",
1897
+ className: cn(
1898
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
1899
+ className
1900
+ ),
1901
+ ...props
1902
+ }
1903
+ );
1904
+ }
1905
+
1906
+ // src/lib/data-list-view.ts
1907
+ var DATA_LIST_VIEW_TILES = [
1908
+ { value: "table", icon: "fa-table", label: "Table view" },
1909
+ { value: "list", icon: "fa-list", label: "List view" },
1910
+ { value: "board", icon: "fa-table-columns", label: "Board view" },
1911
+ { value: "dashboard", icon: "fa-chart-mixed", label: "Dashboard view" },
1912
+ { value: "calendar", icon: "fa-calendar-days", label: "Calendar view" },
1913
+ { value: "folder", icon: "fa-grid-2", label: "Folder view" },
1914
+ { value: "panel", icon: "fa-sidebar", label: "List & details" },
1915
+ { value: "tree-panel", icon: "fa-sitemap", label: "Tree & details" }
1916
+ ];
1917
+ function dataListViewIcon(view) {
1918
+ return DATA_LIST_VIEW_TILES.find((t) => t.value === view)?.icon ?? "fa-table";
1919
+ }
1920
+ function dataListViewAddShortcut(index) {
1921
+ if (index < 0 || index > 8) return void 0;
1922
+ return String(index + 1);
1923
+ }
1924
+
1925
+ // src/lib/data-list-view-surface.ts
1926
+ function getDataListViewRenderKind(view) {
1927
+ switch (view) {
1928
+ case "table":
1929
+ return "data-table";
1930
+ case "list":
1931
+ return "list-with-toolbar";
1932
+ case "board":
1933
+ return "board-with-toolbar";
1934
+ case "dashboard":
1935
+ return "dashboard-with-toolbar";
1936
+ case "calendar":
1937
+ return "calendar-with-toolbar";
1938
+ case "folder":
1939
+ return "folder-with-toolbar";
1940
+ case "panel":
1941
+ return "panel-with-toolbar";
1942
+ case "tree-panel":
1943
+ return "tree-panel-with-toolbar";
1944
+ default: {
1945
+ const _x = view;
1946
+ return _x;
1947
+ }
1948
+ }
1949
+ }
1950
+
1951
+ // src/lib/data-list-view-registry.ts
1952
+ var DEFINITIONS = DATA_LIST_VIEW_TILES.map((tile) => {
1953
+ const renderKind = getDataListViewRenderKind(tile.value);
1954
+ const hubMetricsStrip = renderKind !== "calendar-with-toolbar" && renderKind !== "dashboard-with-toolbar";
1955
+ return {
1956
+ value: tile.value,
1957
+ label: tile.label,
1958
+ icon: tile.icon,
1959
+ renderKind,
1960
+ hubMetricsStrip
1961
+ };
1962
+ });
1963
+ new Map(
1964
+ DEFINITIONS.map((d) => [d.value, d])
1965
+ );
1966
+ var DATA_LIST_VIEW_REGISTRY = DEFINITIONS;
1967
+ var DATA_LIST_SURFACE_VIEW_TYPES = new Set(
1968
+ DATA_LIST_VIEW_REGISTRY.map((d) => d.value)
1969
+ );
1970
+ function isDataListSurfaceViewType(viewType) {
1971
+ return DATA_LIST_SURFACE_VIEW_TYPES.has(viewType);
1972
+ }
1973
+
1974
+ // src/lib/list-page-table-properties.ts
1975
+ function createListPageEditViewHandler(tableRef, options) {
1976
+ const delay = 160;
1977
+ return (tab, { updateTab }) => {
1978
+ const mustSwitchToTableSurface = !isDataListSurfaceViewType(tab.viewType);
1979
+ if (mustSwitchToTableSurface) {
1980
+ updateTab({ viewType: "table", icon: dataListViewIcon("table") });
1981
+ }
1982
+ window.setTimeout(() => {
1983
+ tableRef.current?.openPropertiesDrawer();
1984
+ }, mustSwitchToTableSurface ? delay : 0);
1985
+ };
1986
+ }
1987
+ function viewSegmentedToolbarClass(className) {
1988
+ return cn(
1989
+ "inline-flex items-center gap-0.5 rounded-lg bg-muted/60 p-[3px]",
1990
+ className
1991
+ );
1992
+ }
1993
+ function viewSegmentedButtonClass(isActive, opts) {
1994
+ return cn(
1995
+ "inline-flex items-center rounded-md transition-all whitespace-nowrap",
1996
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
1997
+ "gap-1.5 px-2.5 py-1 text-xs min-h-8",
1998
+ isActive ? "bg-background text-foreground font-medium shadow-sm" : "text-muted-foreground hover:text-interactive-hover-foreground"
1999
+ );
2000
+ }
2001
+ var VIEW_TYPES = DATA_LIST_VIEW_TILES.map((t) => ({
2002
+ type: t.value,
2003
+ label: t.label,
2004
+ icon: t.icon
2005
+ }));
2006
+ function makeTabId(type) {
2007
+ const rand = Math.random().toString(36).slice(2, 8);
2008
+ return `${type}-${Date.now().toString(36)}-${rand}`;
2009
+ }
2010
+ function viewToolbarCountBadgeClass(filterId, isActive) {
2011
+ const palettes = {
2012
+ all: {
2013
+ active: "bg-slate-600 text-white dark:bg-slate-500",
2014
+ inactive: "bg-slate-100 text-slate-800 dark:bg-slate-800/70 dark:text-slate-100"
2015
+ },
2016
+ upcoming: {
2017
+ active: "bg-amber-600 text-white",
2018
+ inactive: "bg-amber-100 text-amber-950 dark:bg-amber-950/45 dark:text-amber-100"
2019
+ },
2020
+ ongoing: {
2021
+ active: "bg-blue-600 text-white",
2022
+ inactive: "bg-blue-100 text-blue-950 dark:bg-blue-950/45 dark:text-blue-100"
2023
+ },
2024
+ completed: {
2025
+ active: "bg-emerald-600 text-white",
2026
+ inactive: "bg-emerald-100 text-emerald-950 dark:bg-emerald-950/45 dark:text-emerald-100"
2027
+ }
2028
+ };
2029
+ const p = palettes[filterId] ?? palettes.all;
2030
+ return isActive ? p.active : p.inactive;
2031
+ }
2032
+ function ListPageTemplate({
2033
+ header,
2034
+ metrics,
2035
+ showMetrics = true,
2036
+ defaultTabs,
2037
+ tabs: tabsProp,
2038
+ onTabsChange,
2039
+ activeTabId: activeTabIdProp,
2040
+ onActiveTabChange,
2041
+ getTabCount,
2042
+ renderContent,
2043
+ exportOpen = false,
2044
+ onExportOpenChange,
2045
+ exportTotalRows = 0,
2046
+ onEditView,
2047
+ tablePropertiesRef,
2048
+ hideViewsToolbar = false,
2049
+ supportedViewTypes
2050
+ }) {
2051
+ const addableViewTypes = React12.useMemo(() => {
2052
+ if (!supportedViewTypes || supportedViewTypes.length === 0) return VIEW_TYPES;
2053
+ const allowed = new Set(supportedViewTypes);
2054
+ return VIEW_TYPES.filter((v) => allowed.has(v.type));
2055
+ }, [supportedViewTypes]);
2056
+ const controlled = tabsProp !== void 0 && onTabsChange !== void 0 && activeTabIdProp !== void 0 && onActiveTabChange !== void 0;
2057
+ const [internalTabs, setInternalTabs] = React12.useState(defaultTabs);
2058
+ const [internalActiveId, setInternalActiveId] = React12.useState(defaultTabs[0]?.id ?? "");
2059
+ const tabs = controlled ? tabsProp : internalTabs;
2060
+ const setTabsState = React12.useCallback(
2061
+ (action) => {
2062
+ if (controlled) {
2063
+ const next = typeof action === "function" ? action(tabsProp) : action;
2064
+ onTabsChange(next);
2065
+ } else {
2066
+ setInternalTabs(action);
2067
+ }
2068
+ },
2069
+ [controlled, onTabsChange, tabsProp, setInternalTabs]
2070
+ );
2071
+ const activeTabId = controlled ? activeTabIdProp : internalActiveId;
2072
+ const setActiveTabId = controlled ? onActiveTabChange : setInternalActiveId;
2073
+ const [renameOpen, setRenameOpen] = React12.useState(false);
2074
+ const [renameValue, setRenameValue] = React12.useState("");
2075
+ const [renameTabId, setRenameTabId] = React12.useState(null);
2076
+ const [reviewOpen, setReviewOpen] = React12.useState(false);
2077
+ const [reviewTab, setReviewTab] = React12.useState(null);
2078
+ const activeTab = tabs.find((t) => t.id === activeTabId) ?? tabs[0];
2079
+ const editViewFromRef = React12.useMemo(
2080
+ () => tablePropertiesRef ? createListPageEditViewHandler(tablePropertiesRef) : void 0,
2081
+ [tablePropertiesRef]
2082
+ );
2083
+ const resolvedOnEditView = onEditView ?? editViewFromRef;
2084
+ function addView(type) {
2085
+ const def = VIEW_TYPES.find((d) => d.type === type);
2086
+ const count = tabs.filter((t) => t.viewType === type).length;
2087
+ const id = makeTabId(type);
2088
+ const label = count === 0 ? def.label : `${def.label} ${count + 1}`;
2089
+ const newTab = { id, label, viewType: type, icon: def.icon, filterId: "all" };
2090
+ setTabsState((prev) => [...prev, newTab]);
2091
+ setActiveTabId(id);
2092
+ }
2093
+ function removeTab(id, e) {
2094
+ e.stopPropagation();
2095
+ setTabsState((prev) => {
2096
+ const next = prev.filter((t) => t.id !== id);
2097
+ if (activeTabId === id && next.length > 0) {
2098
+ const idx = Math.max(0, prev.findIndex((t) => t.id === id) - 1);
2099
+ setActiveTabId(next[Math.min(idx, next.length - 1)].id);
2100
+ }
2101
+ return next;
2102
+ });
2103
+ }
2104
+ function updateTab(id, patch) {
2105
+ setTabsState((prev) => prev.map((t) => t.id === id ? { ...t, ...patch } : t));
2106
+ }
2107
+ function duplicateTab(tab) {
2108
+ const id = makeTabId(tab.viewType);
2109
+ const newTab = {
2110
+ id,
2111
+ label: `Copy of ${tab.label}`,
2112
+ viewType: tab.viewType,
2113
+ icon: tab.icon,
2114
+ filterId: tab.filterId
2115
+ };
2116
+ setTabsState((prev) => [...prev, newTab]);
2117
+ setActiveTabId(id);
2118
+ }
2119
+ function openRename(tab) {
2120
+ setRenameTabId(tab.id);
2121
+ setRenameValue(tab.label);
2122
+ setRenameOpen(true);
2123
+ }
2124
+ function commitRename() {
2125
+ if (!renameTabId) return;
2126
+ const v = renameValue.trim();
2127
+ if (v) updateTab(renameTabId, { label: v });
2128
+ setRenameOpen(false);
2129
+ setRenameTabId(null);
2130
+ }
2131
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2132
+ !hideViewsToolbar && addableViewTypes.slice(0, 9).map((v, i) => {
2133
+ const keys = dataListViewAddShortcut(i);
2134
+ return keys ? /* @__PURE__ */ jsx(
2135
+ Shortcut,
2136
+ {
2137
+ keys,
2138
+ onInvoke: () => addView(v.type)
2139
+ },
2140
+ v.type
2141
+ ) : null;
2142
+ }),
2143
+ activeTab && !hideViewsToolbar && /* @__PURE__ */ jsxs(Fragment, { children: [
2144
+ /* @__PURE__ */ jsx(Shortcut, { keys: "F2", onInvoke: () => openRename(activeTab) }),
2145
+ /* @__PURE__ */ jsx(
2146
+ Shortcut,
2147
+ {
2148
+ keys: "\u2318E",
2149
+ disabled: !resolvedOnEditView,
2150
+ onInvoke: () => resolvedOnEditView?.(activeTab, { updateTab: (p) => updateTab(activeTab.id, p) })
2151
+ }
2152
+ ),
2153
+ /* @__PURE__ */ jsx(Shortcut, { keys: "\u2318D", onInvoke: () => duplicateTab(activeTab) }),
2154
+ /* @__PURE__ */ jsx(Shortcut, { keys: "\u2318I", onInvoke: () => {
2155
+ setReviewTab(activeTab);
2156
+ setReviewOpen(true);
2157
+ } }),
2158
+ /* @__PURE__ */ jsx(
2159
+ Shortcut,
2160
+ {
2161
+ keys: "\u2318\u232B",
2162
+ disabled: tabs.length <= 1,
2163
+ onInvoke: (e) => removeTab(activeTab.id, e)
2164
+ }
2165
+ )
2166
+ ] }),
2167
+ header,
2168
+ showMetrics && metrics,
2169
+ !hideViewsToolbar && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", { className: "mt-3 shrink-0 overflow-x-auto px-4 lg:px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex w-max items-center gap-1 py-1.5", children: [
2170
+ /* @__PURE__ */ jsx(
2171
+ "div",
2172
+ {
2173
+ role: "toolbar",
2174
+ "aria-label": "Views",
2175
+ "data-slot": "view-segmented-toolbar",
2176
+ className: viewSegmentedToolbarClass(),
2177
+ children: tabs.map((tab) => {
2178
+ const isActive = tab.id === activeTabId;
2179
+ const isOnly = tabs.length === 1;
2180
+ const count = getTabCount?.(tab.filterId);
2181
+ const tabInner = /* @__PURE__ */ jsxs(Fragment, { children: [
2182
+ /* @__PURE__ */ jsx("i", { className: cn("fa-light shrink-0 text-xs", tab.icon), "aria-hidden": "true" }),
2183
+ tab.label,
2184
+ count !== void 0 && /* @__PURE__ */ jsx(
2185
+ "span",
2186
+ {
2187
+ "data-slot": "view-toolbar-count",
2188
+ className: cn(
2189
+ "text-xs tabular-nums rounded-full px-1 py-px min-w-[1.125rem] text-center font-semibold",
2190
+ viewToolbarCountBadgeClass(tab.filterId, isActive)
2191
+ ),
2192
+ children: count
2193
+ }
2194
+ )
2195
+ ] });
2196
+ const viewSettingsMenu = /* @__PURE__ */ jsxs(DropdownMenu, { children: [
2197
+ /* @__PURE__ */ jsx(Tip, { label: "View settings", side: "bottom", children: /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
2198
+ "button",
2199
+ {
2200
+ type: "button",
2201
+ className: cn(
2202
+ "inline-flex items-center justify-center min-h-8 min-w-6 shrink-0 rounded-e-md rounded-s-none px-0.5",
2203
+ "text-muted-foreground hover:text-interactive-hover-foreground hover:bg-foreground/[0.04]",
2204
+ "transition-colors",
2205
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:z-10"
2206
+ ),
2207
+ "aria-label": "View settings",
2208
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
2209
+ }
2210
+ ) }) }),
2211
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", children: [
2212
+ /* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "text-xs text-muted-foreground", children: [
2213
+ "View: ",
2214
+ VIEW_TYPES.find((v) => v.type === tab.viewType)?.label
2215
+ ] }),
2216
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2217
+ /* @__PURE__ */ jsxs(
2218
+ DropdownMenuItem,
2219
+ {
2220
+ shortcut: "F2",
2221
+ onSelect: () => openRename(tab),
2222
+ children: [
2223
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-pen text-xs", "aria-hidden": "true" }),
2224
+ "Rename"
2225
+ ]
2226
+ }
2227
+ ),
2228
+ /* @__PURE__ */ jsxs(
2229
+ DropdownMenuItem,
2230
+ {
2231
+ disabled: !resolvedOnEditView,
2232
+ shortcut: "\u2318E",
2233
+ onSelect: () => resolvedOnEditView?.(tab, { updateTab: (patch) => updateTab(tab.id, patch) }),
2234
+ children: [
2235
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-sliders text-xs", "aria-hidden": "true" }),
2236
+ "Edit"
2237
+ ]
2238
+ }
2239
+ ),
2240
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { shortcut: "\u2318D", onSelect: () => duplicateTab(tab), children: [
2241
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-copy text-xs", "aria-hidden": "true" }),
2242
+ "Duplicate"
2243
+ ] }),
2244
+ /* @__PURE__ */ jsxs(
2245
+ DropdownMenuItem,
2246
+ {
2247
+ shortcut: "\u2318I",
2248
+ onSelect: () => {
2249
+ setReviewTab(tab);
2250
+ setReviewOpen(true);
2251
+ },
2252
+ children: [
2253
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-clipboard-list text-xs", "aria-hidden": "true" }),
2254
+ "Review view"
2255
+ ]
2256
+ }
2257
+ ),
2258
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2259
+ !isOnly && /* @__PURE__ */ jsxs(
2260
+ DropdownMenuItem,
2261
+ {
2262
+ shortcut: "\u2318\u232B",
2263
+ onSelect: (e) => removeTab(tab.id, e),
2264
+ className: "text-destructive focus:text-destructive",
2265
+ children: [
2266
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-trash text-xs", "aria-hidden": "true" }),
2267
+ "Remove view"
2268
+ ]
2269
+ }
2270
+ )
2271
+ ] })
2272
+ ] });
2273
+ return /* @__PURE__ */ jsxs("div", { className: "group relative inline-flex items-center", children: [
2274
+ isActive ? /* @__PURE__ */ jsxs(
2275
+ "div",
2276
+ {
2277
+ className: cn(
2278
+ viewSegmentedButtonClass(true),
2279
+ "gap-0 p-0 inline-flex items-stretch"
2280
+ ),
2281
+ children: [
2282
+ /* @__PURE__ */ jsx(
2283
+ "button",
2284
+ {
2285
+ type: "button",
2286
+ "aria-pressed": true,
2287
+ "data-slot": "view-segmented-item",
2288
+ onClick: () => setActiveTabId(tab.id),
2289
+ className: cn(
2290
+ "inline-flex items-center gap-1.5 ps-2.5 pe-0.5 py-1 text-xs min-h-8",
2291
+ "rounded-s-md rounded-e-none",
2292
+ "bg-transparent text-foreground font-medium",
2293
+ "hover:bg-foreground/[0.04]",
2294
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:z-10"
2295
+ ),
2296
+ children: tabInner
2297
+ }
2298
+ ),
2299
+ viewSettingsMenu
2300
+ ]
2301
+ }
2302
+ ) : /* @__PURE__ */ jsx(
2303
+ "button",
2304
+ {
2305
+ type: "button",
2306
+ "aria-pressed": false,
2307
+ "data-slot": "view-segmented-item",
2308
+ onClick: () => setActiveTabId(tab.id),
2309
+ className: cn(
2310
+ viewSegmentedButtonClass(false),
2311
+ /* Tighter trailing edge when remove control follows */
2312
+ !isOnly && "pe-1.5"
2313
+ ),
2314
+ children: tabInner
2315
+ }
2316
+ ),
2317
+ !isActive && !isOnly && /* @__PURE__ */ jsx(Tip, { side: "bottom", label: `Remove ${tab.label} view`, children: /* @__PURE__ */ jsx(
2318
+ "button",
2319
+ {
2320
+ type: "button",
2321
+ "aria-label": `Remove ${tab.label} view`,
2322
+ onClick: (e) => removeTab(tab.id, e),
2323
+ className: "inline-flex items-center justify-center size-6 min-h-6 min-w-6 rounded transition-opacity opacity-0 group-hover:opacity-60 hover:!opacity-100 hover:text-destructive focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2324
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark text-xs", "aria-hidden": "true" })
2325
+ }
2326
+ ) })
2327
+ ] }, tab.id);
2328
+ })
2329
+ }
2330
+ ),
2331
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
2332
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2333
+ Button,
2334
+ {
2335
+ type: "button",
2336
+ variant: "ghost",
2337
+ className: "shrink-0 text-muted-foreground",
2338
+ children: [
2339
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-plus text-sm", "aria-hidden": "true" }),
2340
+ "Add view"
2341
+ ]
2342
+ }
2343
+ ) }),
2344
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", children: [
2345
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs", children: "Add a view" }),
2346
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2347
+ addableViewTypes.map((v, i) => /* @__PURE__ */ jsxs(
2348
+ DropdownMenuItem,
2349
+ {
2350
+ shortcut: dataListViewAddShortcut(i),
2351
+ onSelect: () => addView(v.type),
2352
+ children: [
2353
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${v.icon}`, "aria-hidden": "true" }),
2354
+ v.label
2355
+ ]
2356
+ },
2357
+ v.type
2358
+ ))
2359
+ ] })
2360
+ ] })
2361
+ ] }) }) }),
2362
+ activeTab ? /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: renderContent(activeTab, (patch) => updateTab(activeTab.id, patch)) }, activeTab.id) : null,
2363
+ onExportOpenChange && /* @__PURE__ */ jsx(
2364
+ ExportDrawer,
2365
+ {
2366
+ open: exportOpen,
2367
+ onOpenChange: onExportOpenChange,
2368
+ totalRows: exportTotalRows ?? getTabCount?.(activeTab.filterId) ?? 0
2369
+ }
2370
+ ),
2371
+ /* @__PURE__ */ jsx(Dialog, { open: renameOpen, onOpenChange: setRenameOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-sm", children: [
2372
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2373
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Rename view" }),
2374
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Enter a new name for this view." })
2375
+ ] }),
2376
+ /* @__PURE__ */ jsx(
2377
+ Input,
2378
+ {
2379
+ className: "mt-3 h-9 text-sm",
2380
+ value: renameValue,
2381
+ onChange: (e) => setRenameValue(e.target.value),
2382
+ onKeyDown: (e) => {
2383
+ if (e.key === "Enter") commitRename();
2384
+ },
2385
+ autoFocus: true,
2386
+ "aria-label": "View name"
2387
+ }
2388
+ ),
2389
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
2390
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setRenameOpen(false), children: "Cancel" }),
2391
+ /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: commitRename, children: "Save" })
2392
+ ] })
2393
+ ] }) }),
2394
+ /* @__PURE__ */ jsx(
2395
+ Dialog,
2396
+ {
2397
+ open: reviewOpen && !!reviewTab,
2398
+ onOpenChange: (open) => {
2399
+ setReviewOpen(open);
2400
+ if (!open) setReviewTab(null);
2401
+ },
2402
+ children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-md", children: [
2403
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2404
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Review view" }),
2405
+ /* @__PURE__ */ jsx(DialogDescription, { children: "Summary of this view\u2019s configuration." })
2406
+ ] }),
2407
+ reviewTab && /* @__PURE__ */ jsxs("dl", { className: "mt-2 space-y-3 text-sm", children: [
2408
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4 border-b border-border pb-2", children: [
2409
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Name" }),
2410
+ /* @__PURE__ */ jsx("dd", { className: "font-medium text-foreground text-end", children: reviewTab.label })
2411
+ ] }),
2412
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4 border-b border-border pb-2", children: [
2413
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "View type" }),
2414
+ /* @__PURE__ */ jsx("dd", { className: "text-foreground text-end", children: VIEW_TYPES.find((v) => v.type === reviewTab.viewType)?.label })
2415
+ ] }),
2416
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4 border-b border-border pb-2", children: [
2417
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Lifecycle filter" }),
2418
+ /* @__PURE__ */ jsx("dd", { className: "text-foreground text-end capitalize", children: reviewTab.filterId })
2419
+ ] }),
2420
+ getTabCount && /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-4", children: [
2421
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Row count" }),
2422
+ /* @__PURE__ */ jsx("dd", { className: "tabular-nums text-foreground text-end", children: getTabCount(reviewTab.filterId) })
2423
+ ] })
2424
+ ] }),
2425
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: () => setReviewOpen(false), children: "Close" }) })
2426
+ ] })
2427
+ }
2428
+ )
2429
+ ] });
2430
+ }
2431
+ function NestedSecondaryPanelShell({
2432
+ open,
2433
+ compact,
2434
+ children,
2435
+ "aria-label": ariaLabel = "Secondary navigation",
2436
+ className
2437
+ }) {
2438
+ return /* @__PURE__ */ jsx(
2439
+ "nav",
2440
+ {
2441
+ "aria-label": ariaLabel,
2442
+ "data-state": open ? "open" : "closed",
2443
+ "data-layout": open ? compact ? "icon" : "expanded" : "closed",
2444
+ suppressHydrationWarning: true,
2445
+ className: cn(
2446
+ "flex flex-col overflow-hidden",
2447
+ "transition-[width,margin,opacity] duration-200 ease-linear",
2448
+ open ? cn(
2449
+ // Match the primary sidebar: fill the full viewport height
2450
+ // (minus our 0.5rem top + 0.5rem bottom margin from `m-2` →
2451
+ // 1rem on desktop where the panel is `md:sticky md:top-2`;
2452
+ // 2rem on mobile where the panel scrolls inline and we leave
2453
+ // a little more breathing room). No upper cap so tall screens
2454
+ // get a fully-extended rail.
2455
+ "shrink-0 m-2 mx-2 rounded-xl ring-1 ring-sidebar-border shadow-sm relative md:sticky md:top-2 bg-[var(--secondary-panel-bg)]",
2456
+ compact ? "w-12 min-w-12 max-w-12 h-[calc(100svh-2rem)] md:h-[calc(100svh-1rem)]" : "w-64 min-w-64 max-w-64 h-[calc(100svh-2rem)] md:h-[calc(100svh-1rem)]"
2457
+ ) : "h-0 min-h-0 shrink overflow-hidden border-0 p-0 m-0 min-w-0 w-0 max-w-0 opacity-0 pointer-events-none",
2458
+ className
2459
+ ),
2460
+ children: /* @__PURE__ */ jsx(
2461
+ "div",
2462
+ {
2463
+ className: cn(
2464
+ "flex flex-1 flex-col overflow-y-auto overflow-x-hidden",
2465
+ open ? "min-w-0" : "hidden min-w-0 w-0 p-0"
2466
+ ),
2467
+ children
2468
+ }
2469
+ )
2470
+ }
2471
+ );
2472
+ }
2473
+ var LIST_PAGE_VIEW_FRAME_GUTTER = "mx-4 mb-6 lg:mx-6";
2474
+ function ListPageViewFrame({
2475
+ children,
2476
+ className,
2477
+ maxWidthClassName,
2478
+ gutterClassName = LIST_PAGE_VIEW_FRAME_GUTTER,
2479
+ ...rest
2480
+ }) {
2481
+ 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 });
2482
+ }
2483
+ function mulberry32(seed) {
2484
+ let s = seed >>> 0;
2485
+ return () => {
2486
+ s = s + 1831565813 >>> 0;
2487
+ let t = s;
2488
+ t = Math.imul(t ^ t >>> 15, t | 1);
2489
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
2490
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
2491
+ };
2492
+ }
2493
+ function hashString(str) {
2494
+ let h = 2166136261;
2495
+ for (let i = 0; i < str.length; i++) {
2496
+ h ^= str.charCodeAt(i);
2497
+ h = Math.imul(h, 16777619);
2498
+ }
2499
+ return h >>> 0;
2500
+ }
2501
+ function DotPattern({
2502
+ width = 14,
2503
+ height = 14,
2504
+ x = 0,
2505
+ y = 0,
2506
+ cx = 1,
2507
+ cy = 1,
2508
+ cr = 0.8,
2509
+ className,
2510
+ glow = false,
2511
+ glowCount = 2,
2512
+ glowRadius = 240,
2513
+ ...props
2514
+ }) {
2515
+ const id = React12.useId();
2516
+ const maskId = `${id}-mask`;
2517
+ const gradId = `${id}-grad`;
2518
+ const clouds = React12.useMemo(() => {
2519
+ const rng = mulberry32(hashString(`${id}|${glowCount}`));
2520
+ const rand = (min, max) => min + rng() * (max - min);
2521
+ return Array.from({ length: glowCount }).map((_, i) => {
2522
+ const startX = rand(85, 120);
2523
+ const endX = rand(-20, 15);
2524
+ const midX = (startX + endX) / 2 + rand(-6, 6);
2525
+ const startY = rand(85, 115);
2526
+ const endY = rand(-15, 10);
2527
+ const midY = (startY + endY) / 2 + rand(-4, 4);
2528
+ const duration = rand(8, 12);
2529
+ const delay = -(i / glowCount) * duration;
2530
+ return {
2531
+ key: i,
2532
+ xs: [`${startX}%`, `${midX}%`, `${endX}%`],
2533
+ ys: [`${startY}%`, `${midY}%`, `${endY}%`],
2534
+ duration,
2535
+ delay
2536
+ };
2537
+ });
2538
+ }, [glowCount, id]);
2539
+ return /* @__PURE__ */ jsxs(
2540
+ "svg",
2541
+ {
2542
+ "aria-hidden": "true",
2543
+ className: cn(
2544
+ "pointer-events-none absolute inset-0 h-full w-full fill-neutral-400/80",
2545
+ className
2546
+ ),
2547
+ ...props,
2548
+ children: [
2549
+ /* @__PURE__ */ jsxs("defs", { children: [
2550
+ /* @__PURE__ */ jsx(
2551
+ "pattern",
2552
+ {
2553
+ id,
2554
+ width,
2555
+ height,
2556
+ patternUnits: "userSpaceOnUse",
2557
+ patternContentUnits: "userSpaceOnUse",
2558
+ x,
2559
+ y,
2560
+ children: /* @__PURE__ */ jsx("circle", { cx, cy, r: cr })
2561
+ }
2562
+ ),
2563
+ glow ? /* @__PURE__ */ jsxs(Fragment, { children: [
2564
+ /* @__PURE__ */ jsxs("radialGradient", { id: gradId, children: [
2565
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "white", stopOpacity: "0.9" }),
2566
+ /* @__PURE__ */ jsx("stop", { offset: "40%", stopColor: "white", stopOpacity: "0.55" }),
2567
+ /* @__PURE__ */ jsx("stop", { offset: "75%", stopColor: "white", stopOpacity: "0.18" }),
2568
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "white", stopOpacity: "0" })
2569
+ ] }),
2570
+ /* @__PURE__ */ jsx("mask", { id: maskId, children: clouds.map((c) => /* @__PURE__ */ jsx(
2571
+ motion.circle,
2572
+ {
2573
+ r: glowRadius,
2574
+ fill: `url(#${gradId})`,
2575
+ initial: { cx: c.xs[0], cy: c.ys[0], opacity: 0 },
2576
+ animate: {
2577
+ cx: c.xs,
2578
+ cy: c.ys,
2579
+ // Long hold with soft fade at both ends.
2580
+ opacity: [0, 1, 1, 0]
2581
+ },
2582
+ transition: {
2583
+ duration: c.duration,
2584
+ delay: c.delay,
2585
+ repeat: Infinity,
2586
+ ease: "linear",
2587
+ times: [0, 0.3, 0.7, 1]
2588
+ }
2589
+ },
2590
+ `cloud-${c.key}`
2591
+ )) })
2592
+ ] }) : null
2593
+ ] }),
2594
+ /* @__PURE__ */ jsx(
2595
+ "rect",
2596
+ {
2597
+ width: "100%",
2598
+ height: "100%",
2599
+ strokeWidth: 0,
2600
+ fill: `url(#${id})`,
2601
+ mask: glow ? `url(#${maskId})` : void 0
2602
+ }
2603
+ )
2604
+ ]
2605
+ }
2606
+ );
2607
+ }
2608
+ var DEFAULT_GUTTER = "mx-auto flex min-h-[min(72vh,36rem)] w-full min-w-0 flex-col justify-center gap-0 px-6 py-8 sm:px-8 sm:py-10 md:px-12 md:py-12 lg:px-16";
2609
+ var HERO_BACKDROP_MASK = "[mask-image:linear-gradient(to_bottom,transparent_0%,black_5%,black_95%,transparent_100%)] [-webkit-mask-image:linear-gradient(to_bottom,transparent_0%,black_5%,black_95%,transparent_100%)]";
2610
+ function DedicatedSearchLandingBackdrop() {
2611
+ return /* @__PURE__ */ jsxs(
2612
+ "div",
2613
+ {
2614
+ "aria-hidden": true,
2615
+ className: cn(
2616
+ "pointer-events-none absolute inset-0 -z-10 select-none overflow-hidden",
2617
+ HERO_BACKDROP_MASK
2618
+ ),
2619
+ children: [
2620
+ /* @__PURE__ */ jsx(
2621
+ "div",
2622
+ {
2623
+ className: "absolute -left-[20%] -top-[30%] h-[min(54vmin,27rem)] w-[min(54vmin,27rem)] rounded-full blur-[76px]",
2624
+ style: {
2625
+ background: "radial-gradient(circle at 42% 36%, var(--leo-surface-tint-b) 0%, transparent 68%)"
2626
+ }
2627
+ }
2628
+ ),
2629
+ /* @__PURE__ */ jsx(
2630
+ "div",
2631
+ {
2632
+ className: "absolute -right-[12%] top-[2%] h-[min(46vmin,23rem)] w-[min(46vmin,23rem)] rounded-full blur-[68px]",
2633
+ style: {
2634
+ background: "radial-gradient(circle at 48% 48%, var(--leo-surface-tint-a) 0%, transparent 66%)"
2635
+ }
2636
+ }
2637
+ ),
2638
+ /* @__PURE__ */ jsx(
2639
+ "div",
2640
+ {
2641
+ className: "absolute bottom-[-16%] left-[14%] h-[min(50vmin,25rem)] w-[min(50vmin,25rem)] rounded-full blur-[84px]",
2642
+ style: {
2643
+ background: "radial-gradient(circle at 44% 40%, var(--leo-surface-tint-b) 0%, transparent 70%)"
2644
+ }
2645
+ }
2646
+ ),
2647
+ /* @__PURE__ */ jsx(
2648
+ "div",
2649
+ {
2650
+ className: "absolute bottom-[4%] right-[6%] h-[min(40vmin,20rem)] w-[min(40vmin,20rem)] rounded-full blur-[60px]",
2651
+ style: {
2652
+ background: "radial-gradient(circle at 52% 44%, var(--leo-surface-tint-a) 0%, transparent 72%)"
2653
+ }
2654
+ }
2655
+ ),
2656
+ /* @__PURE__ */ jsx(
2657
+ "div",
2658
+ {
2659
+ className: "absolute left-[36%] top-[32%] h-[min(38vmin,19rem)] w-[min(38vmin,19rem)] -translate-x-1/2 rounded-full blur-[74px]",
2660
+ style: {
2661
+ background: "radial-gradient(circle at 50% 50%, var(--leo-surface-tint-b) 0%, transparent 68%)"
2662
+ }
2663
+ }
2664
+ ),
2665
+ /* @__PURE__ */ jsx(
2666
+ DotPattern,
2667
+ {
2668
+ width: 15,
2669
+ height: 15,
2670
+ cr: 0.65,
2671
+ className: cn(
2672
+ "absolute inset-0 opacity-[0.34] mix-blend-multiply dark:opacity-[0.22] dark:mix-blend-soft-light",
2673
+ "fill-[color-mix(in_oklch,var(--brand-color)_14%,var(--background))]"
2674
+ )
2675
+ }
2676
+ )
2677
+ ]
2678
+ }
2679
+ );
2680
+ }
2681
+ function DedicatedSearchLandingTemplate({
2682
+ title,
2683
+ composer,
2684
+ trailing,
2685
+ maxWidthClassName = "max-w-5xl",
2686
+ frameClassName = "min-w-0",
2687
+ gutterClassName = DEFAULT_GUTTER
2688
+ }) {
2689
+ return /* @__PURE__ */ jsxs("div", { className: "relative isolate min-w-0 w-full overflow-hidden", children: [
2690
+ /* @__PURE__ */ jsx(DedicatedSearchLandingBackdrop, {}),
2691
+ /* @__PURE__ */ jsxs(
2692
+ ListPageViewFrame,
2693
+ {
2694
+ maxWidthClassName,
2695
+ className: cn("relative z-10", frameClassName),
2696
+ gutterClassName,
2697
+ children: [
2698
+ /* @__PURE__ */ jsx("header", { className: "min-w-0", children: typeof title === "string" ? /* @__PURE__ */ jsx(
2699
+ "h1",
2700
+ {
2701
+ className: "text-balance text-3xl font-semibold tracking-tight text-foreground sm:text-4xl",
2702
+ style: { fontFamily: "var(--font-heading)" },
2703
+ children: title
2704
+ }
2705
+ ) : title }),
2706
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 mt-6 sm:mt-8", children: composer }),
2707
+ trailing ? /* @__PURE__ */ jsx("div", { className: "min-w-0 mt-10 sm:mt-12 md:mt-14 lg:mt-16", children: trailing }) : null
2708
+ ]
2709
+ }
2710
+ )
2711
+ ] });
2712
+ }
2713
+ var DEDICATED_SEARCH_RESULTS_OUTER_CONTENT_CLASSNAME = "border-t border-border/40 bg-gradient-to-b from-muted/25 via-background to-background";
2714
+ function DedicatedSearchResultsHeaderChrome({ children, className }) {
2715
+ return /* @__PURE__ */ jsx("div", { className: cn("border-b border-border/50 bg-muted/15", className), children });
2716
+ }
2717
+
2718
+ export { DEDICATED_SEARCH_RESULTS_OUTER_CONTENT_CLASSNAME, DedicatedSearchLandingTemplate, DedicatedSearchResultsHeaderChrome, ListPageTemplate, NestedSecondaryPanelShell, VIEW_TYPES };
2719
+ //# sourceMappingURL=index.js.map
2720
+ //# sourceMappingURL=index.js.map