@exxatdesignux/ui 0.2.19 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/CHANGELOG.md +60 -7
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +42 -7
  4. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
  5. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
  6. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
  7. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
  8. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
  9. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
  10. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
  11. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
  12. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
  13. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
  14. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
  15. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
  16. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
  17. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
  18. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
  19. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
  20. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
  21. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  23. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  24. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  25. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  26. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  27. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  28. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
  29. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
  30. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
  31. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
  32. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
  33. package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
  34. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +4 -15
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
  39. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  40. package/consumer-extras/handbook/glossary.md +57 -0
  41. package/consumer-extras/handbook/reference-implementations.md +126 -0
  42. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  43. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  44. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  45. package/consumer-extras/patterns/data-views-pattern.md +17 -54
  46. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  47. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  48. package/dist/components/data-table/filter-date-calendar.js +280 -0
  49. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  50. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  51. package/dist/components/data-table/filter-text-value-input.js +561 -0
  52. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  53. package/dist/components/data-table/index.d.ts +45 -0
  54. package/dist/components/data-table/index.js +3085 -0
  55. package/dist/components/data-table/index.js.map +1 -0
  56. package/dist/components/data-table/pagination.d.ts +28 -0
  57. package/dist/components/data-table/pagination.js +3264 -0
  58. package/dist/components/data-table/pagination.js.map +1 -0
  59. package/dist/components/data-table/types.d.ts +84 -0
  60. package/dist/components/data-table/types.js +3 -0
  61. package/dist/components/data-table/types.js.map +1 -0
  62. package/dist/components/data-table/use-table-state.d.ts +116 -0
  63. package/dist/components/data-table/use-table-state.js +670 -0
  64. package/dist/components/data-table/use-table-state.js.map +1 -0
  65. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  66. package/dist/components/data-views/board-card-primitives.js +84 -0
  67. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  68. package/dist/components/data-views/data-row-list.d.ts +33 -0
  69. package/dist/components/data-views/data-row-list.js +106 -0
  70. package/dist/components/data-views/data-row-list.js.map +1 -0
  71. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  72. package/dist/components/data-views/finder-panel-view.js +388 -0
  73. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  74. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  75. package/dist/components/data-views/folder-grid-view.js +58 -0
  76. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  77. package/dist/components/data-views/hub-table.d.ts +167 -0
  78. package/dist/components/data-views/hub-table.js +5561 -0
  79. package/dist/components/data-views/hub-table.js.map +1 -0
  80. package/dist/components/data-views/index.d.ts +27 -0
  81. package/dist/components/data-views/index.js +6575 -0
  82. package/dist/components/data-views/index.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  84. package/dist/components/data-views/list-page-board-card.js +264 -0
  85. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  86. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  87. package/dist/components/data-views/list-page-board-template.js +137 -0
  88. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  89. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  90. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  91. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  93. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  94. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  96. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  97. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  98. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  99. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  100. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  102. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  103. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  104. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  105. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  106. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  107. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  108. package/dist/components/data-views/os-folder-glyph.js +104 -0
  109. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  110. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  111. package/dist/components/data-views/outline-tree-menu.js +131 -0
  112. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  113. package/dist/components/table-properties/column-row.d.ts +22 -0
  114. package/dist/components/table-properties/column-row.js +153 -0
  115. package/dist/components/table-properties/column-row.js.map +1 -0
  116. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  117. package/dist/components/table-properties/draggable-list.js +53 -0
  118. package/dist/components/table-properties/draggable-list.js.map +1 -0
  119. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  120. package/dist/components/table-properties/drawer-button.js +2748 -0
  121. package/dist/components/table-properties/drawer-button.js.map +1 -0
  122. package/dist/components/table-properties/drawer.d.ts +100 -0
  123. package/dist/components/table-properties/drawer.js +2595 -0
  124. package/dist/components/table-properties/drawer.js.map +1 -0
  125. package/dist/components/table-properties/filter-card.d.ts +24 -0
  126. package/dist/components/table-properties/filter-card.js +854 -0
  127. package/dist/components/table-properties/filter-card.js.map +1 -0
  128. package/dist/components/table-properties/index.d.ts +14 -0
  129. package/dist/components/table-properties/index.js +2768 -0
  130. package/dist/components/table-properties/index.js.map +1 -0
  131. package/dist/components/table-properties/sort-card.d.ts +20 -0
  132. package/dist/components/table-properties/sort-card.js +102 -0
  133. package/dist/components/table-properties/sort-card.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  135. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  136. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  137. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  138. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  139. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  140. package/dist/components/templates/index.d.ts +9 -0
  141. package/dist/components/templates/index.js +2720 -0
  142. package/dist/components/templates/index.js.map +1 -0
  143. package/dist/components/templates/list-page.d.ts +83 -0
  144. package/dist/components/templates/list-page.js +2433 -0
  145. package/dist/components/templates/list-page.js.map +1 -0
  146. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  147. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  148. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  149. package/dist/components/ui/accordion.d.ts +10 -0
  150. package/dist/components/ui/accordion.js +74 -0
  151. package/dist/components/ui/accordion.js.map +1 -0
  152. package/dist/components/ui/alert-dialog.d.ts +37 -0
  153. package/dist/components/ui/alert-dialog.js +201 -0
  154. package/dist/components/ui/alert-dialog.js.map +1 -0
  155. package/dist/components/ui/avatar.d.ts +84 -0
  156. package/dist/components/ui/avatar.js +328 -0
  157. package/dist/components/ui/avatar.js.map +1 -0
  158. package/dist/components/ui/badge.d.ts +13 -0
  159. package/dist/components/ui/badge.js +49 -0
  160. package/dist/components/ui/badge.js.map +1 -0
  161. package/dist/components/ui/banner.d.ts +62 -0
  162. package/dist/components/ui/banner.js +364 -0
  163. package/dist/components/ui/banner.js.map +1 -0
  164. package/dist/components/ui/breadcrumb.d.ts +14 -0
  165. package/dist/components/ui/breadcrumb.js +114 -0
  166. package/dist/components/ui/breadcrumb.js.map +1 -0
  167. package/dist/components/ui/button.d.ts +16 -0
  168. package/dist/components/ui/button.js +59 -0
  169. package/dist/components/ui/button.js.map +1 -0
  170. package/dist/components/ui/calendar.d.ts +13 -0
  171. package/dist/components/ui/calendar.js +238 -0
  172. package/dist/components/ui/calendar.js.map +1 -0
  173. package/dist/components/ui/card.d.ts +14 -0
  174. package/dist/components/ui/card.js +102 -0
  175. package/dist/components/ui/card.js.map +1 -0
  176. package/dist/components/ui/chart.d.ts +58 -0
  177. package/dist/components/ui/chart.js +292 -0
  178. package/dist/components/ui/chart.js.map +1 -0
  179. package/dist/components/ui/checkbox.d.ts +23 -0
  180. package/dist/components/ui/checkbox.js +155 -0
  181. package/dist/components/ui/checkbox.js.map +1 -0
  182. package/dist/components/ui/coach-mark.d.ts +27 -0
  183. package/dist/components/ui/coach-mark.js +306 -0
  184. package/dist/components/ui/coach-mark.js.map +1 -0
  185. package/dist/components/ui/collapsible.d.ts +8 -0
  186. package/dist/components/ui/collapsible.js +35 -0
  187. package/dist/components/ui/collapsible.js.map +1 -0
  188. package/dist/components/ui/command.d.ts +36 -0
  189. package/dist/components/ui/command.js +274 -0
  190. package/dist/components/ui/command.js.map +1 -0
  191. package/dist/components/ui/context-menu.d.ts +32 -0
  192. package/dist/components/ui/context-menu.js +245 -0
  193. package/dist/components/ui/context-menu.js.map +1 -0
  194. package/dist/components/ui/date-picker-field.d.ts +38 -0
  195. package/dist/components/ui/date-picker-field.js +550 -0
  196. package/dist/components/ui/date-picker-field.js.map +1 -0
  197. package/dist/components/ui/dialog.d.ts +22 -0
  198. package/dist/components/ui/dialog.js +200 -0
  199. package/dist/components/ui/dialog.js.map +1 -0
  200. package/dist/components/ui/dot-pattern.d.ts +21 -0
  201. package/dist/components/ui/dot-pattern.js +139 -0
  202. package/dist/components/ui/dot-pattern.js.map +1 -0
  203. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  204. package/dist/components/ui/drag-handle-grip.js +15 -0
  205. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  206. package/dist/components/ui/drawer.d.ts +16 -0
  207. package/dist/components/ui/drawer.js +125 -0
  208. package/dist/components/ui/drawer.js.map +1 -0
  209. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  210. package/dist/components/ui/dropdown-menu.js +353 -0
  211. package/dist/components/ui/dropdown-menu.js.map +1 -0
  212. package/dist/components/ui/export-drawer.d.ts +11 -0
  213. package/dist/components/ui/export-drawer.js +1658 -0
  214. package/dist/components/ui/export-drawer.js.map +1 -0
  215. package/dist/components/ui/field.d.ts +30 -0
  216. package/dist/components/ui/field.js +249 -0
  217. package/dist/components/ui/field.js.map +1 -0
  218. package/dist/components/ui/form.d.ts +28 -0
  219. package/dist/components/ui/form.js +110 -0
  220. package/dist/components/ui/form.js.map +1 -0
  221. package/dist/components/ui/hover-card.d.ts +9 -0
  222. package/dist/components/ui/hover-card.js +43 -0
  223. package/dist/components/ui/hover-card.js.map +1 -0
  224. package/dist/components/ui/input-group.d.ts +20 -0
  225. package/dist/components/ui/input-group.js +219 -0
  226. package/dist/components/ui/input-group.js.map +1 -0
  227. package/dist/components/ui/input-mask.d.ts +39 -0
  228. package/dist/components/ui/input-mask.js +118 -0
  229. package/dist/components/ui/input-mask.js.map +1 -0
  230. package/dist/components/ui/input.d.ts +5 -0
  231. package/dist/components/ui/input.js +30 -0
  232. package/dist/components/ui/input.js.map +1 -0
  233. package/dist/components/ui/kbd.d.ts +20 -0
  234. package/dist/components/ui/kbd.js +45 -0
  235. package/dist/components/ui/kbd.js.map +1 -0
  236. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  237. package/dist/components/ui/key-metrics-context.js +26 -0
  238. package/dist/components/ui/key-metrics-context.js.map +1 -0
  239. package/dist/components/ui/key-metrics.d.ts +131 -0
  240. package/dist/components/ui/key-metrics.js +1015 -0
  241. package/dist/components/ui/key-metrics.js.map +1 -0
  242. package/dist/components/ui/label.d.ts +6 -0
  243. package/dist/components/ui/label.js +28 -0
  244. package/dist/components/ui/label.js.map +1 -0
  245. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  246. package/dist/components/ui/list-page-view-frame.js +24 -0
  247. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  248. package/dist/components/ui/page-header.d.ts +51 -0
  249. package/dist/components/ui/page-header.js +372 -0
  250. package/dist/components/ui/page-header.js.map +1 -0
  251. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  252. package/dist/components/ui/payment-card-fields.js +80 -0
  253. package/dist/components/ui/payment-card-fields.js.map +1 -0
  254. package/dist/components/ui/popover.d.ts +10 -0
  255. package/dist/components/ui/popover.js +47 -0
  256. package/dist/components/ui/popover.js.map +1 -0
  257. package/dist/components/ui/radio-group.d.ts +29 -0
  258. package/dist/components/ui/radio-group.js +190 -0
  259. package/dist/components/ui/radio-group.js.map +1 -0
  260. package/dist/components/ui/resizable.d.ts +16 -0
  261. package/dist/components/ui/resizable.js +51 -0
  262. package/dist/components/ui/resizable.js.map +1 -0
  263. package/dist/components/ui/scroll-area.d.ts +8 -0
  264. package/dist/components/ui/scroll-area.js +66 -0
  265. package/dist/components/ui/scroll-area.js.map +1 -0
  266. package/dist/components/ui/select.d.ts +18 -0
  267. package/dist/components/ui/select.js +186 -0
  268. package/dist/components/ui/select.js.map +1 -0
  269. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  270. package/dist/components/ui/selection-tile-grid.js +347 -0
  271. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  272. package/dist/components/ui/separator.d.ts +7 -0
  273. package/dist/components/ui/separator.js +33 -0
  274. package/dist/components/ui/separator.js.map +1 -0
  275. package/dist/components/ui/sheet.d.ts +18 -0
  276. package/dist/components/ui/sheet.js +181 -0
  277. package/dist/components/ui/sheet.js.map +1 -0
  278. package/dist/components/ui/sidebar.d.ts +94 -0
  279. package/dist/components/ui/sidebar.js +805 -0
  280. package/dist/components/ui/sidebar.js.map +1 -0
  281. package/dist/components/ui/skeleton.d.ts +5 -0
  282. package/dist/components/ui/skeleton.js +22 -0
  283. package/dist/components/ui/skeleton.js.map +1 -0
  284. package/dist/components/ui/slider.d.ts +7 -0
  285. package/dist/components/ui/slider.js +66 -0
  286. package/dist/components/ui/slider.js.map +1 -0
  287. package/dist/components/ui/sonner.d.ts +6 -0
  288. package/dist/components/ui/sonner.js +38 -0
  289. package/dist/components/ui/sonner.js.map +1 -0
  290. package/dist/components/ui/status-badge.d.ts +38 -0
  291. package/dist/components/ui/status-badge.js +77 -0
  292. package/dist/components/ui/status-badge.js.map +1 -0
  293. package/dist/components/ui/table.d.ts +13 -0
  294. package/dist/components/ui/table.js +115 -0
  295. package/dist/components/ui/table.js.map +1 -0
  296. package/dist/components/ui/tabs.d.ts +15 -0
  297. package/dist/components/ui/tabs.js +93 -0
  298. package/dist/components/ui/tabs.js.map +1 -0
  299. package/dist/components/ui/textarea.d.ts +6 -0
  300. package/dist/components/ui/textarea.js +25 -0
  301. package/dist/components/ui/textarea.js.map +1 -0
  302. package/dist/components/ui/tip.d.ts +12 -0
  303. package/dist/components/ui/tip.js +61 -0
  304. package/dist/components/ui/tip.js.map +1 -0
  305. package/dist/components/ui/toggle-group.d.ts +14 -0
  306. package/dist/components/ui/toggle-group.js +104 -0
  307. package/dist/components/ui/toggle-group.js.map +1 -0
  308. package/dist/components/ui/toggle-switch.d.ts +10 -0
  309. package/dist/components/ui/toggle-switch.js +33 -0
  310. package/dist/components/ui/toggle-switch.js.map +1 -0
  311. package/dist/components/ui/toggle.d.ts +13 -0
  312. package/dist/components/ui/toggle.js +51 -0
  313. package/dist/components/ui/toggle.js.map +1 -0
  314. package/dist/components/ui/tooltip.d.ts +10 -0
  315. package/dist/components/ui/tooltip.js +68 -0
  316. package/dist/components/ui/tooltip.js.map +1 -0
  317. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  318. package/dist/components/ui/view-segmented-control.js +167 -0
  319. package/dist/components/ui/view-segmented-control.js.map +1 -0
  320. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  321. package/dist/hooks/use-app-theme.d.ts +24 -0
  322. package/dist/hooks/use-app-theme.js +286 -0
  323. package/dist/hooks/use-app-theme.js.map +1 -0
  324. package/dist/hooks/use-coach-mark.d.ts +86 -0
  325. package/dist/hooks/use-coach-mark.js +218 -0
  326. package/dist/hooks/use-coach-mark.js.map +1 -0
  327. package/dist/hooks/use-mobile.d.ts +3 -0
  328. package/dist/hooks/use-mobile.js +29 -0
  329. package/dist/hooks/use-mobile.js.map +1 -0
  330. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  331. package/dist/hooks/use-mod-key-label.js +25 -0
  332. package/dist/hooks/use-mod-key-label.js.map +1 -0
  333. package/dist/index.d.ts +120 -0
  334. package/dist/index.js +13324 -0
  335. package/dist/index.js.map +1 -0
  336. package/dist/lib/compose-refs.d.ts +6 -0
  337. package/dist/lib/compose-refs.js +17 -0
  338. package/dist/lib/compose-refs.js.map +1 -0
  339. package/dist/lib/conditional-rule-match.d.ts +30 -0
  340. package/dist/lib/conditional-rule-match.js +66 -0
  341. package/dist/lib/conditional-rule-match.js.map +1 -0
  342. package/dist/lib/data-list-display-options.d.ts +26 -0
  343. package/dist/lib/data-list-display-options.js +14 -0
  344. package/dist/lib/data-list-display-options.js.map +1 -0
  345. package/dist/lib/data-list-view-registry.d.ts +2 -0
  346. package/dist/lib/data-list-view-registry.js +102 -0
  347. package/dist/lib/data-list-view-registry.js.map +1 -0
  348. package/dist/lib/data-list-view-surface.d.ts +2 -0
  349. package/dist/lib/data-list-view-surface.js +80 -0
  350. package/dist/lib/data-list-view-surface.js.map +1 -0
  351. package/dist/lib/data-list-view.d.ts +21 -0
  352. package/dist/lib/data-list-view.js +25 -0
  353. package/dist/lib/data-list-view.js.map +1 -0
  354. package/dist/lib/date-filter.d.ts +22 -0
  355. package/dist/lib/date-filter.js +61 -0
  356. package/dist/lib/date-filter.js.map +1 -0
  357. package/dist/lib/dev-log.d.ts +8 -0
  358. package/dist/lib/dev-log.js +10 -0
  359. package/dist/lib/dev-log.js.map +1 -0
  360. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  361. package/dist/lib/dropdown-menu-surface.js +6 -0
  362. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  363. package/dist/lib/editable-target.d.ts +12 -0
  364. package/dist/lib/editable-target.js +12 -0
  365. package/dist/lib/editable-target.js.map +1 -0
  366. package/dist/lib/list-page-table-properties.d.ts +35 -0
  367. package/dist/lib/list-page-table-properties.js +81 -0
  368. package/dist/lib/list-page-table-properties.js.map +1 -0
  369. package/dist/lib/raf-throttle.d.ts +23 -0
  370. package/dist/lib/raf-throttle.js +27 -0
  371. package/dist/lib/raf-throttle.js.map +1 -0
  372. package/dist/lib/row-height.d.ts +16 -0
  373. package/dist/lib/row-height.js +10 -0
  374. package/dist/lib/row-height.js.map +1 -0
  375. package/dist/lib/table-properties-types.d.ts +83 -0
  376. package/dist/lib/table-properties-types.js +19 -0
  377. package/dist/lib/table-properties-types.js.map +1 -0
  378. package/dist/lib/utils.d.ts +5 -0
  379. package/dist/lib/utils.js +11 -0
  380. package/dist/lib/utils.js.map +1 -0
  381. package/package.json +83 -19
  382. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  383. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  384. package/src/components/data-table/index.tsx +1678 -0
  385. package/src/components/data-table/pagination.tsx +255 -0
  386. package/src/components/data-table/types.ts +96 -0
  387. package/src/components/data-table/use-table-state.ts +767 -0
  388. package/src/components/data-views/board-card-primitives.tsx +93 -0
  389. package/src/components/data-views/data-row-list.tsx +183 -0
  390. package/src/components/data-views/finder-panel-view.tsx +405 -0
  391. package/src/components/data-views/folder-grid-view.tsx +86 -0
  392. package/src/components/data-views/hub-table.tsx +498 -0
  393. package/src/components/data-views/index.ts +28 -0
  394. package/src/components/data-views/list-page-board-card.tsx +192 -0
  395. package/src/components/data-views/list-page-board-template.tsx +122 -0
  396. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  397. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  398. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  399. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  400. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  401. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  402. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  403. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  404. package/src/components/table-properties/column-row.tsx +90 -0
  405. package/src/components/table-properties/draggable-list.ts +54 -0
  406. package/src/components/table-properties/drawer-button.tsx +300 -0
  407. package/src/components/table-properties/drawer.tsx +1148 -0
  408. package/src/components/table-properties/filter-card.tsx +251 -0
  409. package/src/components/table-properties/index.ts +36 -0
  410. package/src/components/table-properties/sort-card.tsx +63 -0
  411. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  412. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  413. package/src/components/templates/index.ts +33 -0
  414. package/src/components/templates/list-page.tsx +602 -0
  415. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  416. package/src/components/ui/accordion.tsx +92 -0
  417. package/src/components/ui/alert-dialog.tsx +221 -0
  418. package/src/components/ui/avatar.tsx +13 -2
  419. package/src/components/ui/banner.tsx +2 -2
  420. package/src/components/ui/button.tsx +4 -4
  421. package/src/components/ui/calendar.tsx +1 -1
  422. package/src/components/ui/coach-mark.tsx +1 -1
  423. package/src/components/ui/context-menu.tsx +291 -0
  424. package/src/components/ui/date-picker-field.tsx +2 -2
  425. package/src/components/ui/dot-pattern.tsx +183 -0
  426. package/src/components/ui/export-drawer.tsx +375 -0
  427. package/src/components/ui/hover-card.tsx +66 -0
  428. package/src/components/ui/key-metrics-context.tsx +78 -0
  429. package/src/components/ui/key-metrics.tsx +1133 -0
  430. package/src/components/ui/list-page-view-frame.tsx +64 -0
  431. package/src/components/ui/page-header.tsx +244 -0
  432. package/src/components/ui/payment-card-fields.tsx +2 -2
  433. package/src/components/ui/resizable.tsx +68 -0
  434. package/src/components/ui/scroll-area.tsx +72 -0
  435. package/src/components/ui/selection-tile-grid.tsx +9 -2
  436. package/src/components/ui/sidebar.tsx +84 -12
  437. package/src/components/ui/slider.tsx +83 -0
  438. package/src/globals.css +2201 -7
  439. package/src/globals.d.ts +20 -0
  440. package/src/index.ts +68 -1
  441. package/src/lib/conditional-rule-match.ts +119 -0
  442. package/src/lib/data-list-display-options.ts +35 -0
  443. package/src/lib/data-list-view-registry.ts +104 -0
  444. package/src/lib/data-list-view-surface.ts +83 -0
  445. package/src/lib/data-list-view.ts +47 -0
  446. package/src/lib/dev-log.ts +10 -0
  447. package/src/lib/editable-target.ts +20 -0
  448. package/src/lib/list-page-table-properties.ts +48 -0
  449. package/src/lib/raf-throttle.ts +45 -0
  450. package/src/lib/row-height.ts +19 -0
  451. package/src/lib/table-properties-types.ts +98 -0
  452. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  453. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  454. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  455. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  456. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  457. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  458. package/template/AGENTS.md +104 -78
  459. package/template/app/(app)/dashboard/loading.tsx +15 -3
  460. package/template/app/(app)/dashboard/page.tsx +14 -2
  461. package/template/app/(app)/examples/page.tsx +0 -2
  462. package/template/app/(app)/layout.tsx +17 -4
  463. package/template/app/(app)/loading.tsx +18 -1
  464. package/template/app/(app)/question-bank/find/page.tsx +1 -2
  465. package/template/app/(app)/question-bank/layout.tsx +1 -1
  466. package/template/app/(app)/question-bank/library/page.tsx +1 -2
  467. package/template/app/(app)/question-bank/list/page.tsx +1 -2
  468. package/template/app/(app)/question-bank/new/page.tsx +15 -20
  469. package/template/app/(app)/question-bank/page.tsx +1 -2
  470. package/template/app/(app)/settings/page.tsx +5 -4
  471. package/template/app/globals.css +14 -16
  472. package/template/components/ask-leo-sidebar.tsx +5 -1
  473. package/template/components/brand-color-picker.tsx +2 -2
  474. package/template/components/charts-overview.tsx +1 -1
  475. package/template/components/compliance-board-view.tsx +142 -0
  476. package/template/components/compliance-client.tsx +92 -0
  477. package/template/components/compliance-page-header.tsx +89 -0
  478. package/template/components/compliance-table.tsx +468 -0
  479. package/template/components/dashboard-report-charts.tsx +1 -1
  480. package/template/components/dashboard-tabs.tsx +1 -1
  481. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  482. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  483. package/template/components/data-table/index.tsx +1 -1634
  484. package/template/components/data-table/pagination.tsx +1 -255
  485. package/template/components/data-table/types.ts +1 -94
  486. package/template/components/data-table/use-table-state.test.ts +420 -0
  487. package/template/components/data-table/use-table-state.ts +1 -758
  488. package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
  489. package/template/components/data-view-dashboard-charts-team.tsx +971 -0
  490. package/template/components/data-view-dashboard-charts.tsx +1503 -0
  491. package/template/components/data-views/board-card-primitives.tsx +1 -93
  492. package/template/components/data-views/data-row-list.tsx +1 -183
  493. package/template/components/data-views/finder-panel-view.tsx +1 -405
  494. package/template/components/data-views/folder-grid-view.tsx +1 -86
  495. package/template/components/data-views/hub-table.tsx +1 -0
  496. package/template/components/data-views/index.ts +50 -37
  497. package/template/components/data-views/list-page-board-card.tsx +1 -192
  498. package/template/components/data-views/list-page-board-template.tsx +1 -122
  499. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  500. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  501. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  502. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  503. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  504. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  505. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  506. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  507. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  508. package/template/components/export-drawer.test.tsx +71 -0
  509. package/template/components/export-drawer.tsx +1 -375
  510. package/template/components/exxat-product-logo.tsx +5 -5
  511. package/template/components/hub-tree-panel-view.tsx +2 -2
  512. package/template/components/invite-collaborators-drawer.tsx +3 -3
  513. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  514. package/template/components/key-metrics.tsx +1 -1063
  515. package/template/components/leo-insight-indicator.tsx +2 -2
  516. package/template/components/new-placement-back-btn.tsx +28 -0
  517. package/template/components/new-placement-form.tsx +942 -0
  518. package/template/components/new-question-composer.tsx +456 -408
  519. package/template/components/onboarding/index.ts +9 -0
  520. package/template/components/onboarding/onboarding-01.tsx +1 -1
  521. package/template/components/onboarding/onboarding-02.tsx +1 -1
  522. package/template/components/onboarding/onboarding-03.tsx +1 -1
  523. package/template/components/onboarding/onboarding-04.tsx +1 -1
  524. package/template/components/page-header.tsx +8 -226
  525. package/template/components/placement-board-card.tsx +250 -0
  526. package/template/components/placement-detail.tsx +438 -0
  527. package/template/components/placements-board-view.tsx +397 -0
  528. package/template/components/placements-client.tsx +220 -0
  529. package/template/components/placements-list-view.tsx +124 -0
  530. package/template/components/placements-page-header.tsx +166 -0
  531. package/template/components/placements-table-cells.test.tsx +22 -0
  532. package/template/components/placements-table-cells.tsx +173 -0
  533. package/template/components/placements-table-columns.tsx +210 -0
  534. package/template/components/placements-table.tsx +934 -0
  535. package/template/components/product-switcher.tsx +3 -4
  536. package/template/components/product-wordmark.tsx +2 -1
  537. package/template/components/question-bank-client.tsx +5 -5
  538. package/template/components/question-bank-hub-client.tsx +1 -1
  539. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  540. package/template/components/question-bank-secondary-nav.tsx +3 -3
  541. package/template/components/question-bank-table.tsx +541 -431
  542. package/template/components/rotations-empty-state.tsx +50 -0
  543. package/template/components/rotations-panel-activator.tsx +8 -0
  544. package/template/components/settings-appearance-card.tsx +3 -4
  545. package/template/components/settings-client.tsx +15 -59
  546. package/template/components/settings-form-row.tsx +4 -9
  547. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  548. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
  549. package/template/components/sidebar/index.ts +16 -0
  550. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  551. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
  552. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  553. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  554. package/template/components/site-header.tsx +1 -1
  555. package/template/components/sites-board-view.tsx +67 -0
  556. package/template/components/sites-client.tsx +154 -0
  557. package/template/components/sites-table.tsx +249 -0
  558. package/template/components/table-properties/column-row.tsx +1 -90
  559. package/template/components/table-properties/draggable-list.ts +1 -49
  560. package/template/components/table-properties/drawer-button.tsx +1 -262
  561. package/template/components/table-properties/drawer.tsx +1 -1166
  562. package/template/components/table-properties/filter-card.tsx +1 -251
  563. package/template/components/table-properties/sort-card.tsx +1 -59
  564. package/template/components/table-properties/types.ts +28 -71
  565. package/template/components/team-board-view.tsx +122 -0
  566. package/template/components/team-client.tsx +100 -0
  567. package/template/components/team-page-header.tsx +92 -0
  568. package/template/components/team-table.tsx +553 -0
  569. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  570. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  571. package/template/components/templates/list-page.tsx +1 -608
  572. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
  573. package/template/components/templates/new-focus-template.tsx +659 -0
  574. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  575. package/template/components/ui/accordion.tsx +1 -0
  576. package/template/components/ui/alert-dialog.tsx +1 -0
  577. package/template/components/ui/context-menu.tsx +1 -0
  578. package/template/components/ui/dot-pattern.tsx +1 -183
  579. package/template/components/ui/hover-card.tsx +1 -0
  580. package/template/components/ui/resizable.tsx +1 -68
  581. package/template/components/ui/scroll-area.tsx +1 -0
  582. package/template/components/ui/slider.tsx +1 -0
  583. package/template/docs/blueprints/README.md +86 -0
  584. package/template/docs/blueprints/_template.md +91 -0
  585. package/template/docs/blueprints/board-card.md +123 -0
  586. package/template/docs/blueprints/data-table.md +139 -0
  587. package/template/docs/blueprints/key-metrics.md +128 -0
  588. package/template/docs/blueprints/list-page-template.md +123 -0
  589. package/template/docs/blueprints/page-header.md +130 -0
  590. package/template/docs/command-menu-pattern.md +1 -1
  591. package/template/docs/component-selection-guide.md +224 -0
  592. package/template/docs/components-audit-2026-05.md +158 -0
  593. package/template/docs/data-views-pattern.md +17 -54
  594. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  595. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  596. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  597. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  598. package/template/docs/migrations/README.md +100 -0
  599. package/template/docs/migrations/_template.md +64 -0
  600. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  601. package/template/docs/token-taxonomy.md +416 -0
  602. package/template/eslint.config.mjs +27 -0
  603. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  604. package/template/lib/command-menu-config.ts +0 -1
  605. package/template/lib/command-menu-search-data.ts +27 -11
  606. package/template/lib/compliance-supported-views.ts +10 -0
  607. package/template/lib/conditional-rule-match.ts +6 -97
  608. package/template/lib/data-list-display-options.ts +1 -49
  609. package/template/lib/data-list-view-registry.ts +1 -104
  610. package/template/lib/data-list-view-surface.ts +1 -83
  611. package/template/lib/data-list-view.ts +1 -47
  612. package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
  613. package/template/lib/data-view-dashboard-storage.ts +35 -38
  614. package/template/lib/dev-log.ts +1 -8
  615. package/template/lib/editable-target.ts +1 -10
  616. package/template/lib/list-page-table-properties.ts +1 -48
  617. package/template/lib/list-status-badges.ts +97 -4
  618. package/template/lib/mock/compliance-kpi.ts +61 -0
  619. package/template/lib/mock/compliance.ts +146 -0
  620. package/template/lib/mock/navigation.tsx +0 -9
  621. package/template/lib/mock/placements-kpi.ts +134 -0
  622. package/template/lib/mock/placements.ts +176 -0
  623. package/template/lib/mock/sites-directory.ts +16 -0
  624. package/template/lib/mock/sites-kpi.ts +25 -0
  625. package/template/lib/mock/team-kpi.ts +60 -0
  626. package/template/lib/mock/team.ts +118 -0
  627. package/template/lib/placement-board-card-layout.ts +79 -0
  628. package/template/lib/placements-supported-views.ts +12 -0
  629. package/template/lib/question-bank-supported-views.ts +0 -1
  630. package/template/lib/raf-throttle.ts +1 -45
  631. package/template/lib/row-height.ts +4 -10
  632. package/template/lib/sidebar-state-cookie.ts +11 -2
  633. package/template/lib/sites-supported-views.ts +10 -0
  634. package/template/lib/table-state-lifecycle.ts +2 -2
  635. package/template/lib/team-supported-views.ts +10 -0
  636. package/template/package.json +1 -0
  637. package/template/tests/setup.ts +25 -0
  638. package/consumer-extras/AGENTS.md +0 -76
  639. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  640. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  641. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  642. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  643. package/src/components/ui/button-group.tsx +0 -81
  644. package/src/theme.css +0 -16
  645. package/src/tokens/README.md +0 -15
  646. package/src/tokens/base.css +0 -337
  647. package/src/tokens/high-contrast.css +0 -1195
  648. package/src/tokens/layers.css +0 -224
  649. package/src/tokens/tailwind-bridge.css +0 -118
  650. package/src/tokens/themes.css +0 -201
  651. package/template/app/(app)/data-list/layout.tsx +0 -43
  652. package/template/app/(app)/data-list/page.tsx +0 -10
  653. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  654. package/template/components/app-route-loading.tsx +0 -14
  655. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  656. package/template/components/dashboard-onboarding.tsx +0 -21
  657. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  658. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  659. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  660. package/template/components/list-hub-board-view.tsx +0 -68
  661. package/template/components/list-hub-client.tsx +0 -186
  662. package/template/components/list-hub-list-view.tsx +0 -36
  663. package/template/components/list-hub-panel-activator.tsx +0 -8
  664. package/template/components/list-hub-secondary-nav.tsx +0 -121
  665. package/template/components/list-hub-table.tsx +0 -336
  666. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  667. package/template/components/question-bank-list-view.tsx +0 -53
  668. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  669. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  670. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  671. package/template/components/secondary-panels/registry.tsx +0 -15
  672. package/template/components/section-cards.tsx +0 -106
  673. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  674. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  675. package/template/components/templates/page-loading-shell.tsx +0 -262
  676. package/template/components/ui/button-group.tsx +0 -1
  677. package/template/docs/consumer-app-pattern.md +0 -39
  678. package/template/docs/focused-workflow-page-pattern.md +0 -84
  679. package/template/lib/list-hub-nav.ts +0 -121
  680. package/template/lib/mock/list-hub-directory.ts +0 -27
  681. package/template/lib/mock/list-hub-kpi.ts +0 -27
  682. package/template/lib/page-loading-variant.ts +0 -40
  683. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  684. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  685. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  686. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  687. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  688. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
@@ -0,0 +1,2595 @@
1
+ "use client";
2
+ import * as React11 from 'react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { Label as Label$1, RadioGroup as RadioGroup$1, Slot, Dialog, Select as Select$1, DropdownMenu as DropdownMenu$1, Tooltip as Tooltip$1, Popover as Popover$1 } from 'radix-ui';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
+ import { cva } from 'class-variance-authority';
8
+ import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from 'lucide-react';
9
+ import { getDefaultClassNames, DayPicker } from 'react-day-picker';
10
+ import { useMaskInput } from 'use-mask-input';
11
+
12
+ function cn(...inputs) {
13
+ return twMerge(clsx(inputs));
14
+ }
15
+
16
+ // src/lib/data-list-view.ts
17
+ var DATA_LIST_VIEW_TILES = [
18
+ { value: "table", icon: "fa-table", label: "Table view" },
19
+ { value: "list", icon: "fa-list", label: "List view" },
20
+ { value: "board", icon: "fa-table-columns", label: "Board view" },
21
+ { value: "dashboard", icon: "fa-chart-mixed", label: "Dashboard view" },
22
+ { value: "calendar", icon: "fa-calendar-days", label: "Calendar view" },
23
+ { value: "folder", icon: "fa-grid-2", label: "Folder view" },
24
+ { value: "panel", icon: "fa-sidebar", label: "List & details" },
25
+ { value: "tree-panel", icon: "fa-sitemap", label: "Tree & details" }
26
+ ];
27
+ function dataListViewLabel(view) {
28
+ return DATA_LIST_VIEW_TILES.find((t) => t.value === view)?.label ?? view;
29
+ }
30
+
31
+ // src/lib/data-list-view-surface.ts
32
+ function getDataListViewRenderKind(view) {
33
+ switch (view) {
34
+ case "table":
35
+ return "data-table";
36
+ case "list":
37
+ return "list-with-toolbar";
38
+ case "board":
39
+ return "board-with-toolbar";
40
+ case "dashboard":
41
+ return "dashboard-with-toolbar";
42
+ case "calendar":
43
+ return "calendar-with-toolbar";
44
+ case "folder":
45
+ return "folder-with-toolbar";
46
+ case "panel":
47
+ return "panel-with-toolbar";
48
+ case "tree-panel":
49
+ return "tree-panel-with-toolbar";
50
+ default: {
51
+ const _x = view;
52
+ return _x;
53
+ }
54
+ }
55
+ }
56
+
57
+ // src/lib/data-list-view-registry.ts
58
+ var DEFINITIONS = DATA_LIST_VIEW_TILES.map((tile) => {
59
+ const renderKind = getDataListViewRenderKind(tile.value);
60
+ const hubMetricsStrip = renderKind !== "calendar-with-toolbar" && renderKind !== "dashboard-with-toolbar";
61
+ return {
62
+ value: tile.value,
63
+ label: tile.label,
64
+ icon: tile.icon,
65
+ renderKind,
66
+ hubMetricsStrip
67
+ };
68
+ });
69
+ new Map(
70
+ DEFINITIONS.map((d) => [d.value, d])
71
+ );
72
+ var DATA_LIST_VIEW_REGISTRY = DEFINITIONS;
73
+ function dataListViewTilesForHub(supported) {
74
+ const allowed = new Set(supported);
75
+ return DATA_LIST_VIEW_REGISTRY.filter((d) => allowed.has(d.value)).map((d) => ({
76
+ type: d.value,
77
+ label: d.label,
78
+ icon: d.icon
79
+ }));
80
+ }
81
+ new Set(
82
+ DATA_LIST_VIEW_REGISTRY.map((d) => d.value)
83
+ );
84
+
85
+ // src/lib/row-height.ts
86
+ var ROW_HEIGHT_TILES = [
87
+ { value: "compact", label: "Compact", icon: "fa-down-to-line" },
88
+ { value: "default", label: "Default", icon: "fa-arrows-up-down" },
89
+ { value: "comfortable", label: "Comfortable", icon: "fa-up-to-line" }
90
+ ];
91
+ var Label = React11.forwardRef(function Label2({ className, ...props }, ref) {
92
+ return /* @__PURE__ */ jsx(
93
+ Label$1.Root,
94
+ {
95
+ ref,
96
+ "data-slot": "label",
97
+ className: cn(
98
+ "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",
99
+ className
100
+ ),
101
+ ...props
102
+ }
103
+ );
104
+ });
105
+ var radioGroupItemVariants = cva(
106
+ [
107
+ "group/radio-group-item peer relative flex shrink-0 aspect-square rounded-full border border-input",
108
+ "outline-none transition-[color,box-shadow,transform,background-color,border-color] duration-150",
109
+ "motion-reduce:transition-none",
110
+ "group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2",
111
+ "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
112
+ "disabled:cursor-not-allowed disabled:opacity-50",
113
+ "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:data-[state=checked]:border-primary",
114
+ "dark:bg-input/15 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
115
+ ].join(" "),
116
+ {
117
+ variants: {
118
+ variant: {
119
+ default: [
120
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary"
121
+ ].join(" "),
122
+ outline: [
123
+ "bg-background",
124
+ "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"
125
+ ].join(" "),
126
+ secondary: [
127
+ "data-[state=checked]:border-secondary data-[state=checked]:bg-secondary data-[state=checked]:text-secondary-foreground"
128
+ ].join(" "),
129
+ success: [
130
+ "data-[state=checked]:border-chart-2 data-[state=checked]:bg-chart-2 data-[state=checked]:text-primary-foreground"
131
+ ].join(" "),
132
+ destructive: [
133
+ "data-[state=checked]:border-destructive data-[state=checked]:bg-destructive data-[state=checked]:text-destructive-foreground"
134
+ ].join(" "),
135
+ warning: [
136
+ "data-[state=checked]:border-amber-500 data-[state=checked]:bg-amber-500 data-[state=checked]:text-amber-950"
137
+ ].join(" "),
138
+ muted: [
139
+ "data-[state=checked]:border-muted-foreground/50 data-[state=checked]:bg-muted data-[state=checked]:text-foreground"
140
+ ].join(" ")
141
+ },
142
+ size: {
143
+ sm: "size-3.5 min-h-3.5 min-w-3.5 max-h-3.5 max-w-3.5",
144
+ default: "size-4 min-h-4 min-w-4 max-h-4 max-w-4",
145
+ lg: "size-5 min-h-5 min-w-5 max-h-5 max-w-5"
146
+ },
147
+ motion: {
148
+ none: "",
149
+ pop: [
150
+ "motion-safe:active:scale-95",
151
+ "data-[state=checked]:motion-safe:scale-[1.04]"
152
+ ].join(" "),
153
+ glow: "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35",
154
+ "pop-glow": [
155
+ "motion-safe:active:scale-95",
156
+ "data-[state=checked]:motion-safe:scale-[1.04]",
157
+ "data-[state=checked]:shadow-[0_0_0_3px] data-[state=checked]:shadow-primary/35"
158
+ ].join(" ")
159
+ }
160
+ },
161
+ defaultVariants: {
162
+ variant: "default",
163
+ size: "default",
164
+ motion: "none"
165
+ }
166
+ }
167
+ );
168
+ var radioIndicatorDotVariants = cva(
169
+ "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",
170
+ {
171
+ variants: {
172
+ variant: {
173
+ default: "bg-primary-foreground",
174
+ outline: "bg-primary",
175
+ secondary: "bg-secondary-foreground",
176
+ success: "bg-primary-foreground",
177
+ destructive: "bg-destructive-foreground",
178
+ warning: "bg-amber-950",
179
+ muted: "bg-foreground"
180
+ },
181
+ size: {
182
+ sm: "size-1.5",
183
+ default: "size-2",
184
+ lg: "size-2.5"
185
+ }
186
+ },
187
+ defaultVariants: {
188
+ variant: "default",
189
+ size: "default"
190
+ }
191
+ }
192
+ );
193
+ var radioIndicatorWrapperVariants = cva("relative flex size-full items-center justify-center", {
194
+ variants: {
195
+ motion: {
196
+ none: "",
197
+ pop: "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150",
198
+ glow: "",
199
+ "pop-glow": "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95 motion-safe:duration-150"
200
+ }
201
+ },
202
+ defaultVariants: { motion: "none" }
203
+ });
204
+ var RadioGroupItemChromeContext = React11.createContext({});
205
+ function RadioGroup({
206
+ className,
207
+ itemVariant,
208
+ itemSize,
209
+ itemMotion,
210
+ ...props
211
+ }) {
212
+ const ctx = React11.useMemo(
213
+ () => ({ itemVariant, itemSize, itemMotion }),
214
+ [itemVariant, itemSize, itemMotion]
215
+ );
216
+ return /* @__PURE__ */ jsx(RadioGroupItemChromeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
217
+ RadioGroup$1.Root,
218
+ {
219
+ "data-slot": "radio-group",
220
+ className: cn("grid w-full gap-2", className),
221
+ ...props
222
+ }
223
+ ) });
224
+ }
225
+ var RadioGroupItem = React11.forwardRef(function RadioGroupItem2({ className, variant: variantProp, size: sizeProp, motion: motionProp, ...props }, ref) {
226
+ const ctx = React11.useContext(RadioGroupItemChromeContext);
227
+ const variant = variantProp ?? ctx.itemVariant;
228
+ const size = sizeProp ?? ctx.itemSize;
229
+ const motion = motionProp ?? ctx.itemMotion ?? "none";
230
+ const vResolved = variant ?? "default";
231
+ const sResolved = size ?? "default";
232
+ return /* @__PURE__ */ jsx(
233
+ RadioGroup$1.Item,
234
+ {
235
+ ref,
236
+ "data-slot": "radio-group-item",
237
+ "data-variant": vResolved,
238
+ "data-motion": motion,
239
+ className: cn(radioGroupItemVariants({ variant, size, motion }), className),
240
+ ...props,
241
+ children: /* @__PURE__ */ jsx(
242
+ RadioGroup$1.Indicator,
243
+ {
244
+ "data-slot": "radio-group-indicator",
245
+ className: radioIndicatorWrapperVariants({ motion }),
246
+ children: /* @__PURE__ */ jsx("span", { className: radioIndicatorDotVariants({ variant: vResolved, size: sResolved }) })
247
+ }
248
+ )
249
+ }
250
+ );
251
+ });
252
+ function selectionTileClassNames(selected) {
253
+ return cn(
254
+ "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",
255
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
256
+ 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"
257
+ );
258
+ }
259
+ function selectionTilePreviewClassNames(selected) {
260
+ return cn(
261
+ "relative box-border flex aspect-square w-full max-w-full flex-col rounded-lg border p-1 transition-colors",
262
+ selected ? "border-brand bg-brand/5 shadow-sm" : "border-border bg-background hover:border-border/80"
263
+ );
264
+ }
265
+ function SelectionTileGraphic({
266
+ option,
267
+ selected
268
+ }) {
269
+ if (option.leading != null) {
270
+ 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 });
271
+ }
272
+ if (option.icon) {
273
+ return /* @__PURE__ */ jsx(
274
+ "i",
275
+ {
276
+ className: cn(
277
+ "fa-light shrink-0 text-[18px] leading-none",
278
+ option.icon,
279
+ selected && "text-brand"
280
+ ),
281
+ "aria-hidden": "true"
282
+ }
283
+ );
284
+ }
285
+ return null;
286
+ }
287
+ function SelectionTileLabelText({
288
+ option
289
+ }) {
290
+ return /* @__PURE__ */ jsx("span", { className: "text-center leading-tight", children: option.label });
291
+ }
292
+ function SelectionTileCaptionBelow({
293
+ option,
294
+ selected,
295
+ ariaHidden = false
296
+ }) {
297
+ return /* @__PURE__ */ jsx(
298
+ "span",
299
+ {
300
+ className: cn(
301
+ "max-w-full px-0.5 text-center text-xs leading-tight",
302
+ selected ? "font-medium text-foreground" : "text-muted-foreground"
303
+ ),
304
+ ...ariaHidden ? { "aria-hidden": true } : {},
305
+ children: option.label
306
+ }
307
+ );
308
+ }
309
+ function SelectionTileGrid({
310
+ sectionLabel,
311
+ options,
312
+ columns = 4,
313
+ value,
314
+ onValueChange,
315
+ interaction,
316
+ idPrefix = "tile",
317
+ className,
318
+ labelPlacement = "inside",
319
+ itemVariant,
320
+ itemSize,
321
+ itemMotion
322
+ }) {
323
+ const gridClass = cn(
324
+ "gap-2",
325
+ columns === 2 && "grid grid-cols-2",
326
+ columns === 3 && "grid grid-cols-3",
327
+ columns === 4 && "grid grid-cols-4"
328
+ );
329
+ if (interaction === "radio") {
330
+ return /* @__PURE__ */ jsxs("div", { className, children: [
331
+ sectionLabel ? /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: sectionLabel }) : null,
332
+ /* @__PURE__ */ jsx(
333
+ RadioGroup,
334
+ {
335
+ value,
336
+ onValueChange: (v) => onValueChange(v),
337
+ className: gridClass,
338
+ itemVariant,
339
+ itemSize,
340
+ itemMotion,
341
+ children: options.map((opt) => {
342
+ const selected = value === opt.value;
343
+ const id = `${idPrefix}-${opt.value}`;
344
+ if (labelPlacement === "below") {
345
+ return /* @__PURE__ */ jsxs(
346
+ Label,
347
+ {
348
+ htmlFor: id,
349
+ className: cn(
350
+ "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"
351
+ ),
352
+ children: [
353
+ /* @__PURE__ */ jsxs("span", { className: cn("flex w-full justify-center", selectionTilePreviewClassNames(selected)), children: [
354
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: opt.value, id, className: "sr-only" }),
355
+ /* @__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 }) })
356
+ ] }),
357
+ /* @__PURE__ */ jsx(SelectionTileCaptionBelow, { option: opt, selected })
358
+ ]
359
+ },
360
+ opt.value
361
+ );
362
+ }
363
+ return /* @__PURE__ */ jsxs(
364
+ Label,
365
+ {
366
+ htmlFor: id,
367
+ className: cn(
368
+ "cursor-pointer rounded-lg focus-within:rounded-lg focus-within:ring-2 focus-within:ring-ring focus-within:outline-none",
369
+ selectionTileClassNames(selected)
370
+ ),
371
+ children: [
372
+ /* @__PURE__ */ jsx(RadioGroupItem, { value: opt.value, id, className: "sr-only" }),
373
+ /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }),
374
+ /* @__PURE__ */ jsx(SelectionTileLabelText, { option: opt })
375
+ ]
376
+ },
377
+ opt.value
378
+ );
379
+ })
380
+ }
381
+ )
382
+ ] });
383
+ }
384
+ return /* @__PURE__ */ jsxs("div", { className, children: [
385
+ sectionLabel ? /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: sectionLabel }) : null,
386
+ /* @__PURE__ */ jsx("div", { className: gridClass, children: options.map((opt) => {
387
+ const selected = value === opt.value;
388
+ if (labelPlacement === "below") {
389
+ return /* @__PURE__ */ jsxs(
390
+ "button",
391
+ {
392
+ type: "button",
393
+ "aria-label": opt.label,
394
+ "aria-pressed": selected,
395
+ onClick: () => onValueChange(opt.value),
396
+ 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",
397
+ children: [
398
+ /* @__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 }) }) }),
399
+ /* @__PURE__ */ jsx(SelectionTileCaptionBelow, { option: opt, selected, ariaHidden: true })
400
+ ]
401
+ },
402
+ opt.value
403
+ );
404
+ }
405
+ return /* @__PURE__ */ jsxs(
406
+ "button",
407
+ {
408
+ type: "button",
409
+ "aria-label": opt.label,
410
+ "aria-pressed": selected,
411
+ onClick: () => onValueChange(opt.value),
412
+ className: selectionTileClassNames(selected),
413
+ children: [
414
+ /* @__PURE__ */ jsx(SelectionTileGraphic, { option: opt, selected }),
415
+ /* @__PURE__ */ jsx(SelectionTileLabelText, { option: opt })
416
+ ]
417
+ },
418
+ opt.value
419
+ );
420
+ }) })
421
+ ] });
422
+ }
423
+
424
+ // src/lib/dropdown-menu-surface.ts
425
+ var DROPDOWN_MENU_CONTENT_SURFACE_CLASS = "min-w-52 w-max max-w-[min(24rem,calc(100vw-2rem))]";
426
+ function DropdownMenu({
427
+ ...props
428
+ }) {
429
+ return /* @__PURE__ */ jsx(DropdownMenu$1.Root, { "data-slot": "dropdown-menu", ...props });
430
+ }
431
+ function DropdownMenuTrigger({
432
+ className,
433
+ ...props
434
+ }) {
435
+ return /* @__PURE__ */ jsx(
436
+ DropdownMenu$1.Trigger,
437
+ {
438
+ "data-slot": "dropdown-menu-trigger",
439
+ suppressHydrationWarning: true,
440
+ className: cn("cursor-pointer", className),
441
+ ...props
442
+ }
443
+ );
444
+ }
445
+ function DropdownMenuContent({
446
+ className,
447
+ align = "start",
448
+ sideOffset = 4,
449
+ ...props
450
+ }) {
451
+ return /* @__PURE__ */ jsx(DropdownMenu$1.Portal, { children: /* @__PURE__ */ jsx(
452
+ DropdownMenu$1.Content,
453
+ {
454
+ "data-slot": "dropdown-menu-content",
455
+ sideOffset,
456
+ align,
457
+ className: cn(
458
+ "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",
459
+ DROPDOWN_MENU_CONTENT_SURFACE_CLASS,
460
+ className
461
+ ),
462
+ ...props
463
+ }
464
+ ) });
465
+ }
466
+ function DropdownMenuItem({
467
+ className,
468
+ inset,
469
+ variant = "default",
470
+ shortcut,
471
+ children,
472
+ asChild,
473
+ ...props
474
+ }) {
475
+ return /* @__PURE__ */ jsx(
476
+ DropdownMenu$1.Item,
477
+ {
478
+ "data-slot": "dropdown-menu-item",
479
+ "data-inset": inset,
480
+ "data-variant": variant,
481
+ asChild,
482
+ className: cn(
483
+ "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",
484
+ className
485
+ ),
486
+ ...props,
487
+ children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
488
+ children,
489
+ shortcut ? /* @__PURE__ */ jsx(DropdownMenuShortcut, { children: shortcut }) : null
490
+ ] })
491
+ }
492
+ );
493
+ }
494
+ function DropdownMenuLabel({
495
+ className,
496
+ inset,
497
+ ...props
498
+ }) {
499
+ return /* @__PURE__ */ jsx(
500
+ DropdownMenu$1.Label,
501
+ {
502
+ "data-slot": "dropdown-menu-label",
503
+ "data-inset": inset,
504
+ className: cn(
505
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:ps-7",
506
+ className
507
+ ),
508
+ ...props
509
+ }
510
+ );
511
+ }
512
+ function DropdownMenuSeparator({
513
+ className,
514
+ ...props
515
+ }) {
516
+ return /* @__PURE__ */ jsx(
517
+ DropdownMenu$1.Separator,
518
+ {
519
+ "data-slot": "dropdown-menu-separator",
520
+ className: cn("-mx-1 my-1 h-px bg-border", className),
521
+ ...props
522
+ }
523
+ );
524
+ }
525
+ function DropdownMenuShortcut({
526
+ className,
527
+ ...props
528
+ }) {
529
+ return /* @__PURE__ */ jsx(
530
+ "span",
531
+ {
532
+ "data-slot": "dropdown-menu-shortcut",
533
+ className: cn(
534
+ "ms-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
535
+ className
536
+ ),
537
+ ...props
538
+ }
539
+ );
540
+ }
541
+ var buttonVariants = cva(
542
+ "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",
543
+ {
544
+ variants: {
545
+ variant: {
546
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
547
+ 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",
548
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
549
+ 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",
550
+ 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",
551
+ link: "text-primary underline-offset-4 hover:underline"
552
+ },
553
+ size: {
554
+ default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5",
555
+ 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",
556
+ 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",
557
+ lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pe-3.5 has-data-[icon=inline-start]:ps-3.5",
558
+ icon: "size-9",
559
+ "icon-xs": "size-6 in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
560
+ "icon-sm": "size-8 in-data-[slot=button-group]:rounded-lg",
561
+ "icon-lg": "size-10"
562
+ }
563
+ },
564
+ defaultVariants: {
565
+ variant: "default",
566
+ size: "default"
567
+ }
568
+ }
569
+ );
570
+ var Button = React11.forwardRef(({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
571
+ const Comp = asChild ? Slot.Root : "button";
572
+ return /* @__PURE__ */ jsx(
573
+ Comp,
574
+ {
575
+ ref,
576
+ "data-slot": "button",
577
+ "data-variant": variant,
578
+ "data-size": size,
579
+ className: cn(buttonVariants({ variant, size }), className),
580
+ ...props
581
+ }
582
+ );
583
+ });
584
+ Button.displayName = "Button";
585
+ function Sheet({ ...props }) {
586
+ return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
587
+ }
588
+ function SheetPortal({
589
+ ...props
590
+ }) {
591
+ return /* @__PURE__ */ jsx(Dialog.Portal, { "data-slot": "sheet-portal", ...props });
592
+ }
593
+ function SheetOverlay({
594
+ className,
595
+ ...props
596
+ }) {
597
+ return /* @__PURE__ */ jsx(
598
+ Dialog.Overlay,
599
+ {
600
+ "data-slot": "sheet-overlay",
601
+ className: cn(
602
+ "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",
603
+ className
604
+ ),
605
+ ...props
606
+ }
607
+ );
608
+ }
609
+ function SheetContent({
610
+ className,
611
+ children,
612
+ side = "right",
613
+ showCloseButton = true,
614
+ showOverlay = true,
615
+ ...props
616
+ }) {
617
+ return /* @__PURE__ */ jsxs(SheetPortal, { children: [
618
+ showOverlay && /* @__PURE__ */ jsx(SheetOverlay, {}),
619
+ /* @__PURE__ */ jsxs(
620
+ Dialog.Content,
621
+ {
622
+ "data-slot": "sheet-content",
623
+ "data-side": side,
624
+ className: cn(
625
+ "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",
626
+ className
627
+ ),
628
+ ...props,
629
+ children: [
630
+ children,
631
+ showCloseButton && /* @__PURE__ */ jsx(Dialog.Close, { "data-slot": "sheet-close", asChild: true, children: /* @__PURE__ */ jsxs(
632
+ Button,
633
+ {
634
+ variant: "ghost",
635
+ className: "absolute top-3 end-3",
636
+ size: "icon-sm",
637
+ children: [
638
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark", "aria-hidden": "true" }),
639
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
640
+ ]
641
+ }
642
+ ) })
643
+ ]
644
+ }
645
+ )
646
+ ] });
647
+ }
648
+ function SheetTitle({
649
+ className,
650
+ ...props
651
+ }) {
652
+ return /* @__PURE__ */ jsx(
653
+ Dialog.Title,
654
+ {
655
+ "data-slot": "sheet-title",
656
+ className: cn(
657
+ "text-base font-medium text-foreground",
658
+ className
659
+ ),
660
+ ...props
661
+ }
662
+ );
663
+ }
664
+ function Select({
665
+ ...props
666
+ }) {
667
+ return /* @__PURE__ */ jsx(Select$1.Root, { "data-slot": "select", ...props });
668
+ }
669
+ function SelectValue({
670
+ ...props
671
+ }) {
672
+ return /* @__PURE__ */ jsx(Select$1.Value, { "data-slot": "select-value", ...props });
673
+ }
674
+ function SelectTrigger({
675
+ className,
676
+ size = "default",
677
+ children,
678
+ ...props
679
+ }) {
680
+ return /* @__PURE__ */ jsxs(
681
+ Select$1.Trigger,
682
+ {
683
+ "data-slot": "select-trigger",
684
+ "data-size": size,
685
+ className: cn(
686
+ "flex w-fit cursor-pointer items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pe-2 ps-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/15 dark:hover:bg-input/50 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",
687
+ className
688
+ ),
689
+ ...props,
690
+ children: [
691
+ children,
692
+ /* @__PURE__ */ jsx(Select$1.Icon, { asChild: true, children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down pointer-events-none size-4 text-muted-foreground", "aria-hidden": "true" }) })
693
+ ]
694
+ }
695
+ );
696
+ }
697
+ function SelectContent({
698
+ className,
699
+ children,
700
+ position = "item-aligned",
701
+ align = "center",
702
+ ...props
703
+ }) {
704
+ return /* @__PURE__ */ jsx(Select$1.Portal, { children: /* @__PURE__ */ jsxs(
705
+ Select$1.Content,
706
+ {
707
+ "data-slot": "select-content",
708
+ "data-align-trigger": position === "item-aligned",
709
+ className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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-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", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 rtl:data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 rtl:data-[side=right]:-translate-x-1 data-[side=top]:-translate-y-1", className),
710
+ position,
711
+ align,
712
+ ...props,
713
+ children: [
714
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
715
+ /* @__PURE__ */ jsx(
716
+ Select$1.Viewport,
717
+ {
718
+ "data-position": position,
719
+ className: cn(
720
+ "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
721
+ position === "popper" && ""
722
+ ),
723
+ children
724
+ }
725
+ ),
726
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
727
+ ]
728
+ }
729
+ ) });
730
+ }
731
+ function SelectItem({
732
+ className,
733
+ children,
734
+ ...props
735
+ }) {
736
+ return /* @__PURE__ */ jsxs(
737
+ Select$1.Item,
738
+ {
739
+ "data-slot": "select-item",
740
+ className: cn(
741
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pe-8 ps-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground 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([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
742
+ className
743
+ ),
744
+ ...props,
745
+ children: [
746
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute end-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsx(Select$1.ItemIndicator, { children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-check pointer-events-none", "aria-hidden": "true" }) }) }),
747
+ /* @__PURE__ */ jsx(Select$1.ItemText, { children })
748
+ ]
749
+ }
750
+ );
751
+ }
752
+ function SelectScrollUpButton({
753
+ className,
754
+ ...props
755
+ }) {
756
+ return /* @__PURE__ */ jsx(
757
+ Select$1.ScrollUpButton,
758
+ {
759
+ "data-slot": "select-scroll-up-button",
760
+ className: cn(
761
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
762
+ className
763
+ ),
764
+ ...props,
765
+ children: /* @__PURE__ */ jsx(
766
+ "i",
767
+ {
768
+ className: "fa-light fa-chevron-up",
769
+ "aria-hidden": "true"
770
+ }
771
+ )
772
+ }
773
+ );
774
+ }
775
+ function SelectScrollDownButton({
776
+ className,
777
+ ...props
778
+ }) {
779
+ return /* @__PURE__ */ jsx(
780
+ Select$1.ScrollDownButton,
781
+ {
782
+ "data-slot": "select-scroll-down-button",
783
+ className: cn(
784
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
785
+ className
786
+ ),
787
+ ...props,
788
+ children: /* @__PURE__ */ jsx(
789
+ "i",
790
+ {
791
+ className: "fa-light fa-chevron-down",
792
+ "aria-hidden": "true"
793
+ }
794
+ )
795
+ }
796
+ );
797
+ }
798
+ function Tooltip({
799
+ ...props
800
+ }) {
801
+ return /* @__PURE__ */ jsx(Tooltip$1.Root, { "data-slot": "tooltip", ...props });
802
+ }
803
+ function TooltipTrigger({
804
+ className,
805
+ ...props
806
+ }) {
807
+ return /* @__PURE__ */ jsx(
808
+ Tooltip$1.Trigger,
809
+ {
810
+ "data-slot": "tooltip-trigger",
811
+ suppressHydrationWarning: true,
812
+ className: cn("cursor-pointer", className),
813
+ ...props
814
+ }
815
+ );
816
+ }
817
+ function TooltipContent({
818
+ className,
819
+ sideOffset = 0,
820
+ children,
821
+ ...props
822
+ }) {
823
+ return /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsxs(
824
+ Tooltip$1.Content,
825
+ {
826
+ "data-slot": "tooltip-content",
827
+ sideOffset,
828
+ className: cn(
829
+ "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",
830
+ className
831
+ ),
832
+ ...props,
833
+ children: [
834
+ children,
835
+ /* @__PURE__ */ jsx(Tooltip$1.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" })
836
+ ]
837
+ }
838
+ ) });
839
+ }
840
+ function Tip({ label, children, side = "top" }) {
841
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
842
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children }),
843
+ /* @__PURE__ */ jsx(TooltipContent, { side, className: "flex flex-wrap items-center gap-1.5", children: label })
844
+ ] });
845
+ }
846
+ function ToggleSwitch({ checked, onChange, id }) {
847
+ return /* @__PURE__ */ jsx(
848
+ "button",
849
+ {
850
+ id,
851
+ type: "button",
852
+ role: "switch",
853
+ "aria-checked": checked,
854
+ onClick: () => onChange(!checked),
855
+ className: cn(
856
+ "relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-input transition-colors",
857
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
858
+ checked ? "bg-primary" : "bg-input"
859
+ ),
860
+ children: /* @__PURE__ */ jsx("span", { className: cn(
861
+ "pointer-events-none inline-block size-4 rounded-full bg-primary-foreground shadow-sm transition-transform",
862
+ checked ? "translate-x-4" : "translate-x-0"
863
+ ) })
864
+ }
865
+ );
866
+ }
867
+ var Input = React11.forwardRef(
868
+ function Input2({ className, type, ...props }, ref) {
869
+ return /* @__PURE__ */ jsx(
870
+ "input",
871
+ {
872
+ ref,
873
+ type,
874
+ "data-slot": "input",
875
+ className: cn(
876
+ "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",
877
+ className
878
+ ),
879
+ ...props
880
+ }
881
+ );
882
+ }
883
+ );
884
+ function Calendar({
885
+ className,
886
+ classNames,
887
+ showOutsideDays = true,
888
+ captionLayout = "label",
889
+ buttonVariant = "ghost",
890
+ formatters,
891
+ components,
892
+ ...props
893
+ }) {
894
+ const defaultClassNames = getDefaultClassNames();
895
+ return /* @__PURE__ */ jsx(
896
+ DayPicker,
897
+ {
898
+ showOutsideDays,
899
+ className: cn(
900
+ "group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
901
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
902
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
903
+ className
904
+ ),
905
+ captionLayout,
906
+ formatters: {
907
+ formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
908
+ ...formatters
909
+ },
910
+ classNames: {
911
+ root: cn("w-fit", defaultClassNames.root),
912
+ months: cn(
913
+ "relative flex flex-col gap-4 md:flex-row",
914
+ defaultClassNames.months
915
+ ),
916
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
917
+ nav: cn(
918
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
919
+ defaultClassNames.nav
920
+ ),
921
+ button_previous: cn(
922
+ buttonVariants({ variant: buttonVariant }),
923
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
924
+ defaultClassNames.button_previous
925
+ ),
926
+ button_next: cn(
927
+ buttonVariants({ variant: buttonVariant }),
928
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
929
+ defaultClassNames.button_next
930
+ ),
931
+ month_caption: cn(
932
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
933
+ defaultClassNames.month_caption
934
+ ),
935
+ dropdowns: cn(
936
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
937
+ defaultClassNames.dropdowns
938
+ ),
939
+ dropdown_root: cn(
940
+ "relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
941
+ defaultClassNames.dropdown_root
942
+ ),
943
+ dropdown: cn(
944
+ "absolute inset-0 bg-popover opacity-0",
945
+ defaultClassNames.dropdown
946
+ ),
947
+ caption_label: cn(
948
+ "font-medium select-none",
949
+ 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",
950
+ defaultClassNames.caption_label
951
+ ),
952
+ table: "w-full border-collapse",
953
+ weekdays: cn("flex", defaultClassNames.weekdays),
954
+ weekday: cn(
955
+ "flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
956
+ defaultClassNames.weekday
957
+ ),
958
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
959
+ week_number_header: cn(
960
+ "w-(--cell-size) select-none",
961
+ defaultClassNames.week_number_header
962
+ ),
963
+ week_number: cn(
964
+ "text-[0.8rem] text-muted-foreground select-none",
965
+ defaultClassNames.week_number
966
+ ),
967
+ day: cn(
968
+ "group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
969
+ props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md" : "[&:first-child[data-selected=true]_button]:rounded-l-md",
970
+ defaultClassNames.day
971
+ ),
972
+ range_start: cn(
973
+ "rounded-l-md bg-accent",
974
+ defaultClassNames.range_start
975
+ ),
976
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
977
+ range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
978
+ today: cn(
979
+ "rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
980
+ defaultClassNames.today
981
+ ),
982
+ outside: cn(
983
+ "text-muted-foreground aria-selected:text-muted-foreground",
984
+ defaultClassNames.outside
985
+ ),
986
+ disabled: cn(
987
+ "text-muted-foreground opacity-50",
988
+ defaultClassNames.disabled
989
+ ),
990
+ hidden: cn("invisible", defaultClassNames.hidden),
991
+ ...classNames
992
+ },
993
+ components: {
994
+ Root: ({ className: className2, rootRef, ...props2 }) => {
995
+ return /* @__PURE__ */ jsx(
996
+ "div",
997
+ {
998
+ "data-slot": "calendar",
999
+ ref: rootRef,
1000
+ className: cn(className2),
1001
+ ...props2
1002
+ }
1003
+ );
1004
+ },
1005
+ Chevron: ({ className: className2, orientation, ...props2 }) => {
1006
+ if (orientation === "left") {
1007
+ return /* @__PURE__ */ jsx(ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
1008
+ }
1009
+ if (orientation === "right") {
1010
+ return /* @__PURE__ */ jsx(
1011
+ ChevronRightIcon,
1012
+ {
1013
+ className: cn("size-4", className2),
1014
+ ...props2
1015
+ }
1016
+ );
1017
+ }
1018
+ return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
1019
+ },
1020
+ DayButton: CalendarDayButton,
1021
+ WeekNumber: ({ children, ...props2 }) => {
1022
+ return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
1023
+ },
1024
+ ...components
1025
+ },
1026
+ ...props
1027
+ }
1028
+ );
1029
+ }
1030
+ function CalendarDayButton({
1031
+ className,
1032
+ day,
1033
+ modifiers,
1034
+ ...props
1035
+ }) {
1036
+ const defaultClassNames = getDefaultClassNames();
1037
+ const ref = React11.useRef(null);
1038
+ React11.useEffect(() => {
1039
+ if (modifiers.focused) ref.current?.focus();
1040
+ }, [modifiers.focused]);
1041
+ return /* @__PURE__ */ jsx(
1042
+ Button,
1043
+ {
1044
+ ref,
1045
+ variant: "ghost",
1046
+ size: "icon",
1047
+ "data-day": day.date.toLocaleDateString(),
1048
+ "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
1049
+ "data-range-start": modifiers.range_start,
1050
+ "data-range-end": modifiers.range_end,
1051
+ "data-range-middle": modifiers.range_middle,
1052
+ className: cn(
1053
+ "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",
1054
+ defaultClassNames.day,
1055
+ className
1056
+ ),
1057
+ ...props
1058
+ }
1059
+ );
1060
+ }
1061
+
1062
+ // src/lib/date-filter.ts
1063
+ function ymdToLocalDate(ymd) {
1064
+ if (!ymd || !/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return void 0;
1065
+ const [y, m, d] = ymd.split("-").map(Number);
1066
+ return new Date(y, m - 1, d, 12, 0, 0, 0);
1067
+ }
1068
+ function localDateToYmd(d) {
1069
+ const y = d.getFullYear();
1070
+ const m = String(d.getMonth() + 1).padStart(2, "0");
1071
+ const day = String(d.getDate()).padStart(2, "0");
1072
+ return `${y}-${m}-${day}`;
1073
+ }
1074
+ function FilterDateCalendar({
1075
+ valueYmd,
1076
+ onChangeYmd,
1077
+ label
1078
+ }) {
1079
+ const [timeZone, setTimeZone] = React11.useState();
1080
+ React11.useEffect(() => {
1081
+ setTimeZone(Intl.DateTimeFormat().resolvedOptions().timeZone);
1082
+ }, []);
1083
+ return /* @__PURE__ */ jsx(
1084
+ "div",
1085
+ {
1086
+ className: "rounded-lg border border-border overflow-hidden",
1087
+ role: "group",
1088
+ "aria-label": label,
1089
+ children: /* @__PURE__ */ jsx(
1090
+ Calendar,
1091
+ {
1092
+ mode: "single",
1093
+ selected: ymdToLocalDate(valueYmd),
1094
+ onSelect: (d) => onChangeYmd(d ? localDateToYmd(d) : void 0),
1095
+ captionLayout: "dropdown",
1096
+ timeZone,
1097
+ className: "rounded-lg border-0"
1098
+ }
1099
+ )
1100
+ }
1101
+ );
1102
+ }
1103
+ function InputGroup({ className, ...props }) {
1104
+ return /* @__PURE__ */ jsx(
1105
+ "div",
1106
+ {
1107
+ "data-slot": "input-group",
1108
+ role: "group",
1109
+ className: cn(
1110
+ "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",
1111
+ className
1112
+ ),
1113
+ ...props
1114
+ }
1115
+ );
1116
+ }
1117
+ var inputGroupAddonVariants = cva(
1118
+ "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",
1119
+ {
1120
+ variants: {
1121
+ align: {
1122
+ "inline-start": "order-first ps-2 has-[>button]:ms-[-0.3rem] has-[>kbd]:ms-[-0.15rem]",
1123
+ "inline-end": "order-last pe-2 has-[>button]:me-[-0.3rem] has-[>kbd]:me-[-0.15rem]",
1124
+ "block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
1125
+ "block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
1126
+ }
1127
+ },
1128
+ defaultVariants: {
1129
+ align: "inline-start"
1130
+ }
1131
+ }
1132
+ );
1133
+ function InputGroupAddon({
1134
+ className,
1135
+ align = "inline-start",
1136
+ ...props
1137
+ }) {
1138
+ return /* @__PURE__ */ jsx(
1139
+ "div",
1140
+ {
1141
+ role: "group",
1142
+ "data-slot": "input-group-addon",
1143
+ "data-align": align,
1144
+ className: cn(inputGroupAddonVariants({ align }), className),
1145
+ onClick: (e) => {
1146
+ if (e.target.closest("button")) {
1147
+ return;
1148
+ }
1149
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
1150
+ },
1151
+ ...props
1152
+ }
1153
+ );
1154
+ }
1155
+ var inputGroupButtonVariants = cva(
1156
+ "flex items-center gap-2 text-sm shadow-none",
1157
+ {
1158
+ variants: {
1159
+ size: {
1160
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
1161
+ sm: "",
1162
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
1163
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0"
1164
+ }
1165
+ },
1166
+ defaultVariants: {
1167
+ size: "xs"
1168
+ }
1169
+ }
1170
+ );
1171
+ function InputGroupButton({
1172
+ className,
1173
+ type = "button",
1174
+ variant = "ghost",
1175
+ size = "xs",
1176
+ ...props
1177
+ }) {
1178
+ return /* @__PURE__ */ jsx(
1179
+ Button,
1180
+ {
1181
+ type,
1182
+ "data-size": size,
1183
+ variant,
1184
+ className: cn(inputGroupButtonVariants({ size }), className),
1185
+ ...props
1186
+ }
1187
+ );
1188
+ }
1189
+
1190
+ // src/lib/compose-refs.ts
1191
+ function composeRefs(...refs) {
1192
+ return (node) => {
1193
+ for (const ref of refs) {
1194
+ if (ref == null) continue;
1195
+ if (typeof ref === "function") {
1196
+ ref(node);
1197
+ } else {
1198
+ ref.current = node;
1199
+ }
1200
+ }
1201
+ };
1202
+ }
1203
+ var exxatInputMaskDefaults = {
1204
+ placeholder: "_",
1205
+ showMaskOnHover: false
1206
+ };
1207
+ var exxatMaskPatterns = {
1208
+ /** US NANP 10-digit display */
1209
+ phoneUS: "(999) 999-9999",
1210
+ /** US ZIP or ZIP+4 */
1211
+ zipUS: "99999[-9999]",
1212
+ /** Calendar-style date (validate separately). */
1213
+ dateMDY: "99/99/9999"};
1214
+ var MaskedInput = React11.forwardRef(function MaskedInput2({ mask, maskOptions, className, type = "text", ...props }, ref) {
1215
+ const maskRef = useMaskInput({
1216
+ mask,
1217
+ options: { ...exxatInputMaskDefaults, ...maskOptions }
1218
+ });
1219
+ return /* @__PURE__ */ jsx(
1220
+ Input,
1221
+ {
1222
+ ref: composeRefs(ref, maskRef),
1223
+ type,
1224
+ className: cn(className),
1225
+ ...props
1226
+ }
1227
+ );
1228
+ });
1229
+ function Popover({ ...props }) {
1230
+ return /* @__PURE__ */ jsx(Popover$1.Root, { ...props });
1231
+ }
1232
+ function PopoverTrigger({ className, ...props }) {
1233
+ return /* @__PURE__ */ jsx(Popover$1.Trigger, { className: cn("cursor-pointer", className), ...props });
1234
+ }
1235
+ function PopoverContent({
1236
+ className,
1237
+ align = "start",
1238
+ sideOffset = 4,
1239
+ ...props
1240
+ }) {
1241
+ return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
1242
+ Popover$1.Content,
1243
+ {
1244
+ "data-slot": "popover-content",
1245
+ align,
1246
+ sideOffset,
1247
+ className: cn(
1248
+ "z-50 rounded-lg border border-border bg-popover shadow-md outline-none",
1249
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
1250
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
1251
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
1252
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
1253
+ "data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
1254
+ className
1255
+ ),
1256
+ ...props
1257
+ }
1258
+ ) });
1259
+ }
1260
+ var DATE_PICKER_ICON_CLASS = "fa-light fa-calendar";
1261
+ function parseMdyToLocalDate(raw) {
1262
+ const match = raw.trim().match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
1263
+ if (!match) return void 0;
1264
+ const month = Number(match[1]);
1265
+ const day = Number(match[2]);
1266
+ const year = Number(match[3]);
1267
+ if (month < 1 || month > 12 || day < 1 || day > 31) return void 0;
1268
+ const date = new Date(year, month - 1, day, 12, 0, 0, 0);
1269
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) return void 0;
1270
+ return date;
1271
+ }
1272
+ function formatLocalDateToMdy(date) {
1273
+ const month = String(date.getMonth() + 1).padStart(2, "0");
1274
+ const day = String(date.getDate()).padStart(2, "0");
1275
+ const year = String(date.getFullYear());
1276
+ return `${month}/${day}/${year}`;
1277
+ }
1278
+ function DateTextInputField({
1279
+ value,
1280
+ onValueChange,
1281
+ "aria-label": ariaLabel,
1282
+ id,
1283
+ placeholder = "MM/DD/YYYY",
1284
+ className,
1285
+ inputClassName,
1286
+ autoFocus,
1287
+ disabled,
1288
+ fromYear = 2020,
1289
+ toYear = 2032,
1290
+ iconButtonVariant = "ghost",
1291
+ popoverAlign = "end",
1292
+ popoverClassName
1293
+ }) {
1294
+ return /* @__PURE__ */ jsxs(InputGroup, { className, children: [
1295
+ /* @__PURE__ */ jsx(
1296
+ MaskedInput,
1297
+ {
1298
+ "data-slot": "input-group-control",
1299
+ id,
1300
+ mask: exxatMaskPatterns.dateMDY,
1301
+ "aria-label": ariaLabel,
1302
+ placeholder,
1303
+ value,
1304
+ onChange: (event) => onValueChange(event.target.value),
1305
+ className: cn(
1306
+ "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",
1307
+ inputClassName
1308
+ ),
1309
+ autoFocus,
1310
+ disabled
1311
+ }
1312
+ ),
1313
+ /* @__PURE__ */ jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsxs(Popover, { children: [
1314
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1315
+ InputGroupButton,
1316
+ {
1317
+ type: "button",
1318
+ variant: iconButtonVariant,
1319
+ size: "icon-xs",
1320
+ disabled,
1321
+ "aria-label": `${ariaLabel} pick date`,
1322
+ children: /* @__PURE__ */ jsx("i", { className: DATE_PICKER_ICON_CLASS, "aria-hidden": "true" })
1323
+ }
1324
+ ) }),
1325
+ /* @__PURE__ */ jsx(
1326
+ PopoverContent,
1327
+ {
1328
+ className: cn("z-[80] w-auto p-0", popoverClassName),
1329
+ align: popoverAlign,
1330
+ sideOffset: 6,
1331
+ children: /* @__PURE__ */ jsx(
1332
+ Calendar,
1333
+ {
1334
+ mode: "single",
1335
+ selected: parseMdyToLocalDate(value),
1336
+ onSelect: (next) => onValueChange(next ? formatLocalDateToMdy(next) : ""),
1337
+ initialFocus: true,
1338
+ fromYear,
1339
+ toYear,
1340
+ captionLayout: "dropdown"
1341
+ }
1342
+ )
1343
+ }
1344
+ )
1345
+ ] }) })
1346
+ ] });
1347
+ }
1348
+ var MASK_BY_KIND = {
1349
+ phone: exxatMaskPatterns.phoneUS,
1350
+ zip: exxatMaskPatterns.zipUS,
1351
+ dateMDY: exxatMaskPatterns.dateMDY
1352
+ };
1353
+ function FilterTextValueInput({
1354
+ id,
1355
+ mask,
1356
+ value,
1357
+ onValueChange,
1358
+ "aria-label": ariaLabel,
1359
+ placeholder,
1360
+ className,
1361
+ autoFocus
1362
+ }) {
1363
+ if (mask === "dateMDY") {
1364
+ return /* @__PURE__ */ jsx(
1365
+ DateTextInputField,
1366
+ {
1367
+ id,
1368
+ value,
1369
+ onValueChange,
1370
+ "aria-label": ariaLabel,
1371
+ placeholder,
1372
+ inputClassName: className,
1373
+ autoFocus,
1374
+ iconButtonVariant: "ghost",
1375
+ popoverAlign: "end"
1376
+ }
1377
+ );
1378
+ }
1379
+ if (mask) {
1380
+ return /* @__PURE__ */ jsx(
1381
+ MaskedInput,
1382
+ {
1383
+ id,
1384
+ mask: MASK_BY_KIND[mask],
1385
+ "aria-label": ariaLabel,
1386
+ placeholder,
1387
+ value,
1388
+ onChange: (e) => onValueChange(e.target.value),
1389
+ className,
1390
+ autoFocus
1391
+ }
1392
+ );
1393
+ }
1394
+ return /* @__PURE__ */ jsx(
1395
+ Input,
1396
+ {
1397
+ id,
1398
+ type: "text",
1399
+ "aria-label": ariaLabel,
1400
+ placeholder,
1401
+ value,
1402
+ onChange: (e) => onValueChange(e.target.value),
1403
+ className,
1404
+ autoFocus
1405
+ }
1406
+ );
1407
+ }
1408
+
1409
+ // src/lib/table-properties-types.ts
1410
+ var OPERATOR_LABELS = {
1411
+ is: "is",
1412
+ is_not: "is not",
1413
+ contains: "contains",
1414
+ not_contains: "does not contain"
1415
+ };
1416
+ var RULE_COLORS = [
1417
+ { name: "Green", bg: "var(--conditional-rule-green)" },
1418
+ { name: "Yellow", bg: "var(--conditional-rule-yellow)" },
1419
+ { name: "Blue", bg: "var(--conditional-rule-blue)" },
1420
+ { name: "Red", bg: "var(--conditional-rule-red)" },
1421
+ { name: "Purple", bg: "var(--conditional-rule-purple)" },
1422
+ { name: "Orange", bg: "var(--conditional-rule-orange)" }
1423
+ ];
1424
+ function DrawerFilterCard(props) {
1425
+ const {
1426
+ fieldDef,
1427
+ expanded,
1428
+ onToggleExpand,
1429
+ onRemove,
1430
+ renderOptionLabel
1431
+ } = props;
1432
+ const isCond = props.variant === "conditional";
1433
+ const filter = props.filter;
1434
+ const filterId = filter.id;
1435
+ const onUpdate = props.onUpdate;
1436
+ const [optSearch, setOptSearch] = React11.useState("");
1437
+ const options = fieldDef.options ?? [];
1438
+ const showSearch = options.length > 8;
1439
+ const filteredOpts = optSearch ? options.filter((o) => o.label.toLowerCase().includes(optSearch.toLowerCase())) : options;
1440
+ const values = filter.values;
1441
+ React11.useEffect(() => {
1442
+ if (fieldDef.type !== "select" && fieldDef.type !== "date") return;
1443
+ if (filter.operator !== "is" && filter.operator !== "is_not") {
1444
+ onUpdate(filterId, { operator: "is" });
1445
+ }
1446
+ }, [filter.operator, filter.id, fieldDef.type, filterId, onUpdate]);
1447
+ function toggleValue(val) {
1448
+ const next = values.includes(val) ? values.filter((v) => v !== val) : [...values, val];
1449
+ onUpdate(filterId, { values: next });
1450
+ }
1451
+ function cycleOperator() {
1452
+ const ops = fieldDef.operators;
1453
+ const idx = ops.indexOf(filter.operator);
1454
+ const i = idx === -1 ? 0 : idx;
1455
+ onUpdate(filterId, { operator: ops[(i + 1) % ops.length] });
1456
+ }
1457
+ const removeLabel = isCond ? "rule" : "filter";
1458
+ const rule = isCond ? props.filter : null;
1459
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs("div", { children: [
1460
+ /* @__PURE__ */ jsxs(
1461
+ "div",
1462
+ {
1463
+ className: "flex items-start justify-between px-3 pt-2.5 pb-2 gap-2 cursor-pointer",
1464
+ role: "button",
1465
+ tabIndex: 0,
1466
+ "aria-label": expanded ? `Collapse ${fieldDef.label}` : `Expand ${fieldDef.label}`,
1467
+ onClick: onToggleExpand,
1468
+ onKeyDown: (e) => {
1469
+ if (e.key === "Enter" || e.key === " ") {
1470
+ e.preventDefault();
1471
+ onToggleExpand();
1472
+ }
1473
+ },
1474
+ children: [
1475
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1476
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: fieldDef.label }),
1477
+ /* @__PURE__ */ jsxs(
1478
+ Button,
1479
+ {
1480
+ type: "button",
1481
+ variant: "ghost",
1482
+ size: "xs",
1483
+ "aria-label": `Operator: ${OPERATOR_LABELS[filter.operator]} \u2014 click to cycle`,
1484
+ onClick: (e) => {
1485
+ e.stopPropagation();
1486
+ cycleOperator();
1487
+ },
1488
+ className: "h-auto py-0 px-1 -ms-1 text-xs text-muted-foreground font-normal",
1489
+ children: [
1490
+ OPERATOR_LABELS[filter.operator],
1491
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
1492
+ ]
1493
+ }
1494
+ )
1495
+ ] }),
1496
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 shrink-0 self-start", children: [
1497
+ /* @__PURE__ */ jsx(Tip, { label: `Remove ${fieldDef.label} ${removeLabel}`, side: "top", children: /* @__PURE__ */ jsx(
1498
+ Button,
1499
+ {
1500
+ type: "button",
1501
+ variant: "ghost",
1502
+ size: "icon-sm",
1503
+ "aria-label": `Remove ${fieldDef.label} ${removeLabel}`,
1504
+ className: "text-muted-foreground hover:text-destructive",
1505
+ onClick: (e) => {
1506
+ e.stopPropagation();
1507
+ onRemove(filterId);
1508
+ },
1509
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-trash text-xs", "aria-hidden": "true" })
1510
+ }
1511
+ ) }),
1512
+ /* @__PURE__ */ jsx(
1513
+ "i",
1514
+ {
1515
+ className: `fa-light ${expanded ? "fa-chevron-up" : "fa-chevron-down"} text-xs text-muted-foreground mt-2`,
1516
+ "aria-hidden": "true"
1517
+ }
1518
+ )
1519
+ ] })
1520
+ ]
1521
+ }
1522
+ ),
1523
+ expanded && /* @__PURE__ */ jsxs("div", { className: "border-t border-border", children: [
1524
+ fieldDef.type === "select" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1525
+ showSearch && /* @__PURE__ */ jsx("div", { className: "px-3 pt-2 pb-1", children: /* @__PURE__ */ jsx(Input, { placeholder: "Search\u2026", value: optSearch, onChange: (e) => setOptSearch(e.target.value), className: "h-7 text-xs" }) }),
1526
+ /* @__PURE__ */ jsxs("div", { role: "listbox", "aria-multiselectable": "true", "aria-label": `${fieldDef.label} options`, className: "py-1 max-h-52 overflow-y-auto", children: [
1527
+ filteredOpts.map((opt) => {
1528
+ const checked = values.includes(opt.value);
1529
+ return /* @__PURE__ */ jsxs(
1530
+ "div",
1531
+ {
1532
+ role: "option",
1533
+ "aria-selected": checked,
1534
+ tabIndex: 0,
1535
+ onClick: () => toggleValue(opt.value),
1536
+ onKeyDown: (e) => {
1537
+ if (e.key === "Enter" || e.key === " ") {
1538
+ e.preventDefault();
1539
+ toggleValue(opt.value);
1540
+ }
1541
+ },
1542
+ className: "flex items-center gap-2.5 px-3 py-2 text-sm hover:bg-interactive-hover cursor-pointer select-none focus-visible:outline-none focus-visible:bg-interactive-hover",
1543
+ children: [
1544
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", "data-slot": "checkbox", "data-state": checked ? "checked" : "unchecked", className: cn(
1545
+ "inline-flex items-center justify-center size-3.5 shrink-0 rounded-[3px] border transition-colors",
1546
+ checked ? "bg-primary border-primary text-primary-foreground" : "border-input bg-background"
1547
+ ), children: checked && /* @__PURE__ */ jsx("i", { className: "fa-solid fa-check text-current", style: { fontSize: "7px" } }) }),
1548
+ renderOptionLabel ? renderOptionLabel(opt.value) : /* @__PURE__ */ jsx("span", { className: "text-foreground", children: opt.label })
1549
+ ]
1550
+ },
1551
+ opt.value
1552
+ );
1553
+ }),
1554
+ filteredOpts.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-xs text-muted-foreground", children: "No options found" })
1555
+ ] })
1556
+ ] }) : fieldDef.type === "date" ? /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
1557
+ FilterDateCalendar,
1558
+ {
1559
+ label: `${fieldDef.label} \u2014 choose date`,
1560
+ valueYmd: filter.values[0],
1561
+ onChangeYmd: (ymd) => onUpdate(filterId, { values: ymd ? [ymd] : [] })
1562
+ }
1563
+ ) }) : fieldDef.type === "text" ? /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(
1564
+ FilterTextValueInput,
1565
+ {
1566
+ mask: fieldDef.textMask,
1567
+ "aria-label": `${fieldDef.label} value`,
1568
+ placeholder: `Enter ${fieldDef.label.toLowerCase()}\u2026`,
1569
+ value: values[0] ?? "",
1570
+ onValueChange: (next) => onUpdate(filterId, { values: [next] }),
1571
+ className: "text-sm",
1572
+ autoFocus: true
1573
+ }
1574
+ ) }) : null,
1575
+ values.length > 0 ? /* @__PURE__ */ jsx("div", { className: "sticky bottom-0 border-t border-border bg-card p-2", children: /* @__PURE__ */ jsxs(
1576
+ Button,
1577
+ {
1578
+ type: "button",
1579
+ variant: "outline",
1580
+ size: "sm",
1581
+ onClick: () => onUpdate(filterId, { values: [] }),
1582
+ className: "w-full justify-center gap-1.5 text-xs text-muted-foreground",
1583
+ children: [
1584
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark text-xs", "aria-hidden": "true" }),
1585
+ "Clear selection"
1586
+ ]
1587
+ }
1588
+ ) }) : null
1589
+ ] }),
1590
+ isCond && rule && /* @__PURE__ */ jsxs("div", { className: "border-t border-border px-3 py-2.5", children: [
1591
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2", children: "Highlight color" }),
1592
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: RULE_COLORS.map((c) => /* @__PURE__ */ jsx(
1593
+ Button,
1594
+ {
1595
+ type: "button",
1596
+ size: "icon-xs",
1597
+ variant: "outline",
1598
+ "aria-label": c.name,
1599
+ className: cn(
1600
+ "rounded-md border-2 p-0 transition-all",
1601
+ rule.bgColor === c.bg ? "border-foreground scale-110" : "border-transparent hover:scale-105"
1602
+ ),
1603
+ style: { background: c.bg },
1604
+ onClick: () => onUpdate(filterId, { bgColor: c.bg })
1605
+ },
1606
+ c.name
1607
+ )) })
1608
+ ] })
1609
+ ] }) });
1610
+ }
1611
+ function DragHandleGripIcon({ className }) {
1612
+ return /* @__PURE__ */ jsx("i", { className: cn("fa-solid fa-grip-dots-vertical shrink-0", className), "aria-hidden": "true" });
1613
+ }
1614
+ function DrawerSortCard(props) {
1615
+ const { rule, fieldLabel, isPrimary, onRemove, onToggleDir } = props;
1616
+ const label = fieldLabel || rule.fieldKey;
1617
+ if (!label) return null;
1618
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border bg-background overflow-hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5", children: [
1619
+ /* @__PURE__ */ jsx(DragHandleGripIcon, { className: "text-[13px] text-muted-foreground/40" }),
1620
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1621
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
1622
+ isPrimary && /* @__PURE__ */ jsx("span", { className: "text-xs font-bold text-accent-foreground bg-accent rounded px-1 py-0.5 leading-none uppercase tracking-wide shrink-0", children: "Primary" }),
1623
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground truncate", children: label })
1624
+ ] }),
1625
+ /* @__PURE__ */ jsxs(
1626
+ "button",
1627
+ {
1628
+ type: "button",
1629
+ "aria-label": `Direction: ${rule.direction === "asc" ? "Ascending" : "Descending"} \u2014 click to toggle`,
1630
+ onClick: onToggleDir,
1631
+ className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-interactive-hover-foreground transition-colors mt-0.5",
1632
+ children: [
1633
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${rule.direction === "asc" ? "fa-arrow-up-a-z" : "fa-arrow-down-a-z"} text-xs`, "aria-hidden": "true" }),
1634
+ rule.direction === "asc" ? "Ascending" : "Descending",
1635
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
1636
+ ]
1637
+ }
1638
+ )
1639
+ ] }),
1640
+ /* @__PURE__ */ jsx(Tip, { label: `Remove ${label} sort`, side: "top", children: /* @__PURE__ */ jsx(
1641
+ "button",
1642
+ {
1643
+ type: "button",
1644
+ "aria-label": `Remove ${label} sort`,
1645
+ onClick: onRemove,
1646
+ className: "inline-flex items-center justify-center size-7 rounded text-muted-foreground hover:text-destructive hover:bg-interactive-hover transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring shrink-0",
1647
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-trash text-xs", "aria-hidden": "true" })
1648
+ }
1649
+ ) })
1650
+ ] }) });
1651
+ }
1652
+ function ColumnRow({
1653
+ label,
1654
+ isFirst,
1655
+ isLast,
1656
+ visible,
1657
+ onToggleVisible,
1658
+ onMoveUp,
1659
+ onMoveDown,
1660
+ draggable,
1661
+ onDragStart,
1662
+ onDragOver,
1663
+ onDrop,
1664
+ onDragEnd,
1665
+ isDragging,
1666
+ isOver
1667
+ }) {
1668
+ return /* @__PURE__ */ jsxs(
1669
+ "div",
1670
+ {
1671
+ role: "listitem",
1672
+ draggable,
1673
+ onDragStart,
1674
+ onDragOver,
1675
+ onDrop,
1676
+ onDragEnd,
1677
+ className: cn(
1678
+ "flex items-center gap-2 px-2 py-2 rounded-lg group hover:bg-interactive-hover-subtle transition-colors cursor-grab active:cursor-grabbing",
1679
+ isDragging && "opacity-40",
1680
+ isOver && "ring-2 ring-ring bg-accent/30"
1681
+ ),
1682
+ children: [
1683
+ /* @__PURE__ */ jsx(DragHandleGripIcon, { className: "text-[13px] text-muted-foreground/40 transition-colors group-hover:text-muted-foreground" }),
1684
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-foreground", children: label }),
1685
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity", children: [
1686
+ /* @__PURE__ */ jsx(Tip, { label: `Move ${label} up`, side: "top", children: /* @__PURE__ */ jsx(
1687
+ "button",
1688
+ {
1689
+ type: "button",
1690
+ "aria-label": `Move ${label} up`,
1691
+ disabled: isFirst,
1692
+ onClick: onMoveUp,
1693
+ className: "inline-flex items-center justify-center size-6 rounded text-muted-foreground hover:text-interactive-hover-foreground hover:bg-interactive-hover disabled:opacity-30 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1694
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-up text-xs", "aria-hidden": "true" })
1695
+ }
1696
+ ) }),
1697
+ /* @__PURE__ */ jsx(Tip, { label: `Move ${label} down`, side: "top", children: /* @__PURE__ */ jsx(
1698
+ "button",
1699
+ {
1700
+ type: "button",
1701
+ "aria-label": `Move ${label} down`,
1702
+ disabled: isLast,
1703
+ onClick: onMoveDown,
1704
+ className: "inline-flex items-center justify-center size-6 rounded text-muted-foreground hover:text-interactive-hover-foreground hover:bg-interactive-hover disabled:opacity-30 disabled:pointer-events-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1705
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-down text-xs", "aria-hidden": "true" })
1706
+ }
1707
+ ) })
1708
+ ] }),
1709
+ /* @__PURE__ */ jsx(
1710
+ ToggleSwitch,
1711
+ {
1712
+ checked: visible,
1713
+ onChange: onToggleVisible
1714
+ }
1715
+ )
1716
+ ]
1717
+ }
1718
+ );
1719
+ }
1720
+ function useDraggableList(items, getId, onReorder) {
1721
+ const [dragId, setDragId] = React11.useState(null);
1722
+ const [overId, setOverId] = React11.useState(null);
1723
+ function getItemProps(id) {
1724
+ return {
1725
+ draggable: true,
1726
+ onDragStart: (e) => {
1727
+ e.dataTransfer.effectAllowed = "move";
1728
+ setDragId(id);
1729
+ },
1730
+ onDragOver: (e) => {
1731
+ e.preventDefault();
1732
+ e.dataTransfer.dropEffect = "move";
1733
+ setOverId(id);
1734
+ },
1735
+ onDrop: (e) => {
1736
+ e.preventDefault();
1737
+ if (!dragId || dragId === id) {
1738
+ setDragId(null);
1739
+ setOverId(null);
1740
+ return;
1741
+ }
1742
+ const from = items.findIndex((i) => getId(i) === dragId);
1743
+ const to = items.findIndex((i) => getId(i) === id);
1744
+ if (from === -1 || to === -1) {
1745
+ setDragId(null);
1746
+ setOverId(null);
1747
+ return;
1748
+ }
1749
+ const next = [...items];
1750
+ const [moved] = next.splice(from, 1);
1751
+ next.splice(to, 0, moved);
1752
+ onReorder(next);
1753
+ setDragId(null);
1754
+ setOverId(null);
1755
+ },
1756
+ onDragEnd: () => {
1757
+ setDragId(null);
1758
+ setOverId(null);
1759
+ },
1760
+ "data-dragging": dragId === id,
1761
+ "data-over": overId === id && dragId !== id
1762
+ };
1763
+ }
1764
+ return { dragId, overId, getItemProps };
1765
+ }
1766
+ var PROPERTIES_SHEET_PORTAL_Z = "z-[90]";
1767
+ function TablePropertiesDrawer({
1768
+ open,
1769
+ onOpenChange,
1770
+ initialPanel,
1771
+ showGridlines,
1772
+ onShowGridlinesChange,
1773
+ rowHeight,
1774
+ onRowHeightChange,
1775
+ pagination,
1776
+ onPaginationChange,
1777
+ activeFilters,
1778
+ onAddFilter,
1779
+ onUpdateFilter,
1780
+ onRemoveFilter,
1781
+ getFilterConnector,
1782
+ onToggleFilterConnector,
1783
+ filterBarVisible,
1784
+ onFilterBarVisibleChange,
1785
+ drawerExpandedFilters,
1786
+ onDrawerExpandedFiltersChange,
1787
+ totalRows,
1788
+ filteredRows,
1789
+ sortRules,
1790
+ onSortRulesChange,
1791
+ onAddSortRule,
1792
+ onRemoveSortRule,
1793
+ onToggleSortDir,
1794
+ colOrder,
1795
+ onColOrderChange,
1796
+ hiddenCols,
1797
+ onToggleColVisibility,
1798
+ onMoveCol,
1799
+ groupBy,
1800
+ onGroupByChange,
1801
+ primarySortKey,
1802
+ conditionalRules,
1803
+ onAddConditionalRule,
1804
+ onRemoveConditionalRule,
1805
+ onUpdateConditionalRule,
1806
+ filterFields,
1807
+ currentView,
1808
+ onViewChange,
1809
+ supportedViewTypes,
1810
+ lifecycleTabLabel,
1811
+ fieldDefinitions,
1812
+ resolveColumnLabel: resolveColumnLabelProp,
1813
+ displayOptions,
1814
+ onDisplayOptionsChange,
1815
+ boardGroupByColumnOptions,
1816
+ renderFilterOptionValue
1817
+ }) {
1818
+ const [sheetPanel, setSheetPanel] = React11.useState("main");
1819
+ React11.useEffect(() => {
1820
+ if (open && initialPanel) {
1821
+ setSheetPanel(initialPanel);
1822
+ } else if (!open) {
1823
+ setSheetPanel("main");
1824
+ }
1825
+ }, [open, initialPanel]);
1826
+ const resolveColumnLabel = React11.useCallback(
1827
+ (key) => resolveColumnLabelProp?.(key) ?? fieldDefinitions.find((f) => f.key === key)?.label ?? key,
1828
+ [resolveColumnLabelProp, fieldDefinitions]
1829
+ );
1830
+ const sortFieldList = React11.useMemo(
1831
+ () => fieldDefinitions.filter(
1832
+ (f) => f.sortable !== false && f.key !== "select" && f.key !== "actions"
1833
+ ),
1834
+ [fieldDefinitions]
1835
+ );
1836
+ const groupFieldList = React11.useMemo(
1837
+ () => fieldDefinitions.filter((f) => f.key !== "select" && f.key !== "actions"),
1838
+ [fieldDefinitions]
1839
+ );
1840
+ const viewSurface = currentView ?? "table";
1841
+ const isBoardView = viewSurface === "board";
1842
+ const boardGroupByLabel = boardGroupByColumnOptions?.find((o) => o.key === displayOptions.boardGroupByColumnKey)?.label;
1843
+ const viewDisplayLabel = dataListViewLabel(viewSurface);
1844
+ const viewDisplayDesc = (() => {
1845
+ if (viewSurface === "board") {
1846
+ return [
1847
+ boardGroupByLabel ? `By ${boardGroupByLabel}` : null,
1848
+ `${displayOptions.boardLineCount}-line`,
1849
+ displayOptions.showColumnLabels ? "Column labels" : "No labels"
1850
+ ].filter(Boolean).join(" \xB7 ");
1851
+ }
1852
+ if (viewSurface === "list") {
1853
+ return [
1854
+ displayOptions.showColumnLabels ? "Column labels" : "No labels",
1855
+ displayOptions.showToolbarSearch ? "Toolbar search" : "No search"
1856
+ ].join(" \xB7 ");
1857
+ }
1858
+ if (viewSurface === "dashboard") {
1859
+ return "Charts \xB7 KPI metrics";
1860
+ }
1861
+ return [showGridlines ? "Gridlines" : null, pagination ? "Paginated" : null].filter(Boolean).join(" \xB7 ") || "Default";
1862
+ })();
1863
+ const viewDisplayIcon = DATA_LIST_VIEW_TILES.find((t) => t.value === viewSurface)?.icon ?? "fa-table";
1864
+ const sortDrag = useDraggableList(sortRules, (r) => r.id, onSortRulesChange);
1865
+ const orderable = colOrder.filter((k) => k !== "select" && k !== "actions");
1866
+ const colDrag = useDraggableList(
1867
+ orderable,
1868
+ (k) => k,
1869
+ (newOrder) => onColOrderChange(["select", ...newOrder, "actions"])
1870
+ );
1871
+ const primarySortLabel = primarySortKey ? resolveColumnLabel(primarySortKey) : sortRules[0]?.fieldKey ? resolveColumnLabel(sortRules[0].fieldKey) : "\u2014";
1872
+ return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, modal: false, children: /* @__PURE__ */ jsx(
1873
+ SheetContent,
1874
+ {
1875
+ side: "right",
1876
+ showCloseButton: false,
1877
+ showOverlay: false,
1878
+ className: "z-[80] w-[min(20rem,calc(100vw-1rem))] p-0 gap-0 flex flex-col border border-border shadow-xl rounded-xl overflow-hidden",
1879
+ style: { top: "0.5rem", bottom: "0.5rem", right: "0.5rem", height: "calc(100svh - 1rem)" },
1880
+ children: sheetPanel === "main" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1881
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 pt-5 pb-3", children: [
1882
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
1883
+ /* @__PURE__ */ jsx(SheetTitle, { className: "text-base font-semibold leading-tight", children: "Properties" }),
1884
+ lifecycleTabLabel ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 truncate", title: lifecycleTabLabel, children: lifecycleTabLabel }) : null
1885
+ ] }),
1886
+ /* @__PURE__ */ jsx(Tip, { label: "Close", side: "bottom", children: /* @__PURE__ */ jsx(
1887
+ Button,
1888
+ {
1889
+ type: "button",
1890
+ variant: "ghost",
1891
+ size: "icon-sm",
1892
+ "aria-label": "Close",
1893
+ onClick: () => onOpenChange(false),
1894
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark text-[13px]", "aria-hidden": "true" })
1895
+ }
1896
+ ) })
1897
+ ] }),
1898
+ onViewChange && currentView && /* @__PURE__ */ jsx("div", { className: "px-4 pb-3", children: /* @__PURE__ */ jsx(
1899
+ SelectionTileGrid,
1900
+ {
1901
+ sectionLabel: "View type",
1902
+ options: supportedViewTypes && supportedViewTypes.length > 0 ? dataListViewTilesForHub(supportedViewTypes).map((t) => ({
1903
+ value: t.type,
1904
+ label: t.label,
1905
+ icon: t.icon
1906
+ })) : DATA_LIST_VIEW_TILES,
1907
+ columns: 4,
1908
+ value: currentView,
1909
+ onValueChange: onViewChange,
1910
+ interaction: "button",
1911
+ idPrefix: "props-view"
1912
+ }
1913
+ ) }),
1914
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto py-2 px-3 space-y-1", children: [
1915
+ {
1916
+ id: "table-display",
1917
+ icon: viewDisplayIcon,
1918
+ label: viewDisplayLabel,
1919
+ desc: viewDisplayDesc
1920
+ },
1921
+ {
1922
+ id: "filter",
1923
+ icon: "fa-filter",
1924
+ label: "Filter",
1925
+ desc: activeFilters.length === 0 ? `Showing all ${filteredRows} rows.` : `${activeFilters.length} filter${activeFilters.length !== 1 ? "s" : ""} active \xB7 ${filteredRows} rows.`
1926
+ },
1927
+ {
1928
+ id: "sort",
1929
+ icon: "fa-arrow-up-arrow-down",
1930
+ label: "Sort",
1931
+ desc: `Sorted by ${primarySortLabel}.`
1932
+ },
1933
+ {
1934
+ id: "group",
1935
+ icon: "fa-layer-group",
1936
+ label: "Group",
1937
+ desc: groupBy ? `Grouped by ${resolveColumnLabel(groupBy)}.` : "No grouping."
1938
+ },
1939
+ {
1940
+ id: "columns",
1941
+ icon: "fa-table-columns",
1942
+ label: "Columns",
1943
+ desc: hiddenCols.size === 0 ? "All columns visible." : `${hiddenCols.size} column${hiddenCols.size !== 1 ? "s" : ""} hidden.`
1944
+ },
1945
+ {
1946
+ id: "conditional-rules",
1947
+ icon: "fa-palette",
1948
+ label: "Conditional rules",
1949
+ desc: conditionalRules.length === 0 ? "No rules applied." : `${conditionalRules.length} rule${conditionalRules.length !== 1 ? "s" : ""} active.`
1950
+ }
1951
+ ].map((item) => /* @__PURE__ */ jsxs(
1952
+ Button,
1953
+ {
1954
+ type: "button",
1955
+ variant: "ghost",
1956
+ onClick: () => setSheetPanel(item.id),
1957
+ className: cn(
1958
+ "w-full h-auto justify-start gap-3 px-3 py-3 rounded-2xl font-normal border border-transparent",
1959
+ "hover:bg-muted/60 hover:text-foreground",
1960
+ "focus-visible:bg-muted/60 focus-visible:text-foreground"
1961
+ ),
1962
+ children: [
1963
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: `fa-light ${item.icon} text-[15px] text-secondary-foreground`, "aria-hidden": "true" }) }),
1964
+ /* @__PURE__ */ jsxs("span", { className: "flex-1 min-w-0 text-start", children: [
1965
+ /* @__PURE__ */ jsx("span", { className: "block text-sm font-medium text-foreground", children: item.label }),
1966
+ /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground mt-0.5", children: item.desc })
1967
+ ] }),
1968
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-right text-xs text-muted-foreground shrink-0", "aria-hidden": "true" })
1969
+ ]
1970
+ },
1971
+ item.id
1972
+ )) })
1973
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1974
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 px-4 pt-4 pb-3", children: [
1975
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
1976
+ /* @__PURE__ */ jsx(Tip, { label: "Back to Properties", side: "bottom", children: /* @__PURE__ */ jsx(
1977
+ Button,
1978
+ {
1979
+ type: "button",
1980
+ variant: "ghost",
1981
+ size: "icon-sm",
1982
+ className: "shrink-0",
1983
+ "aria-label": "Back to Properties",
1984
+ onClick: () => setSheetPanel("main"),
1985
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-chevron-left text-[13px]", "aria-hidden": "true" })
1986
+ }
1987
+ ) }),
1988
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
1989
+ /* @__PURE__ */ jsxs(SheetTitle, { className: "text-base font-semibold text-foreground leading-tight flex items-center gap-1.5", children: [
1990
+ {
1991
+ "table-display": viewDisplayLabel,
1992
+ filter: "Filter",
1993
+ sort: "Sort",
1994
+ group: "Group",
1995
+ columns: "Columns",
1996
+ "conditional-rules": "Conditional rules",
1997
+ main: ""
1998
+ }[sheetPanel],
1999
+ sheetPanel === "filter" && /* @__PURE__ */ jsx("i", { className: "fa-light fa-circle-question text-xs text-muted-foreground", "aria-hidden": "true" })
2000
+ ] }),
2001
+ sheetPanel === "filter" && /* @__PURE__ */ jsx(
2002
+ "p",
2003
+ {
2004
+ className: "text-xs text-muted-foreground mt-0.5",
2005
+ "aria-live": "polite",
2006
+ "aria-atomic": "true",
2007
+ children: activeFilters.length === 0 ? `Showing all ${filteredRows} rows` : `${filteredRows} of ${totalRows} rows match \xB7 ${activeFilters.length} filter${activeFilters.length !== 1 ? "s" : ""} active`
2008
+ }
2009
+ )
2010
+ ] })
2011
+ ] }),
2012
+ /* @__PURE__ */ jsx(Tip, { label: "Close", side: "bottom", children: /* @__PURE__ */ jsx(
2013
+ Button,
2014
+ {
2015
+ type: "button",
2016
+ variant: "ghost",
2017
+ size: "icon-sm",
2018
+ className: "shrink-0",
2019
+ "aria-label": "Close panel",
2020
+ onClick: () => onOpenChange(false),
2021
+ children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-xmark text-[13px]", "aria-hidden": "true" })
2022
+ }
2023
+ ) })
2024
+ ] }),
2025
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto", children: [
2026
+ sheetPanel === "table-display" && /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-5", children: [
2027
+ isBoardView ? /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground leading-relaxed", children: [
2028
+ dataListViewLabel("board"),
2029
+ " groups rows into columns. Sort, filter, and column settings apply to the same dataset as other views (e.g. Table view)."
2030
+ ] }) : null,
2031
+ isBoardView && boardGroupByColumnOptions && boardGroupByColumnOptions.length > 1 ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 py-2", children: [
2032
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2033
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-table-columns text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2034
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2035
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Board columns" }),
2036
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Choose which field splits the board into swimlanes." })
2037
+ ] })
2038
+ ] }),
2039
+ /* @__PURE__ */ jsxs(
2040
+ Select,
2041
+ {
2042
+ value: boardGroupByColumnOptions.some((o) => o.key === displayOptions.boardGroupByColumnKey) ? displayOptions.boardGroupByColumnKey : boardGroupByColumnOptions[0].key,
2043
+ onValueChange: (v) => onDisplayOptionsChange({ boardGroupByColumnKey: v }),
2044
+ children: [
2045
+ /* @__PURE__ */ jsx(
2046
+ SelectTrigger,
2047
+ {
2048
+ size: "sm",
2049
+ className: "w-[9.5rem] shrink-0",
2050
+ id: "board-group-by-field",
2051
+ "aria-label": "Field for board columns",
2052
+ children: /* @__PURE__ */ jsx(SelectValue, {})
2053
+ }
2054
+ ),
2055
+ /* @__PURE__ */ jsx(SelectContent, { align: "end", className: PROPERTIES_SHEET_PORTAL_Z, children: boardGroupByColumnOptions.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.key, children: o.label }, o.key)) })
2056
+ ]
2057
+ }
2058
+ )
2059
+ ] }) : null,
2060
+ viewSurface === "table" ? /* @__PURE__ */ jsxs(Fragment, { children: [
2061
+ /* @__PURE__ */ jsxs("div", { children: [
2062
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-3", children: "Appearance" }),
2063
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: [
2064
+ { id: "gridlines", icon: "fa-border-all", label: "Gridlines", checked: showGridlines, onChange: onShowGridlinesChange },
2065
+ { id: "pagination", icon: "fa-table-list", label: "Pagination", checked: pagination, onChange: onPaginationChange }
2066
+ ].map((row) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between py-2", children: [
2067
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 text-sm", children: [
2068
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${row.icon} text-muted-foreground w-4 text-center`, "aria-hidden": "true" }),
2069
+ /* @__PURE__ */ jsx("label", { htmlFor: `toggle-${row.id}`, className: "cursor-pointer select-none", children: row.label })
2070
+ ] }),
2071
+ /* @__PURE__ */ jsx(ToggleSwitch, { id: `toggle-${row.id}`, checked: row.checked, onChange: row.onChange })
2072
+ ] }, row.id)) })
2073
+ ] }),
2074
+ /* @__PURE__ */ jsx("div", { className: "border-t border-border pt-4", children: /* @__PURE__ */ jsx(
2075
+ SelectionTileGrid,
2076
+ {
2077
+ sectionLabel: "Row height",
2078
+ options: ROW_HEIGHT_TILES,
2079
+ columns: 3,
2080
+ value: rowHeight,
2081
+ onValueChange: onRowHeightChange,
2082
+ interaction: "button",
2083
+ idPrefix: "row-height"
2084
+ }
2085
+ ) })
2086
+ ] }) : null,
2087
+ /* @__PURE__ */ jsxs(
2088
+ "div",
2089
+ {
2090
+ className: cn(
2091
+ "space-y-3",
2092
+ (viewSurface === "board" || viewSurface === "table") && "border-t border-border pt-4"
2093
+ ),
2094
+ children: [
2095
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Display options" }),
2096
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
2097
+ isBoardView && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2098
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2099
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-file-lines text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2100
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Line count" }) })
2101
+ ] }),
2102
+ /* @__PURE__ */ jsxs(
2103
+ Select,
2104
+ {
2105
+ value: String(displayOptions.boardLineCount),
2106
+ onValueChange: (v) => onDisplayOptionsChange({ boardLineCount: Number(v) }),
2107
+ children: [
2108
+ /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-[6.5rem] shrink-0", id: "board-line-count", "aria-label": "Line count", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
2109
+ /* @__PURE__ */ jsxs(SelectContent, { align: "end", className: PROPERTIES_SHEET_PORTAL_Z, children: [
2110
+ /* @__PURE__ */ jsx(SelectItem, { value: "1", children: "1 line" }),
2111
+ /* @__PURE__ */ jsx(SelectItem, { value: "2", children: "2 lines" }),
2112
+ /* @__PURE__ */ jsx(SelectItem, { value: "3", children: "3 lines" })
2113
+ ] })
2114
+ ]
2115
+ }
2116
+ )
2117
+ ] }),
2118
+ viewSurface === "table" && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2119
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2120
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-font text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2121
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2122
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Table title" }),
2123
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Show the page heading and subtitle." })
2124
+ ] })
2125
+ ] }),
2126
+ /* @__PURE__ */ jsx(
2127
+ ToggleSwitch,
2128
+ {
2129
+ id: "toggle-view-title",
2130
+ checked: displayOptions.showViewTitle,
2131
+ onChange: (v) => onDisplayOptionsChange({ showViewTitle: v })
2132
+ }
2133
+ )
2134
+ ] }),
2135
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2136
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2137
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-table-columns text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2138
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2139
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Column labels" }),
2140
+ viewSurface === "table" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Column headers in the table." }) : viewSurface === "list" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Column headers in the list." }) : null
2141
+ ] })
2142
+ ] }),
2143
+ /* @__PURE__ */ jsx(
2144
+ ToggleSwitch,
2145
+ {
2146
+ id: "toggle-column-labels",
2147
+ checked: displayOptions.showColumnLabels,
2148
+ onChange: (v) => onDisplayOptionsChange({ showColumnLabels: v })
2149
+ }
2150
+ )
2151
+ ] }),
2152
+ isBoardView && /* @__PURE__ */ jsxs(Fragment, { children: [
2153
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2154
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2155
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-hashtag text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2156
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Column counts" }) })
2157
+ ] }),
2158
+ /* @__PURE__ */ jsx(
2159
+ ToggleSwitch,
2160
+ {
2161
+ id: "toggle-board-counts",
2162
+ checked: displayOptions.showBoardColumnCounts,
2163
+ onChange: (v) => onDisplayOptionsChange({ showBoardColumnCounts: v })
2164
+ }
2165
+ )
2166
+ ] }),
2167
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2168
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2169
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-square-plus text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2170
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Above new card button" }) })
2171
+ ] }),
2172
+ /* @__PURE__ */ jsx(
2173
+ ToggleSwitch,
2174
+ {
2175
+ id: "toggle-new-card-above",
2176
+ checked: displayOptions.boardNewCardAbove,
2177
+ onChange: (v) => onDisplayOptionsChange({ boardNewCardAbove: v })
2178
+ }
2179
+ )
2180
+ ] })
2181
+ ] }),
2182
+ (viewSurface === "table" || viewSurface === "list") && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 py-2", children: [
2183
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0 flex-1", children: [
2184
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-secondary border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-magnifying-glass text-[15px] text-secondary-foreground", "aria-hidden": "true" }) }),
2185
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2186
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground leading-tight", children: "Search" }),
2187
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Toolbar search for this view." })
2188
+ ] })
2189
+ ] }),
2190
+ /* @__PURE__ */ jsx(
2191
+ ToggleSwitch,
2192
+ {
2193
+ id: "toggle-toolbar-search",
2194
+ checked: displayOptions.showToolbarSearch,
2195
+ onChange: (v) => onDisplayOptionsChange({ showToolbarSearch: v })
2196
+ }
2197
+ )
2198
+ ] })
2199
+ ] })
2200
+ ]
2201
+ }
2202
+ )
2203
+ ] }),
2204
+ sheetPanel === "filter" && /* @__PURE__ */ jsxs("div", { className: "px-4 py-4 space-y-2", children: [
2205
+ activeFilters.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border bg-muted/40 p-4 space-y-3", children: [
2206
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2207
+ /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center size-7 rounded-lg bg-background border border-border shrink-0", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-filter text-muted-foreground text-xs", "aria-hidden": "true" }) }),
2208
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "No filters yet" })
2209
+ ] }),
2210
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground leading-relaxed", children: [
2211
+ "Use filters to show only the rows you need. With multiple filters, use ",
2212
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground/80", children: "and" }),
2213
+ " or ",
2214
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground/80", children: "or" }),
2215
+ " between them to control how they combine."
2216
+ ] }),
2217
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: [
2218
+ { icon: "fa-circle-1", text: 'Click "Add filter" below' },
2219
+ { icon: "fa-circle-2", text: "Choose a field to filter by" },
2220
+ { icon: "fa-circle-3", text: "Pick at least one value \u2014 the grid updates immediately" }
2221
+ ].map((step) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
2222
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${step.icon} text-muted-foreground text-xs shrink-0`, "aria-hidden": "true" }),
2223
+ step.text
2224
+ ] }, step.icon)) })
2225
+ ] }) : /* @__PURE__ */ jsx(Fragment, { children: activeFilters.map((f, idx) => {
2226
+ const fieldDef = filterFields.find((fd) => fd.key === f.fieldKey);
2227
+ if (!fieldDef) return null;
2228
+ const leftId = idx > 0 ? activeFilters[idx - 1].id : null;
2229
+ const connector = leftId ? getFilterConnector(leftId) : "and";
2230
+ return /* @__PURE__ */ jsxs(React11.Fragment, { children: [
2231
+ idx > 0 && leftId && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 py-1", children: [
2232
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border", "aria-hidden": "true" }),
2233
+ /* @__PURE__ */ jsx(Tip, { label: "Click to switch: AND \u2014 every filter must match; OR \u2014 any matching filter is enough.", side: "top", children: /* @__PURE__ */ jsx(
2234
+ "button",
2235
+ {
2236
+ type: "button",
2237
+ onClick: () => onToggleFilterConnector(leftId),
2238
+ className: cn(
2239
+ "shrink-0 rounded-md border px-2.5 py-0.5 text-xs font-semibold uppercase tracking-wide transition-colors",
2240
+ "border-border bg-muted/40 text-muted-foreground hover:bg-interactive-hover hover:text-interactive-hover-foreground",
2241
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
2242
+ ),
2243
+ "aria-label": connector === "and" ? "Filters are combined with AND. Click to use OR instead." : "Filters are combined with OR. Click to use AND instead.",
2244
+ children: connector
2245
+ }
2246
+ ) }),
2247
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border", "aria-hidden": "true" })
2248
+ ] }),
2249
+ /* @__PURE__ */ jsx(
2250
+ DrawerFilterCard,
2251
+ {
2252
+ filter: f,
2253
+ fieldDef,
2254
+ expanded: drawerExpandedFilters.has(f.id),
2255
+ onToggleExpand: () => onDrawerExpandedFiltersChange((prev) => {
2256
+ const next = new Set(prev);
2257
+ if (next.has(f.id)) next.delete(f.id);
2258
+ else next.add(f.id);
2259
+ return next;
2260
+ }),
2261
+ onUpdate: onUpdateFilter,
2262
+ onRemove: (id) => {
2263
+ onRemoveFilter(id);
2264
+ onDrawerExpandedFiltersChange((prev) => {
2265
+ const next = new Set(prev);
2266
+ next.delete(id);
2267
+ return next;
2268
+ });
2269
+ },
2270
+ renderOptionLabel: (value) => renderFilterOptionValue?.(f.fieldKey, value)
2271
+ }
2272
+ )
2273
+ ] }, f.id);
2274
+ }) }),
2275
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
2276
+ /* @__PURE__ */ jsxs(DropdownMenu, { modal: false, children: [
2277
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2278
+ Button,
2279
+ {
2280
+ type: "button",
2281
+ variant: "outline",
2282
+ className: "flex-1 gap-1.5 h-8 border-dashed text-muted-foreground",
2283
+ children: [
2284
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-plus text-xs", "aria-hidden": "true" }),
2285
+ "Add filter"
2286
+ ]
2287
+ }
2288
+ ) }),
2289
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: PROPERTIES_SHEET_PORTAL_Z, children: [
2290
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs", children: "Filter by field" }),
2291
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2292
+ filterFields.map((f) => /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: () => onAddFilter(f.key), children: [
2293
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${f.icon}`, "aria-hidden": "true" }),
2294
+ f.label
2295
+ ] }, f.key))
2296
+ ] })
2297
+ ] }),
2298
+ activeFilters.length > 0 && /* @__PURE__ */ jsx(
2299
+ Button,
2300
+ {
2301
+ type: "button",
2302
+ variant: "ghost",
2303
+ size: "sm",
2304
+ className: "shrink-0 text-destructive hover:text-destructive hover:bg-destructive/10",
2305
+ onClick: () => {
2306
+ activeFilters.forEach((f) => onRemoveFilter(f.id));
2307
+ onDrawerExpandedFiltersChange(/* @__PURE__ */ new Set());
2308
+ },
2309
+ children: "Remove all"
2310
+ }
2311
+ )
2312
+ ] }),
2313
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3 pt-3 mt-1 border-t border-border", children: [
2314
+ /* @__PURE__ */ jsxs("div", { children: [
2315
+ /* @__PURE__ */ jsx("label", { htmlFor: "toggle-filter-bar", className: "text-sm font-medium text-foreground cursor-pointer", children: "Enable filter bar" }),
2316
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Show filters above the table." })
2317
+ ] }),
2318
+ /* @__PURE__ */ jsx(ToggleSwitch, { id: "toggle-filter-bar", checked: filterBarVisible, onChange: onFilterBarVisibleChange })
2319
+ ] })
2320
+ ] }),
2321
+ sheetPanel === "sort" && /* @__PURE__ */ jsxs("div", { className: "px-4 py-4 space-y-2", children: [
2322
+ sortRules.length === 0 ? (
2323
+ /* Empty state */
2324
+ /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-border bg-muted/30 px-4 py-6 text-center space-y-2", children: [
2325
+ /* @__PURE__ */ jsx("div", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-muted mb-1", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-arrow-up-arrow-down text-muted-foreground text-[16px]", "aria-hidden": "true" }) }),
2326
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "No sorts applied" }),
2327
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: "Add a sort rule to order rows by any field. Multiple rules are applied in priority order." }),
2328
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5 text-start pt-1", children: [
2329
+ { icon: "fa-circle-1", text: 'Click "Add sort" below' },
2330
+ { icon: "fa-circle-2", text: "Choose a field to sort by" },
2331
+ { icon: "fa-circle-3", text: "Toggle ascending or descending" }
2332
+ ].map((step) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
2333
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${step.icon} text-muted-foreground text-xs shrink-0`, "aria-hidden": "true" }),
2334
+ step.text
2335
+ ] }, step.icon)) })
2336
+ ] })
2337
+ ) : sortRules.map((rule, idx) => {
2338
+ const dragProps = sortDrag.getItemProps(rule.id);
2339
+ return /* @__PURE__ */ jsxs(React11.Fragment, { children: [
2340
+ idx > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 py-0.5", children: [
2341
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" }),
2342
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground px-1", children: "then by" }),
2343
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-px bg-border" })
2344
+ ] }),
2345
+ /* @__PURE__ */ jsx(
2346
+ "div",
2347
+ {
2348
+ ...dragProps,
2349
+ className: cn(
2350
+ "transition-all",
2351
+ dragProps["data-dragging"] && "opacity-40",
2352
+ dragProps["data-over"] && "ring-2 ring-ring bg-accent/30 rounded-lg"
2353
+ ),
2354
+ children: /* @__PURE__ */ jsx(
2355
+ DrawerSortCard,
2356
+ {
2357
+ rule,
2358
+ fieldLabel: resolveColumnLabel(rule.fieldKey),
2359
+ isPrimary: idx === 0,
2360
+ onRemove: () => onRemoveSortRule(rule.id),
2361
+ onToggleDir: () => onToggleSortDir(rule.id)
2362
+ }
2363
+ )
2364
+ }
2365
+ )
2366
+ ] }, rule.id);
2367
+ }),
2368
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
2369
+ /* @__PURE__ */ jsxs(DropdownMenu, { modal: false, children: [
2370
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2371
+ Button,
2372
+ {
2373
+ type: "button",
2374
+ variant: "outline",
2375
+ className: "flex-1 gap-1.5 h-8 border-dashed text-muted-foreground",
2376
+ children: [
2377
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-plus text-xs", "aria-hidden": "true" }),
2378
+ "Add sort"
2379
+ ]
2380
+ }
2381
+ ) }),
2382
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: PROPERTIES_SHEET_PORTAL_Z, children: [
2383
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs", children: "Sort by field" }),
2384
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2385
+ sortFieldList.filter((f) => !sortRules.some((r) => r.fieldKey === f.key)).map((col) => /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: () => onAddSortRule(col.key), children: [
2386
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-arrow-up-arrow-down text-xs", "aria-hidden": "true" }),
2387
+ col.label
2388
+ ] }, col.key)),
2389
+ sortFieldList.filter((f) => !sortRules.some((r) => r.fieldKey === f.key)).length === 0 && /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-xs text-muted-foreground", children: "All fields added" })
2390
+ ] })
2391
+ ] }),
2392
+ sortRules.length > 0 && /* @__PURE__ */ jsx(
2393
+ Button,
2394
+ {
2395
+ type: "button",
2396
+ variant: "ghost",
2397
+ size: "sm",
2398
+ className: "shrink-0 text-destructive hover:text-destructive hover:bg-destructive/10",
2399
+ onClick: () => onSortRulesChange([]),
2400
+ children: "Remove all"
2401
+ }
2402
+ )
2403
+ ] })
2404
+ ] }),
2405
+ sheetPanel === "group" && /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-2", children: [
2406
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-3", children: groupBy ? `Grouped by ${resolveColumnLabel(groupBy)}.` : "No grouping applied." }),
2407
+ /* @__PURE__ */ jsxs(
2408
+ Button,
2409
+ {
2410
+ type: "button",
2411
+ variant: "ghost",
2412
+ onClick: () => onGroupByChange(null),
2413
+ className: cn(
2414
+ "w-full justify-start gap-2 px-3 py-2 h-auto text-sm font-normal",
2415
+ !groupBy ? "bg-accent text-accent-foreground font-medium" : "text-muted-foreground"
2416
+ ),
2417
+ children: [
2418
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-ban text-xs", "aria-hidden": "true" }),
2419
+ "None"
2420
+ ]
2421
+ }
2422
+ ),
2423
+ groupFieldList.map((col) => /* @__PURE__ */ jsxs(
2424
+ Button,
2425
+ {
2426
+ type: "button",
2427
+ variant: "ghost",
2428
+ onClick: () => onGroupByChange(groupBy === col.key ? null : col.key),
2429
+ className: cn(
2430
+ "w-full justify-start gap-2 px-3 py-2 h-auto text-sm font-normal",
2431
+ groupBy === col.key ? "bg-accent text-accent-foreground font-medium" : ""
2432
+ ),
2433
+ children: [
2434
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-layer-group text-xs text-muted-foreground", "aria-hidden": "true" }),
2435
+ col.label,
2436
+ groupBy === col.key && /* @__PURE__ */ jsx("i", { className: "fa-solid fa-check text-accent-foreground text-xs ms-auto", "aria-hidden": "true" })
2437
+ ]
2438
+ },
2439
+ col.key
2440
+ ))
2441
+ ] }),
2442
+ sheetPanel === "columns" && /* @__PURE__ */ jsxs("div", { className: "px-4 py-4", children: [
2443
+ isBoardView ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-3", children: "Column visibility and order apply when you use Table view. They are saved with this tab." }) : null,
2444
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-3", children: hiddenCols.size === 0 ? "All columns visible. Drag to reorder." : `${hiddenCols.size} column${hiddenCols.size !== 1 ? "s" : ""} hidden. Drag handle to reorder.` }),
2445
+ /* @__PURE__ */ jsx("div", { className: "space-y-0.5", role: "list", "aria-label": "Column order and visibility", children: orderable.map((key, idx, arr) => {
2446
+ const dragProps = colDrag.getItemProps(key);
2447
+ return /* @__PURE__ */ jsx(
2448
+ ColumnRow,
2449
+ {
2450
+ label: resolveColumnLabel(key),
2451
+ isFirst: idx === 0,
2452
+ isLast: idx === arr.length - 1,
2453
+ visible: !hiddenCols.has(key),
2454
+ onToggleVisible: () => onToggleColVisibility(key),
2455
+ onMoveUp: () => onMoveCol(key, "up"),
2456
+ onMoveDown: () => onMoveCol(key, "down"),
2457
+ draggable: dragProps.draggable,
2458
+ onDragStart: dragProps.onDragStart,
2459
+ onDragOver: dragProps.onDragOver,
2460
+ onDrop: dragProps.onDrop,
2461
+ onDragEnd: dragProps.onDragEnd,
2462
+ isDragging: dragProps["data-dragging"],
2463
+ isOver: dragProps["data-over"]
2464
+ },
2465
+ key
2466
+ );
2467
+ }) })
2468
+ ] }),
2469
+ sheetPanel === "conditional-rules" && /* @__PURE__ */ jsx(
2470
+ ConditionalRulesPanel,
2471
+ {
2472
+ filterFields,
2473
+ rules: conditionalRules,
2474
+ onAdd: onAddConditionalRule,
2475
+ onRemove: onRemoveConditionalRule,
2476
+ onUpdate: onUpdateConditionalRule,
2477
+ renderFilterOptionValue
2478
+ }
2479
+ )
2480
+ ] })
2481
+ ] })
2482
+ }
2483
+ ) });
2484
+ }
2485
+ function ConditionalRulesPanel({
2486
+ filterFields,
2487
+ rules,
2488
+ onAdd,
2489
+ onRemove,
2490
+ onUpdate,
2491
+ renderFilterOptionValue
2492
+ }) {
2493
+ const [expandedIds, setExpandedIds] = React11.useState(() => /* @__PURE__ */ new Set());
2494
+ const prevLenRef = React11.useRef(rules.length);
2495
+ React11.useEffect(() => {
2496
+ if (rules.length > prevLenRef.current && rules.length > 0) {
2497
+ const last = rules[rules.length - 1];
2498
+ setExpandedIds(/* @__PURE__ */ new Set([last.id]));
2499
+ }
2500
+ prevLenRef.current = rules.length;
2501
+ }, [rules]);
2502
+ function toggleExpanded(id) {
2503
+ setExpandedIds((prev) => {
2504
+ const next = new Set(prev);
2505
+ if (next.has(id)) next.delete(id);
2506
+ else next.add(id);
2507
+ return next;
2508
+ });
2509
+ }
2510
+ return /* @__PURE__ */ jsxs("div", { className: "px-4 py-4 space-y-2", children: [
2511
+ rules.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-border bg-muted/30 px-4 py-6 text-center space-y-2", children: [
2512
+ /* @__PURE__ */ jsx("div", { className: "inline-flex items-center justify-center size-9 rounded-lg bg-muted mb-1", children: /* @__PURE__ */ jsx("i", { className: "fa-light fa-palette text-muted-foreground text-[16px]", "aria-hidden": "true" }) }),
2513
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "No rules yet" }),
2514
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: "Highlight cells with a background color based on their value." })
2515
+ ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-2", children: rules.map((rule) => {
2516
+ const fd = filterFields.find((f) => f.key === rule.fieldKey);
2517
+ if (!fd) return null;
2518
+ return /* @__PURE__ */ jsx(
2519
+ DrawerFilterCard,
2520
+ {
2521
+ variant: "conditional",
2522
+ filter: rule,
2523
+ fieldDef: fd,
2524
+ expanded: expandedIds.has(rule.id),
2525
+ onToggleExpand: () => toggleExpanded(rule.id),
2526
+ onUpdate,
2527
+ onRemove: (id) => {
2528
+ onRemove(id);
2529
+ setExpandedIds((prev) => {
2530
+ const next = new Set(prev);
2531
+ next.delete(id);
2532
+ return next;
2533
+ });
2534
+ },
2535
+ renderOptionLabel: (value) => renderFilterOptionValue?.(rule.fieldKey, value)
2536
+ },
2537
+ rule.id
2538
+ );
2539
+ }) }),
2540
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
2541
+ /* @__PURE__ */ jsxs(DropdownMenu, { modal: false, children: [
2542
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2543
+ Button,
2544
+ {
2545
+ type: "button",
2546
+ variant: "outline",
2547
+ className: "flex-1 gap-1.5 h-8 border-dashed text-muted-foreground",
2548
+ children: [
2549
+ /* @__PURE__ */ jsx("i", { className: "fa-light fa-plus text-xs", "aria-hidden": "true" }),
2550
+ "Add rule"
2551
+ ]
2552
+ }
2553
+ ) }),
2554
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: PROPERTIES_SHEET_PORTAL_Z, children: [
2555
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-xs", children: "Rule for column" }),
2556
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
2557
+ filterFields.map((f) => /* @__PURE__ */ jsxs(
2558
+ DropdownMenuItem,
2559
+ {
2560
+ onSelect: () => onAdd({
2561
+ fieldKey: f.key,
2562
+ operator: f.operators[0],
2563
+ values: [],
2564
+ bgColor: RULE_COLORS[0].bg
2565
+ }),
2566
+ children: [
2567
+ /* @__PURE__ */ jsx("i", { className: `fa-light ${f.icon}`, "aria-hidden": "true" }),
2568
+ f.label
2569
+ ]
2570
+ },
2571
+ f.key
2572
+ ))
2573
+ ] })
2574
+ ] }),
2575
+ rules.length > 0 && /* @__PURE__ */ jsx(
2576
+ Button,
2577
+ {
2578
+ type: "button",
2579
+ variant: "ghost",
2580
+ size: "sm",
2581
+ className: "shrink-0 text-destructive hover:text-destructive hover:bg-destructive/10",
2582
+ onClick: () => {
2583
+ rules.forEach((r) => onRemove(r.id));
2584
+ setExpandedIds(/* @__PURE__ */ new Set());
2585
+ },
2586
+ children: "Remove all"
2587
+ }
2588
+ )
2589
+ ] })
2590
+ ] });
2591
+ }
2592
+
2593
+ export { TablePropertiesDrawer };
2594
+ //# sourceMappingURL=drawer.js.map
2595
+ //# sourceMappingURL=drawer.js.map