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