@flanksource/clicky-ui 0.1.0 → 0.2.1

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 (378) hide show
  1. package/README.md +29 -2
  2. package/dist/api-explorer.d.ts +5 -0
  3. package/dist/api-explorer.d.ts.map +1 -0
  4. package/dist/api-explorer.js +25 -0
  5. package/dist/api-explorer.js.map +1 -0
  6. package/dist/clicky.d.ts +2 -0
  7. package/dist/clicky.d.ts.map +1 -0
  8. package/dist/clicky.js +5 -0
  9. package/dist/clicky.js.map +1 -0
  10. package/dist/components/DatePicker.d.ts +18 -0
  11. package/dist/components/DatePicker.d.ts.map +1 -0
  12. package/dist/components/DatePicker.js +63 -0
  13. package/dist/components/DatePicker.js.map +1 -0
  14. package/dist/components/DateTimePicker.d.ts +18 -0
  15. package/dist/components/DateTimePicker.d.ts.map +1 -0
  16. package/dist/components/DateTimePicker.js +84 -0
  17. package/dist/components/DateTimePicker.js.map +1 -0
  18. package/dist/components/FilterBar.d.ts +180 -0
  19. package/dist/components/FilterBar.d.ts.map +1 -0
  20. package/dist/components/FilterBar.js +1685 -0
  21. package/dist/components/FilterBar.js.map +1 -0
  22. package/dist/components/MultiSelect.d.ts +19 -0
  23. package/dist/components/MultiSelect.d.ts.map +1 -0
  24. package/dist/components/MultiSelect.js +143 -0
  25. package/dist/components/MultiSelect.js.map +1 -0
  26. package/dist/components/RangeSlider.d.ts +16 -0
  27. package/dist/components/RangeSlider.d.ts.map +1 -0
  28. package/dist/components/RangeSlider.js +92 -0
  29. package/dist/components/RangeSlider.js.map +1 -0
  30. package/dist/components/button.d.ts +21 -0
  31. package/dist/components/button.d.ts.map +1 -0
  32. package/dist/components/button.js +126 -0
  33. package/dist/components/button.js.map +1 -0
  34. package/dist/components/density-switcher.d.ts +7 -0
  35. package/dist/components/density-switcher.d.ts.map +1 -0
  36. package/dist/components/density-switcher.js +32 -0
  37. package/dist/components/density-switcher.js.map +1 -0
  38. package/dist/components/icon-menu-picker.d.ts +22 -0
  39. package/dist/components/icon-menu-picker.d.ts.map +1 -0
  40. package/dist/components/icon-menu-picker.js +181 -0
  41. package/dist/components/icon-menu-picker.js.map +1 -0
  42. package/dist/components/select.d.ts +15 -0
  43. package/dist/components/select.d.ts.map +1 -0
  44. package/dist/components/select.js +39 -0
  45. package/dist/components/select.js.map +1 -0
  46. package/dist/components/theme-switcher.d.ts +7 -0
  47. package/dist/components/theme-switcher.d.ts.map +1 -0
  48. package/dist/components/theme-switcher.js +42 -0
  49. package/dist/components/theme-switcher.js.map +1 -0
  50. package/dist/components.d.ts +14 -0
  51. package/dist/components.d.ts.map +1 -0
  52. package/dist/components.js +31 -0
  53. package/dist/components.js.map +1 -0
  54. package/dist/data/AnsiHtml.d.ts +7 -0
  55. package/dist/data/AnsiHtml.d.ts.map +1 -0
  56. package/dist/data/AnsiHtml.js +71 -0
  57. package/dist/data/AnsiHtml.js.map +1 -0
  58. package/dist/data/Avatar.d.ts +32 -0
  59. package/dist/data/Avatar.d.ts.map +1 -0
  60. package/dist/data/Avatar.js +201 -0
  61. package/dist/data/Avatar.js.map +1 -0
  62. package/dist/data/AvatarBadge.d.ts +26 -0
  63. package/dist/data/AvatarBadge.d.ts.map +1 -0
  64. package/dist/data/AvatarBadge.js +104 -0
  65. package/dist/data/AvatarBadge.js.map +1 -0
  66. package/dist/data/Badge.d.ts +44 -0
  67. package/dist/data/Badge.d.ts.map +1 -0
  68. package/dist/data/Badge.js +667 -0
  69. package/dist/data/Badge.js.map +1 -0
  70. package/dist/data/Clicky.d.ts +147 -0
  71. package/dist/data/Clicky.d.ts.map +1 -0
  72. package/dist/data/Clicky.fixtures.d.ts +3 -0
  73. package/dist/data/Clicky.fixtures.d.ts.map +1 -0
  74. package/dist/data/Clicky.js +1960 -0
  75. package/dist/data/Clicky.js.map +1 -0
  76. package/dist/data/DataTable.d.ts +95 -0
  77. package/dist/data/DataTable.d.ts.map +1 -0
  78. package/dist/data/DataTable.js +1464 -0
  79. package/dist/data/DataTable.js.map +1 -0
  80. package/dist/data/FilterPill.d.ts +29 -0
  81. package/dist/data/FilterPill.d.ts.map +1 -0
  82. package/dist/data/FilterPill.js +153 -0
  83. package/dist/data/FilterPill.js.map +1 -0
  84. package/dist/data/Gauge.d.ts +15 -0
  85. package/dist/data/Gauge.d.ts.map +1 -0
  86. package/dist/data/Gauge.js +63 -0
  87. package/dist/data/Gauge.js.map +1 -0
  88. package/dist/data/Icon.d.ts +53 -0
  89. package/dist/data/Icon.d.ts.map +1 -0
  90. package/dist/data/Icon.js +115 -0
  91. package/dist/data/Icon.js.map +1 -0
  92. package/dist/data/JsonView.d.ts +8 -0
  93. package/dist/data/JsonView.d.ts.map +1 -0
  94. package/dist/data/JsonView.js +74 -0
  95. package/dist/data/JsonView.js.map +1 -0
  96. package/dist/data/KeyValueList.d.ts +17 -0
  97. package/dist/data/KeyValueList.d.ts.map +1 -0
  98. package/dist/data/KeyValueList.js +33 -0
  99. package/dist/data/KeyValueList.js.map +1 -0
  100. package/dist/data/LogViewer.d.ts +10 -0
  101. package/dist/data/LogViewer.d.ts.map +1 -0
  102. package/dist/data/LogViewer.js +46 -0
  103. package/dist/data/LogViewer.js.map +1 -0
  104. package/dist/data/LogsTable.d.ts +27 -0
  105. package/dist/data/LogsTable.d.ts.map +1 -0
  106. package/dist/data/LogsTable.js +580 -0
  107. package/dist/data/LogsTable.js.map +1 -0
  108. package/dist/data/Markdown.d.ts +6 -0
  109. package/dist/data/Markdown.d.ts.map +1 -0
  110. package/dist/data/Markdown.js +59 -0
  111. package/dist/data/Markdown.js.map +1 -0
  112. package/dist/data/MatrixTable.d.ts +22 -0
  113. package/dist/data/MatrixTable.d.ts.map +1 -0
  114. package/dist/data/MatrixTable.js +164 -0
  115. package/dist/data/MatrixTable.js.map +1 -0
  116. package/dist/data/MethodBadge.d.ts +6 -0
  117. package/dist/data/MethodBadge.d.ts.map +1 -0
  118. package/dist/data/MethodBadge.js +18 -0
  119. package/dist/data/MethodBadge.js.map +1 -0
  120. package/dist/data/ProgressBar.d.ts +13 -0
  121. package/dist/data/ProgressBar.d.ts.map +1 -0
  122. package/dist/data/ProgressBar.js +34 -0
  123. package/dist/data/ProgressBar.js.map +1 -0
  124. package/dist/data/SortableHeader.d.ts +12 -0
  125. package/dist/data/SortableHeader.d.ts.map +1 -0
  126. package/dist/data/SortableHeader.js +33 -0
  127. package/dist/data/SortableHeader.js.map +1 -0
  128. package/dist/data/TabButton.d.ts +12 -0
  129. package/dist/data/TabButton.d.ts.map +1 -0
  130. package/dist/data/TabButton.js +45 -0
  131. package/dist/data/TabButton.js.map +1 -0
  132. package/dist/data/Tree.d.ts +35 -0
  133. package/dist/data/Tree.d.ts.map +1 -0
  134. package/dist/data/Tree.js +236 -0
  135. package/dist/data/Tree.js.map +1 -0
  136. package/dist/data/TreeGroupHeader.d.ts +11 -0
  137. package/dist/data/TreeGroupHeader.d.ts.map +1 -0
  138. package/dist/data/TreeGroupHeader.js +41 -0
  139. package/dist/data/TreeGroupHeader.js.map +1 -0
  140. package/dist/data/TreeNode.d.ts +43 -0
  141. package/dist/data/TreeNode.d.ts.map +1 -0
  142. package/dist/data/TreeNode.js +100 -0
  143. package/dist/data/TreeNode.js.map +1 -0
  144. package/dist/data/cells/StatusDot.d.ts +11 -0
  145. package/dist/data/cells/StatusDot.d.ts.map +1 -0
  146. package/dist/data/cells/StatusDot.js +38 -0
  147. package/dist/data/cells/StatusDot.js.map +1 -0
  148. package/dist/data/cells/TagList.d.ts +59 -0
  149. package/dist/data/cells/TagList.d.ts.map +1 -0
  150. package/dist/data/cells/TagList.js +257 -0
  151. package/dist/data/cells/TagList.js.map +1 -0
  152. package/dist/data/cells/Timestamp.d.ts +46 -0
  153. package/dist/data/cells/Timestamp.d.ts.map +1 -0
  154. package/dist/data/cells/Timestamp.js +146 -0
  155. package/dist/data/cells/Timestamp.js.map +1 -0
  156. package/dist/data/cells/status-mapping.d.ts +8 -0
  157. package/dist/data/cells/status-mapping.d.ts.map +1 -0
  158. package/dist/data/cells/status-mapping.js +44 -0
  159. package/dist/data/cells/status-mapping.js.map +1 -0
  160. package/dist/data/code-highlight.d.ts +12 -0
  161. package/dist/data/code-highlight.d.ts.map +1 -0
  162. package/dist/data/code-highlight.js +28 -0
  163. package/dist/data/code-highlight.js.map +1 -0
  164. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +9 -0
  165. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -0
  166. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +445 -0
  167. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -0
  168. package/dist/data/diagnostics/DiagnosticsTree.d.ts +9 -0
  169. package/dist/data/diagnostics/DiagnosticsTree.d.ts.map +1 -0
  170. package/dist/data/diagnostics/DiagnosticsTree.js +78 -0
  171. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -0
  172. package/dist/data/diagnostics/ErrorDetails.d.ts +20 -0
  173. package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -0
  174. package/dist/data/diagnostics/ErrorDetails.js +157 -0
  175. package/dist/data/diagnostics/ErrorDetails.js.map +1 -0
  176. package/dist/data/diagnostics/GoroutineCard.d.ts +10 -0
  177. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -0
  178. package/dist/data/diagnostics/GoroutineCard.js +75 -0
  179. package/dist/data/diagnostics/GoroutineCard.js.map +1 -0
  180. package/dist/data/diagnostics/JvmStackTrace.d.ts +11 -0
  181. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -0
  182. package/dist/data/diagnostics/JvmStackTrace.js +26 -0
  183. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -0
  184. package/dist/data/diagnostics/RenderedStackTrace.d.ts +18 -0
  185. package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -0
  186. package/dist/data/diagnostics/RenderedStackTrace.js +235 -0
  187. package/dist/data/diagnostics/RenderedStackTrace.js.map +1 -0
  188. package/dist/data/diagnostics/ThreadCard.d.ts +10 -0
  189. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -0
  190. package/dist/data/diagnostics/ThreadCard.js +78 -0
  191. package/dist/data/diagnostics/ThreadCard.js.map +1 -0
  192. package/dist/data/diagnostics/error-diagnostics.d.ts +26 -0
  193. package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -0
  194. package/dist/data/diagnostics/error-diagnostics.js +108 -0
  195. package/dist/data/diagnostics/error-diagnostics.js.map +1 -0
  196. package/dist/data/diagnostics/fixtures.d.ts +3 -0
  197. package/dist/data/diagnostics/fixtures.d.ts.map +1 -0
  198. package/dist/data/diagnostics/jvm-stacktrace.d.ts +34 -0
  199. package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -0
  200. package/dist/data/diagnostics/jvm-stacktrace.js +190 -0
  201. package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -0
  202. package/dist/data/diagnostics/stacktrace-parse.d.ts +11 -0
  203. package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -0
  204. package/dist/data/diagnostics/stacktrace-parse.js +87 -0
  205. package/dist/data/diagnostics/stacktrace-parse.js.map +1 -0
  206. package/dist/data/diagnostics/stacktrace.d.ts +38 -0
  207. package/dist/data/diagnostics/stacktrace.d.ts.map +1 -0
  208. package/dist/data/diagnostics/stacktrace.js +119 -0
  209. package/dist/data/diagnostics/stacktrace.js.map +1 -0
  210. package/dist/data/diagnostics/types.d.ts +30 -0
  211. package/dist/data/diagnostics/types.d.ts.map +1 -0
  212. package/dist/data/diagnostics/utils.d.ts +8 -0
  213. package/dist/data/diagnostics/utils.d.ts.map +1 -0
  214. package/dist/data/diagnostics/utils.js +59 -0
  215. package/dist/data/diagnostics/utils.js.map +1 -0
  216. package/dist/data/har/HarPanel.d.ts +9 -0
  217. package/dist/data/har/HarPanel.d.ts.map +1 -0
  218. package/dist/data/har/HarPanel.js +175 -0
  219. package/dist/data/har/HarPanel.js.map +1 -0
  220. package/dist/data/har/fixtures.d.ts +3 -0
  221. package/dist/data/har/fixtures.d.ts.map +1 -0
  222. package/dist/data/har/types.d.ts +47 -0
  223. package/dist/data/har/types.d.ts.map +1 -0
  224. package/dist/data.d.ts +39 -0
  225. package/dist/data.d.ts.map +1 -0
  226. package/dist/data.js +109 -0
  227. package/dist/data.js.map +1 -0
  228. package/dist/hooks/use-density.d.ts +22 -0
  229. package/dist/hooks/use-density.d.ts.map +1 -0
  230. package/dist/hooks/use-density.js +54 -0
  231. package/dist/hooks/use-density.js.map +1 -0
  232. package/dist/hooks/use-history-route.d.ts +6 -0
  233. package/dist/hooks/use-history-route.d.ts.map +1 -0
  234. package/dist/hooks/use-history-route.js +31 -0
  235. package/dist/hooks/use-history-route.js.map +1 -0
  236. package/dist/hooks/use-sort.d.ts +17 -0
  237. package/dist/hooks/use-sort.d.ts.map +1 -0
  238. package/dist/hooks/use-sort.js +42 -0
  239. package/dist/hooks/use-sort.js.map +1 -0
  240. package/dist/hooks/use-theme.d.ts +17 -0
  241. package/dist/hooks/use-theme.d.ts.map +1 -0
  242. package/dist/hooks/use-theme.js +68 -0
  243. package/dist/hooks/use-theme.js.map +1 -0
  244. package/dist/hooks.d.ts +5 -0
  245. package/dist/hooks.d.ts.map +1 -0
  246. package/dist/hooks.js +14 -0
  247. package/dist/hooks.js.map +1 -0
  248. package/dist/index.d.ts +7 -0
  249. package/dist/index.d.ts.map +1 -0
  250. package/dist/index.js +193 -0
  251. package/dist/index.js.map +1 -0
  252. package/dist/layout/Section.d.ts +23 -0
  253. package/dist/layout/Section.d.ts.map +1 -0
  254. package/dist/layout/Section.js +73 -0
  255. package/dist/layout/Section.js.map +1 -0
  256. package/dist/layout/SplitPane.d.ts +13 -0
  257. package/dist/layout/SplitPane.d.ts.map +1 -0
  258. package/dist/layout/SplitPane.js +72 -0
  259. package/dist/layout/SplitPane.js.map +1 -0
  260. package/dist/lib/palette.d.ts +4 -0
  261. package/dist/lib/palette.d.ts.map +1 -0
  262. package/dist/lib/palette.js +35 -0
  263. package/dist/lib/palette.js.map +1 -0
  264. package/dist/lib/size.d.ts +6 -0
  265. package/dist/lib/size.d.ts.map +1 -0
  266. package/dist/lib/size.js +14 -0
  267. package/dist/lib/size.js.map +1 -0
  268. package/dist/lib/utils.d.ts +3 -0
  269. package/dist/lib/utils.d.ts.map +1 -0
  270. package/dist/lib/utils.js +9 -0
  271. package/dist/lib/utils.js.map +1 -0
  272. package/dist/overlay/HoverCard.d.ts +13 -0
  273. package/dist/overlay/HoverCard.d.ts.map +1 -0
  274. package/dist/overlay/HoverCard.js +170 -0
  275. package/dist/overlay/HoverCard.js.map +1 -0
  276. package/dist/overlay/Modal.d.ts +17 -0
  277. package/dist/overlay/Modal.d.ts.map +1 -0
  278. package/dist/overlay/Modal.js +91 -0
  279. package/dist/overlay/Modal.js.map +1 -0
  280. package/dist/rpc/AcceptPicker.d.ts +52 -0
  281. package/dist/rpc/AcceptPicker.d.ts.map +1 -0
  282. package/dist/rpc/AcceptPicker.js +126 -0
  283. package/dist/rpc/AcceptPicker.js.map +1 -0
  284. package/dist/rpc/ApiExplorer.d.ts +11 -0
  285. package/dist/rpc/ApiExplorer.d.ts.map +1 -0
  286. package/dist/rpc/ApiExplorer.js +37 -0
  287. package/dist/rpc/ApiExplorer.js.map +1 -0
  288. package/dist/rpc/CommandForm.d.ts +15 -0
  289. package/dist/rpc/CommandForm.d.ts.map +1 -0
  290. package/dist/rpc/CommandForm.js +356 -0
  291. package/dist/rpc/CommandForm.js.map +1 -0
  292. package/dist/rpc/CommandOutput.d.ts +11 -0
  293. package/dist/rpc/CommandOutput.d.ts.map +1 -0
  294. package/dist/rpc/CommandOutput.js +195 -0
  295. package/dist/rpc/CommandOutput.js.map +1 -0
  296. package/dist/rpc/EndpointList.d.ts +18 -0
  297. package/dist/rpc/EndpointList.d.ts.map +1 -0
  298. package/dist/rpc/EndpointList.js +56 -0
  299. package/dist/rpc/EndpointList.js.map +1 -0
  300. package/dist/rpc/EntityExplorerApp.d.ts +15 -0
  301. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -0
  302. package/dist/rpc/EntityExplorerApp.js +282 -0
  303. package/dist/rpc/EntityExplorerApp.js.map +1 -0
  304. package/dist/rpc/ExecutionResult.d.ts +14 -0
  305. package/dist/rpc/ExecutionResult.d.ts.map +1 -0
  306. package/dist/rpc/ExecutionResult.js +51 -0
  307. package/dist/rpc/ExecutionResult.js.map +1 -0
  308. package/dist/rpc/FilterForm.d.ts +22 -0
  309. package/dist/rpc/FilterForm.d.ts.map +1 -0
  310. package/dist/rpc/FilterForm.js +392 -0
  311. package/dist/rpc/FilterForm.js.map +1 -0
  312. package/dist/rpc/InlineError.d.ts +7 -0
  313. package/dist/rpc/InlineError.d.ts.map +1 -0
  314. package/dist/rpc/InlineError.js +54 -0
  315. package/dist/rpc/InlineError.js.map +1 -0
  316. package/dist/rpc/OperationActionDialog.d.ts +12 -0
  317. package/dist/rpc/OperationActionDialog.d.ts.map +1 -0
  318. package/dist/rpc/OperationActionDialog.js +105 -0
  319. package/dist/rpc/OperationActionDialog.js.map +1 -0
  320. package/dist/rpc/OperationCatalog.d.ts +21 -0
  321. package/dist/rpc/OperationCatalog.d.ts.map +1 -0
  322. package/dist/rpc/OperationCatalog.js +339 -0
  323. package/dist/rpc/OperationCatalog.js.map +1 -0
  324. package/dist/rpc/OperationCommandPage.d.ts +22 -0
  325. package/dist/rpc/OperationCommandPage.d.ts.map +1 -0
  326. package/dist/rpc/OperationCommandPage.js +484 -0
  327. package/dist/rpc/OperationCommandPage.js.map +1 -0
  328. package/dist/rpc/OperationEntityPage.d.ts +23 -0
  329. package/dist/rpc/OperationEntityPage.d.ts.map +1 -0
  330. package/dist/rpc/OperationEntityPage.js +218 -0
  331. package/dist/rpc/OperationEntityPage.js.map +1 -0
  332. package/dist/rpc/classify.d.ts +8 -0
  333. package/dist/rpc/classify.d.ts.map +1 -0
  334. package/dist/rpc/classify.js +76 -0
  335. package/dist/rpc/classify.js.map +1 -0
  336. package/dist/rpc/clickyMetadata.d.ts +12 -0
  337. package/dist/rpc/clickyMetadata.d.ts.map +1 -0
  338. package/dist/rpc/clickyMetadata.js +71 -0
  339. package/dist/rpc/clickyMetadata.js.map +1 -0
  340. package/dist/rpc/formMetadata.d.ts +27 -0
  341. package/dist/rpc/formMetadata.d.ts.map +1 -0
  342. package/dist/rpc/formMetadata.js +250 -0
  343. package/dist/rpc/formMetadata.js.map +1 -0
  344. package/dist/rpc/types.d.ts +109 -0
  345. package/dist/rpc/types.d.ts.map +1 -0
  346. package/dist/rpc/types.js +8 -0
  347. package/dist/rpc/types.js.map +1 -0
  348. package/dist/rpc/useOperations.d.ts +346 -0
  349. package/dist/rpc/useOperations.d.ts.map +1 -0
  350. package/dist/rpc/useOperations.js +31 -0
  351. package/dist/rpc/useOperations.js.map +1 -0
  352. package/dist/rpc.d.ts +14 -0
  353. package/dist/rpc.d.ts.map +1 -0
  354. package/dist/rpc.js +37 -0
  355. package/dist/rpc.js.map +1 -0
  356. package/dist/styles.css +2 -0
  357. package/dist/styles.d.ts +1 -0
  358. package/dist/styles.d.ts.map +1 -0
  359. package/dist/styles.js +2 -0
  360. package/dist/styles.js.map +1 -0
  361. package/dist/tailwind-preset.d.ts +4 -0
  362. package/dist/tailwind-preset.d.ts.map +1 -0
  363. package/dist/tailwind-preset.js +69 -0
  364. package/dist/tailwind-preset.js.map +1 -0
  365. package/dist/utils.d.ts +4 -0
  366. package/dist/utils.d.ts.map +1 -0
  367. package/dist/utils.js +12 -0
  368. package/dist/utils.js.map +1 -0
  369. package/package.json +83 -40
  370. package/dist/index.d.mts +0 -834
  371. package/dist/index.d.mts.map +0 -1
  372. package/dist/index.mjs +0 -2918
  373. package/dist/index.mjs.map +0 -1
  374. package/dist/tailwind-preset.d.mts +0 -7
  375. package/dist/tailwind-preset.d.mts.map +0 -1
  376. package/dist/tailwind-preset.mjs +0 -64
  377. package/dist/tailwind-preset.mjs.map +0 -1
  378. package/src/styles/tokens.css +0 -78
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterBar.js","sources":["../../src/components/FilterBar.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { FilterPill, type FilterMode } from \"../data/FilterPill\";\nimport { Icon } from \"../data/Icon\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { DatePicker } from \"./DatePicker\";\nimport { DateTimePicker } from \"./DateTimePicker\";\nimport { MultiSelect, type MultiSelectOption } from \"./MultiSelect\";\nimport { RangeSlider } from \"./RangeSlider\";\nimport { Select } from \"./select\";\n\nconst FILTER_INPUT_DEBOUNCE_MS = 500;\n\n// When `autoSubmit` is false, debounced fields forward their draft value\n// immediately (no timer) so the consumer can accumulate state locally and\n// fire one request when Apply is clicked. When true (default) fields debounce\n// upstream, matching the live-filter behaviour used in trace/log UIs.\nconst FilterBarContext = createContext<{ autoSubmit: boolean }>({\n autoSubmit: true,\n});\n\nexport type FilterBarSearchProps = {\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n ariaLabel?: string;\n className?: string;\n};\n\nexport type FilterBarTextFilter = {\n key: string;\n kind: \"text\";\n label: string;\n description?: string;\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarLookupOption = {\n value: string;\n label?: string;\n disabled?: boolean;\n title?: string;\n};\n\nexport type FilterBarLookupInputType = \"text\" | \"number\" | \"date\";\n\nexport type FilterBarLookupFilter = {\n key: string;\n kind: \"lookup\";\n label: string;\n description?: string;\n value: string;\n options: FilterBarLookupOption[];\n onChange: (value: string) => void;\n placeholder?: string;\n inputType?: FilterBarLookupInputType;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarLookupMultiFilter = {\n key: string;\n kind: \"lookup-multi\";\n label: string;\n description?: string;\n value: string[];\n options: FilterBarLookupOption[];\n onChange: (value: string[]) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarMultiFilterMode = Extract<FilterMode, \"include\" | \"exclude\">;\n\nexport type FilterBarMultiFilter = {\n key: string;\n kind: \"multi\";\n label: string;\n description?: string;\n value: Record<string, FilterBarMultiFilterMode>;\n options: MultiSelectOption[];\n onChange: (value: Record<string, FilterBarMultiFilterMode>) => void;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarNestedMultiGroup = {\n groupKey: string;\n label?: string;\n options: MultiSelectOption[];\n};\n\nexport type FilterBarNestedMultiFilter = {\n key: string;\n kind: \"nested-multi\";\n label: string;\n description?: string;\n // Same wire shape as FilterBarMultiFilter so consumers can swap kinds\n // without changing their state slot.\n value: Record<string, FilterBarMultiFilterMode>;\n groups: FilterBarNestedMultiGroup[];\n onChange: (value: Record<string, FilterBarMultiFilterMode>) => void;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarSelectMultiFilter = {\n key: string;\n kind: \"select-multi\";\n label: string;\n description?: string;\n value: string[];\n options: MultiSelectOption[];\n onChange: (value: string[]) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarNumberValue = {\n min?: string;\n max?: string;\n};\n\nexport type FilterBarNumberFilter = {\n key: string;\n kind: \"number\";\n label: string;\n description?: string;\n value: FilterBarNumberValue;\n onChange: (value: FilterBarNumberValue) => void;\n domainMin?: number;\n domainMax?: number;\n step?: number;\n formatValue?: (value: number) => string;\n minPlaceholder?: string;\n maxPlaceholder?: string;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarEnumFilter = {\n key: string;\n kind: \"enum\";\n label: string;\n description?: string;\n value: string;\n options: Array<{ value: string; label?: string }>;\n onChange: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarBooleanFilter = {\n key: string;\n kind: \"boolean\";\n label: string;\n description?: string;\n value: boolean;\n onChange: (value: boolean) => void;\n disabled?: boolean;\n className?: string;\n};\n\nexport type FilterBarFilter =\n | FilterBarTextFilter\n | FilterBarLookupFilter\n | FilterBarLookupMultiFilter\n | FilterBarMultiFilter\n | FilterBarNestedMultiFilter\n | FilterBarSelectMultiFilter\n | FilterBarNumberFilter\n | FilterBarEnumFilter\n | FilterBarBooleanFilter;\n\nexport type FilterBarRangePreset = {\n label: string;\n from: string;\n to: string;\n};\n\nexport type FilterBarRangeProps = {\n from?: string;\n to?: string;\n onApply: (from: string, to: string) => void;\n presets?: FilterBarRangePreset[];\n fromPlaceholder?: string;\n toPlaceholder?: string;\n emptyLabel?: string;\n className?: string;\n};\n\nexport type FilterBarProps = {\n search?: FilterBarSearchProps;\n filters?: FilterBarFilter[];\n timeRange?: FilterBarRangeProps;\n dateRange?: FilterBarRangeProps;\n children?: ReactNode;\n leading?: ReactNode;\n trailing?: ReactNode;\n className?: string;\n // When false, debounced fields forward edits immediately (no timer) and\n // an Apply button is rendered in the trailing slot. The caller is expected\n // to accumulate field state and perform the side effect in `onApply`.\n // Defaults to true.\n autoSubmit?: boolean;\n onApply?: () => void;\n applyLabel?: string;\n isPending?: boolean;\n};\n\nexport function FilterBar({\n search,\n filters,\n timeRange,\n dateRange,\n children,\n leading,\n trailing,\n className,\n autoSubmit = true,\n onApply,\n applyLabel = \"Apply\",\n isPending = false,\n}: FilterBarProps) {\n const hasRangeControls = Boolean(timeRange || dateRange);\n const showApply = !autoSubmit && !!onApply;\n const contextValue = useMemo(() => ({ autoSubmit }), [autoSubmit]);\n\n return (\n <FilterBarContext.Provider value={contextValue}>\n <div\n className={cn(\n \"flex flex-wrap items-center gap-2 rounded-lg border border-input bg-background px-2 py-1.5 shadow-sm\",\n className,\n )}\n >\n {leading && <div className=\"flex items-center gap-2\">{leading}</div>}\n\n {search && <SearchField search={search} />}\n\n {children}\n\n {filters?.map((filter, index) => {\n const grow = !search && index === 0;\n\n if (filter.kind === \"lookup\") {\n return <LookupFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"lookup-multi\") {\n return <LookupMultiFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"multi\") {\n return <MultiFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"nested-multi\") {\n return <NestedMultiFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"select-multi\") {\n return <SelectMultiFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"number\") {\n return <NumberFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"enum\") {\n return <EnumFilterField key={filter.key} filter={filter} grow={grow} />;\n }\n\n if (filter.kind === \"boolean\") {\n return <BooleanFilterField key={filter.key} filter={filter} />;\n }\n\n return <TextFilterField key={filter.key} filter={filter} grow={grow} />;\n })}\n\n {(hasRangeControls || trailing || showApply) && (\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {dateRange && <RangeControlButton kind=\"date\" label=\"Date range\" {...dateRange} />}\n {timeRange && <RangeControlButton kind=\"time\" label=\"Time range\" {...timeRange} />}\n {trailing}\n {showApply && (\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n disabled={isPending}\n onClick={onApply}\n >\n {isPending ? \"Loading…\" : applyLabel}\n </Button>\n )}\n </div>\n )}\n </div>\n </FilterBarContext.Provider>\n );\n}\n\ntype FilterBarFilterPanelChrome = \"full\" | \"embedded\";\n\nexport function FilterBarFilterPanel({\n filter,\n chrome = \"full\",\n}: {\n filter: FilterBarFilter;\n chrome?: FilterBarFilterPanelChrome;\n}) {\n const contextValue = useMemo(() => ({ autoSubmit: true }), []);\n\n return (\n <FilterBarContext.Provider value={contextValue}>\n {filter.kind === \"lookup\" && <LookupFilterField filter={filter} grow />}\n {filter.kind === \"lookup-multi\" && <LookupMultiFilterField filter={filter} grow />}\n {filter.kind === \"multi\" && <MultiFilterPanel filter={filter} chrome={chrome} />}\n {filter.kind === \"nested-multi\" && <NestedMultiFilterPanel filter={filter} chrome={chrome} />}\n {filter.kind === \"select-multi\" && <SelectMultiFilterField filter={filter} grow />}\n {filter.kind === \"number\" && <NumberFilterPanel filter={filter} chrome={chrome} />}\n {filter.kind === \"enum\" && <EnumFilterField filter={filter} grow />}\n {filter.kind === \"boolean\" && <BooleanFilterField filter={filter} />}\n {filter.kind === \"text\" && <TextFilterField filter={filter} grow />}\n </FilterBarContext.Provider>\n );\n}\n\nexport function FilterBarRangePanel({\n kind,\n label,\n from = \"\",\n to = \"\",\n onApply,\n presets: _presets,\n fromPlaceholder,\n toPlaceholder,\n emptyLabel: _emptyLabel,\n}: FilterBarRangeProps & { kind: \"date\" | \"time\"; label: string }) {\n const fromInputRef = useRef<HTMLInputElement>(null);\n const toInputRef = useRef<HTMLInputElement>(null);\n const [draftFrom, setDraftFrom] = useState(from);\n const [draftTo, setDraftTo] = useState(to);\n\n useEffect(() => {\n setDraftFrom(from);\n setDraftTo(to);\n }, [from, to]);\n\n function applyRange(nextFrom: string, nextTo: string) {\n onApply(\n kind === \"time\" ? normalizeDateMath(nextFrom) : nextFrom.trim(),\n kind === \"time\" ? normalizeDateMath(nextTo) : nextTo.trim(),\n );\n }\n\n return (\n <div className=\"w-72 text-popover-foreground\">\n <div className=\"p-3\">\n <div className=\"mb-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-[10px] text-muted-foreground\">From</label>\n <RangeInput\n inputRef={fromInputRef}\n kind={kind}\n ariaLabel={`${label} from`}\n placeholder={fromPlaceholder ?? (kind === \"date\" ? \"\" : \"now-24h\")}\n value={draftFrom}\n onChange={setDraftFrom}\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-[10px] text-muted-foreground\">To</label>\n <RangeInput\n inputRef={toInputRef}\n kind={kind}\n ariaLabel={`${label} to`}\n placeholder={toPlaceholder ?? (kind === \"date\" ? \"\" : \"now\")}\n value={draftTo}\n onChange={setDraftTo}\n />\n </div>\n </div>\n <div className=\"mt-3 flex justify-end\">\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"h-8 px-3 text-xs\"\n onClick={() => applyRange(draftFrom, draftTo)}\n >\n Apply\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction EnumFilterField({ filter, grow }: { filter: FilterBarEnumFilter; grow: boolean }) {\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-1 text-xs\",\n grow ? \"min-w-[12rem] max-w-[18rem] flex-1\" : \"min-w-[11rem] max-w-[15rem] shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n <Select\n aria-label={filter.label}\n className=\"h-6 border-0 bg-transparent px-1 text-xs shadow-none focus-visible:ring-0\"\n value={filter.value}\n placeholder={filter.placeholder ?? `Any ${filter.label.toLowerCase()}`}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.value)}\n options={filter.options.map((option) => ({\n value: option.value,\n label: option.label ?? option.value,\n }))}\n />\n </label>\n );\n}\n\nfunction BooleanFilterField({ filter }: { filter: FilterBarBooleanFilter }) {\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 shrink-0 items-center gap-2 rounded-md border border-input bg-muted/30 px-2 text-xs\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <input\n type=\"checkbox\"\n aria-label={filter.label}\n className=\"h-3.5 w-3.5 accent-primary\"\n checked={filter.value}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.checked)}\n />\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n </label>\n );\n}\n\nfunction SearchField({ search }: { search: FilterBarSearchProps }) {\n const [draft, setDraft] = useDebouncedTextDraft(search.value, search.onChange);\n\n return (\n <div className=\"flex min-w-[14rem] max-w-[24rem] flex-1 items-center gap-2\">\n <label\n className={cn(\n \"flex h-8 min-w-0 flex-1 items-center rounded-md border border-input bg-background px-3 text-sm\",\n search.className,\n )}\n >\n {draft.trim() ? (\n <span className=\"mr-2 whitespace-nowrap text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {search.ariaLabel ?? \"Search\"}\n </span>\n ) : (\n <Icon name=\"codicon:search\" className=\"mr-2 shrink-0 text-muted-foreground\" />\n )}\n <input\n type=\"search\"\n aria-label={search.ariaLabel ?? search.placeholder ?? \"Search\"}\n className=\"w-full bg-transparent outline-none placeholder:text-muted-foreground\"\n placeholder={search.placeholder ?? \"Search…\"}\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n />\n </label>\n </div>\n );\n}\n\nfunction TextFilterField({ filter, grow }: { filter: FilterBarTextFilter; grow: boolean }) {\n const [draft, setDraft] = useDebouncedTextDraft(filter.value, filter.onChange);\n\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs\",\n grow ? \"min-w-[12rem] max-w-[18rem] flex-1\" : \"min-w-[11rem] max-w-[15rem] shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n <input\n type=\"text\"\n aria-label={filter.label}\n className=\"w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n placeholder={filter.placeholder ?? \"Filter…\"}\n value={draft}\n disabled={filter.disabled}\n onChange={(event) => setDraft(event.target.value)}\n />\n </label>\n );\n}\n\nfunction LookupFilterField({ filter, grow }: { filter: FilterBarLookupFilter; grow: boolean }) {\n const [draft, setDraft] = useDebouncedTextDraft(filter.value, filter.onChange);\n const listId = `${filter.key}-lookup-options`;\n\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs\",\n grow ? \"min-w-[12rem] max-w-[18rem] flex-1\" : \"min-w-[11rem] max-w-[15rem] shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n {filter.inputType === \"date\" ? (\n <DateTimePicker\n aria-label={filter.label}\n className=\"w-full\"\n inputClassName=\"w-full min-w-0 border-0 bg-transparent px-0 pr-6 text-sm text-foreground shadow-none focus-visible:ring-0\"\n buttonClassName=\"right-0\"\n placeholder={filter.placeholder ?? \"Filter…\"}\n value={draft}\n list={listId}\n disabled={filter.disabled}\n onChange={setDraft}\n />\n ) : (\n <input\n type={filter.inputType === \"number\" ? \"number\" : \"text\"}\n aria-label={filter.label}\n className=\"w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n placeholder={filter.placeholder ?? \"Filter…\"}\n value={draft}\n list={listId}\n disabled={filter.disabled}\n onChange={(event) => setDraft(event.target.value)}\n />\n )}\n <datalist id={listId}>\n {filter.options.map((option) => (\n <option\n key={option.value}\n value={option.value}\n label={option.label ?? option.value}\n disabled={option.disabled}\n />\n ))}\n </datalist>\n </label>\n );\n}\n\nfunction LookupMultiFilterField({\n filter,\n grow,\n}: {\n filter: FilterBarLookupMultiFilter;\n grow: boolean;\n}) {\n const [draft, setDraft] = useDebouncedTextDraft(filter.value.join(\", \"), (next) =>\n filter.onChange(parseLookupMultiValue(next)),\n );\n const listId = `${filter.key}-lookup-options`;\n\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs\",\n grow ? \"min-w-[12rem] max-w-[18rem] flex-1\" : \"min-w-[11rem] max-w-[15rem] shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n <input\n type=\"text\"\n aria-label={filter.label}\n className=\"w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n placeholder={filter.placeholder ?? \"value-1, value-2\"}\n value={draft}\n list={listId}\n disabled={filter.disabled}\n onChange={(event) => setDraft(event.target.value)}\n />\n <datalist id={listId}>\n {filter.options.map((option) => (\n <option\n key={option.value}\n value={option.value}\n label={option.label ?? option.value}\n disabled={option.disabled}\n />\n ))}\n </datalist>\n </label>\n );\n}\n\nfunction NumberFilterField({ filter, grow }: { filter: FilterBarNumberFilter; grow: boolean }) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n\n useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));\n\n const bounds = resolveNumberFilterBounds(filter);\n const [draft, setDraft] = useDebouncedNumberDraft(filter.value, filter.onChange);\n const sliderMin = clampNumber(parseFilterNumber(draft.min) ?? bounds.min, bounds.min, bounds.max);\n const sliderMax = clampNumber(parseFilterNumber(draft.max) ?? bounds.max, bounds.min, bounds.max);\n const activeMin = Math.min(sliderMin, sliderMax);\n const activeMax = Math.max(sliderMin, sliderMax);\n const summary = summarizeNumberFilter(filter, bounds, draft);\n\n return (\n <div\n ref={rootRef}\n title={filter.description}\n className={cn(\n \"relative min-w-0\",\n grow ? \"min-w-[8rem] max-w-[12rem] flex-1\" : \"shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${filter.label} filter`}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={filter.disabled}\n onClick={() => setOpen((current) => !current)}\n className={cn(\n \"min-w-0 gap-2 font-normal\",\n grow ? \"w-full max-w-[12rem] justify-between\" : \"w-auto max-w-[9.5rem] px-2.5\",\n summary === filter.label && \"text-muted-foreground\",\n )}\n >\n <span className=\"truncate\">{summary}</span>\n <Icon\n name={open ? \"codicon:chevron-up\" : \"codicon:chevron-down\"}\n className=\"text-muted-foreground\"\n />\n </Button>\n\n {open && (\n <div className=\"absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[18rem] max-w-[22rem] rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-lg shadow-black/5\">\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => {\n setDraft({});\n filter.onChange({});\n }}\n disabled={!String(draft.min ?? \"\").trim() && !String(draft.max ?? \"\").trim()}\n >\n Clear all\n </button>\n </div>\n\n <div className=\"space-y-3\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-[11px] text-muted-foreground\">\n <span>{formatNumberValue(bounds.min, filter)}</span>\n <span>{formatNumberValue(bounds.max, filter)}</span>\n </div>\n <div className=\"relative h-6\">\n <RangeSlider\n min={bounds.min}\n max={bounds.max}\n step={bounds.step}\n value={[activeMin, activeMax]}\n ariaLabelMin={`${filter.label} minimum slider`}\n ariaLabelMax={`${filter.label} maximum slider`}\n onChange={([nextMin, nextMax]) =>\n setDraft(numberFilterValueFromSlider([nextMin, nextMax], bounds))\n }\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"space-y-1\">\n <label className=\"text-[10px] text-muted-foreground\">Min</label>\n <input\n type=\"number\"\n inputMode=\"decimal\"\n step={bounds.step}\n aria-label={`${filter.label} minimum`}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={filter.minPlaceholder ?? formatNumberValue(bounds.min, filter)}\n value={draft.min ?? \"\"}\n onChange={(event) =>\n setDraft(\n normalizeNumberFilterValue(\n { min: event.target.value, max: draft.max ?? \"\" },\n \"min-input\",\n ),\n )\n }\n />\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-[10px] text-muted-foreground\">Max</label>\n <input\n type=\"number\"\n inputMode=\"decimal\"\n step={bounds.step}\n aria-label={`${filter.label} maximum`}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={filter.maxPlaceholder ?? formatNumberValue(bounds.max, filter)}\n value={draft.max ?? \"\"}\n onChange={(event) =>\n setDraft(\n normalizeNumberFilterValue(\n { min: draft.min ?? \"\", max: event.target.value },\n \"max-input\",\n ),\n )\n }\n />\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction NumberFilterPanel({\n filter,\n chrome = \"full\",\n}: {\n filter: FilterBarNumberFilter;\n chrome?: FilterBarFilterPanelChrome;\n}) {\n const bounds = resolveNumberFilterBounds(filter);\n const [draft, setDraft] = useDebouncedNumberDraft(filter.value, filter.onChange);\n const sliderMin = clampNumber(parseFilterNumber(draft.min) ?? bounds.min, bounds.min, bounds.max);\n const sliderMax = clampNumber(parseFilterNumber(draft.max) ?? bounds.max, bounds.min, bounds.max);\n const activeMin = Math.min(sliderMin, sliderMax);\n const activeMax = Math.max(sliderMin, sliderMax);\n const embedded = chrome === \"embedded\";\n\n return (\n <div\n data-filter-panel-chrome={chrome}\n className={cn(\n \"min-w-[18rem] max-w-[22rem] text-popover-foreground\",\n embedded\n ? \"p-0\"\n : \"rounded-md border border-border bg-popover p-3 shadow-sm shadow-black/5\",\n )}\n >\n {!embedded && (\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => {\n setDraft({});\n filter.onChange({});\n }}\n disabled={!String(draft.min ?? \"\").trim() && !String(draft.max ?? \"\").trim()}\n >\n Clear all\n </button>\n </div>\n )}\n\n <div className=\"space-y-3\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-[11px] text-muted-foreground\">\n <span>{formatNumberValue(bounds.min, filter)}</span>\n <span>{formatNumberValue(bounds.max, filter)}</span>\n </div>\n <div className=\"relative h-6\">\n <RangeSlider\n min={bounds.min}\n max={bounds.max}\n step={bounds.step}\n value={[activeMin, activeMax]}\n ariaLabelMin={`${filter.label} minimum slider`}\n ariaLabelMax={`${filter.label} maximum slider`}\n onChange={([nextMin, nextMax]) =>\n setDraft(numberFilterValueFromSlider([nextMin, nextMax], bounds))\n }\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"space-y-1\">\n <label className=\"text-[10px] text-muted-foreground\">Min</label>\n <input\n type=\"number\"\n inputMode=\"decimal\"\n step={bounds.step}\n aria-label={`${filter.label} minimum`}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={filter.minPlaceholder ?? formatNumberValue(bounds.min, filter)}\n value={draft.min ?? \"\"}\n onChange={(event) =>\n setDraft(\n normalizeNumberFilterValue(\n { min: event.target.value, max: draft.max ?? \"\" },\n \"min-input\",\n ),\n )\n }\n />\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-[10px] text-muted-foreground\">Max</label>\n <input\n type=\"number\"\n inputMode=\"decimal\"\n step={bounds.step}\n aria-label={`${filter.label} maximum`}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n placeholder={filter.maxPlaceholder ?? formatNumberValue(bounds.max, filter)}\n value={draft.max ?? \"\"}\n onChange={(event) =>\n setDraft(\n normalizeNumberFilterValue(\n { min: draft.min ?? \"\", max: event.target.value },\n \"max-input\",\n ),\n )\n }\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction MultiFilterField({ filter, grow }: { filter: FilterBarMultiFilter; grow: boolean }) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const [optionQuery, setOptionQuery] = useState(\"\");\n const [draft, setDraft] = useDebouncedMultiDraft(filter.value, filter.onChange);\n\n useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));\n\n const summary = summarizeMultiFilter(filter.label, draft);\n const showOptionFilter = filter.options.length > 7;\n const visibleOptions = useMemo(() => {\n const query = optionQuery.trim().toLowerCase();\n if (!query) return filter.options;\n return filter.options.filter((option) =>\n multiSelectOptionText(option).toLowerCase().includes(query),\n );\n }, [filter.options, optionQuery]);\n\n return (\n <div\n ref={rootRef}\n title={filter.description}\n className={cn(\n \"relative min-w-0\",\n grow ? \"min-w-[8rem] max-w-[12rem] flex-1\" : \"shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${filter.label} filter`}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={filter.disabled}\n onClick={() => setOpen((current) => !current)}\n className={cn(\n \"min-w-0 gap-2 font-normal\",\n grow ? \"w-full max-w-[12rem] justify-between\" : \"w-auto max-w-[8.5rem] px-2.5\",\n summary === filter.label && \"text-muted-foreground\",\n )}\n >\n <span className=\"truncate\">{summary}</span>\n <Icon\n name={open ? \"codicon:chevron-up\" : \"codicon:chevron-down\"}\n className=\"text-muted-foreground\"\n />\n </Button>\n\n {open && (\n <div className=\"absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[18rem] max-w-[22rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-lg shadow-black/5\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => setDraft({})}\n disabled={Object.keys(draft).length === 0}\n >\n Clear all\n </button>\n </div>\n\n {showOptionFilter && (\n <div className=\"mb-2 flex items-center gap-2 rounded-md border border-input bg-background px-2\">\n <Icon name=\"codicon:search\" className=\"shrink-0 text-muted-foreground\" />\n <input\n type=\"search\"\n aria-label={`Filter ${filter.label} options`}\n className=\"h-8 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n placeholder={`Filter ${filter.label.toLowerCase()}`}\n value={optionQuery}\n onChange={(event) => setOptionQuery(event.target.value)}\n />\n </div>\n )}\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {visibleOptions.map((option) => {\n const mode = draft[option.value] ?? \"neutral\";\n const title = option.title ?? multiSelectOptionText(option);\n\n return (\n <div\n key={option.value}\n role=\"button\"\n tabIndex={0}\n data-filter-option={option.value}\n className=\"rounded-md px-1.5 py-0.5 hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\"\n onClick={() =>\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)))\n }\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)));\n }\n }}\n >\n <FilterPill\n className=\"w-full justify-between\"\n label={option.label}\n mode={mode}\n title={title}\n togglePosition=\"right\"\n onModeChange={(next) =>\n setDraft(updateMultiFilterValue(draft, option.value, next))\n }\n />\n </div>\n );\n })}\n {visibleOptions.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No options found</div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction MultiFilterPanel({\n filter,\n chrome = \"full\",\n}: {\n filter: FilterBarMultiFilter;\n chrome?: FilterBarFilterPanelChrome;\n}) {\n const [optionQuery, setOptionQuery] = useState(\"\");\n const [draft, setDraft] = useDebouncedMultiDraft(filter.value, filter.onChange);\n const showOptionFilter = filter.options.length > 7;\n const embedded = chrome === \"embedded\";\n const visibleOptions = useMemo(() => {\n const query = optionQuery.trim().toLowerCase();\n if (!query) return filter.options;\n return filter.options.filter((option) =>\n multiSelectOptionText(option).toLowerCase().includes(query),\n );\n }, [filter.options, optionQuery]);\n\n return (\n <div\n data-filter-panel-chrome={chrome}\n className={cn(\n \"min-w-[18rem] max-w-[22rem] text-popover-foreground\",\n embedded\n ? \"p-0\"\n : \"rounded-md border border-border bg-popover p-2 shadow-sm shadow-black/5\",\n )}\n >\n {!embedded && (\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => setDraft({})}\n disabled={Object.keys(draft).length === 0}\n >\n Clear all\n </button>\n </div>\n )}\n\n {showOptionFilter && (\n <div className=\"mb-2 flex items-center gap-2 rounded-md border border-input bg-background px-2\">\n <Icon name=\"codicon:search\" className=\"shrink-0 text-muted-foreground\" />\n <input\n type=\"search\"\n aria-label={`Filter ${filter.label} options`}\n className=\"h-8 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n placeholder={`Filter ${filter.label.toLowerCase()}`}\n value={optionQuery}\n onChange={(event) => setOptionQuery(event.target.value)}\n />\n </div>\n )}\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {visibleOptions.map((option) => {\n const mode = draft[option.value] ?? \"neutral\";\n const title = option.title ?? multiSelectOptionText(option);\n\n return (\n <div\n key={option.value}\n role=\"button\"\n tabIndex={0}\n data-filter-option={option.value}\n className=\"rounded-md px-1.5 py-0.5 hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\"\n onClick={() =>\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)))\n }\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)));\n }\n }}\n >\n <FilterPill\n className=\"w-full justify-between\"\n label={option.label}\n mode={mode}\n title={title}\n togglePosition=\"right\"\n onModeChange={(next) => setDraft(updateMultiFilterValue(draft, option.value, next))}\n />\n </div>\n );\n })}\n {visibleOptions.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No options found</div>\n )}\n </div>\n </div>\n );\n}\n\nfunction NestedMultiFilterPanel({\n filter,\n chrome = \"full\",\n}: {\n filter: FilterBarNestedMultiFilter;\n chrome?: FilterBarFilterPanelChrome;\n}) {\n const [activeGroup, setActiveGroup] = useState<string | null>(filter.groups[0]?.groupKey ?? null);\n const [draft, setDraft] = useDebouncedMultiDraft(filter.value, filter.onChange);\n const groups = filter.groups;\n const embedded = chrome === \"embedded\";\n const activeGroupData = useMemo(\n () => groups.find((group) => group.groupKey === activeGroup) ?? groups[0] ?? null,\n [groups, activeGroup],\n );\n\n const selectedByGroup = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const group of groups) {\n let n = 0;\n for (const option of group.options) {\n if (draft[option.value]) n += 1;\n }\n counts[group.groupKey] = n;\n }\n return counts;\n }, [groups, draft]);\n\n const sortedGroups = useMemo(() => {\n const selected: typeof groups = [];\n const rest: typeof groups = [];\n for (const group of groups) {\n if ((selectedByGroup[group.groupKey] ?? 0) > 0) selected.push(group);\n else rest.push(group);\n }\n return [...selected, ...rest];\n }, [groups, selectedByGroup]);\n\n const clearGroup = (groupKey: string) => {\n const group = groups.find((g) => g.groupKey === groupKey);\n if (!group) return;\n const next = { ...draft };\n for (const option of group.options) {\n delete next[option.value];\n }\n setDraft(next);\n };\n\n return (\n <div role=\"dialog\" className=\"flex\">\n <div\n data-filter-panel-chrome={chrome}\n className={cn(\n \"min-w-[14rem] max-w-[16rem] text-popover-foreground\",\n embedded\n ? \"p-0\"\n : \"rounded-md border border-border bg-popover p-2 shadow-sm shadow-black/5\",\n )}\n >\n {!embedded && (\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => setDraft({})}\n disabled={Object.keys(draft).length === 0}\n >\n Clear all\n </button>\n </div>\n )}\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {sortedGroups.map((group) => {\n const selected = selectedByGroup[group.groupKey] ?? 0;\n const isActive = group.groupKey === activeGroup;\n return (\n <div\n key={group.groupKey}\n role=\"button\"\n tabIndex={0}\n onMouseEnter={() => setActiveGroup(group.groupKey)}\n onFocus={() => setActiveGroup(group.groupKey)}\n onClick={() => setActiveGroup(group.groupKey)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \" || event.key === \"ArrowRight\") {\n event.preventDefault();\n setActiveGroup(group.groupKey);\n }\n }}\n className={cn(\n \"flex cursor-pointer items-center justify-between gap-2 rounded-md px-1.5 py-0.5 text-sm\",\n \"hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\",\n isActive && \"bg-accent/60\",\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{group.label ?? group.groupKey}</span>\n {selected > 0 && (\n <span className=\"rounded-full bg-primary/15 px-1.5 text-[10px] font-medium text-primary\">\n {selected}/{group.options.length}\n </span>\n )}\n <Icon name=\"codicon:chevron-right\" className=\"shrink-0 text-muted-foreground\" />\n </div>\n );\n })}\n {groups.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No groups</div>\n )}\n </div>\n </div>\n\n {activeGroupData && (\n <div\n onMouseEnter={() => setActiveGroup(activeGroupData.groupKey)}\n className=\"ml-1.5 min-w-[16rem] max-w-[20rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-sm shadow-black/5\"\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {activeGroupData.label ?? activeGroupData.groupKey}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => clearGroup(activeGroupData.groupKey)}\n disabled={(selectedByGroup[activeGroupData.groupKey] ?? 0) === 0}\n >\n Clear\n </button>\n </div>\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {activeGroupData.options.map((option) => {\n const mode = draft[option.value] ?? \"neutral\";\n const title = option.title ?? multiSelectOptionText(option);\n return (\n <div\n key={option.value}\n role=\"button\"\n tabIndex={0}\n data-filter-option={option.value}\n className=\"rounded-md px-1.5 py-0.5 hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\"\n onClick={() =>\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)))\n }\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)));\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n setActiveGroup(null);\n }\n }}\n >\n <FilterPill\n className=\"w-full justify-between\"\n label={renderNestedOptionLabel(option, activeGroupData.groupKey)}\n mode={mode}\n title={title}\n togglePosition=\"right\"\n onModeChange={(next) =>\n setDraft(updateMultiFilterValue(draft, option.value, next))\n }\n />\n </div>\n );\n })}\n {activeGroupData.options.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No values</div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction multiSelectOptionText(option: MultiSelectOption) {\n const label = typeof option.label === \"string\" ? option.label : \"\";\n return [option.value, label, option.title ?? \"\"].filter(Boolean).join(\" \");\n}\n\nfunction NestedMultiFilterField({\n filter,\n grow,\n}: {\n filter: FilterBarNestedMultiFilter;\n grow: boolean;\n}) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const [activeGroup, setActiveGroup] = useState<string | null>(null);\n const [draft, setDraft] = useDebouncedMultiDraft(filter.value, filter.onChange);\n\n useDismissablePopup(open, rootRef, triggerRef, () => {\n setOpen(false);\n setActiveGroup(null);\n });\n\n const summary = summarizeMultiFilter(filter.label, draft);\n const groups = filter.groups;\n const activeGroupData = useMemo(\n () => groups.find((group) => group.groupKey === activeGroup) ?? null,\n [groups, activeGroup],\n );\n\n // Selected count per group, used in the outer list.\n const selectedByGroup = useMemo(() => {\n const counts: Record<string, number> = {};\n for (const group of groups) {\n let n = 0;\n for (const option of group.options) {\n if (draft[option.value]) n += 1;\n }\n counts[group.groupKey] = n;\n }\n return counts;\n }, [groups, draft]);\n\n // Groups with active selections sort to the top so the user always sees\n // what's filtered without scrolling. Within each partition, the original\n // order from the consumer is preserved.\n const sortedGroups = useMemo(() => {\n const selected: typeof groups = [];\n const rest: typeof groups = [];\n for (const group of groups) {\n if ((selectedByGroup[group.groupKey] ?? 0) > 0) selected.push(group);\n else rest.push(group);\n }\n return [...selected, ...rest];\n }, [groups, selectedByGroup]);\n\n const clearGroup = (groupKey: string) => {\n const group = groups.find((g) => g.groupKey === groupKey);\n if (!group) return;\n const next = { ...draft };\n for (const option of group.options) {\n delete next[option.value];\n }\n setDraft(next);\n };\n\n return (\n <div\n ref={rootRef}\n title={filter.description}\n className={cn(\n \"relative min-w-0\",\n grow ? \"min-w-[8rem] max-w-[12rem] flex-1\" : \"shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${filter.label} filter`}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={filter.disabled}\n onClick={() => {\n setOpen((current) => !current);\n if (open) setActiveGroup(null);\n }}\n className={cn(\n \"min-w-0 gap-2 font-normal\",\n grow ? \"w-full max-w-[12rem] justify-between\" : \"w-auto max-w-[8.5rem] px-2.5\",\n summary === filter.label && \"text-muted-foreground\",\n )}\n >\n <span className=\"truncate\">{summary}</span>\n <Icon\n name={open ? \"codicon:chevron-up\" : \"codicon:chevron-down\"}\n className=\"text-muted-foreground\"\n />\n </Button>\n\n {open && (\n <div\n role=\"dialog\"\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setOpen(false);\n setActiveGroup(null);\n }\n }}\n className=\"absolute left-0 top-[calc(100%+0.375rem)] z-50 flex\"\n >\n <div className=\"min-w-[14rem] max-w-[16rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-lg shadow-black/5\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => setDraft({})}\n disabled={Object.keys(draft).length === 0}\n >\n Clear all\n </button>\n </div>\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {sortedGroups.map((group) => {\n const selected = selectedByGroup[group.groupKey] ?? 0;\n const isActive = group.groupKey === activeGroup;\n return (\n <div\n key={group.groupKey}\n role=\"button\"\n tabIndex={0}\n onMouseEnter={() => setActiveGroup(group.groupKey)}\n onFocus={() => setActiveGroup(group.groupKey)}\n onClick={() => setActiveGroup(group.groupKey)}\n onKeyDown={(event) => {\n if (\n event.key === \"Enter\" ||\n event.key === \" \" ||\n event.key === \"ArrowRight\"\n ) {\n event.preventDefault();\n setActiveGroup(group.groupKey);\n }\n }}\n className={cn(\n \"flex cursor-pointer items-center justify-between gap-2 rounded-md px-1.5 py-0.5 text-sm\",\n \"hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\",\n isActive && \"bg-accent/60\",\n )}\n >\n <span className=\"min-w-0 flex-1 truncate\">{group.label ?? group.groupKey}</span>\n {selected > 0 && (\n <span className=\"rounded-full bg-primary/15 px-1.5 text-[10px] font-medium text-primary\">\n {selected}/{group.options.length}\n </span>\n )}\n <Icon name=\"codicon:chevron-right\" className=\"shrink-0 text-muted-foreground\" />\n </div>\n );\n })}\n {groups.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No groups</div>\n )}\n </div>\n </div>\n\n {activeGroupData && (\n <div\n onMouseEnter={() => setActiveGroup(activeGroupData.groupKey)}\n className=\"ml-1.5 min-w-[16rem] max-w-[20rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-lg shadow-black/5\"\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {activeGroupData.label ?? activeGroupData.groupKey}\n </div>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => clearGroup(activeGroupData.groupKey)}\n disabled={(selectedByGroup[activeGroupData.groupKey] ?? 0) === 0}\n >\n Clear\n </button>\n </div>\n\n <div className=\"max-h-72 space-y-0.5 overflow-auto\">\n {activeGroupData.options.map((option) => {\n const mode = draft[option.value] ?? \"neutral\";\n const title = option.title ?? multiSelectOptionText(option);\n return (\n <div\n key={option.value}\n role=\"button\"\n tabIndex={0}\n data-filter-option={option.value}\n className=\"rounded-md px-1.5 py-0.5 hover:bg-accent/50 focus-visible:bg-accent/50 focus-visible:outline-none\"\n onClick={() =>\n setDraft(updateMultiFilterValue(draft, option.value, nextFilterMode(mode)))\n }\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setDraft(\n updateMultiFilterValue(draft, option.value, nextFilterMode(mode)),\n );\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n setActiveGroup(null);\n }\n }}\n >\n <FilterPill\n className=\"w-full justify-between\"\n // Show only the value side here — the key is already\n // implied by the parent group panel.\n label={renderNestedOptionLabel(option, activeGroupData.groupKey)}\n mode={mode}\n title={title}\n togglePosition=\"right\"\n onModeChange={(next) =>\n setDraft(updateMultiFilterValue(draft, option.value, next))\n }\n />\n </div>\n );\n })}\n {activeGroupData.options.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No values</div>\n )}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction renderNestedOptionLabel(option: MultiSelectOption, groupKey: string): ReactNode {\n // If the option label already strips the key prefix, use it. Otherwise\n // strip it here so the inner panel doesn't repeat the key on every row.\n if (typeof option.label === \"string\") {\n const prefix = `${groupKey}=`;\n if (option.label.startsWith(prefix)) return option.label.slice(prefix.length);\n return option.label;\n }\n return option.label ?? option.value;\n}\n\nfunction SelectMultiFilterField({\n filter,\n grow,\n}: {\n filter: FilterBarSelectMultiFilter;\n grow: boolean;\n}) {\n return (\n <label\n title={filter.description}\n className={cn(\n \"flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-1 text-xs\",\n grow ? \"min-w-[12rem] max-w-[18rem] flex-1\" : \"min-w-[11rem] max-w-[15rem] shrink-0\",\n filter.disabled && \"opacity-60\",\n filter.className,\n )}\n >\n <span className=\"whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground\">\n {filter.label}\n </span>\n <MultiSelect\n options={filter.options}\n value={filter.value}\n onChange={filter.onChange}\n placeholder={filter.placeholder ?? `Any ${filter.label.toLowerCase()}`}\n {...(filter.disabled !== undefined ? { disabled: filter.disabled } : {})}\n triggerClassName=\"h-6 min-w-0 border-0 bg-transparent px-1 text-xs shadow-none focus-visible:ring-0\"\n menuClassName=\"left-auto right-0\"\n />\n </label>\n );\n}\n\nfunction RangeControlButton({\n kind,\n label,\n from = \"\",\n to = \"\",\n onApply,\n presets: _presets,\n fromPlaceholder,\n toPlaceholder,\n emptyLabel,\n className,\n}: FilterBarRangeProps & { kind: \"date\" | \"time\"; label: string }) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const fromInputRef = useRef<HTMLInputElement>(null);\n const toInputRef = useRef<HTMLInputElement>(null);\n const [open, setOpen] = useState(false);\n const [draftFrom, setDraftFrom] = useState(from);\n const [draftTo, setDraftTo] = useState(to);\n\n useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));\n\n useEffect(() => {\n if (open) {\n setDraftFrom(from);\n setDraftTo(to);\n }\n }, [from, open, to]);\n\n const buttonLabel = formatRangeLabel(kind, from, to, emptyLabel);\n\n function applyRange(nextFrom: string, nextTo: string) {\n onApply(\n kind === \"time\" ? normalizeDateMath(nextFrom) : nextFrom.trim(),\n kind === \"time\" ? normalizeDateMath(nextTo) : nextTo.trim(),\n );\n setOpen(false);\n }\n\n function clearRange() {\n setDraftFrom(\"\");\n setDraftTo(\"\");\n onApply(\"\", \"\");\n setOpen(false);\n }\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label={`${label} filter`}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n onClick={() => setOpen((current) => !current)}\n className=\"h-7 w-fit max-w-[11rem] min-w-0 gap-2 px-2 text-xs font-normal\"\n >\n <Icon name=\"codicon:calendar\" className=\"text-muted-foreground text-[14px]\" />\n <span className=\"truncate font-normal tabular-nums\">{buttonLabel}</span>\n </Button>\n\n {open && (\n <div className=\"absolute right-0 top-[calc(100%+0.375rem)] z-50 w-72 rounded-md border border-border bg-popover text-popover-foreground shadow-md shadow-black/5 outline-none\">\n <div className=\"p-3\">\n <div className=\"mb-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"grid grid-cols-2 gap-2\">\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-[10px] text-muted-foreground\">From</label>\n <RangeInput\n inputRef={fromInputRef}\n kind={kind}\n ariaLabel={`${label} from`}\n placeholder={fromPlaceholder ?? (kind === \"date\" ? \"\" : \"now-24h\")}\n value={draftFrom}\n onChange={setDraftFrom}\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-[10px] text-muted-foreground\">To</label>\n <RangeInput\n inputRef={toInputRef}\n kind={kind}\n ariaLabel={`${label} to`}\n placeholder={toPlaceholder ?? (kind === \"date\" ? \"\" : \"now\")}\n value={draftTo}\n onChange={setDraftTo}\n />\n </div>\n </div>\n <div className=\"mt-3 flex justify-between gap-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 px-3 text-xs\"\n disabled={!from && !to}\n onClick={clearRange}\n >\n Clear\n </Button>\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"h-8 px-3 text-xs\"\n onClick={() => applyRange(draftFrom, draftTo)}\n >\n Apply\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction useDismissablePopup(\n open: boolean,\n rootRef: RefObject<HTMLElement | null>,\n triggerRef: RefObject<HTMLElement | null>,\n onClose: () => void,\n) {\n useEffect(() => {\n if (!open) return;\n\n const onPointerDown = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) {\n onClose();\n }\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n triggerRef.current?.focus();\n }\n };\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [onClose, open, rootRef, triggerRef]);\n}\n\nfunction summarizeMultiFilter(\n label: string,\n value: Record<string, FilterBarMultiFilterMode>,\n): string {\n const includeCount = Object.values(value).filter((mode) => mode === \"include\").length;\n const excludeCount = Object.values(value).filter((mode) => mode === \"exclude\").length;\n\n if (includeCount === 0 && excludeCount === 0) {\n return label;\n }\n\n const counts = [\n includeCount > 0 ? `+${includeCount}` : null,\n excludeCount > 0 ? `-${excludeCount}` : null,\n ].filter(Boolean);\n\n return `${label} ${counts.join(\" \")}`;\n}\n\nfunction parseLookupMultiValue(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction useDebouncedMultiDraft(\n value: Record<string, FilterBarMultiFilterMode>,\n onChange: (value: Record<string, FilterBarMultiFilterMode>) => void,\n) {\n const { autoSubmit } = useContext(FilterBarContext);\n const [draft, setDraft] = useState(value);\n const latestOnChange = useRef(onChange);\n\n useEffect(() => {\n latestOnChange.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n useEffect(() => {\n if (sameMultiFilterValue(draft, value)) return;\n\n if (!autoSubmit) {\n latestOnChange.current(draft);\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n latestOnChange.current(draft);\n }, FILTER_INPUT_DEBOUNCE_MS);\n\n return () => window.clearTimeout(timeoutId);\n }, [autoSubmit, draft, value]);\n\n return [draft, setDraft] as const;\n}\n\nfunction sameMultiFilterValue(\n a: Record<string, FilterBarMultiFilterMode>,\n b: Record<string, FilterBarMultiFilterMode>,\n) {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (a[key] !== b[key]) return false;\n }\n return true;\n}\n\nfunction useDebouncedTextDraft(value: string, onChange: (value: string) => void) {\n const { autoSubmit } = useContext(FilterBarContext);\n const [draft, setDraft] = useState(value);\n const latestOnChange = useRef(onChange);\n\n useEffect(() => {\n latestOnChange.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n useEffect(() => {\n if (draft === value) return;\n\n if (!autoSubmit) {\n latestOnChange.current(draft);\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n latestOnChange.current(draft);\n }, FILTER_INPUT_DEBOUNCE_MS);\n\n return () => window.clearTimeout(timeoutId);\n }, [autoSubmit, draft, value]);\n\n return [draft, setDraft] as const;\n}\n\nfunction useDebouncedNumberDraft(\n value: FilterBarNumberValue,\n onChange: (value: FilterBarNumberValue) => void,\n) {\n const { autoSubmit } = useContext(FilterBarContext);\n const [draft, setDraft] = useState(value);\n const latestOnChange = useRef(onChange);\n\n useEffect(() => {\n latestOnChange.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n setDraft(value);\n }, [value.max, value.min]);\n\n useEffect(() => {\n if (sameNumberFilterValue(draft, value)) return;\n\n if (!autoSubmit) {\n latestOnChange.current(draft);\n return;\n }\n\n const timeoutId = window.setTimeout(() => {\n latestOnChange.current(draft);\n }, FILTER_INPUT_DEBOUNCE_MS);\n\n return () => window.clearTimeout(timeoutId);\n }, [autoSubmit, draft, value]);\n\n return [draft, setDraft] as const;\n}\n\nfunction sameNumberFilterValue(left: FilterBarNumberValue, right: FilterBarNumberValue) {\n return (left.min ?? \"\") === (right.min ?? \"\") && (left.max ?? \"\") === (right.max ?? \"\");\n}\n\ntype NumberFilterBounds = {\n min: number;\n max: number;\n step: number;\n};\n\ntype NumberFilterSource = \"min-input\" | \"max-input\";\n\nfunction resolveNumberFilterBounds(filter: FilterBarNumberFilter): NumberFilterBounds {\n const parsedMin = parseFilterNumber(filter.value.min);\n const parsedMax = parseFilterNumber(filter.value.max);\n const fallbackMin = parsedMin ?? 0;\n const fallbackMax = parsedMax ?? Math.max(fallbackMin + 100, 100);\n const min = filter.domainMin ?? Math.min(fallbackMin, fallbackMax);\n const max = filter.domainMax ?? Math.max(fallbackMax, min + 100);\n const step = filter.step && filter.step > 0 ? filter.step : 1;\n\n return {\n min,\n max: max <= min ? min + step : max,\n step,\n };\n}\n\nfunction summarizeNumberFilter(\n filter: FilterBarNumberFilter,\n bounds: NumberFilterBounds,\n value: FilterBarNumberValue,\n) {\n const parsedMin = parseFilterNumber(value.min);\n const parsedMax = parseFilterNumber(value.max);\n const hasMin = String(value.min ?? \"\").trim() !== \"\";\n const hasMax = String(value.max ?? \"\").trim() !== \"\";\n\n if (!hasMin && !hasMax) {\n return filter.label;\n }\n\n const minLabel =\n parsedMin == null\n ? formatNumberValue(bounds.min, filter)\n : formatNumberValue(parsedMin, filter);\n const maxLabel =\n parsedMax == null\n ? formatNumberValue(bounds.max, filter)\n : formatNumberValue(parsedMax, filter);\n\n if (hasMin && hasMax) {\n if (minLabel === maxLabel) {\n return `${filter.label} ${minLabel}`;\n }\n return `${filter.label} ${minLabel}-${maxLabel}`;\n }\n\n if (hasMin) {\n return `${filter.label} >=${minLabel}`;\n }\n\n return `${filter.label} <=${maxLabel}`;\n}\n\nfunction normalizeNumberFilterValue(\n nextValue: FilterBarNumberValue,\n source: NumberFilterSource,\n): FilterBarNumberValue {\n let min = nextValue.min ?? \"\";\n let max = nextValue.max ?? \"\";\n\n const parsedMin = parseFilterNumber(min);\n const parsedMax = parseFilterNumber(max);\n\n if (parsedMin != null && parsedMax != null && parsedMin > parsedMax) {\n if (source.startsWith(\"min\")) {\n max = min;\n } else {\n min = max;\n }\n }\n\n return { min, max };\n}\n\nfunction numberFilterValueFromSlider(\n value: [number, number],\n bounds: NumberFilterBounds,\n): FilterBarNumberValue {\n const [min, max] = value;\n return {\n min: min <= bounds.min ? \"\" : formatRawNumber(clampNumber(min, bounds.min, bounds.max)),\n max: max >= bounds.max ? \"\" : formatRawNumber(clampNumber(max, bounds.min, bounds.max)),\n };\n}\n\nfunction parseFilterNumber(value: string | undefined) {\n if (!value?.trim()) return null;\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction clampNumber(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction formatNumberValue(value: number, filter: FilterBarNumberFilter) {\n if (filter.formatValue) {\n return filter.formatValue(value);\n }\n\n return formatRawNumber(value);\n}\n\nfunction formatRawNumber(value: number) {\n return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(6)));\n}\n\nfunction updateMultiFilterValue(\n current: Record<string, FilterBarMultiFilterMode>,\n optionValue: string,\n nextMode: FilterMode,\n): Record<string, FilterBarMultiFilterMode> {\n const next = { ...current };\n\n if (nextMode === \"neutral\") {\n delete next[optionValue];\n return next;\n }\n\n if (nextMode === \"include\" || nextMode === \"exclude\") {\n next[optionValue] = nextMode;\n }\n\n return next;\n}\n\nfunction nextFilterMode(mode: FilterMode): FilterMode {\n if (mode === \"include\") return \"exclude\";\n if (mode === \"exclude\") return \"neutral\";\n return \"include\";\n}\n\nfunction normalizeDateMath(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n if (trimmed === \"now\" || trimmed.startsWith(\"now\")) return trimmed;\n if (/^[+-]\\d/.test(trimmed)) return `now${trimmed}`;\n return trimmed;\n}\n\nfunction formatRangeLabel(\n kind: \"date\" | \"time\",\n from: string,\n to: string,\n emptyLabel?: string,\n): string {\n const trimmedFrom = from.trim();\n const trimmedTo = to.trim();\n\n if (!trimmedFrom && !trimmedTo) {\n return emptyLabel ?? (kind === \"date\" ? \"Any date\" : \"now-24h\");\n }\n\n if (kind === \"time\") {\n const normalizedFrom = normalizeDateMath(trimmedFrom);\n const normalizedTo = normalizeDateMath(trimmedTo || \"now\");\n if (!normalizedFrom) return normalizedTo;\n if (normalizedTo === \"now\") return normalizedFrom;\n return `${normalizedFrom} → ${normalizedTo}`;\n }\n\n if (trimmedFrom && trimmedTo && trimmedFrom === trimmedTo) {\n return trimmedFrom;\n }\n\n if (!trimmedFrom) return trimmedTo;\n if (!trimmedTo) return trimmedFrom;\n return `${trimmedFrom} → ${trimmedTo}`;\n}\n\nfunction RangeInput({\n inputRef,\n kind,\n ariaLabel,\n value,\n onChange,\n placeholder,\n}: {\n inputRef: RefObject<HTMLInputElement | null>;\n kind: \"date\" | \"time\";\n ariaLabel: string;\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n}) {\n if (kind === \"date\") {\n return (\n <DatePicker\n ref={inputRef as RefObject<HTMLInputElement>}\n aria-label={ariaLabel}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n inputClassName=\"pr-8\"\n />\n );\n }\n\n return (\n <DateTimePicker\n ref={inputRef as RefObject<HTMLInputElement>}\n aria-label={ariaLabel}\n inputClassName=\"pr-8\"\n placeholder={placeholder}\n value={value}\n onChange={onChange}\n />\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { ReactNode } from 'react';
2
+ export type MultiSelectOption = {
3
+ value: string;
4
+ label: ReactNode;
5
+ disabled?: boolean;
6
+ title?: string;
7
+ };
8
+ export type MultiSelectProps = {
9
+ options: MultiSelectOption[];
10
+ value: string[];
11
+ onChange: (next: string[]) => void;
12
+ placeholder?: string;
13
+ disabled?: boolean;
14
+ className?: string;
15
+ triggerClassName?: string;
16
+ menuClassName?: string;
17
+ };
18
+ export declare function MultiSelect({ options, value, onChange, placeholder, disabled, className, triggerClassName, menuClassName, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=MultiSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiSelect.d.ts","sourceRoot":"","sources":["../../src/components/MultiSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAK7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAA8B,EAC9B,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,EAAE,gBAAgB,2CAwHlB"}
@@ -0,0 +1,143 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState, useEffect, useMemo } from "react";
3
+ import { Button } from "./button.js";
4
+ import { cn } from "../lib/utils.js";
5
+ import { Icon } from "../data/Icon.js";
6
+ function MultiSelect({
7
+ options,
8
+ value,
9
+ onChange,
10
+ placeholder = "Select options",
11
+ disabled,
12
+ className,
13
+ triggerClassName,
14
+ menuClassName
15
+ }) {
16
+ const rootRef = useRef(null);
17
+ const triggerRef = useRef(null);
18
+ const [open, setOpen] = useState(false);
19
+ useEffect(() => {
20
+ if (!open) return;
21
+ const onPointerDown = (event) => {
22
+ var _a;
23
+ if (!((_a = rootRef.current) == null ? void 0 : _a.contains(event.target))) {
24
+ setOpen(false);
25
+ }
26
+ };
27
+ const onKeyDown = (event) => {
28
+ var _a;
29
+ if (event.key === "Escape") {
30
+ setOpen(false);
31
+ (_a = triggerRef.current) == null ? void 0 : _a.focus();
32
+ }
33
+ };
34
+ document.addEventListener("mousedown", onPointerDown);
35
+ document.addEventListener("keydown", onKeyDown);
36
+ return () => {
37
+ document.removeEventListener("mousedown", onPointerDown);
38
+ document.removeEventListener("keydown", onKeyDown);
39
+ };
40
+ }, [open]);
41
+ const selected = useMemo(() => {
42
+ const selectedOptions = options.filter((option) => value.includes(option.value));
43
+ const labels = selectedOptions.map((option) => option.label).filter((label) => typeof label === "string");
44
+ if (selectedOptions.length === 0) return placeholder;
45
+ if (labels.length === 0) return `${selectedOptions.length} selected`;
46
+ if (labels.length <= 2) return labels.join(", ");
47
+ return `${labels.length} selected`;
48
+ }, [options, placeholder, value]);
49
+ function toggleOption(nextValue) {
50
+ if (value.includes(nextValue)) {
51
+ onChange(value.filter((current) => current !== nextValue));
52
+ return;
53
+ }
54
+ onChange([...value, nextValue]);
55
+ }
56
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative", className), children: [
57
+ /* @__PURE__ */ jsxs(
58
+ Button,
59
+ {
60
+ ref: triggerRef,
61
+ type: "button",
62
+ variant: "outline",
63
+ size: "sm",
64
+ disabled,
65
+ "aria-label": `${placeholder} filter`,
66
+ "aria-haspopup": "menu",
67
+ "aria-expanded": open,
68
+ onClick: () => setOpen((current) => !current),
69
+ className: cn(
70
+ "w-fit max-w-[15rem] min-w-0 shrink-0 justify-between gap-3 text-left font-normal",
71
+ triggerClassName,
72
+ value.length === 0 && "text-muted-foreground"
73
+ ),
74
+ children: [
75
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: selected }),
76
+ /* @__PURE__ */ jsx(
77
+ Icon,
78
+ {
79
+ name: open ? "codicon:chevron-up" : "codicon:chevron-down",
80
+ className: "text-muted-foreground"
81
+ }
82
+ )
83
+ ]
84
+ }
85
+ ),
86
+ open && /* @__PURE__ */ jsxs(
87
+ "div",
88
+ {
89
+ role: "menu",
90
+ className: cn(
91
+ "absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[14rem] max-w-[20rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5",
92
+ menuClassName
93
+ ),
94
+ children: [
95
+ /* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center justify-between gap-2 px-2 py-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: [
96
+ /* @__PURE__ */ jsx("span", { children: placeholder }),
97
+ /* @__PURE__ */ jsx(
98
+ "button",
99
+ {
100
+ type: "button",
101
+ className: "text-[10px] text-primary disabled:text-muted-foreground",
102
+ onClick: () => onChange([]),
103
+ disabled: value.length === 0,
104
+ children: "Clear all"
105
+ }
106
+ )
107
+ ] }),
108
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto", children: options.map((option) => {
109
+ const checked = value.includes(option.value);
110
+ return /* @__PURE__ */ jsxs(
111
+ "label",
112
+ {
113
+ className: cn(
114
+ "flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent",
115
+ option.disabled && "cursor-not-allowed opacity-50"
116
+ ),
117
+ children: [
118
+ /* @__PURE__ */ jsx(
119
+ "input",
120
+ {
121
+ type: "checkbox",
122
+ role: "menuitemcheckbox",
123
+ className: "size-4 rounded border border-input",
124
+ checked,
125
+ disabled: option.disabled,
126
+ onChange: () => toggleOption(option.value)
127
+ }
128
+ ),
129
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: option.label })
130
+ ]
131
+ },
132
+ option.value
133
+ );
134
+ }) })
135
+ ]
136
+ }
137
+ )
138
+ ] });
139
+ }
140
+ export {
141
+ MultiSelect
142
+ };
143
+ //# sourceMappingURL=MultiSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiSelect.js","sources":["../../src/components/MultiSelect.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Button } from \"./button\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\n\nexport type MultiSelectOption = {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n title?: string;\n};\n\nexport type MultiSelectProps = {\n options: MultiSelectOption[];\n value: string[];\n onChange: (next: string[]) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n triggerClassName?: string;\n menuClassName?: string;\n};\n\nexport function MultiSelect({\n options,\n value,\n onChange,\n placeholder = \"Select options\",\n disabled,\n className,\n triggerClassName,\n menuClassName,\n}: MultiSelectProps) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n\n const onPointerDown = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setOpen(false);\n triggerRef.current?.focus();\n }\n };\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open]);\n\n const selected = useMemo(() => {\n const selectedOptions = options.filter((option) => value.includes(option.value));\n const labels = selectedOptions\n .map((option) => option.label)\n .filter((label): label is string => typeof label === \"string\");\n\n if (selectedOptions.length === 0) return placeholder;\n if (labels.length === 0) return `${selectedOptions.length} selected`;\n if (labels.length <= 2) return labels.join(\", \");\n return `${labels.length} selected`;\n }, [options, placeholder, value]);\n\n function toggleOption(nextValue: string) {\n if (value.includes(nextValue)) {\n onChange(value.filter((current) => current !== nextValue));\n return;\n }\n onChange([...value, nextValue]);\n }\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={disabled}\n aria-label={`${placeholder} filter`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => setOpen((current) => !current)}\n className={cn(\n \"w-fit max-w-[15rem] min-w-0 shrink-0 justify-between gap-3 text-left font-normal\",\n triggerClassName,\n value.length === 0 && \"text-muted-foreground\",\n )}\n >\n <span className=\"truncate\">{selected}</span>\n <Icon\n name={open ? \"codicon:chevron-up\" : \"codicon:chevron-down\"}\n className=\"text-muted-foreground\"\n />\n </Button>\n {open && (\n <div\n role=\"menu\"\n className={cn(\n \"absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[14rem] max-w-[20rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\",\n menuClassName,\n )}\n >\n <div className=\"mb-1 flex items-center justify-between gap-2 px-2 py-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n <span>{placeholder}</span>\n <button\n type=\"button\"\n className=\"text-[10px] text-primary disabled:text-muted-foreground\"\n onClick={() => onChange([])}\n disabled={value.length === 0}\n >\n Clear all\n </button>\n </div>\n <div className=\"max-h-64 overflow-auto\">\n {options.map((option) => {\n const checked = value.includes(option.value);\n return (\n <label\n key={option.value}\n className={cn(\n \"flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent\",\n option.disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <input\n type=\"checkbox\"\n role=\"menuitemcheckbox\"\n className=\"size-4 rounded border border-input\"\n checked={checked}\n disabled={option.disabled}\n onChange={() => toggleOption(option.value)}\n />\n <span className=\"min-w-0 truncate\">{option.label}</span>\n </label>\n );\n })}\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type RangeSliderValue = [number, number];
2
+ export type RangeSliderProps = {
3
+ min: number;
4
+ max: number;
5
+ value: RangeSliderValue;
6
+ onChange: (value: RangeSliderValue) => void;
7
+ step?: number;
8
+ ariaLabelMin?: string;
9
+ ariaLabelMax?: string;
10
+ className?: string;
11
+ trackClassName?: string;
12
+ rangeClassName?: string;
13
+ thumbClassName?: string;
14
+ };
15
+ export declare function RangeSlider({ min, max, value, onChange, step, ariaLabelMin, ariaLabelMax, className, trackClassName, rangeClassName, thumbClassName: thumbOverrideClassName, }: RangeSliderProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=RangeSlider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../src/components/RangeSlider.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,GAAG,EACH,KAAK,EACL,QAAQ,EACR,IAAQ,EACR,YAA8B,EAC9B,YAA8B,EAC9B,SAAS,EACT,cAAc,EACd,cAAc,EACd,cAAc,EAAE,sBAAsB,GACvC,EAAE,gBAAgB,2CAkDlB"}
@@ -0,0 +1,92 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ const thumbClassName = "[&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-3.5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border [&::-webkit-slider-thumb]:border-background/80 [&::-webkit-slider-thumb]:bg-muted-foreground [&::-webkit-slider-thumb]:shadow-sm [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-3.5 [&::-moz-range-thumb]:appearance-none [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border [&::-moz-range-thumb]:border-background/80 [&::-moz-range-thumb]:bg-muted-foreground [&::-moz-range-thumb]:shadow-sm";
4
+ function RangeSlider({
5
+ min,
6
+ max,
7
+ value,
8
+ onChange,
9
+ step = 1,
10
+ ariaLabelMin = "Minimum value",
11
+ ariaLabelMax = "Maximum value",
12
+ className,
13
+ trackClassName,
14
+ rangeClassName,
15
+ thumbClassName: thumbOverrideClassName
16
+ }) {
17
+ const [lower, upper] = normalizeRangeValue(value, min, max);
18
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative h-6", className), children: [
19
+ /* @__PURE__ */ jsx(
20
+ "div",
21
+ {
22
+ className: cn(
23
+ "absolute left-0 right-0 top-1/2 h-1 -translate-y-1/2 rounded-full bg-border",
24
+ trackClassName
25
+ )
26
+ }
27
+ ),
28
+ /* @__PURE__ */ jsx(
29
+ "div",
30
+ {
31
+ className: cn(
32
+ "absolute top-1/2 h-1 -translate-y-1/2 rounded-full bg-primary/70",
33
+ rangeClassName
34
+ ),
35
+ style: {
36
+ left: `${valueToPercent(lower, min, max)}%`,
37
+ right: `${100 - valueToPercent(upper, min, max)}%`
38
+ }
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(
42
+ "input",
43
+ {
44
+ type: "range",
45
+ "aria-label": ariaLabelMin,
46
+ min,
47
+ max,
48
+ step,
49
+ value: lower,
50
+ className: cn(baseSliderClassName, thumbClassName, thumbOverrideClassName),
51
+ style: { zIndex: lower >= max ? 30 : 20 },
52
+ onChange: (event) => {
53
+ const nextLower = clampNumber(Number(event.target.value), min, max);
54
+ onChange([Math.min(nextLower, upper), upper]);
55
+ }
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsx(
59
+ "input",
60
+ {
61
+ type: "range",
62
+ "aria-label": ariaLabelMax,
63
+ min,
64
+ max,
65
+ step,
66
+ value: upper,
67
+ className: cn(baseSliderClassName, thumbClassName, thumbOverrideClassName),
68
+ onChange: (event) => {
69
+ const nextUpper = clampNumber(Number(event.target.value), min, max);
70
+ onChange([lower, Math.max(nextUpper, lower)]);
71
+ }
72
+ }
73
+ )
74
+ ] });
75
+ }
76
+ const baseSliderClassName = "pointer-events-none absolute inset-0 h-6 w-full appearance-none bg-transparent [&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent";
77
+ function normalizeRangeValue(value, min, max) {
78
+ const lower = clampNumber(Math.min(value[0], value[1]), min, max);
79
+ const upper = clampNumber(Math.max(value[0], value[1]), min, max);
80
+ return [lower, upper];
81
+ }
82
+ function clampNumber(value, min, max) {
83
+ return Math.min(max, Math.max(min, value));
84
+ }
85
+ function valueToPercent(value, min, max) {
86
+ if (max <= min) return 0;
87
+ return (value - min) / (max - min) * 100;
88
+ }
89
+ export {
90
+ RangeSlider
91
+ };
92
+ //# sourceMappingURL=RangeSlider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangeSlider.js","sources":["../../src/components/RangeSlider.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\n\nexport type RangeSliderValue = [number, number];\n\nexport type RangeSliderProps = {\n min: number;\n max: number;\n value: RangeSliderValue;\n onChange: (value: RangeSliderValue) => void;\n step?: number;\n ariaLabelMin?: string;\n ariaLabelMax?: string;\n className?: string;\n trackClassName?: string;\n rangeClassName?: string;\n thumbClassName?: string;\n};\n\nconst thumbClassName =\n \"[&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-3.5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border [&::-webkit-slider-thumb]:border-background/80 [&::-webkit-slider-thumb]:bg-muted-foreground [&::-webkit-slider-thumb]:shadow-sm [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-3.5 [&::-moz-range-thumb]:appearance-none [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border [&::-moz-range-thumb]:border-background/80 [&::-moz-range-thumb]:bg-muted-foreground [&::-moz-range-thumb]:shadow-sm\";\n\nexport function RangeSlider({\n min,\n max,\n value,\n onChange,\n step = 1,\n ariaLabelMin = \"Minimum value\",\n ariaLabelMax = \"Maximum value\",\n className,\n trackClassName,\n rangeClassName,\n thumbClassName: thumbOverrideClassName,\n}: RangeSliderProps) {\n const [lower, upper] = normalizeRangeValue(value, min, max);\n\n return (\n <div className={cn(\"relative h-6\", className)}>\n <div\n className={cn(\n \"absolute left-0 right-0 top-1/2 h-1 -translate-y-1/2 rounded-full bg-border\",\n trackClassName,\n )}\n />\n <div\n className={cn(\n \"absolute top-1/2 h-1 -translate-y-1/2 rounded-full bg-primary/70\",\n rangeClassName,\n )}\n style={{\n left: `${valueToPercent(lower, min, max)}%`,\n right: `${100 - valueToPercent(upper, min, max)}%`,\n }}\n />\n <input\n type=\"range\"\n aria-label={ariaLabelMin}\n min={min}\n max={max}\n step={step}\n value={lower}\n className={cn(baseSliderClassName, thumbClassName, thumbOverrideClassName)}\n style={{ zIndex: lower >= max ? 30 : 20 }}\n onChange={(event) => {\n const nextLower = clampNumber(Number(event.target.value), min, max);\n onChange([Math.min(nextLower, upper), upper]);\n }}\n />\n <input\n type=\"range\"\n aria-label={ariaLabelMax}\n min={min}\n max={max}\n step={step}\n value={upper}\n className={cn(baseSliderClassName, thumbClassName, thumbOverrideClassName)}\n onChange={(event) => {\n const nextUpper = clampNumber(Number(event.target.value), min, max);\n onChange([lower, Math.max(nextUpper, lower)]);\n }}\n />\n </div>\n );\n}\n\nconst baseSliderClassName =\n \"pointer-events-none absolute inset-0 h-6 w-full appearance-none bg-transparent [&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent\";\n\nfunction normalizeRangeValue(value: RangeSliderValue, min: number, max: number): RangeSliderValue {\n const lower = clampNumber(Math.min(value[0], value[1]), min, max);\n const upper = clampNumber(Math.max(value[0], value[1]), min, max);\n return [lower, upper];\n}\n\nfunction clampNumber(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction valueToPercent(value: number, min: number, max: number) {\n if (max <= min) return 0;\n return ((value - min) / (max - min)) * 100;\n}\n"],"names":[],"mappings":";;AAkBA,MAAM,iBACJ;AAEK,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAClB,GAAqB;AACnB,QAAM,CAAC,OAAO,KAAK,IAAI,oBAAoB,OAAO,KAAK,GAAG;AAE1D,8BACG,OAAA,EAAI,WAAW,GAAG,gBAAgB,SAAS,GAC1C,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,UACL,MAAM,GAAG,eAAe,OAAO,KAAK,GAAG,CAAC;AAAA,UACxC,OAAO,GAAG,MAAM,eAAe,OAAO,KAAK,GAAG,CAAC;AAAA,QAAA;AAAA,MACjD;AAAA,IAAA;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,WAAW,GAAG,qBAAqB,gBAAgB,sBAAsB;AAAA,QACzE,OAAO,EAAE,QAAQ,SAAS,MAAM,KAAK,GAAA;AAAA,QACrC,UAAU,CAAC,UAAU;AACnB,gBAAM,YAAY,YAAY,OAAO,MAAM,OAAO,KAAK,GAAG,KAAK,GAAG;AAClE,mBAAS,CAAC,KAAK,IAAI,WAAW,KAAK,GAAG,KAAK,CAAC;AAAA,QAC9C;AAAA,MAAA;AAAA,IAAA;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,WAAW,GAAG,qBAAqB,gBAAgB,sBAAsB;AAAA,QACzE,UAAU,CAAC,UAAU;AACnB,gBAAM,YAAY,YAAY,OAAO,MAAM,OAAO,KAAK,GAAG,KAAK,GAAG;AAClE,mBAAS,CAAC,OAAO,KAAK,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA,QAC9C;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,MAAM,sBACJ;AAEF,SAAS,oBAAoB,OAAyB,KAAa,KAA+B;AAChG,QAAM,QAAQ,YAAY,KAAK,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG;AAChE,QAAM,QAAQ,YAAY,KAAK,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG;AAChE,SAAO,CAAC,OAAO,KAAK;AACtB;AAEA,SAAS,YAAY,OAAe,KAAa,KAAa;AAC5D,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,eAAe,OAAe,KAAa,KAAa;AAC/D,MAAI,OAAO,IAAK,QAAO;AACvB,UAAS,QAAQ,QAAQ,MAAM,OAAQ;AACzC;"}
@@ -0,0 +1,21 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import { ButtonHTMLAttributes, ReactNode } from 'react';
3
+ declare const buttonVariants: (props?: ({
4
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
+ size?: "sm" | "lg" | "default" | "icon" | null | undefined;
6
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
7
+ export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants> & {
8
+ asChild?: boolean;
9
+ loading?: boolean;
10
+ loadingLabel?: ReactNode;
11
+ };
12
+ export declare const Button: import('react').ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
13
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
14
+ size?: "sm" | "lg" | "default" | "icon" | null | undefined;
15
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string> & {
16
+ asChild?: boolean;
17
+ loading?: boolean;
18
+ loadingLabel?: ReactNode;
19
+ } & import('react').RefAttributes<HTMLButtonElement>>;
20
+ export { buttonVariants };
21
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/components/button.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAc,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9E,QAAA,MAAM,cAAc;;;8EAwBnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,GAC/D,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,CAAC;AA6CJ,eAAO,MAAM,MAAM;;;;cAhDL,OAAO;cACP,OAAO;mBACF,SAAS;qDA2F3B,CAAC;AAGF,OAAO,EAAE,cAAc,EAAE,CAAC"}