@flanksource/clicky-ui 0.2.18 → 0.2.20

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 (445) hide show
  1. package/dist/ai.cjs +26 -0
  2. package/dist/ai.cjs.map +1 -0
  3. package/dist/ai.d.ts +2 -0
  4. package/dist/ai.d.ts.map +1 -0
  5. package/dist/ai.js +26 -0
  6. package/dist/ai.js.map +1 -0
  7. package/dist/chat.cjs +7 -0
  8. package/dist/chat.cjs.map +1 -1
  9. package/dist/chat.js +7 -0
  10. package/dist/chat.js.map +1 -1
  11. package/dist/components/FilterBar.cjs +49 -18
  12. package/dist/components/FilterBar.cjs.map +1 -1
  13. package/dist/components/FilterBar.d.ts +0 -2
  14. package/dist/components/FilterBar.d.ts.map +1 -1
  15. package/dist/components/FilterBar.js +50 -19
  16. package/dist/components/FilterBar.js.map +1 -1
  17. package/dist/components/SearchInput.cjs +63 -0
  18. package/dist/components/SearchInput.cjs.map +1 -0
  19. package/dist/components/SearchInput.d.ts +31 -0
  20. package/dist/components/SearchInput.d.ts.map +1 -0
  21. package/dist/components/SearchInput.js +63 -0
  22. package/dist/components/SearchInput.js.map +1 -0
  23. package/dist/components/SegmentedControl.cjs +88 -0
  24. package/dist/components/SegmentedControl.cjs.map +1 -0
  25. package/dist/components/SegmentedControl.d.ts +38 -0
  26. package/dist/components/SegmentedControl.d.ts.map +1 -0
  27. package/dist/components/SegmentedControl.js +88 -0
  28. package/dist/components/SegmentedControl.js.map +1 -0
  29. package/dist/components/Switch.cjs +51 -0
  30. package/dist/components/Switch.cjs.map +1 -0
  31. package/dist/components/Switch.d.ts +23 -0
  32. package/dist/components/Switch.d.ts.map +1 -0
  33. package/dist/components/Switch.js +51 -0
  34. package/dist/components/Switch.js.map +1 -0
  35. package/dist/components/TimeRange.cjs +53 -45
  36. package/dist/components/TimeRange.cjs.map +1 -1
  37. package/dist/components/TimeRange.d.ts.map +1 -1
  38. package/dist/components/TimeRange.js +53 -45
  39. package/dist/components/TimeRange.js.map +1 -1
  40. package/dist/components/TreePickerField.cjs +5 -1
  41. package/dist/components/TreePickerField.cjs.map +1 -1
  42. package/dist/components/TreePickerField.d.ts.map +1 -1
  43. package/dist/components/TreePickerField.js +5 -1
  44. package/dist/components/TreePickerField.js.map +1 -1
  45. package/dist/components/filter-bar-utils.cjs +5 -0
  46. package/dist/components/filter-bar-utils.cjs.map +1 -1
  47. package/dist/components/filter-bar-utils.d.ts +2 -0
  48. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  49. package/dist/components/filter-bar-utils.js +5 -0
  50. package/dist/components/filter-bar-utils.js.map +1 -1
  51. package/dist/components/json-schema-form-fields.cjs +8 -2
  52. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  53. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  54. package/dist/components/json-schema-form-fields.js +8 -2
  55. package/dist/components/json-schema-form-fields.js.map +1 -1
  56. package/dist/components/json-schema-form-resolve.cjs +1 -1
  57. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  58. package/dist/components/json-schema-form-resolve.js +1 -1
  59. package/dist/components/json-schema-form-resolve.js.map +1 -1
  60. package/dist/components.cjs +21 -1
  61. package/dist/components.cjs.map +1 -1
  62. package/dist/components.d.ts +11 -1
  63. package/dist/components.d.ts.map +1 -1
  64. package/dist/components.js +21 -1
  65. package/dist/components.js.map +1 -1
  66. package/dist/data/Clicky.cjs +33 -44
  67. package/dist/data/Clicky.cjs.map +1 -1
  68. package/dist/data/Clicky.d.ts +0 -9
  69. package/dist/data/Clicky.d.ts.map +1 -1
  70. package/dist/data/Clicky.js +31 -42
  71. package/dist/data/Clicky.js.map +1 -1
  72. package/dist/data/DataTable.cjs +73 -50
  73. package/dist/data/DataTable.cjs.map +1 -1
  74. package/dist/data/DataTable.d.ts +4 -0
  75. package/dist/data/DataTable.d.ts.map +1 -1
  76. package/dist/data/DataTable.js +73 -50
  77. package/dist/data/DataTable.js.map +1 -1
  78. package/dist/data/Icon.cjs +2 -5
  79. package/dist/data/Icon.cjs.map +1 -1
  80. package/dist/data/Icon.d.ts +1 -21
  81. package/dist/data/Icon.d.ts.map +1 -1
  82. package/dist/data/Icon.js +3 -6
  83. package/dist/data/Icon.js.map +1 -1
  84. package/dist/data/MatrixTable.cjs +4 -4
  85. package/dist/data/MatrixTable.cjs.map +1 -1
  86. package/dist/data/MatrixTable.js +4 -4
  87. package/dist/data/MatrixTable.js.map +1 -1
  88. package/dist/data/RadialGauge.cjs +76 -0
  89. package/dist/data/RadialGauge.cjs.map +1 -0
  90. package/dist/data/RadialGauge.d.ts +24 -0
  91. package/dist/data/RadialGauge.d.ts.map +1 -0
  92. package/dist/data/RadialGauge.js +76 -0
  93. package/dist/data/RadialGauge.js.map +1 -0
  94. package/dist/data/StatusBreakdown.cjs +0 -4
  95. package/dist/data/StatusBreakdown.cjs.map +1 -1
  96. package/dist/data/StatusBreakdown.d.ts +0 -2
  97. package/dist/data/StatusBreakdown.d.ts.map +1 -1
  98. package/dist/data/StatusBreakdown.js +1 -5
  99. package/dist/data/StatusBreakdown.js.map +1 -1
  100. package/dist/data/TabButton.cjs +17 -2
  101. package/dist/data/TabButton.cjs.map +1 -1
  102. package/dist/data/TabButton.d.ts +5 -1
  103. package/dist/data/TabButton.d.ts.map +1 -1
  104. package/dist/data/TabButton.js +17 -2
  105. package/dist/data/TabButton.js.map +1 -1
  106. package/dist/data/Timeline.cjs +61 -0
  107. package/dist/data/Timeline.cjs.map +1 -0
  108. package/dist/data/Timeline.d.ts +36 -0
  109. package/dist/data/Timeline.d.ts.map +1 -0
  110. package/dist/data/Timeline.js +61 -0
  111. package/dist/data/Timeline.js.map +1 -0
  112. package/dist/data/TimeseriesCoreBars.cjs +2 -25
  113. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  114. package/dist/data/TimeseriesCoreBars.d.ts +0 -19
  115. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  116. package/dist/data/TimeseriesCoreBars.js +2 -25
  117. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  118. package/dist/data/TimeseriesCoreBars.model.cjs +27 -0
  119. package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -0
  120. package/dist/data/TimeseriesCoreBars.model.d.ts +20 -0
  121. package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -0
  122. package/dist/data/TimeseriesCoreBars.model.js +27 -0
  123. package/dist/data/TimeseriesCoreBars.model.js.map +1 -0
  124. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  125. package/dist/data/TimeseriesPanel.axes.d.ts +1 -1
  126. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -1
  127. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  128. package/dist/data/TimeseriesPanel.cjs +4 -54
  129. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  130. package/dist/data/TimeseriesPanel.d.ts +2 -138
  131. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  132. package/dist/data/TimeseriesPanel.js +2 -52
  133. package/dist/data/TimeseriesPanel.js.map +1 -1
  134. package/dist/data/TimeseriesPanel.model.cjs +53 -0
  135. package/dist/data/TimeseriesPanel.model.cjs.map +1 -0
  136. package/dist/data/TimeseriesPanel.model.d.ts +88 -0
  137. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -0
  138. package/dist/data/TimeseriesPanel.model.js +53 -0
  139. package/dist/data/TimeseriesPanel.model.js.map +1 -0
  140. package/dist/data/Tree.cjs +1 -1
  141. package/dist/data/Tree.cjs.map +1 -1
  142. package/dist/data/Tree.js +1 -1
  143. package/dist/data/Tree.js.map +1 -1
  144. package/dist/data/ai/ChatFab.cjs +29 -0
  145. package/dist/data/ai/ChatFab.cjs.map +1 -0
  146. package/dist/data/ai/ChatFab.d.ts +12 -0
  147. package/dist/data/ai/ChatFab.d.ts.map +1 -0
  148. package/dist/data/ai/ChatFab.js +29 -0
  149. package/dist/data/ai/ChatFab.js.map +1 -0
  150. package/dist/data/ai/ChatWindow.cjs +178 -0
  151. package/dist/data/ai/ChatWindow.cjs.map +1 -0
  152. package/dist/data/ai/ChatWindow.d.ts +38 -0
  153. package/dist/data/ai/ChatWindow.d.ts.map +1 -0
  154. package/dist/data/ai/ChatWindow.js +156 -0
  155. package/dist/data/ai/ChatWindow.js.map +1 -0
  156. package/dist/data/ai/ChatWindowManager.cjs +139 -0
  157. package/dist/data/ai/ChatWindowManager.cjs.map +1 -0
  158. package/dist/data/ai/ChatWindowManager.d.ts +12 -0
  159. package/dist/data/ai/ChatWindowManager.d.ts.map +1 -0
  160. package/dist/data/ai/ChatWindowManager.js +139 -0
  161. package/dist/data/ai/ChatWindowManager.js.map +1 -0
  162. package/dist/data/ai/ContextBadges.cjs +74 -0
  163. package/dist/data/ai/ContextBadges.cjs.map +1 -0
  164. package/dist/data/ai/ContextBadges.d.ts +16 -0
  165. package/dist/data/ai/ContextBadges.d.ts.map +1 -0
  166. package/dist/data/ai/ContextBadges.js +74 -0
  167. package/dist/data/ai/ContextBadges.js.map +1 -0
  168. package/dist/data/ai/ThreadPicker.cjs +148 -0
  169. package/dist/data/ai/ThreadPicker.cjs.map +1 -0
  170. package/dist/data/ai/ThreadPicker.d.ts +37 -0
  171. package/dist/data/ai/ThreadPicker.d.ts.map +1 -0
  172. package/dist/data/ai/ThreadPicker.js +148 -0
  173. package/dist/data/ai/ThreadPicker.js.map +1 -0
  174. package/dist/data/ai/ToolPreferences.cjs +80 -0
  175. package/dist/data/ai/ToolPreferences.cjs.map +1 -0
  176. package/dist/data/ai/ToolPreferences.d.ts +19 -0
  177. package/dist/data/ai/ToolPreferences.d.ts.map +1 -0
  178. package/dist/data/ai/ToolPreferences.js +80 -0
  179. package/dist/data/ai/ToolPreferences.js.map +1 -0
  180. package/dist/data/ai/chat-window-context.cjs +78 -0
  181. package/dist/data/ai/chat-window-context.cjs.map +1 -0
  182. package/dist/data/ai/chat-window-context.d.ts +57 -0
  183. package/dist/data/ai/chat-window-context.d.ts.map +1 -0
  184. package/dist/data/ai/chat-window-context.js +78 -0
  185. package/dist/data/ai/chat-window-context.js.map +1 -0
  186. package/dist/data/ai/context.cjs +43 -0
  187. package/dist/data/ai/context.cjs.map +1 -0
  188. package/dist/data/ai/context.d.ts +35 -0
  189. package/dist/data/ai/context.d.ts.map +1 -0
  190. package/dist/data/ai/context.js +43 -0
  191. package/dist/data/ai/context.js.map +1 -0
  192. package/dist/data/ai/index.d.ts +10 -0
  193. package/dist/data/ai/index.d.ts.map +1 -0
  194. package/dist/data/cache-browser/CacheDetailPanel.cjs +15 -0
  195. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -1
  196. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
  197. package/dist/data/cache-browser/CacheDetailPanel.js +15 -0
  198. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -1
  199. package/dist/data/cache-browser/cache-browser.fixtures.d.ts +10 -0
  200. package/dist/data/cache-browser/cache-browser.fixtures.d.ts.map +1 -0
  201. package/dist/data/cache-browser/download.cjs +13 -0
  202. package/dist/data/cache-browser/download.cjs.map +1 -0
  203. package/dist/data/cache-browser/download.d.ts +3 -0
  204. package/dist/data/cache-browser/download.d.ts.map +1 -0
  205. package/dist/data/cache-browser/download.js +13 -0
  206. package/dist/data/cache-browser/download.js.map +1 -0
  207. package/dist/data/chat/Chat.cjs +40 -2
  208. package/dist/data/chat/Chat.cjs.map +1 -1
  209. package/dist/data/chat/Chat.d.ts +5 -2
  210. package/dist/data/chat/Chat.d.ts.map +1 -1
  211. package/dist/data/chat/Chat.fixtures.cjs +86 -0
  212. package/dist/data/chat/Chat.fixtures.cjs.map +1 -0
  213. package/dist/data/chat/Chat.fixtures.d.ts +4 -0
  214. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
  215. package/dist/data/chat/Chat.fixtures.js +86 -0
  216. package/dist/data/chat/Chat.fixtures.js.map +1 -0
  217. package/dist/data/chat/Chat.js +41 -3
  218. package/dist/data/chat/Chat.js.map +1 -1
  219. package/dist/data/chat/ContextUsage.cjs +99 -0
  220. package/dist/data/chat/ContextUsage.cjs.map +1 -0
  221. package/dist/data/chat/ContextUsage.d.ts +19 -0
  222. package/dist/data/chat/ContextUsage.d.ts.map +1 -0
  223. package/dist/data/chat/ContextUsage.js +99 -0
  224. package/dist/data/chat/ContextUsage.js.map +1 -0
  225. package/dist/data/chat/ModelSelector.cjs +28 -14
  226. package/dist/data/chat/ModelSelector.cjs.map +1 -1
  227. package/dist/data/chat/ModelSelector.d.ts +5 -4
  228. package/dist/data/chat/ModelSelector.d.ts.map +1 -1
  229. package/dist/data/chat/ModelSelector.js +28 -14
  230. package/dist/data/chat/ModelSelector.js.map +1 -1
  231. package/dist/data/chat/clickyOperationsToTools.cjs +21 -1
  232. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  233. package/dist/data/chat/clickyOperationsToTools.d.ts +5 -4
  234. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  235. package/dist/data/chat/clickyOperationsToTools.js +21 -1
  236. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  237. package/dist/data/chat/index.d.ts +4 -1
  238. package/dist/data/chat/index.d.ts.map +1 -1
  239. package/dist/data/chat/provider-icons.cjs +15 -0
  240. package/dist/data/chat/provider-icons.cjs.map +1 -0
  241. package/dist/data/chat/provider-icons.d.ts +7 -0
  242. package/dist/data/chat/provider-icons.d.ts.map +1 -0
  243. package/dist/data/chat/provider-icons.js +15 -0
  244. package/dist/data/chat/provider-icons.js.map +1 -0
  245. package/dist/data/chat/types.cjs.map +1 -1
  246. package/dist/data/chat/types.d.ts +41 -9
  247. package/dist/data/chat/types.d.ts.map +1 -1
  248. package/dist/data/chat/types.js.map +1 -1
  249. package/dist/data/clicky-parse.cjs +42 -0
  250. package/dist/data/clicky-parse.cjs.map +1 -0
  251. package/dist/data/clicky-parse.d.ts +11 -0
  252. package/dist/data/clicky-parse.d.ts.map +1 -0
  253. package/dist/data/clicky-parse.js +42 -0
  254. package/dist/data/clicky-parse.js.map +1 -0
  255. package/dist/data/diagnostics/FrameSourceWindow.cjs +0 -4
  256. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  257. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -11
  258. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  259. package/dist/data/diagnostics/FrameSourceWindow.js +1 -5
  260. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  261. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs +7 -0
  262. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -0
  263. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +12 -0
  264. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -0
  265. package/dist/data/diagnostics/FrameSourceWindow.utils.js +7 -0
  266. package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -0
  267. package/dist/data/diagnostics/JvmStackTrace.cjs +2 -1
  268. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  269. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  270. package/dist/data/diagnostics/JvmStackTrace.js +2 -1
  271. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  272. package/dist/data/icon-fallback.cjs +12 -0
  273. package/dist/data/icon-fallback.cjs.map +1 -0
  274. package/dist/data/icon-fallback.d.ts +19 -0
  275. package/dist/data/icon-fallback.d.ts.map +1 -0
  276. package/dist/data/icon-fallback.js +12 -0
  277. package/dist/data/icon-fallback.js.map +1 -0
  278. package/dist/data/status-breakdown-utils.cjs +7 -0
  279. package/dist/data/status-breakdown-utils.cjs.map +1 -0
  280. package/dist/data/status-breakdown-utils.d.ts +4 -0
  281. package/dist/data/status-breakdown-utils.d.ts.map +1 -0
  282. package/dist/data/status-breakdown-utils.js +7 -0
  283. package/dist/data/status-breakdown-utils.js.map +1 -0
  284. package/dist/data/test-runner/TestRunSummary.cjs +36 -0
  285. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  286. package/dist/data/test-runner/TestRunSummary.d.ts +7 -1
  287. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  288. package/dist/data/test-runner/TestRunSummary.js +36 -0
  289. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  290. package/dist/data/test-runner/TestRunner.cjs +5 -3
  291. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  292. package/dist/data/test-runner/TestRunner.d.ts +13 -1
  293. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  294. package/dist/data/test-runner/TestRunner.js +5 -3
  295. package/dist/data/test-runner/TestRunner.js.map +1 -1
  296. package/dist/data/version-info.cjs +3 -3
  297. package/dist/data/version-info.js +3 -3
  298. package/dist/data.cjs +19 -6
  299. package/dist/data.cjs.map +1 -1
  300. package/dist/data.d.ts +14 -6
  301. package/dist/data.d.ts.map +1 -1
  302. package/dist/data.js +18 -5
  303. package/dist/data.js.map +1 -1
  304. package/dist/index.cjs +57 -7
  305. package/dist/index.cjs.map +1 -1
  306. package/dist/index.js +56 -6
  307. package/dist/index.js.map +1 -1
  308. package/dist/layout/AppShell.cjs +332 -0
  309. package/dist/layout/AppShell.cjs.map +1 -0
  310. package/dist/layout/AppShell.d.ts +75 -0
  311. package/dist/layout/AppShell.d.ts.map +1 -0
  312. package/dist/layout/AppShell.js +332 -0
  313. package/dist/layout/AppShell.js.map +1 -0
  314. package/dist/layout/AppSidebar.cjs +239 -0
  315. package/dist/layout/AppSidebar.cjs.map +1 -0
  316. package/dist/layout/AppSidebar.d.ts +62 -0
  317. package/dist/layout/AppSidebar.d.ts.map +1 -0
  318. package/dist/layout/AppSidebar.js +239 -0
  319. package/dist/layout/AppSidebar.js.map +1 -0
  320. package/dist/layout/Panel.cjs +66 -0
  321. package/dist/layout/Panel.cjs.map +1 -0
  322. package/dist/layout/Panel.d.ts +34 -0
  323. package/dist/layout/Panel.d.ts.map +1 -0
  324. package/dist/layout/Panel.js +66 -0
  325. package/dist/layout/Panel.js.map +1 -0
  326. package/dist/layout/Tabs.cjs +36 -0
  327. package/dist/layout/Tabs.cjs.map +1 -0
  328. package/dist/layout/Tabs.d.ts +36 -0
  329. package/dist/layout/Tabs.d.ts.map +1 -0
  330. package/dist/layout/Tabs.js +36 -0
  331. package/dist/layout/Tabs.js.map +1 -0
  332. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  333. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  334. package/dist/overlay/DropdownMenu.js.map +1 -1
  335. package/dist/overlay/Modal.cjs +4 -2
  336. package/dist/overlay/Modal.cjs.map +1 -1
  337. package/dist/overlay/Modal.d.ts +1 -1
  338. package/dist/overlay/Modal.d.ts.map +1 -1
  339. package/dist/overlay/Modal.js +4 -2
  340. package/dist/overlay/Modal.js.map +1 -1
  341. package/dist/overlay/Toast.cjs +89 -0
  342. package/dist/overlay/Toast.cjs.map +1 -0
  343. package/dist/overlay/Toast.d.ts +14 -0
  344. package/dist/overlay/Toast.d.ts.map +1 -0
  345. package/dist/overlay/Toast.js +89 -0
  346. package/dist/overlay/Toast.js.map +1 -0
  347. package/dist/overlay/toast-context.cjs +12 -0
  348. package/dist/overlay/toast-context.cjs.map +1 -0
  349. package/dist/overlay/toast-context.d.ts +24 -0
  350. package/dist/overlay/toast-context.d.ts.map +1 -0
  351. package/dist/overlay/toast-context.js +12 -0
  352. package/dist/overlay/toast-context.js.map +1 -0
  353. package/dist/rpc/AcceptPicker.cjs +81 -58
  354. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  355. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  356. package/dist/rpc/AcceptPicker.js +81 -58
  357. package/dist/rpc/AcceptPicker.js.map +1 -1
  358. package/dist/rpc/CommandForm.cjs +5 -35
  359. package/dist/rpc/CommandForm.cjs.map +1 -1
  360. package/dist/rpc/CommandForm.d.ts +0 -3
  361. package/dist/rpc/CommandForm.d.ts.map +1 -1
  362. package/dist/rpc/CommandForm.js +2 -32
  363. package/dist/rpc/CommandForm.js.map +1 -1
  364. package/dist/rpc/CommandOutput.cjs +2 -1
  365. package/dist/rpc/CommandOutput.cjs.map +1 -1
  366. package/dist/rpc/CommandOutput.d.ts.map +1 -1
  367. package/dist/rpc/CommandOutput.js +2 -1
  368. package/dist/rpc/CommandOutput.js.map +1 -1
  369. package/dist/rpc/EntityExplorerApp.cjs +28 -83
  370. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  371. package/dist/rpc/EntityExplorerApp.d.ts +1 -4
  372. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  373. package/dist/rpc/EntityExplorerApp.js +13 -68
  374. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  375. package/dist/rpc/OperationCatalog.cjs +2 -2
  376. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  377. package/dist/rpc/OperationCatalog.d.ts +1 -1
  378. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  379. package/dist/rpc/OperationCatalog.js +1 -1
  380. package/dist/rpc/OperationCatalog.js.map +1 -1
  381. package/dist/rpc/OperationCommandPage.cjs +6 -4
  382. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  383. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  384. package/dist/rpc/OperationCommandPage.js +3 -1
  385. package/dist/rpc/OperationCommandPage.js.map +1 -1
  386. package/dist/rpc/RouterProvider.cjs +10 -0
  387. package/dist/rpc/RouterProvider.cjs.map +1 -0
  388. package/dist/rpc/RouterProvider.d.ts +10 -0
  389. package/dist/rpc/RouterProvider.d.ts.map +1 -0
  390. package/dist/rpc/RouterProvider.js +10 -0
  391. package/dist/rpc/RouterProvider.js.map +1 -0
  392. package/dist/rpc/apiClient.cjs +4 -4
  393. package/dist/rpc/apiClient.cjs.map +1 -1
  394. package/dist/rpc/apiClient.js +4 -4
  395. package/dist/rpc/apiClient.js.map +1 -1
  396. package/dist/rpc/command-form-utils.cjs +43 -0
  397. package/dist/rpc/command-form-utils.cjs.map +1 -0
  398. package/dist/rpc/command-form-utils.d.ts +5 -0
  399. package/dist/rpc/command-form-utils.d.ts.map +1 -0
  400. package/dist/rpc/command-form-utils.js +43 -0
  401. package/dist/rpc/command-form-utils.js.map +1 -0
  402. package/dist/rpc/commandHref.cjs +62 -0
  403. package/dist/rpc/commandHref.cjs.map +1 -0
  404. package/dist/rpc/commandHref.d.ts +7 -0
  405. package/dist/rpc/commandHref.d.ts.map +1 -0
  406. package/dist/rpc/commandHref.js +62 -0
  407. package/dist/rpc/commandHref.js.map +1 -0
  408. package/dist/rpc/formMetadata.cjs +1 -1
  409. package/dist/rpc/formMetadata.cjs.map +1 -1
  410. package/dist/rpc/formMetadata.js +1 -1
  411. package/dist/rpc/formMetadata.js.map +1 -1
  412. package/dist/rpc/router.cjs +83 -0
  413. package/dist/rpc/router.cjs.map +1 -0
  414. package/dist/rpc/router.d.ts +24 -0
  415. package/dist/rpc/router.d.ts.map +1 -0
  416. package/dist/rpc/router.js +83 -0
  417. package/dist/rpc/router.js.map +1 -0
  418. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts +3 -0
  419. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -0
  420. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts +3 -0
  421. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -0
  422. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +24 -0
  423. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -0
  424. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts +3 -0
  425. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -0
  426. package/dist/rpc/rpc-story.fixtures.d.ts +16 -0
  427. package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -0
  428. package/dist/rpc.cjs +17 -0
  429. package/dist/rpc.cjs.map +1 -1
  430. package/dist/rpc.d.ts +5 -0
  431. package/dist/rpc.d.ts.map +1 -1
  432. package/dist/rpc.js +18 -1
  433. package/dist/rpc.js.map +1 -1
  434. package/dist/styles.cjs +1 -0
  435. package/dist/styles.cjs.map +1 -1
  436. package/dist/styles.css +1 -1
  437. package/dist/styles.d.ts.map +1 -1
  438. package/dist/styles.js +1 -0
  439. package/dist/styles.js.map +1 -1
  440. package/dist/tailwind-preset.cjs +36 -19
  441. package/dist/tailwind-preset.cjs.map +1 -1
  442. package/dist/tailwind-preset.d.ts.map +1 -1
  443. package/dist/tailwind-preset.js +36 -19
  444. package/dist/tailwind-preset.js.map +1 -1
  445. package/package.json +11 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TimeRange.js","sources":["../../src/components/TimeRange.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { Icon } from \"../data/Icon\";\nimport { UiArrowRight, UiCalendar, UiClose, UiWatch } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { Select } from \"./select\";\n\nexport type TimeRangeKind = \"time\" | \"date\";\n\nexport type TimeRangePresetGroup = \"min\" | \"hr\" | \"day\" | \"wk+\" | \"this\" | \"last\";\n\nexport type TimeRangePreset = {\n /** Visible label for the preset row. */\n label: string;\n /** Start value applied when the preset is selected, e.g. `now-1h`. */\n from: string;\n /** End value applied when the preset is selected, usually `now`. */\n to: string;\n};\n\nexport type TimeRangeChipRow = {\n /** Stable row id used as the React key. */\n id: string;\n /** Group label shown beside the chips. */\n label: string;\n /** Preset chips rendered in this row. */\n chips: {\n /** Compact label shown in the chip. */\n label: string;\n /** Start value applied when clicked, e.g. `now-15m`. */\n token: string;\n /** Optional end value; defaults to `now`. */\n to?: string;\n /** Accessible label for the chip button. */\n ariaLabel?: string;\n /** Optional browser tooltip. */\n title?: string;\n }[];\n};\n\nexport type TimeRangeProps = {\n /** Controls whether the inputs accept date-only or date-time values. */\n kind?: TimeRangeKind;\n /** Label shown in the trigger before the selected range summary. */\n label?: string;\n /** Current start value. Relative values such as `now-1h` are supported. */\n from?: string;\n /** Current end value. Relative values such as `now` are supported. */\n to?: string;\n /** Called when the user applies a typed value or preset. */\n onApply: (from: string, to: string) => void;\n /** Presets or preset groups to show in the popup. */\n presets?: Array<TimeRangePreset | TimeRangePresetGroup>;\n /** Explicit chip rows; overrides the built-in preset group layout. */\n chipRows?: TimeRangeChipRow[];\n /** Enables time fields for date-time ranges. */\n timeEnabled?: boolean;\n /** Selected timezone shown in the popup. */\n timeZone?: string;\n /** Available timezone options. */\n timeZones?: string[];\n /** Placeholder for the start input. */\n fromPlaceholder?: string;\n /** Placeholder for the end input. */\n toPlaceholder?: string;\n /** Trigger text when neither boundary is set. */\n emptyLabel?: string;\n /** Aligns the popup to the trigger's left or right edge. */\n align?: \"left\" | \"right\";\n /** Disables opening and applying changes. */\n disabled?: boolean;\n /** Classes applied to the root wrapper. */\n className?: string;\n /** Classes applied to the trigger button. */\n triggerClassName?: string;\n /** Classes applied to the popup panel. */\n panelClassName?: string;\n};\n\nconst defaultTimeChipRows: TimeRangeChipRow[] = [\n {\n id: \"minutes\",\n label: \"Min\",\n chips: [\n { label: \"5m\", token: \"now-5m\" },\n { label: \"15m\", token: \"now-15m\" },\n { label: \"30m\", token: \"now-30m\" },\n ],\n },\n {\n id: \"hours\",\n label: \"Hr\",\n chips: [\n { label: \"1h\", token: \"now-1h\" },\n { label: \"2h\", token: \"now-2h\" },\n { label: \"4h\", token: \"now-4h\" },\n { label: \"8h\", token: \"now-8h\" },\n { label: \"12h\", token: \"now-12h\" },\n ],\n },\n {\n id: \"days\",\n label: \"Day\",\n chips: [\n { label: \"1d\", token: \"now-1d\" },\n { label: \"2d\", token: \"now-2d\" },\n { label: \"3d\", token: \"now-3d\" },\n { label: \"1w\", token: \"now-1w\" },\n ],\n },\n {\n id: \"weeks\",\n label: \"Wk+\",\n chips: [\n { label: \"2w\", token: \"now-2w\" },\n { label: \"1M\", token: \"now-1M\" },\n { label: \"3M\", token: \"now-3M\" },\n { label: \"6M\", token: \"now-6M\" },\n { label: \"1y\", token: \"now-1y\" },\n ],\n },\n];\n\nconst timeChipRowsByGroup: Record<\n Exclude<TimeRangePresetGroup, \"this\" | \"last\">,\n TimeRangeChipRow\n> = {\n min: defaultTimeChipRows[0]!,\n hr: defaultTimeChipRows[1]!,\n day: defaultTimeChipRows[2]!,\n \"wk+\": defaultTimeChipRows[3]!,\n};\n\nconst defaultDateChipRows: TimeRangeChipRow[] = [\n {\n id: \"days\",\n label: \"Day\",\n chips: [\n { label: \"1d\", token: \"now-1d\" },\n { label: \"2d\", token: \"now-2d\" },\n { label: \"3d\", token: \"now-3d\" },\n { label: \"7d\", token: \"now-7d\" },\n ],\n },\n {\n id: \"weeks\",\n label: \"Wk\",\n chips: [\n { label: \"1w\", token: \"now-1w\" },\n { label: \"2w\", token: \"now-2w\" },\n { label: \"4w\", token: \"now-4w\" },\n ],\n },\n {\n id: \"months\",\n label: \"Mo\",\n chips: [\n { label: \"1M\", token: \"now-1M\" },\n { label: \"3M\", token: \"now-3M\" },\n { label: \"6M\", token: \"now-6M\" },\n { label: \"1y\", token: \"now-1y\" },\n ],\n },\n];\n\nconst thisLastChipRows: Record<Extract<TimeRangePresetGroup, \"this\" | \"last\">, TimeRangeChipRow> = {\n this: {\n id: \"this\",\n label: \"This\",\n chips: [\n { label: \"Week\", token: \"now/w\", to: \"now/w+1w\", ariaLabel: \"this week\" },\n {\n label: \"Month\",\n token: \"now/M\",\n to: \"now/M+1M\",\n ariaLabel: \"this month\",\n },\n {\n label: \"Quarter\",\n token: \"now/q\",\n to: \"now/q+1q\",\n ariaLabel: \"this quarter\",\n },\n { label: \"Year\", token: \"now/y\", to: \"now/y+1y\", ariaLabel: \"this year\" },\n ],\n },\n last: {\n id: \"last\",\n label: \"Last\",\n chips: [\n { label: \"Week\", token: \"now/w-1w\", to: \"now/w\", ariaLabel: \"last week\" },\n {\n label: \"Month\",\n token: \"now/M-1M\",\n to: \"now/M\",\n ariaLabel: \"last month\",\n },\n {\n label: \"Quarter\",\n token: \"now/q-1q\",\n to: \"now/q\",\n ariaLabel: \"last quarter\",\n },\n { label: \"Year\", token: \"now/y-1y\", to: \"now/y\", ariaLabel: \"last year\" },\n ],\n },\n};\n\nexport function TimeRange({\n kind = \"time\",\n label = \"Time range\",\n from = \"\",\n to = \"\",\n onApply,\n presets,\n chipRows,\n timeEnabled = false,\n timeZone,\n timeZones,\n fromPlaceholder,\n toPlaceholder,\n emptyLabel,\n align = \"right\",\n disabled = false,\n className,\n triggerClassName,\n panelClassName,\n}: TimeRangeProps) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const [draftFrom, setDraftFrom] = useState(from);\n const [draftTo, setDraftTo] = useState(to);\n const resolvedDefaultTimeZone = timeZone ?? getDefaultTimeZone();\n const [selectedTimeZone, setSelectedTimeZone] = useState(resolvedDefaultTimeZone);\n\n const activeTimeZones = resolveTimeZones(timeZones, selectedTimeZone);\n const { rows: activeChipRows, presets: activePresets } = resolvePresetConfig(\n kind,\n presets,\n chipRows,\n );\n\n useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));\n\n useEffect(() => {\n if (open) {\n setDraftFrom(from);\n setDraftTo(to);\n setSelectedTimeZone(resolvedDefaultTimeZone);\n }\n }, [from, open, resolvedDefaultTimeZone, to]);\n\n const buttonLabel =\n formatSelectedPresetLabel(from, to, activeChipRows, activePresets) ??\n formatRangeLabel(kind, from, to, emptyLabel);\n const activeToken = normalizeRangeValue(kind, from, {\n timeEnabled,\n timeZone: selectedTimeZone,\n });\n\n function applyRange(nextFrom: string, nextTo: string) {\n onApply(\n normalizeRangeValue(kind, nextFrom, {\n timeEnabled,\n timeZone: selectedTimeZone,\n }),\n normalizeRangeValue(kind, nextTo, {\n timeEnabled,\n timeZone: selectedTimeZone,\n }),\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 inline-flex\", 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 disabled={disabled}\n onClick={() => setOpen((current) => !current)}\n className={cn(\n \"h-7 w-fit max-w-[12rem] min-w-0 gap-2 px-2 text-xs font-normal\",\n triggerClassName,\n )}\n >\n <Icon\n icon={kind === \"time\" ? UiWatch : UiCalendar}\n className=\"text-muted-foreground text-[14px]\"\n />\n <span className=\"truncate font-normal tabular-nums\">{buttonLabel}</span>\n </Button>\n\n {open && (\n <div\n role=\"dialog\"\n aria-label={label}\n className={cn(\n \"absolute top-[calc(100%+0.375rem)] z-50 w-[22.5rem] overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg shadow-black/5 outline-none\",\n align === \"left\" ? \"left-0\" : \"right-0\",\n panelClassName,\n )}\n >\n <div className=\"flex items-center justify-between border-b border-border/60 px-3.5 py-2.5\">\n <span className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {label}\n </span>\n <span className=\"font-mono text-[10px] text-muted-foreground\">\n {timeEnabled ? selectedTimeZone : \"Relative\"}\n </span>\n </div>\n\n {activeChipRows.length > 0 && (\n <ChipRowList rows={activeChipRows} activeToken={activeToken} onApply={applyRange} />\n )}\n {activePresets.length > 0 && (\n <div className={activeChipRows.length > 0 ? \"px-3.5 pb-3\" : \"px-3.5 pt-3\"}>\n <PresetList presets={activePresets} onApply={applyRange} />\n </div>\n )}\n\n <div className=\"border-t border-border/60 bg-muted/30 px-3.5 py-2.5\">\n <div className=\"mb-1.5 flex items-center justify-between gap-2\">\n <div className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n Custom\n </div>\n {timeEnabled && (\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <span className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n TZ\n </span>\n <Select\n aria-label={`${label} timezone`}\n value={selectedTimeZone}\n options={activeTimeZones.map((zone) => ({\n value: zone,\n label: zone,\n }))}\n onChange={(event) => setSelectedTimeZone(event.target.value)}\n className=\"h-7 w-40 truncate px-2 pr-7 font-mono text-xs\"\n />\n </div>\n )}\n </div>\n <div className=\"grid grid-cols-[1fr_auto_1fr] items-center gap-1.5\">\n <DraftRangeInput\n aria-label={`${label} from`}\n placeholder={\n fromPlaceholder ?? (kind === \"date\" ? \"YYYY-MM-DD or now-1d\" : \"now-24h\")\n }\n value={draftFrom}\n onChange={setDraftFrom}\n onClear={() => setDraftFrom(\"\")}\n pickerKind={kind}\n timeEnabled={timeEnabled}\n />\n <Icon icon={UiArrowRight} className=\"text-muted-foreground text-[12px]\" />\n <DraftRangeInput\n aria-label={`${label} to`}\n placeholder={toPlaceholder ?? (kind === \"date\" ? \"YYYY-MM-DD or now\" : \"now\")}\n value={draftTo}\n onChange={setDraftTo}\n onClear={() => setDraftTo(\"\")}\n pickerKind={kind}\n timeEnabled={timeEnabled}\n />\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border/60 px-3 py-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-xs\"\n disabled={!from && !to}\n onClick={clearRange}\n >\n Clear\n </Button>\n <div className=\"flex gap-1.5\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-xs\"\n onClick={() => setOpen(false)}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"h-7 px-3.5 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 DraftRangeInput({\n value,\n onChange,\n onClear,\n placeholder,\n pickerKind,\n timeEnabled,\n ...rest\n}: {\n value: string;\n onChange: (value: string) => void;\n onClear: () => void;\n placeholder: string | undefined;\n pickerKind?: TimeRangeKind;\n timeEnabled: boolean;\n \"aria-label\": string;\n}) {\n const ariaLabel = rest[\"aria-label\"];\n const showCalendar = pickerKind !== undefined;\n const showTimeInput = pickerKind === \"time\" && timeEnabled;\n const { date: datePart, time: timePart } = splitDateTime(value);\n\n function setDatePart(nextDate: string) {\n if (!showTimeInput) {\n onChange(nextDate);\n return;\n }\n if (!nextDate) {\n onChange(timePart ? `T${timePart}` : \"\");\n return;\n }\n onChange(timePart ? `${nextDate}T${timePart}` : nextDate);\n }\n\n function setTimePart(nextTime: string) {\n if (!nextTime) {\n onChange(datePart);\n return;\n }\n onChange(datePart ? `${datePart}T${nextTime}` : `T${nextTime}`);\n }\n\n return (\n <div className=\"space-y-1\">\n <DraftTextInput\n ariaLabel={ariaLabel}\n placeholder={placeholder}\n value={showTimeInput ? datePart : value}\n onChange={showTimeInput ? setDatePart : onChange}\n onClear={onClear}\n showCalendar={showCalendar}\n />\n {showTimeInput && (\n <DraftTimeInput ariaLabel={`${ariaLabel} time`} value={timePart} onChange={setTimePart} />\n )}\n </div>\n );\n}\n\nfunction resolvePresetConfig(\n kind: TimeRangeKind,\n presets: TimeRangeProps[\"presets\"],\n chipRows: TimeRangeChipRow[] | undefined,\n) {\n if (presets === undefined) {\n return {\n rows: chipRows ?? (kind === \"date\" ? defaultDateChipRows : defaultTimeChipRows),\n presets: [] as TimeRangePreset[],\n };\n }\n\n const rows: TimeRangeChipRow[] = chipRows ? [...chipRows] : [];\n const presetList: TimeRangePreset[] = [];\n\n for (const preset of presets) {\n if (typeof preset !== \"string\") {\n presetList.push(preset);\n continue;\n }\n if (preset === \"this\" || preset === \"last\") {\n rows.push(thisLastChipRows[preset]);\n continue;\n }\n rows.push(timeChipRowsByGroup[preset]);\n }\n\n return { rows, presets: presetList };\n}\n\nfunction DraftTextInput({\n ariaLabel,\n value,\n onChange,\n onClear,\n placeholder,\n showCalendar,\n}: {\n ariaLabel: string;\n value: string;\n onChange: (value: string) => void;\n onClear: () => void;\n placeholder: string | undefined;\n showCalendar: boolean;\n}) {\n const pickerRef = useRef<HTMLInputElement | null>(null);\n const hasValue = value.length > 0;\n const paddingRight = showCalendar ? (hasValue ? \"pr-12\" : \"pr-7\") : \"pr-7\";\n\n return (\n <div className=\"relative\">\n <input\n type=\"text\"\n aria-label={ariaLabel}\n placeholder={placeholder}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className={cn(\n \"h-8 w-full rounded-md border border-input bg-background px-2 font-mono text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n paddingRight,\n )}\n />\n {hasValue && (\n <button\n type=\"button\"\n aria-label={`Clear ${ariaLabel}`}\n onClick={onClear}\n className={cn(\n \"absolute inset-y-0 inline-flex w-5 items-center justify-center text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n showCalendar ? \"right-6\" : \"right-1\",\n )}\n >\n <Icon icon={UiClose} className=\"text-[12px]\" />\n </button>\n )}\n {showCalendar && (\n <>\n <input\n ref={pickerRef}\n type=\"date\"\n tabIndex={-1}\n aria-hidden=\"true\"\n value={/^\\d{4}-\\d{2}-\\d{2}$/.test(value.trim()) ? value.trim() : \"\"}\n onChange={(event) => onChange(event.target.value)}\n className=\"pointer-events-none absolute left-0 top-0 h-0 w-0 opacity-0\"\n />\n <button\n type=\"button\"\n aria-label={`Pick ${ariaLabel}`}\n onClick={() => pickerRef.current?.showPicker?.()}\n className=\"absolute inset-y-0 right-1 inline-flex w-5 items-center justify-center text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Icon icon={UiCalendar} className=\"text-[12px]\" />\n </button>\n </>\n )}\n </div>\n );\n}\n\nfunction DraftTimeInput({\n ariaLabel,\n value,\n onChange,\n}: {\n ariaLabel: string;\n value: string;\n onChange: (value: string) => void;\n}) {\n return (\n <input\n type=\"time\"\n aria-label={ariaLabel}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 font-mono text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n );\n}\n\nfunction splitDateTime(value: string) {\n const trimmed = value.trim();\n const match = /^(\\d{4}-\\d{2}-\\d{2})?T?(\\d{2}:\\d{2})?/.exec(trimmed);\n if (!match || trimmed.startsWith(\"now\") || /^[+-]/.test(trimmed)) {\n return { date: trimmed, time: \"\" };\n }\n return { date: match[1] ?? \"\", time: match[2] ?? \"\" };\n}\n\nfunction ChipRowList({\n rows,\n activeToken,\n onApply,\n}: {\n rows: TimeRangeChipRow[];\n activeToken: string;\n onApply: (from: string, to: string) => void;\n}) {\n if (rows.length === 0) return null;\n\n return (\n <div className=\"px-3.5 py-3\" role=\"list\" aria-label=\"Time filters\">\n {rows.map((row, index) => (\n <div\n key={row.id}\n className={cn(\n \"grid grid-cols-[2rem_1fr] items-center gap-2\",\n index === rows.length - 1 ? \"\" : \"mb-1.5\",\n )}\n role=\"listitem\"\n >\n <span className=\"text-[9.5px] font-bold uppercase tracking-wider text-muted-foreground\">\n {row.label}\n </span>\n <div className=\"flex divide-x divide-border overflow-hidden rounded-[5px] border border-border\">\n {row.chips.map((chip) => {\n const active = chip.token === activeToken;\n return (\n <button\n key={chip.token}\n type=\"button\"\n title={chip.title ?? chip.ariaLabel ?? chip.token}\n aria-label={chip.ariaLabel ?? chip.token}\n aria-pressed={active}\n onClick={() => onApply(chip.token, chip.to ?? \"now\")}\n className={cn(\n \"flex-1 min-w-0 px-0 py-1.5 text-center font-mono text-[11.5px] leading-none transition-colors focus-visible:relative focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"bg-foreground font-semibold text-background\"\n : \"bg-background font-medium text-muted-foreground hover:bg-muted\",\n )}\n >\n {chip.label}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction PresetList({\n presets,\n onApply,\n}: {\n presets: TimeRangePreset[];\n onApply: (from: string, to: string) => void;\n}) {\n if (presets.length === 0) return null;\n\n return (\n <div className=\"mb-3 space-y-1\" role=\"list\" aria-label=\"Time filters\">\n {presets.map((preset) => (\n <button\n key={`${preset.label}-${preset.from}-${preset.to}`}\n type=\"button\"\n className=\"flex h-8 w-full items-center justify-between gap-3 rounded-md border border-border bg-background px-2 text-left text-xs hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n onClick={() => onApply(preset.from, preset.to)}\n >\n <span className=\"min-w-0 truncate font-medium\">{preset.label}</span>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground\">\n {formatPresetRange(preset)}\n </span>\n </button>\n ))}\n </div>\n );\n}\n\nfunction formatSelectedPresetLabel(\n from: string,\n to: string,\n rows: TimeRangeChipRow[],\n presets: TimeRangePreset[],\n) {\n const normalizedFrom = from.trim();\n const normalizedTo = to.trim();\n if (!normalizedFrom && !normalizedTo) return undefined;\n\n for (const row of rows) {\n for (const chip of row.chips) {\n if (chip.token === normalizedFrom && (chip.to ?? \"now\") === normalizedTo) {\n return chip.ariaLabel ?? chip.title ?? chip.label;\n }\n }\n }\n\n return presets.find((preset) => preset.from === normalizedFrom && preset.to === normalizedTo)\n ?.label;\n}\n\nfunction formatPresetRange({ from, to }: TimeRangePreset) {\n if (!from) return to;\n if (!to || to === \"now\") return from;\n return `${from} -> ${to}`;\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 normalizeRangeValue(\n kind: TimeRangeKind,\n value: string,\n options: { timeEnabled?: boolean; timeZone?: string } = {},\n) {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n if (trimmed === \"now\" || trimmed.startsWith(\"now\")) return trimmed;\n if (kind === \"time\" && /^[+-]\\d/.test(trimmed)) return `now${trimmed}`;\n if (kind === \"time\" && options.timeEnabled) {\n return encodeDateTimeWithOffset(trimmed, options.timeZone ?? getDefaultTimeZone());\n }\n return trimmed;\n}\n\nfunction formatRangeLabel(kind: TimeRangeKind, from: string, to: string, emptyLabel?: 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 = normalizeRangeValue(kind, trimmedFrom);\n const normalizedTo = normalizeRangeValue(kind, 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 getDefaultTimeZone() {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n\nfunction resolveTimeZones(timeZones: string[] | undefined, selectedTimeZone: string) {\n const zones = timeZones && timeZones.length > 0 ? timeZones : [selectedTimeZone, \"UTC\"];\n return Array.from(new Set([selectedTimeZone, ...zones, \"UTC\"].filter(Boolean)));\n}\n\nfunction encodeDateTimeWithOffset(value: string, timeZone: string) {\n if (!isLocalDateTime(value) || hasExplicitOffset(value)) return value;\n\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?$/);\n if (!match) return value;\n\n const [, year, month, day, hour, minute, second = \"00\"] = match;\n const localUtcMillis = Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n );\n const offsetMinutes = getTimeZoneOffsetMinutes(timeZone, localUtcMillis);\n return `${year}-${month}-${day}T${hour}:${minute}:${second}${formatOffset(offsetMinutes)}`;\n}\n\nfunction isLocalDateTime(value: string) {\n return /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2})?(?:\\.\\d+)?$/.test(value.trim());\n}\n\nfunction hasExplicitOffset(value: string) {\n return /(?:Z|[+-]\\d{2}:?\\d{2})$/i.test(value.trim());\n}\n\nfunction getTimeZoneOffsetMinutes(timeZone: string, localUtcMillis: number) {\n try {\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n const parts = Object.fromEntries(\n formatter\n .formatToParts(new Date(localUtcMillis))\n .filter((part) => part.type !== \"literal\")\n .map((part) => [part.type, part.value]),\n );\n const zonedUtcMillis = Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n return (zonedUtcMillis - localUtcMillis) / 60_000;\n } catch {\n return 0;\n }\n}\n\nfunction formatOffset(offsetMinutes: number) {\n const sign = offsetMinutes >= 0 ? \"+\" : \"-\";\n const abs = Math.abs(offsetMinutes);\n const hours = Math.floor(abs / 60)\n .toString()\n .padStart(2, \"0\");\n const minutes = Math.floor(abs % 60)\n .toString()\n .padStart(2, \"0\");\n return `${sign}${hours}:${minutes}`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TimeRange.js","sources":["../../src/components/TimeRange.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { Icon } from \"../data/Icon\";\nimport { UiArrowRight, UiCalendar, UiClose, UiWatch } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\nimport { Select } from \"./select\";\n\nexport type TimeRangeKind = \"time\" | \"date\";\n\nexport type TimeRangePresetGroup = \"min\" | \"hr\" | \"day\" | \"wk+\" | \"this\" | \"last\";\n\nexport type TimeRangePreset = {\n /** Visible label for the preset row. */\n label: string;\n /** Start value applied when the preset is selected, e.g. `now-1h`. */\n from: string;\n /** End value applied when the preset is selected, usually `now`. */\n to: string;\n};\n\nexport type TimeRangeChipRow = {\n /** Stable row id used as the React key. */\n id: string;\n /** Group label shown beside the chips. */\n label: string;\n /** Preset chips rendered in this row. */\n chips: {\n /** Compact label shown in the chip. */\n label: string;\n /** Start value applied when clicked, e.g. `now-15m`. */\n token: string;\n /** Optional end value; defaults to `now`. */\n to?: string;\n /** Accessible label for the chip button. */\n ariaLabel?: string;\n /** Optional browser tooltip. */\n title?: string;\n }[];\n};\n\nexport type TimeRangeProps = {\n /** Controls whether the inputs accept date-only or date-time values. */\n kind?: TimeRangeKind;\n /** Label shown in the trigger before the selected range summary. */\n label?: string;\n /** Current start value. Relative values such as `now-1h` are supported. */\n from?: string;\n /** Current end value. Relative values such as `now` are supported. */\n to?: string;\n /** Called when the user applies a typed value or preset. */\n onApply: (from: string, to: string) => void;\n /** Presets or preset groups to show in the popup. */\n presets?: Array<TimeRangePreset | TimeRangePresetGroup>;\n /** Explicit chip rows; overrides the built-in preset group layout. */\n chipRows?: TimeRangeChipRow[];\n /** Enables time fields for date-time ranges. */\n timeEnabled?: boolean;\n /** Selected timezone shown in the popup. */\n timeZone?: string;\n /** Available timezone options. */\n timeZones?: string[];\n /** Placeholder for the start input. */\n fromPlaceholder?: string;\n /** Placeholder for the end input. */\n toPlaceholder?: string;\n /** Trigger text when neither boundary is set. */\n emptyLabel?: string;\n /** Aligns the popup to the trigger's left or right edge. */\n align?: \"left\" | \"right\";\n /** Disables opening and applying changes. */\n disabled?: boolean;\n /** Classes applied to the root wrapper. */\n className?: string;\n /** Classes applied to the trigger button. */\n triggerClassName?: string;\n /** Classes applied to the popup panel. */\n panelClassName?: string;\n};\n\nconst defaultTimeChipRows: TimeRangeChipRow[] = [\n {\n id: \"minutes\",\n label: \"Min\",\n chips: [\n { label: \"5m\", token: \"now-5m\" },\n { label: \"15m\", token: \"now-15m\" },\n { label: \"30m\", token: \"now-30m\" },\n ],\n },\n {\n id: \"hours\",\n label: \"Hr\",\n chips: [\n { label: \"1h\", token: \"now-1h\" },\n { label: \"2h\", token: \"now-2h\" },\n { label: \"4h\", token: \"now-4h\" },\n { label: \"8h\", token: \"now-8h\" },\n { label: \"12h\", token: \"now-12h\" },\n ],\n },\n {\n id: \"days\",\n label: \"Day\",\n chips: [\n { label: \"1d\", token: \"now-1d\" },\n { label: \"2d\", token: \"now-2d\" },\n { label: \"3d\", token: \"now-3d\" },\n { label: \"1w\", token: \"now-1w\" },\n ],\n },\n {\n id: \"weeks\",\n label: \"Wk+\",\n chips: [\n { label: \"2w\", token: \"now-2w\" },\n { label: \"1M\", token: \"now-1M\" },\n { label: \"3M\", token: \"now-3M\" },\n { label: \"6M\", token: \"now-6M\" },\n { label: \"1y\", token: \"now-1y\" },\n ],\n },\n];\n\nconst timeChipRowsByGroup: Record<\n Exclude<TimeRangePresetGroup, \"this\" | \"last\">,\n TimeRangeChipRow\n> = {\n min: defaultTimeChipRows[0]!,\n hr: defaultTimeChipRows[1]!,\n day: defaultTimeChipRows[2]!,\n \"wk+\": defaultTimeChipRows[3]!,\n};\n\nconst defaultDateChipRows: TimeRangeChipRow[] = [\n {\n id: \"days\",\n label: \"Day\",\n chips: [\n { label: \"1d\", token: \"now-1d\" },\n { label: \"2d\", token: \"now-2d\" },\n { label: \"3d\", token: \"now-3d\" },\n { label: \"7d\", token: \"now-7d\" },\n ],\n },\n {\n id: \"weeks\",\n label: \"Wk\",\n chips: [\n { label: \"1w\", token: \"now-1w\" },\n { label: \"2w\", token: \"now-2w\" },\n { label: \"4w\", token: \"now-4w\" },\n ],\n },\n {\n id: \"months\",\n label: \"Mo\",\n chips: [\n { label: \"1M\", token: \"now-1M\" },\n { label: \"3M\", token: \"now-3M\" },\n { label: \"6M\", token: \"now-6M\" },\n { label: \"1y\", token: \"now-1y\" },\n ],\n },\n];\n\nconst thisLastChipRows: Record<Extract<TimeRangePresetGroup, \"this\" | \"last\">, TimeRangeChipRow> = {\n this: {\n id: \"this\",\n label: \"This\",\n chips: [\n { label: \"Week\", token: \"now/w\", to: \"now/w+1w\", ariaLabel: \"this week\" },\n {\n label: \"Month\",\n token: \"now/M\",\n to: \"now/M+1M\",\n ariaLabel: \"this month\",\n },\n {\n label: \"Quarter\",\n token: \"now/q\",\n to: \"now/q+1q\",\n ariaLabel: \"this quarter\",\n },\n { label: \"Year\", token: \"now/y\", to: \"now/y+1y\", ariaLabel: \"this year\" },\n ],\n },\n last: {\n id: \"last\",\n label: \"Last\",\n chips: [\n { label: \"Week\", token: \"now/w-1w\", to: \"now/w\", ariaLabel: \"last week\" },\n {\n label: \"Month\",\n token: \"now/M-1M\",\n to: \"now/M\",\n ariaLabel: \"last month\",\n },\n {\n label: \"Quarter\",\n token: \"now/q-1q\",\n to: \"now/q\",\n ariaLabel: \"last quarter\",\n },\n { label: \"Year\", token: \"now/y-1y\", to: \"now/y\", ariaLabel: \"last year\" },\n ],\n },\n};\n\nexport function TimeRange({\n kind = \"time\",\n label = \"Time range\",\n from = \"\",\n to = \"\",\n onApply,\n presets,\n chipRows,\n timeEnabled = false,\n timeZone,\n timeZones,\n fromPlaceholder,\n toPlaceholder,\n emptyLabel,\n align = \"right\",\n disabled = false,\n className,\n triggerClassName,\n panelClassName,\n}: TimeRangeProps) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const [draftFrom, setDraftFrom] = useState(from);\n const [draftTo, setDraftTo] = useState(to);\n const resolvedDefaultTimeZone = timeZone ?? getDefaultTimeZone();\n const [selectedTimeZone, setSelectedTimeZone] = useState(resolvedDefaultTimeZone);\n\n const activeTimeZones = resolveTimeZones(timeZones, selectedTimeZone);\n const { rows: activeChipRows, presets: activePresets } = resolvePresetConfig(\n kind,\n presets,\n chipRows,\n );\n\n useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));\n\n useEffect(() => {\n if (open) {\n setDraftFrom(from);\n setDraftTo(to);\n setSelectedTimeZone(resolvedDefaultTimeZone);\n }\n }, [from, open, resolvedDefaultTimeZone, to]);\n\n const buttonLabel =\n formatSelectedPresetLabel(from, to, activeChipRows, activePresets) ??\n formatRangeLabel(kind, from, to, emptyLabel);\n const activeToken = normalizeRangeValue(kind, from, {\n timeEnabled,\n timeZone: selectedTimeZone,\n });\n\n function applyRange(nextFrom: string, nextTo: string) {\n onApply(\n normalizeRangeValue(kind, nextFrom, {\n timeEnabled,\n timeZone: selectedTimeZone,\n }),\n normalizeRangeValue(kind, nextTo, {\n timeEnabled,\n timeZone: selectedTimeZone,\n }),\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 inline-flex\", 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 disabled={disabled}\n onClick={() => setOpen((current) => !current)}\n className={cn(\n \"h-7 w-fit max-w-[12rem] min-w-0 gap-2 px-2 text-xs font-normal\",\n triggerClassName,\n )}\n >\n <Icon\n icon={kind === \"time\" ? UiWatch : UiCalendar}\n className=\"text-muted-foreground text-[14px]\"\n />\n <span className=\"truncate font-normal tabular-nums\">{buttonLabel}</span>\n </Button>\n\n {open && (\n <div\n role=\"dialog\"\n aria-label={label}\n className={cn(\n \"fixed inset-x-2 bottom-4 top-16 z-50 flex flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg shadow-black/10 outline-none md:absolute md:bottom-auto md:top-[calc(100%+0.375rem)] md:block md:w-[22.5rem] md:shadow-black/5\",\n align === \"left\" ? \"md:left-0\" : \"md:right-0\",\n panelClassName,\n )}\n >\n <div className=\"flex items-center justify-between border-b border-border/60 px-3.5 py-2.5\">\n <span className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {label}\n </span>\n <span className=\"font-mono text-[10px] text-muted-foreground\">\n {timeEnabled ? selectedTimeZone : \"Relative\"}\n </span>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto md:overflow-visible\">\n {activeChipRows.length > 0 && (\n <ChipRowList rows={activeChipRows} activeToken={activeToken} onApply={applyRange} />\n )}\n {activePresets.length > 0 && (\n <div className={activeChipRows.length > 0 ? \"px-3.5 pb-3\" : \"px-3.5 pt-3\"}>\n <PresetList presets={activePresets} onApply={applyRange} />\n </div>\n )}\n\n <div className=\"border-t border-border/60 bg-muted/30 px-3.5 py-2.5\">\n <div className=\"mb-1.5 flex flex-wrap items-center justify-between gap-2\">\n <div className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n Custom\n </div>\n {timeEnabled && (\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <span className=\"text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n TZ\n </span>\n <Select\n aria-label={`${label} timezone`}\n value={selectedTimeZone}\n options={activeTimeZones.map((zone) => ({\n value: zone,\n label: zone,\n }))}\n onChange={(event) => setSelectedTimeZone(event.target.value)}\n className=\"h-7 w-40 truncate px-2 pr-7 font-mono text-xs\"\n />\n </div>\n )}\n </div>\n <div className=\"grid gap-1.5 md:grid-cols-[1fr_auto_1fr] md:items-center\">\n <DraftRangeInput\n aria-label={`${label} from`}\n placeholder={\n fromPlaceholder ?? (kind === \"date\" ? \"YYYY-MM-DD or now-1d\" : \"now-24h\")\n }\n value={draftFrom}\n onChange={setDraftFrom}\n onClear={() => setDraftFrom(\"\")}\n pickerKind={kind}\n timeEnabled={timeEnabled}\n />\n <Icon\n icon={UiArrowRight}\n className=\"hidden text-muted-foreground text-[12px] md:block\"\n />\n <DraftRangeInput\n aria-label={`${label} to`}\n placeholder={toPlaceholder ?? (kind === \"date\" ? \"YYYY-MM-DD or now\" : \"now\")}\n value={draftTo}\n onChange={setDraftTo}\n onClear={() => setDraftTo(\"\")}\n pickerKind={kind}\n timeEnabled={timeEnabled}\n />\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border/60 px-3 py-2\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-xs\"\n disabled={!from && !to}\n onClick={clearRange}\n >\n Clear\n </Button>\n <div className=\"flex gap-1.5\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2.5 text-xs\"\n onClick={() => setOpen(false)}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"h-7 px-3.5 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 DraftRangeInput({\n value,\n onChange,\n onClear,\n placeholder,\n pickerKind,\n timeEnabled,\n ...rest\n}: {\n value: string;\n onChange: (value: string) => void;\n onClear: () => void;\n placeholder: string | undefined;\n pickerKind?: TimeRangeKind;\n timeEnabled: boolean;\n \"aria-label\": string;\n}) {\n const ariaLabel = rest[\"aria-label\"];\n const showCalendar = pickerKind !== undefined;\n const showTimeInput = pickerKind === \"time\" && timeEnabled;\n const { date: datePart, time: timePart } = splitDateTime(value);\n\n function setDatePart(nextDate: string) {\n if (!showTimeInput) {\n onChange(nextDate);\n return;\n }\n if (!nextDate) {\n onChange(timePart ? `T${timePart}` : \"\");\n return;\n }\n onChange(timePart ? `${nextDate}T${timePart}` : nextDate);\n }\n\n function setTimePart(nextTime: string) {\n if (!nextTime) {\n onChange(datePart);\n return;\n }\n onChange(datePart ? `${datePart}T${nextTime}` : `T${nextTime}`);\n }\n\n return (\n <div className=\"space-y-1\">\n <DraftTextInput\n ariaLabel={ariaLabel}\n placeholder={placeholder}\n value={showTimeInput ? datePart : value}\n onChange={showTimeInput ? setDatePart : onChange}\n onClear={onClear}\n showCalendar={showCalendar}\n />\n {showTimeInput && (\n <DraftTimeInput ariaLabel={`${ariaLabel} time`} value={timePart} onChange={setTimePart} />\n )}\n </div>\n );\n}\n\nfunction resolvePresetConfig(\n kind: TimeRangeKind,\n presets: TimeRangeProps[\"presets\"],\n chipRows: TimeRangeChipRow[] | undefined,\n) {\n if (presets === undefined) {\n return {\n rows: chipRows ?? (kind === \"date\" ? defaultDateChipRows : defaultTimeChipRows),\n presets: [] as TimeRangePreset[],\n };\n }\n\n const rows: TimeRangeChipRow[] = chipRows ? [...chipRows] : [];\n const presetList: TimeRangePreset[] = [];\n\n for (const preset of presets) {\n if (typeof preset !== \"string\") {\n presetList.push(preset);\n continue;\n }\n if (preset === \"this\" || preset === \"last\") {\n rows.push(thisLastChipRows[preset]);\n continue;\n }\n rows.push(timeChipRowsByGroup[preset]);\n }\n\n return { rows, presets: presetList };\n}\n\nfunction DraftTextInput({\n ariaLabel,\n value,\n onChange,\n onClear,\n placeholder,\n showCalendar,\n}: {\n ariaLabel: string;\n value: string;\n onChange: (value: string) => void;\n onClear: () => void;\n placeholder: string | undefined;\n showCalendar: boolean;\n}) {\n const pickerRef = useRef<HTMLInputElement | null>(null);\n const hasValue = value.length > 0;\n const paddingRight = showCalendar ? (hasValue ? \"pr-12\" : \"pr-7\") : \"pr-7\";\n\n return (\n <div className=\"relative\">\n <input\n type=\"text\"\n aria-label={ariaLabel}\n placeholder={placeholder}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className={cn(\n \"h-8 w-full rounded-md border border-input bg-background px-2 font-mono text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n paddingRight,\n )}\n />\n {hasValue && (\n <button\n type=\"button\"\n aria-label={`Clear ${ariaLabel}`}\n onClick={onClear}\n className={cn(\n \"absolute inset-y-0 inline-flex w-5 items-center justify-center text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n showCalendar ? \"right-6\" : \"right-1\",\n )}\n >\n <Icon icon={UiClose} className=\"text-[12px]\" />\n </button>\n )}\n {showCalendar && (\n <>\n <input\n ref={pickerRef}\n type=\"date\"\n tabIndex={-1}\n aria-hidden=\"true\"\n value={/^\\d{4}-\\d{2}-\\d{2}$/.test(value.trim()) ? value.trim() : \"\"}\n onChange={(event) => onChange(event.target.value)}\n className=\"pointer-events-none absolute left-0 top-0 h-0 w-0 opacity-0\"\n />\n <button\n type=\"button\"\n aria-label={`Pick ${ariaLabel}`}\n onClick={() => pickerRef.current?.showPicker?.()}\n className=\"absolute inset-y-0 right-1 inline-flex w-5 items-center justify-center text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Icon icon={UiCalendar} className=\"text-[12px]\" />\n </button>\n </>\n )}\n </div>\n );\n}\n\nfunction DraftTimeInput({\n ariaLabel,\n value,\n onChange,\n}: {\n ariaLabel: string;\n value: string;\n onChange: (value: string) => void;\n}) {\n return (\n <input\n type=\"time\"\n aria-label={ariaLabel}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"h-8 w-full rounded-md border border-input bg-background px-2 font-mono text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n );\n}\n\nfunction splitDateTime(value: string) {\n const trimmed = value.trim();\n const match = /^(\\d{4}-\\d{2}-\\d{2})?T?(\\d{2}:\\d{2})?/.exec(trimmed);\n if (!match || trimmed.startsWith(\"now\") || /^[+-]/.test(trimmed)) {\n return { date: trimmed, time: \"\" };\n }\n return { date: match[1] ?? \"\", time: match[2] ?? \"\" };\n}\n\nfunction ChipRowList({\n rows,\n activeToken,\n onApply,\n}: {\n rows: TimeRangeChipRow[];\n activeToken: string;\n onApply: (from: string, to: string) => void;\n}) {\n if (rows.length === 0) return null;\n\n return (\n <div className=\"px-3.5 py-3\" role=\"list\" aria-label=\"Time filters\">\n {rows.map((row, index) => (\n <div\n key={row.id}\n className={cn(\n \"grid grid-cols-[2rem_1fr] items-center gap-2\",\n index === rows.length - 1 ? \"\" : \"mb-1.5\",\n )}\n role=\"listitem\"\n >\n <span className=\"text-[9.5px] font-bold uppercase tracking-wider text-muted-foreground\">\n {row.label}\n </span>\n <div className=\"flex divide-x divide-border overflow-hidden rounded-[5px] border border-border\">\n {row.chips.map((chip) => {\n const active = chip.token === activeToken;\n return (\n <button\n key={chip.token}\n type=\"button\"\n title={chip.title ?? chip.ariaLabel ?? chip.token}\n aria-label={chip.ariaLabel ?? chip.token}\n aria-pressed={active}\n onClick={() => onApply(chip.token, chip.to ?? \"now\")}\n className={cn(\n \"flex-1 min-w-0 px-0 py-1.5 text-center font-mono text-[11.5px] leading-none transition-colors focus-visible:relative focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n active\n ? \"bg-foreground font-semibold text-background\"\n : \"bg-background font-medium text-muted-foreground hover:bg-muted\",\n )}\n >\n {chip.label}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction PresetList({\n presets,\n onApply,\n}: {\n presets: TimeRangePreset[];\n onApply: (from: string, to: string) => void;\n}) {\n if (presets.length === 0) return null;\n\n return (\n <div className=\"mb-3 space-y-1\" role=\"list\" aria-label=\"Time filters\">\n {presets.map((preset) => (\n <button\n key={`${preset.label}-${preset.from}-${preset.to}`}\n type=\"button\"\n className=\"flex h-8 w-full items-center justify-between gap-3 rounded-md border border-border bg-background px-2 text-left text-xs hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n onClick={() => onApply(preset.from, preset.to)}\n >\n <span className=\"min-w-0 truncate font-medium\">{preset.label}</span>\n <span className=\"shrink-0 font-mono text-[11px] text-muted-foreground\">\n {formatPresetRange(preset)}\n </span>\n </button>\n ))}\n </div>\n );\n}\n\nfunction formatSelectedPresetLabel(\n from: string,\n to: string,\n rows: TimeRangeChipRow[],\n presets: TimeRangePreset[],\n) {\n const normalizedFrom = from.trim();\n const normalizedTo = to.trim();\n if (!normalizedFrom && !normalizedTo) return undefined;\n\n for (const row of rows) {\n for (const chip of row.chips) {\n if (chip.token === normalizedFrom && (chip.to ?? \"now\") === normalizedTo) {\n return chip.ariaLabel ?? chip.title ?? chip.label;\n }\n }\n }\n\n return presets.find((preset) => preset.from === normalizedFrom && preset.to === normalizedTo)\n ?.label;\n}\n\nfunction formatPresetRange({ from, to }: TimeRangePreset) {\n if (!from) return to;\n if (!to || to === \"now\") return from;\n return `${from} -> ${to}`;\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 normalizeRangeValue(\n kind: TimeRangeKind,\n value: string,\n options: { timeEnabled?: boolean; timeZone?: string } = {},\n) {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n if (trimmed === \"now\" || trimmed.startsWith(\"now\")) return trimmed;\n if (kind === \"time\" && /^[+-]\\d/.test(trimmed)) return `now${trimmed}`;\n if (kind === \"time\" && options.timeEnabled) {\n return encodeDateTimeWithOffset(trimmed, options.timeZone ?? getDefaultTimeZone());\n }\n return trimmed;\n}\n\nfunction formatRangeLabel(kind: TimeRangeKind, from: string, to: string, emptyLabel?: 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 = normalizeRangeValue(kind, trimmedFrom);\n const normalizedTo = normalizeRangeValue(kind, 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 getDefaultTimeZone() {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n\nfunction resolveTimeZones(timeZones: string[] | undefined, selectedTimeZone: string) {\n const zones = timeZones && timeZones.length > 0 ? timeZones : [selectedTimeZone, \"UTC\"];\n return Array.from(new Set([selectedTimeZone, ...zones, \"UTC\"].filter(Boolean)));\n}\n\nfunction encodeDateTimeWithOffset(value: string, timeZone: string) {\n if (!isLocalDateTime(value) || hasExplicitOffset(value)) return value;\n\n const match = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?$/);\n if (!match) return value;\n\n const [, year, month, day, hour, minute, second = \"00\"] = match;\n const localUtcMillis = Date.UTC(\n Number(year),\n Number(month) - 1,\n Number(day),\n Number(hour),\n Number(minute),\n Number(second),\n );\n const offsetMinutes = getTimeZoneOffsetMinutes(timeZone, localUtcMillis);\n return `${year}-${month}-${day}T${hour}:${minute}:${second}${formatOffset(offsetMinutes)}`;\n}\n\nfunction isLocalDateTime(value: string) {\n return /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2})?(?:\\.\\d+)?$/.test(value.trim());\n}\n\nfunction hasExplicitOffset(value: string) {\n return /(?:Z|[+-]\\d{2}:?\\d{2})$/i.test(value.trim());\n}\n\nfunction getTimeZoneOffsetMinutes(timeZone: string, localUtcMillis: number) {\n try {\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n const parts = Object.fromEntries(\n formatter\n .formatToParts(new Date(localUtcMillis))\n .filter((part) => part.type !== \"literal\")\n .map((part) => [part.type, part.value]),\n );\n const zonedUtcMillis = Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n return (zonedUtcMillis - localUtcMillis) / 60_000;\n } catch {\n return 0;\n }\n}\n\nfunction formatOffset(offsetMinutes: number) {\n const sign = offsetMinutes >= 0 ? \"+\" : \"-\";\n const abs = Math.abs(offsetMinutes);\n const hours = Math.floor(abs / 60)\n .toString()\n .padStart(2, \"0\");\n const minutes = Math.floor(abs % 60)\n .toString()\n .padStart(2, \"0\");\n return `${sign}${hours}:${minutes}`;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA+EA,MAAM,sBAA0C;AAAA,EAC9C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,OAAO,OAAO,UAAA;AAAA,MACvB,EAAE,OAAO,OAAO,OAAO,UAAA;AAAA,IAAU;AAAA,EACnC;AAAA,EAEF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,OAAO,OAAO,UAAA;AAAA,IAAU;AAAA,EACnC;AAAA,EAEF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,IAAS;AAAA,EACjC;AAAA,EAEF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,IAAS;AAAA,EACjC;AAEJ;AAEA,MAAM,sBAGF;AAAA,EACF,KAAK,oBAAoB,CAAC;AAAA,EAC1B,IAAI,oBAAoB,CAAC;AAAA,EACzB,KAAK,oBAAoB,CAAC;AAAA,EAC1B,OAAO,oBAAoB,CAAC;AAC9B;AAEA,MAAM,sBAA0C;AAAA,EAC9C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,IAAS;AAAA,EACjC;AAAA,EAEF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,IAAS;AAAA,EACjC;AAAA,EAEF;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,MACtB,EAAE,OAAO,MAAM,OAAO,SAAA;AAAA,IAAS;AAAA,EACjC;AAEJ;AAEA,MAAM,mBAA6F;AAAA,EACjG,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,QAAQ,OAAO,SAAS,IAAI,YAAY,WAAW,YAAA;AAAA,MAC5D;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,WAAW;AAAA,MAAA;AAAA,MAEb;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,WAAW;AAAA,MAAA;AAAA,MAEb,EAAE,OAAO,QAAQ,OAAO,SAAS,IAAI,YAAY,WAAW,YAAA;AAAA,IAAY;AAAA,EAC1E;AAAA,EAEF,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,MACL,EAAE,OAAO,QAAQ,OAAO,YAAY,IAAI,SAAS,WAAW,YAAA;AAAA,MAC5D;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,WAAW;AAAA,MAAA;AAAA,MAEb;AAAA,QACE,OAAO;AAAA,QACP,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,WAAW;AAAA,MAAA;AAAA,MAEb,EAAE,OAAO,QAAQ,OAAO,YAAY,IAAI,SAAS,WAAW,YAAA;AAAA,IAAY;AAAA,EAC1E;AAEJ;AAEO,SAAS,UAAU;AAAA,EACxB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,aAAa,OAA0B,IAAI;AACjD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAC/C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,EAAE;AACzC,QAAM,0BAA0B,YAAY,mBAAA;AAC5C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,uBAAuB;AAEhF,QAAM,kBAAkB,iBAAiB,WAAW,gBAAgB;AACpE,QAAM,EAAE,MAAM,gBAAgB,SAAS,kBAAkB;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,sBAAoB,MAAM,SAAS,YAAY,MAAM,QAAQ,KAAK,CAAC;AAEnE,YAAU,MAAM;AACd,QAAI,MAAM;AACR,mBAAa,IAAI;AACjB,iBAAW,EAAE;AACb,0BAAoB,uBAAuB;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,yBAAyB,EAAE,CAAC;AAE5C,QAAM,cACJ,0BAA0B,MAAM,IAAI,gBAAgB,aAAa,KACjE,iBAAiB,MAAM,MAAM,IAAI,UAAU;AAC7C,QAAM,cAAc,oBAAoB,MAAM,MAAM;AAAA,IAClD;AAAA,IACA,UAAU;AAAA,EAAA,CACX;AAED,WAAS,WAAW,UAAkB,QAAgB;AACpD;AAAA,MACE,oBAAoB,MAAM,UAAU;AAAA,QAClC;AAAA,QACA,UAAU;AAAA,MAAA,CACX;AAAA,MACD,oBAAoB,MAAM,QAAQ;AAAA,QAChC;AAAA,QACA,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAEH,YAAQ,KAAK;AAAA,EACf;AAEA,WAAS,aAAa;AACpB,iBAAa,EAAE;AACf,eAAW,EAAE;AACb,YAAQ,IAAI,EAAE;AACd,YAAQ,KAAK;AAAA,EACf;AAEA,SACE,qBAAC,SAAI,KAAK,SAAS,WAAW,GAAG,wBAAwB,SAAS,GAChE,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,cAAY,GAAG,KAAK;AAAA,QACpB,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd;AAAA,QACA,SAAS,MAAM,QAAQ,CAAC,YAAY,CAAC,OAAO;AAAA,QAC5C,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,SAAS,SAAS,UAAU;AAAA,cAClC,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,oBAAC,QAAA,EAAK,WAAU,qCAAqC,UAAA,YAAA,CAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGlE,QACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA,UAAU,SAAS,cAAc;AAAA,UACjC;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,6EACb,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,WAAU,4EACb,UAAA,OACH;AAAA,gCACC,QAAA,EAAK,WAAU,+CACb,UAAA,cAAc,mBAAmB,WAAA,CACpC;AAAA,UAAA,GACF;AAAA,UAEA,qBAAC,OAAA,EAAI,WAAU,sDACZ,UAAA;AAAA,YAAA,eAAe,SAAS,KACvB,oBAAC,aAAA,EAAY,MAAM,gBAAgB,aAA0B,SAAS,WAAA,CAAY;AAAA,YAEnF,cAAc,SAAS,KACtB,oBAAC,OAAA,EAAI,WAAW,eAAe,SAAS,IAAI,gBAAgB,eAC1D,UAAA,oBAAC,YAAA,EAAW,SAAS,eAAe,SAAS,YAAY,GAC3D;AAAA,YAGF,qBAAC,OAAA,EAAI,WAAU,uDACb,UAAA;AAAA,cAAA,qBAAC,OAAA,EAAI,WAAU,4DACb,UAAA;AAAA,gBAAA,oBAAC,OAAA,EAAI,WAAU,4EAA2E,UAAA,UAE1F;AAAA,gBACC,eACC,qBAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,kBAAA,oBAAC,QAAA,EAAK,WAAU,4EAA2E,UAAA,MAE3F;AAAA,kBACA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,cAAY,GAAG,KAAK;AAAA,sBACpB,OAAO;AAAA,sBACP,SAAS,gBAAgB,IAAI,CAAC,UAAU;AAAA,wBACtC,OAAO;AAAA,wBACP,OAAO;AAAA,sBAAA,EACP;AAAA,sBACF,UAAU,CAAC,UAAU,oBAAoB,MAAM,OAAO,KAAK;AAAA,sBAC3D,WAAU;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACZ,EAAA,CACF;AAAA,cAAA,GAEJ;AAAA,cACA,qBAAC,OAAA,EAAI,WAAU,4DACb,UAAA;AAAA,gBAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,cAAY,GAAG,KAAK;AAAA,oBACpB,aACE,oBAAoB,SAAS,SAAS,yBAAyB;AAAA,oBAEjE,OAAO;AAAA,oBACP,UAAU;AAAA,oBACV,SAAS,MAAM,aAAa,EAAE;AAAA,oBAC9B,YAAY;AAAA,oBACZ;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEF;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAM;AAAA,oBACN,WAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEZ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,cAAY,GAAG,KAAK;AAAA,oBACpB,aAAa,kBAAkB,SAAS,SAAS,sBAAsB;AAAA,oBACvE,OAAO;AAAA,oBACP,UAAU;AAAA,oBACV,SAAS,MAAM,WAAW,EAAE;AAAA,oBAC5B,YAAY;AAAA,oBACZ;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACF,EAAA,CACF;AAAA,YAAA,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UAEA,qBAAC,OAAA,EAAI,WAAU,yEACb,UAAA;AAAA,YAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,WAAU;AAAA,gBACV,UAAU,CAAC,QAAQ,CAAC;AAAA,gBACpB,SAAS;AAAA,gBACV,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAM,QAAQ,KAAK;AAAA,kBAC7B,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAM,WAAW,WAAW,OAAO;AAAA,kBAC7C,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED,EAAA,CACF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GAEJ;AAEJ;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAQG;AACD,QAAM,YAAY,KAAK,YAAY;AACnC,QAAM,eAAe,eAAe;AACpC,QAAM,gBAAgB,eAAe,UAAU;AAC/C,QAAM,EAAE,MAAM,UAAU,MAAM,SAAA,IAAa,cAAc,KAAK;AAE9D,WAAS,YAAY,UAAkB;AACrC,QAAI,CAAC,eAAe;AAClB,eAAS,QAAQ;AACjB;AAAA,IACF;AACA,QAAI,CAAC,UAAU;AACb,eAAS,WAAW,IAAI,QAAQ,KAAK,EAAE;AACvC;AAAA,IACF;AACA,aAAS,WAAW,GAAG,QAAQ,IAAI,QAAQ,KAAK,QAAQ;AAAA,EAC1D;AAEA,WAAS,YAAY,UAAkB;AACrC,QAAI,CAAC,UAAU;AACb,eAAS,QAAQ;AACjB;AAAA,IACF;AACA,aAAS,WAAW,GAAG,QAAQ,IAAI,QAAQ,KAAK,IAAI,QAAQ,EAAE;AAAA,EAChE;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO,gBAAgB,WAAW;AAAA,QAClC,UAAU,gBAAgB,cAAc;AAAA,QACxC;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,IAED,iBACC,oBAAC,gBAAA,EAAe,WAAW,GAAG,SAAS,SAAS,OAAO,UAAU,UAAU,YAAA,CAAa;AAAA,EAAA,GAE5F;AAEJ;AAEA,SAAS,oBACP,MACA,SACA,UACA;AACA,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,MACL,MAAM,aAAa,SAAS,SAAS,sBAAsB;AAAA,MAC3D,SAAS,CAAA;AAAA,IAAC;AAAA,EAEd;AAEA,QAAM,OAA2B,WAAW,CAAC,GAAG,QAAQ,IAAI,CAAA;AAC5D,QAAM,aAAgC,CAAA;AAEtC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,WAAW,UAAU;AAC9B,iBAAW,KAAK,MAAM;AACtB;AAAA,IACF;AACA,QAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,WAAK,KAAK,iBAAiB,MAAM,CAAC;AAClC;AAAA,IACF;AACA,SAAK,KAAK,oBAAoB,MAAM,CAAC;AAAA,EACvC;AAEA,SAAO,EAAE,MAAM,SAAS,WAAA;AAC1B;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,YAAY,OAAgC,IAAI;AACtD,QAAM,WAAW,MAAM,SAAS;AAChC,QAAM,eAAe,eAAgB,WAAW,UAAU,SAAU;AAEpE,SACE,qBAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,QAChD,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAED,YACC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAY,SAAS,SAAS;AAAA,QAC9B,SAAS;AAAA,QACT,WAAW;AAAA,UACT;AAAA,UACA,eAAe,YAAY;AAAA,QAAA;AAAA,QAG7B,UAAA,oBAAC,MAAA,EAAK,MAAM,SAAS,WAAU,cAAA,CAAc;AAAA,MAAA;AAAA,IAAA;AAAA,IAGhD,gBACC,qBAAA,UAAA,EACE,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL,MAAK;AAAA,UACL,UAAU;AAAA,UACV,eAAY;AAAA,UACZ,OAAO,sBAAsB,KAAK,MAAM,MAAM,IAAI,MAAM,KAAA,IAAS;AAAA,UACjE,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,UAChD,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAY,QAAQ,SAAS;AAAA,UAC7B,SAAS,MAAA;;AAAM,yCAAU,YAAV,mBAAmB,eAAnB;AAAA;AAAA,UACf,WAAU;AAAA,UAEV,UAAA,oBAAC,MAAA,EAAK,MAAM,YAAY,WAAU,cAAA,CAAc;AAAA,QAAA;AAAA,MAAA;AAAA,IAClD,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ;AAAA,MACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,MAChD,WAAU;AAAA,IAAA;AAAA,EAAA;AAGhB;AAEA,SAAS,cAAc,OAAe;AACpC,QAAM,UAAU,MAAM,KAAA;AACtB,QAAM,QAAQ,wCAAwC,KAAK,OAAO;AAClE,MAAI,CAAC,SAAS,QAAQ,WAAW,KAAK,KAAK,QAAQ,KAAK,OAAO,GAAG;AAChE,WAAO,EAAE,MAAM,SAAS,MAAM,GAAA;AAAA,EAChC;AACA,SAAO,EAAE,MAAM,MAAM,CAAC,KAAK,IAAI,MAAM,MAAM,CAAC,KAAK,GAAA;AACnD;AAEA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,SACE,oBAAC,OAAA,EAAI,WAAU,eAAc,MAAK,QAAO,cAAW,gBACjD,UAAA,KAAK,IAAI,CAAC,KAAK,UACd;AAAA,IAAC;AAAA,IAAA;AAAA,MAEC,WAAW;AAAA,QACT;AAAA,QACA,UAAU,KAAK,SAAS,IAAI,KAAK;AAAA,MAAA;AAAA,MAEnC,MAAK;AAAA,MAEL,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,yEACb,UAAA,IAAI,OACP;AAAA,QACA,oBAAC,SAAI,WAAU,kFACZ,cAAI,MAAM,IAAI,CAAC,SAAS;AACvB,gBAAM,SAAS,KAAK,UAAU;AAC9B,iBACE;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,MAAK;AAAA,cACL,OAAO,KAAK,SAAS,KAAK,aAAa,KAAK;AAAA,cAC5C,cAAY,KAAK,aAAa,KAAK;AAAA,cACnC,gBAAc;AAAA,cACd,SAAS,MAAM,QAAQ,KAAK,OAAO,KAAK,MAAM,KAAK;AAAA,cACnD,WAAW;AAAA,gBACT;AAAA,gBACA,SACI,gDACA;AAAA,cAAA;AAAA,cAGL,UAAA,KAAK;AAAA,YAAA;AAAA,YAbD,KAAK;AAAA,UAAA;AAAA,QAgBhB,CAAC,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,IAhCK,IAAI;AAAA,EAAA,CAkCZ,GACH;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AACF,GAGG;AACD,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,SACE,oBAAC,OAAA,EAAI,WAAU,kBAAiB,MAAK,QAAO,cAAW,gBACpD,UAAA,QAAQ,IAAI,CAAC,WACZ;AAAA,IAAC;AAAA,IAAA;AAAA,MAEC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAS,MAAM,QAAQ,OAAO,MAAM,OAAO,EAAE;AAAA,MAE7C,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,gCAAgC,UAAA,OAAO,OAAM;AAAA,4BAC5D,QAAA,EAAK,WAAU,wDACb,UAAA,kBAAkB,MAAM,EAAA,CAC3B;AAAA,MAAA;AAAA,IAAA;AAAA,IARK,GAAG,OAAO,KAAK,IAAI,OAAO,IAAI,IAAI,OAAO,EAAE;AAAA,EAAA,CAUnD,GACH;AAEJ;AAEA,SAAS,0BACP,MACA,IACA,MACA,SACA;;AACA,QAAM,iBAAiB,KAAK,KAAA;AAC5B,QAAM,eAAe,GAAG,KAAA;AACxB,MAAI,CAAC,kBAAkB,CAAC,aAAc,QAAO;AAE7C,aAAW,OAAO,MAAM;AACtB,eAAW,QAAQ,IAAI,OAAO;AAC5B,UAAI,KAAK,UAAU,mBAAmB,KAAK,MAAM,WAAW,cAAc;AACxE,eAAO,KAAK,aAAa,KAAK,SAAS,KAAK;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAEA,UAAO,aAAQ,KAAK,CAAC,WAAW,OAAO,SAAS,kBAAkB,OAAO,OAAO,YAAY,MAArF,mBACH;AACN;AAEA,SAAS,kBAAkB,EAAE,MAAM,MAAuB;AACxD,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,MAAM,OAAO,MAAO,QAAO;AAChC,SAAO,GAAG,IAAI,OAAO,EAAE;AACzB;AAEA,SAAS,oBACP,MACA,SACA,YACA,SACA;AACA,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AAEX,UAAM,gBAAgB,CAAC,UAAsB;;AAC3C,UAAI,GAAC,aAAQ,YAAR,mBAAiB,SAAS,MAAM,UAAiB;AACpD,gBAAA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,UAAyB;;AAC1C,UAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAA;AACA,yBAAW,YAAX,mBAAoB;AAAA,MACtB;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,aAAa;AACpD,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,aAAa;AACvD,eAAS,oBAAoB,WAAW,SAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,SAAS,UAAU,CAAC;AACzC;AAEA,SAAS,oBACP,MACA,OACA,UAAwD,CAAA,GACxD;AACA,QAAM,UAAU,MAAM,KAAA;AACtB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,YAAY,SAAS,QAAQ,WAAW,KAAK,EAAG,QAAO;AAC3D,MAAI,SAAS,UAAU,UAAU,KAAK,OAAO,EAAG,QAAO,MAAM,OAAO;AACpE,MAAI,SAAS,UAAU,QAAQ,aAAa;AAC1C,WAAO,yBAAyB,SAAS,QAAQ,YAAY,oBAAoB;AAAA,EACnF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAqB,MAAc,IAAY,YAAqB;AAC5F,QAAM,cAAc,KAAK,KAAA;AACzB,QAAM,YAAY,GAAG,KAAA;AAErB,MAAI,CAAC,eAAe,CAAC,WAAW;AAC9B,WAAO,eAAe,SAAS,SAAS,aAAa;AAAA,EACvD;AAEA,MAAI,SAAS,QAAQ;AACnB,UAAM,iBAAiB,oBAAoB,MAAM,WAAW;AAC5D,UAAM,eAAe,oBAAoB,MAAM,aAAa,KAAK;AACjE,QAAI,CAAC,eAAgB,QAAO;AAC5B,QAAI,iBAAiB,MAAO,QAAO;AACnC,WAAO,GAAG,cAAc,OAAO,YAAY;AAAA,EAC7C;AAEA,MAAI,eAAe,aAAa,gBAAgB,WAAW;AACzD,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,YAAa,QAAO;AACzB,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,GAAG,WAAW,OAAO,SAAS;AACvC;AAEA,SAAS,qBAAqB;AAC5B,MAAI;AACF,WAAO,KAAK,eAAA,EAAiB,gBAAA,EAAkB,YAAY;AAAA,EAC7D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,WAAiC,kBAA0B;AACnF,QAAM,QAAQ,aAAa,UAAU,SAAS,IAAI,YAAY,CAAC,kBAAkB,KAAK;AACtF,SAAO,MAAM,KAAK,IAAI,IAAI,CAAC,kBAAkB,GAAG,OAAO,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC;AAChF;AAEA,SAAS,yBAAyB,OAAe,UAAkB;AACjE,MAAI,CAAC,gBAAgB,KAAK,KAAK,kBAAkB,KAAK,EAAG,QAAO;AAEhE,QAAM,QAAQ,MAAM,MAAM,kEAAkE;AAC5F,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,CAAA,EAAG,MAAM,OAAO,KAAK,MAAM,QAAQ,SAAS,IAAI,IAAI;AAC1D,QAAM,iBAAiB,KAAK;AAAA,IAC1B,OAAO,IAAI;AAAA,IACX,OAAO,KAAK,IAAI;AAAA,IAChB,OAAO,GAAG;AAAA,IACV,OAAO,IAAI;AAAA,IACX,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,EAAA;AAEf,QAAM,gBAAgB,yBAAyB,UAAU,cAAc;AACvE,SAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,MAAM,GAAG,aAAa,aAAa,CAAC;AAC1F;AAEA,SAAS,gBAAgB,OAAe;AACtC,SAAO,uDAAuD,KAAK,MAAM,KAAA,CAAM;AACjF;AAEA,SAAS,kBAAkB,OAAe;AACxC,SAAO,2BAA2B,KAAK,MAAM,KAAA,CAAM;AACrD;AAEA,SAAS,yBAAyB,UAAkB,gBAAwB;AAC1E,MAAI;AACF,UAAM,YAAY,IAAI,KAAK,eAAe,SAAS;AAAA,MACjD;AAAA,MACA,MAAM;AAAA,MACN,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA,CACT;AACD,UAAM,QAAQ,OAAO;AAAA,MACnB,UACG,cAAc,IAAI,KAAK,cAAc,CAAC,EACtC,OAAO,CAAC,SAAS,KAAK,SAAS,SAAS,EACxC,IAAI,CAAC,SAAS,CAAC,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,IAAA;AAE1C,UAAM,iBAAiB,KAAK;AAAA,MAC1B,OAAO,MAAM,IAAI;AAAA,MACjB,OAAO,MAAM,KAAK,IAAI;AAAA,MACtB,OAAO,MAAM,GAAG;AAAA,MAChB,OAAO,MAAM,IAAI;AAAA,MACjB,OAAO,MAAM,MAAM;AAAA,MACnB,OAAO,MAAM,MAAM;AAAA,IAAA;AAErB,YAAQ,iBAAiB,kBAAkB;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,aAAa,eAAuB;AAC3C,QAAM,OAAO,iBAAiB,IAAI,MAAM;AACxC,QAAM,MAAM,KAAK,IAAI,aAAa;AAClC,QAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,EAC9B,WACA,SAAS,GAAG,GAAG;AAClB,QAAM,UAAU,KAAK,MAAM,MAAM,EAAE,EAChC,WACA,SAAS,GAAG,GAAG;AAClB,SAAO,GAAG,IAAI,GAAG,KAAK,IAAI,OAAO;AACnC;"}
@@ -100,7 +100,11 @@ function TreePickerField({
100
100
  position: "fixed",
101
101
  top: pos.top,
102
102
  left: pos.left,
103
- width: pos.width,
103
+ // Grow to fit the widest row/toolbar, but never narrower than the
104
+ // trigger nor wider than maxWidth — so labels show in full and the
105
+ // toolbar's intrinsic-width search input never forces a scrollbar.
106
+ minWidth: pos.width,
107
+ width: "max-content",
104
108
  maxWidth: pos.maxWidth
105
109
  },
106
110
  className: utils.cn(
@@ -1 +1 @@
1
- {"version":3,"file":"TreePickerField.cjs","sources":["../../src/components/TreePickerField.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { Tree, type TreeProps } from \"../data/Tree\";\nimport { inputSizeClass, type FormSize } from \"./json-schema-form-size\";\n\n// Upper bound the open panel grows to so wide trees show full labels before\n// truncating; the panel is never narrower than the trigger.\nconst PANEL_MAX_WIDTH_PX = 480;\n\nexport interface TreePickerFieldProps<T> {\n /** Root nodes of the tree to browse. */\n roots: T[];\n getKey: (node: T) => string | number;\n getChildren: (node: T) => T[] | undefined;\n renderRow: TreeProps<T>[\"renderRow\"];\n getSearchText?: (node: T) => string;\n defaultOpen?: (node: T, depth: number) => boolean;\n /**\n * Decides which nodes commit a selection when clicked. A click on a\n * non-selectable node still toggles its expansion (it never closes the\n * picker). Defaults to every node selectable.\n */\n isSelectable?: (node: T) => boolean;\n /** Fires for a selectable node, then closes the dropdown. */\n onSelect: (node: T) => void;\n /** Current-selection display in the trigger; falls back to `placeholder`. */\n label?: ReactNode;\n placeholder?: string;\n disabled?: boolean;\n size?: FormSize;\n className?: string;\n triggerClassName?: string;\n panelClassName?: string;\n}\n\n// TreePickerField is a form-field-styled trigger (matching Combobox's closed\n// input) that opens a portal-anchored dropdown holding a Tree. The dropdown is\n// positioned with fixed coordinates measured from the trigger so it escapes any\n// overflow-hidden / scroll ancestor (e.g. a modal body). A click on a selectable\n// node commits and closes; a non-selectable node only toggles expansion.\nexport function TreePickerField<T>({\n roots,\n getKey,\n getChildren,\n renderRow,\n getSearchText,\n defaultOpen,\n isSelectable,\n onSelect,\n label,\n placeholder = \"Select…\",\n disabled,\n size,\n className,\n triggerClassName,\n panelClassName,\n}: TreePickerFieldProps<T>) {\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<{ top: number; left: number; width: number; maxWidth: number } | null>(\n null,\n );\n const rootRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n // Position the portaled panel from the trigger rect, repositioning while open.\n useLayoutEffect(() => {\n if (!open) {\n setPos(null);\n return;\n }\n const update = () => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const viewportCap = window.innerWidth - rect.left - 8;\n const maxWidth = Math.max(rect.width, Math.min(PANEL_MAX_WIDTH_PX, viewportCap));\n setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width, maxWidth });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n // Dismiss on an outside pointer-down (the trigger and panel are exempt).\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!rootRef.current?.contains(target) && !panelRef.current?.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <button\n ref={anchorRef}\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"tree\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n className={cn(\n \"relative flex w-full items-center rounded-md border border-input bg-background text-left text-foreground\",\n size ? inputSizeClass[size] : \"h-control-h px-control-px text-sm\",\n \"pr-8\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n triggerClassName,\n )}\n >\n <span className={cn(\"min-w-0 flex-1 truncate\", label == null && \"text-muted-foreground\")}>\n {label ?? placeholder}\n </span>\n <span className=\"pointer-events-none absolute right-0 flex h-full items-center px-2 text-muted-foreground\">\n <Icon icon={UiChevronDown} className=\"text-xs\" />\n </span>\n </button>\n\n {open &&\n pos &&\n createPortal(\n <div\n ref={panelRef}\n data-slot=\"tree-picker-popup\"\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n width: pos.width,\n maxWidth: pos.maxWidth,\n }}\n className={cn(\n \"z-50 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-popover shadow-md\",\n panelClassName,\n )}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") setOpen(false);\n }}\n >\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <Tree<T>\n roots={roots}\n getKey={getKey}\n getChildren={getChildren}\n renderRow={renderRow}\n {...(getSearchText ? { getSearchText } : {})}\n {...(defaultOpen ? { defaultOpen } : {})}\n onSelect={(node) => {\n if (!isSelectable || isSelectable(node)) {\n onSelect(node);\n setOpen(false);\n }\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":["useState","useRef","useLayoutEffect","useEffect","jsxs","cn","inputSizeClass","jsx","Icon","UiChevronDown","createPortal","Tree"],"mappings":"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"}
1
+ {"version":3,"file":"TreePickerField.cjs","sources":["../../src/components/TreePickerField.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { Tree, type TreeProps } from \"../data/Tree\";\nimport { inputSizeClass, type FormSize } from \"./json-schema-form-size\";\n\n// Upper bound the open panel grows to so wide trees show full labels before\n// truncating; the panel is never narrower than the trigger.\nconst PANEL_MAX_WIDTH_PX = 480;\n\nexport interface TreePickerFieldProps<T> {\n /** Root nodes of the tree to browse. */\n roots: T[];\n getKey: (node: T) => string | number;\n getChildren: (node: T) => T[] | undefined;\n renderRow: TreeProps<T>[\"renderRow\"];\n getSearchText?: (node: T) => string;\n defaultOpen?: (node: T, depth: number) => boolean;\n /**\n * Decides which nodes commit a selection when clicked. A click on a\n * non-selectable node still toggles its expansion (it never closes the\n * picker). Defaults to every node selectable.\n */\n isSelectable?: (node: T) => boolean;\n /** Fires for a selectable node, then closes the dropdown. */\n onSelect: (node: T) => void;\n /** Current-selection display in the trigger; falls back to `placeholder`. */\n label?: ReactNode;\n placeholder?: string;\n disabled?: boolean;\n size?: FormSize;\n className?: string;\n triggerClassName?: string;\n panelClassName?: string;\n}\n\n// TreePickerField is a form-field-styled trigger (matching Combobox's closed\n// input) that opens a portal-anchored dropdown holding a Tree. The dropdown is\n// positioned with fixed coordinates measured from the trigger so it escapes any\n// overflow-hidden / scroll ancestor (e.g. a modal body). A click on a selectable\n// node commits and closes; a non-selectable node only toggles expansion.\nexport function TreePickerField<T>({\n roots,\n getKey,\n getChildren,\n renderRow,\n getSearchText,\n defaultOpen,\n isSelectable,\n onSelect,\n label,\n placeholder = \"Select…\",\n disabled,\n size,\n className,\n triggerClassName,\n panelClassName,\n}: TreePickerFieldProps<T>) {\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<{ top: number; left: number; width: number; maxWidth: number } | null>(\n null,\n );\n const rootRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n // Position the portaled panel from the trigger rect, repositioning while open.\n useLayoutEffect(() => {\n if (!open) {\n setPos(null);\n return;\n }\n const update = () => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const viewportCap = window.innerWidth - rect.left - 8;\n const maxWidth = Math.max(rect.width, Math.min(PANEL_MAX_WIDTH_PX, viewportCap));\n setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width, maxWidth });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n // Dismiss on an outside pointer-down (the trigger and panel are exempt).\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!rootRef.current?.contains(target) && !panelRef.current?.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <button\n ref={anchorRef}\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"tree\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n className={cn(\n \"relative flex w-full items-center rounded-md border border-input bg-background text-left text-foreground\",\n size ? inputSizeClass[size] : \"h-control-h px-control-px text-sm\",\n \"pr-8\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n triggerClassName,\n )}\n >\n <span className={cn(\"min-w-0 flex-1 truncate\", label == null && \"text-muted-foreground\")}>\n {label ?? placeholder}\n </span>\n <span className=\"pointer-events-none absolute right-0 flex h-full items-center px-2 text-muted-foreground\">\n <Icon icon={UiChevronDown} className=\"text-xs\" />\n </span>\n </button>\n\n {open &&\n pos &&\n createPortal(\n <div\n ref={panelRef}\n data-slot=\"tree-picker-popup\"\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n // Grow to fit the widest row/toolbar, but never narrower than the\n // trigger nor wider than maxWidth — so labels show in full and the\n // toolbar's intrinsic-width search input never forces a scrollbar.\n minWidth: pos.width,\n width: \"max-content\",\n maxWidth: pos.maxWidth,\n }}\n className={cn(\n \"z-50 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-popover shadow-md\",\n panelClassName,\n )}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") setOpen(false);\n }}\n >\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <Tree<T>\n roots={roots}\n getKey={getKey}\n getChildren={getChildren}\n renderRow={renderRow}\n {...(getSearchText ? { getSearchText } : {})}\n {...(defaultOpen ? { defaultOpen } : {})}\n onSelect={(node) => {\n if (!isSelectable || isSelectable(node)) {\n onSelect(node);\n setOpen(false);\n }\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":["useState","useRef","useLayoutEffect","useEffect","jsxs","cn","inputSizeClass","jsx","Icon","UiChevronDown","createPortal","Tree"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TreePickerField.d.ts","sourceRoot":"","sources":["../../src/components/TreePickerField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMxE,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,wCAAwC;IACxC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC;IACrC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC;IAC1C,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACpC,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAOD,wBAAgB,eAAe,CAAC,CAAC,EAAE,EACjC,KAAK,EACL,MAAM,EACN,WAAW,EACX,SAAS,EACT,aAAa,EACb,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,WAAuB,EACvB,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,cAAc,GACf,EAAE,oBAAoB,CAAC,CAAC,CAAC,2CAiHzB"}
1
+ {"version":3,"file":"TreePickerField.d.ts","sourceRoot":"","sources":["../../src/components/TreePickerField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMxE,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,wCAAwC;IACxC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC;IACrC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC;IAC1C,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;IACpC,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAOD,wBAAgB,eAAe,CAAC,CAAC,EAAE,EACjC,KAAK,EACL,MAAM,EACN,WAAW,EACX,SAAS,EACT,aAAa,EACb,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,WAAuB,EACvB,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,cAAc,GACf,EAAE,oBAAoB,CAAC,CAAC,CAAC,2CAqHzB"}
@@ -98,7 +98,11 @@ function TreePickerField({
98
98
  position: "fixed",
99
99
  top: pos.top,
100
100
  left: pos.left,
101
- width: pos.width,
101
+ // Grow to fit the widest row/toolbar, but never narrower than the
102
+ // trigger nor wider than maxWidth — so labels show in full and the
103
+ // toolbar's intrinsic-width search input never forces a scrollbar.
104
+ minWidth: pos.width,
105
+ width: "max-content",
102
106
  maxWidth: pos.maxWidth
103
107
  },
104
108
  className: cn(
@@ -1 +1 @@
1
- {"version":3,"file":"TreePickerField.js","sources":["../../src/components/TreePickerField.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { Tree, type TreeProps } from \"../data/Tree\";\nimport { inputSizeClass, type FormSize } from \"./json-schema-form-size\";\n\n// Upper bound the open panel grows to so wide trees show full labels before\n// truncating; the panel is never narrower than the trigger.\nconst PANEL_MAX_WIDTH_PX = 480;\n\nexport interface TreePickerFieldProps<T> {\n /** Root nodes of the tree to browse. */\n roots: T[];\n getKey: (node: T) => string | number;\n getChildren: (node: T) => T[] | undefined;\n renderRow: TreeProps<T>[\"renderRow\"];\n getSearchText?: (node: T) => string;\n defaultOpen?: (node: T, depth: number) => boolean;\n /**\n * Decides which nodes commit a selection when clicked. A click on a\n * non-selectable node still toggles its expansion (it never closes the\n * picker). Defaults to every node selectable.\n */\n isSelectable?: (node: T) => boolean;\n /** Fires for a selectable node, then closes the dropdown. */\n onSelect: (node: T) => void;\n /** Current-selection display in the trigger; falls back to `placeholder`. */\n label?: ReactNode;\n placeholder?: string;\n disabled?: boolean;\n size?: FormSize;\n className?: string;\n triggerClassName?: string;\n panelClassName?: string;\n}\n\n// TreePickerField is a form-field-styled trigger (matching Combobox's closed\n// input) that opens a portal-anchored dropdown holding a Tree. The dropdown is\n// positioned with fixed coordinates measured from the trigger so it escapes any\n// overflow-hidden / scroll ancestor (e.g. a modal body). A click on a selectable\n// node commits and closes; a non-selectable node only toggles expansion.\nexport function TreePickerField<T>({\n roots,\n getKey,\n getChildren,\n renderRow,\n getSearchText,\n defaultOpen,\n isSelectable,\n onSelect,\n label,\n placeholder = \"Select…\",\n disabled,\n size,\n className,\n triggerClassName,\n panelClassName,\n}: TreePickerFieldProps<T>) {\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<{ top: number; left: number; width: number; maxWidth: number } | null>(\n null,\n );\n const rootRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n // Position the portaled panel from the trigger rect, repositioning while open.\n useLayoutEffect(() => {\n if (!open) {\n setPos(null);\n return;\n }\n const update = () => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const viewportCap = window.innerWidth - rect.left - 8;\n const maxWidth = Math.max(rect.width, Math.min(PANEL_MAX_WIDTH_PX, viewportCap));\n setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width, maxWidth });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n // Dismiss on an outside pointer-down (the trigger and panel are exempt).\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!rootRef.current?.contains(target) && !panelRef.current?.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <button\n ref={anchorRef}\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"tree\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n className={cn(\n \"relative flex w-full items-center rounded-md border border-input bg-background text-left text-foreground\",\n size ? inputSizeClass[size] : \"h-control-h px-control-px text-sm\",\n \"pr-8\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n triggerClassName,\n )}\n >\n <span className={cn(\"min-w-0 flex-1 truncate\", label == null && \"text-muted-foreground\")}>\n {label ?? placeholder}\n </span>\n <span className=\"pointer-events-none absolute right-0 flex h-full items-center px-2 text-muted-foreground\">\n <Icon icon={UiChevronDown} className=\"text-xs\" />\n </span>\n </button>\n\n {open &&\n pos &&\n createPortal(\n <div\n ref={panelRef}\n data-slot=\"tree-picker-popup\"\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n width: pos.width,\n maxWidth: pos.maxWidth,\n }}\n className={cn(\n \"z-50 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-popover shadow-md\",\n panelClassName,\n )}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") setOpen(false);\n }}\n >\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <Tree<T>\n roots={roots}\n getKey={getKey}\n getChildren={getChildren}\n renderRow={renderRow}\n {...(getSearchText ? { getSearchText } : {})}\n {...(defaultOpen ? { defaultOpen } : {})}\n onSelect={(node) => {\n if (!isSelectable || isSelectable(node)) {\n onSelect(node);\n setOpen(false);\n }\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TreePickerField.js","sources":["../../src/components/TreePickerField.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport { Tree, type TreeProps } from \"../data/Tree\";\nimport { inputSizeClass, type FormSize } from \"./json-schema-form-size\";\n\n// Upper bound the open panel grows to so wide trees show full labels before\n// truncating; the panel is never narrower than the trigger.\nconst PANEL_MAX_WIDTH_PX = 480;\n\nexport interface TreePickerFieldProps<T> {\n /** Root nodes of the tree to browse. */\n roots: T[];\n getKey: (node: T) => string | number;\n getChildren: (node: T) => T[] | undefined;\n renderRow: TreeProps<T>[\"renderRow\"];\n getSearchText?: (node: T) => string;\n defaultOpen?: (node: T, depth: number) => boolean;\n /**\n * Decides which nodes commit a selection when clicked. A click on a\n * non-selectable node still toggles its expansion (it never closes the\n * picker). Defaults to every node selectable.\n */\n isSelectable?: (node: T) => boolean;\n /** Fires for a selectable node, then closes the dropdown. */\n onSelect: (node: T) => void;\n /** Current-selection display in the trigger; falls back to `placeholder`. */\n label?: ReactNode;\n placeholder?: string;\n disabled?: boolean;\n size?: FormSize;\n className?: string;\n triggerClassName?: string;\n panelClassName?: string;\n}\n\n// TreePickerField is a form-field-styled trigger (matching Combobox's closed\n// input) that opens a portal-anchored dropdown holding a Tree. The dropdown is\n// positioned with fixed coordinates measured from the trigger so it escapes any\n// overflow-hidden / scroll ancestor (e.g. a modal body). A click on a selectable\n// node commits and closes; a non-selectable node only toggles expansion.\nexport function TreePickerField<T>({\n roots,\n getKey,\n getChildren,\n renderRow,\n getSearchText,\n defaultOpen,\n isSelectable,\n onSelect,\n label,\n placeholder = \"Select…\",\n disabled,\n size,\n className,\n triggerClassName,\n panelClassName,\n}: TreePickerFieldProps<T>) {\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<{ top: number; left: number; width: number; maxWidth: number } | null>(\n null,\n );\n const rootRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLButtonElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n // Position the portaled panel from the trigger rect, repositioning while open.\n useLayoutEffect(() => {\n if (!open) {\n setPos(null);\n return;\n }\n const update = () => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const viewportCap = window.innerWidth - rect.left - 8;\n const maxWidth = Math.max(rect.width, Math.min(PANEL_MAX_WIDTH_PX, viewportCap));\n setPos({ top: rect.bottom + 4, left: rect.left, width: rect.width, maxWidth });\n };\n update();\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n // Dismiss on an outside pointer-down (the trigger and panel are exempt).\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: MouseEvent) => {\n const target = e.target as Node;\n if (!rootRef.current?.contains(target) && !panelRef.current?.contains(target)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n }, [open]);\n\n return (\n <div ref={rootRef} className={cn(\"relative\", className)}>\n <button\n ref={anchorRef}\n type=\"button\"\n disabled={disabled}\n aria-haspopup=\"tree\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n className={cn(\n \"relative flex w-full items-center rounded-md border border-input bg-background text-left text-foreground\",\n size ? inputSizeClass[size] : \"h-control-h px-control-px text-sm\",\n \"pr-8\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n triggerClassName,\n )}\n >\n <span className={cn(\"min-w-0 flex-1 truncate\", label == null && \"text-muted-foreground\")}>\n {label ?? placeholder}\n </span>\n <span className=\"pointer-events-none absolute right-0 flex h-full items-center px-2 text-muted-foreground\">\n <Icon icon={UiChevronDown} className=\"text-xs\" />\n </span>\n </button>\n\n {open &&\n pos &&\n createPortal(\n <div\n ref={panelRef}\n data-slot=\"tree-picker-popup\"\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n // Grow to fit the widest row/toolbar, but never narrower than the\n // trigger nor wider than maxWidth — so labels show in full and the\n // toolbar's intrinsic-width search input never forces a scrollbar.\n minWidth: pos.width,\n width: \"max-content\",\n maxWidth: pos.maxWidth,\n }}\n className={cn(\n \"z-50 flex max-h-[60vh] flex-col overflow-hidden rounded-md border border-border bg-popover shadow-md\",\n panelClassName,\n )}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") setOpen(false);\n }}\n >\n <div className=\"min-h-0 flex-1 overflow-auto\">\n <Tree<T>\n roots={roots}\n getKey={getKey}\n getChildren={getChildren}\n renderRow={renderRow}\n {...(getSearchText ? { getSearchText } : {})}\n {...(defaultOpen ? { defaultOpen } : {})}\n onSelect={(node) => {\n if (!isSelectable || isSelectable(node)) {\n onSelect(node);\n setOpen(false);\n }\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function applyFilterExtensions(filter, extensions) {
4
+ if (!extensions || extensions.length === 0) return filter;
5
+ return extensions.reduce((current, ext) => ext(current), filter);
6
+ }
3
7
  function clearFilterBarFilter(filter) {
4
8
  if (filter.kind === "text" || filter.kind === "lookup" || filter.kind === "enum") {
5
9
  filter.onChange("");
@@ -32,6 +36,7 @@ function isFilterBarFilterActive(filter) {
32
36
  if (filter.kind === "boolean") return filter.value;
33
37
  return Object.keys(filter.value).length > 0;
34
38
  }
39
+ exports.applyFilterExtensions = applyFilterExtensions;
35
40
  exports.clearFilterBarFilter = clearFilterBarFilter;
36
41
  exports.isFilterBarFilterActive = isFilterBarFilterActive;
37
42
  //# sourceMappingURL=filter-bar-utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar-utils.cjs","sources":["../../src/components/filter-bar-utils.ts"],"sourcesContent":["import type { FilterBarFilter } from \"./FilterBar\";\n\nexport function clearFilterBarFilter(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n filter.onChange(\"\");\n return;\n }\n\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n filter.onChange([]);\n return;\n }\n\n if (filter.kind === \"number\") {\n filter.onChange({});\n return;\n }\n\n if (filter.kind === \"boolean\") {\n filter.onChange(false);\n return;\n }\n\n filter.onChange({});\n}\n\nexport function isFilterBarFilterActive(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n return String(filter.value ?? \"\").trim() !== \"\";\n }\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n return filter.value.length > 0;\n }\n if (filter.kind === \"number\") {\n return (\n String(filter.value.min ?? \"\").trim() !== \"\" || String(filter.value.max ?? \"\").trim() !== \"\"\n );\n }\n if (filter.kind === \"boolean\") return filter.value;\n return Object.keys(filter.value).length > 0;\n}\n"],"names":[],"mappings":";;AAEO,SAAS,qBAAqB,QAAyB;AAC5D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,SAAS,KAAK;AACrB;AAAA,EACF;AAEA,SAAO,SAAS,EAAE;AACpB;AAEO,SAAS,wBAAwB,QAAyB;AAC/D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,OAAO,OAAO,SAAS,EAAE,EAAE,WAAW;AAAA,EAC/C;AACA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,OAAO,MAAM,SAAS;AAAA,EAC/B;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WACE,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,KAAA,MAAW,MAAM,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW;AAAA,EAE9F;AACA,MAAI,OAAO,SAAS,UAAW,QAAO,OAAO;AAC7C,SAAO,OAAO,KAAK,OAAO,KAAK,EAAE,SAAS;AAC5C;;;"}
1
+ {"version":3,"file":"filter-bar-utils.cjs","sources":["../../src/components/filter-bar-utils.ts"],"sourcesContent":["import type { FilterBarFilter } from \"./FilterBar\";\n\n// FilterExtension decorates a resolved filter before it renders — the FilterBar\n// analogue of JsonSchemaForm's PreExtension. Consumers compose these in array\n// order (each sees the prior's output) to stamp domain-specific touches such as\n// an entity `icon` keyed on the filter's name, keeping FilterBar domain-agnostic.\nexport type FilterExtension = (filter: FilterBarFilter) => FilterBarFilter;\n\n// applyFilterExtensions runs a filter through the composed extension stack.\nexport function applyFilterExtensions(\n filter: FilterBarFilter,\n extensions: FilterExtension[] | undefined,\n): FilterBarFilter {\n if (!extensions || extensions.length === 0) return filter;\n return extensions.reduce((current, ext) => ext(current), filter);\n}\n\nexport function clearFilterBarFilter(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n filter.onChange(\"\");\n return;\n }\n\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n filter.onChange([]);\n return;\n }\n\n if (filter.kind === \"number\") {\n filter.onChange({});\n return;\n }\n\n if (filter.kind === \"boolean\") {\n filter.onChange(false);\n return;\n }\n\n filter.onChange({});\n}\n\nexport function isFilterBarFilterActive(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n return String(filter.value ?? \"\").trim() !== \"\";\n }\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n return filter.value.length > 0;\n }\n if (filter.kind === \"number\") {\n return (\n String(filter.value.min ?? \"\").trim() !== \"\" || String(filter.value.max ?? \"\").trim() !== \"\"\n );\n }\n if (filter.kind === \"boolean\") return filter.value;\n return Object.keys(filter.value).length > 0;\n}\n"],"names":[],"mappings":";;AASO,SAAS,sBACd,QACA,YACiB;AACjB,MAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO;AACnD,SAAO,WAAW,OAAO,CAAC,SAAS,QAAQ,IAAI,OAAO,GAAG,MAAM;AACjE;AAEO,SAAS,qBAAqB,QAAyB;AAC5D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,SAAS,KAAK;AACrB;AAAA,EACF;AAEA,SAAO,SAAS,EAAE;AACpB;AAEO,SAAS,wBAAwB,QAAyB;AAC/D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,OAAO,OAAO,SAAS,EAAE,EAAE,WAAW;AAAA,EAC/C;AACA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,OAAO,MAAM,SAAS;AAAA,EAC/B;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WACE,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,KAAA,MAAW,MAAM,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW;AAAA,EAE9F;AACA,MAAI,OAAO,SAAS,UAAW,QAAO,OAAO;AAC7C,SAAO,OAAO,KAAK,OAAO,KAAK,EAAE,SAAS;AAC5C;;;;"}
@@ -1,4 +1,6 @@
1
1
  import { FilterBarFilter } from './FilterBar';
2
+ export type FilterExtension = (filter: FilterBarFilter) => FilterBarFilter;
3
+ export declare function applyFilterExtensions(filter: FilterBarFilter, extensions: FilterExtension[] | undefined): FilterBarFilter;
2
4
  export declare function clearFilterBarFilter(filter: FilterBarFilter): void;
3
5
  export declare function isFilterBarFilterActive(filter: FilterBarFilter): boolean;
4
6
  //# sourceMappingURL=filter-bar-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar-utils.d.ts","sourceRoot":"","sources":["../../src/components/filter-bar-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,QAsB3D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,WAc9D"}
1
+ {"version":3,"file":"filter-bar-utils.d.ts","sourceRoot":"","sources":["../../src/components/filter-bar-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,eAAe,CAAC;AAG3E,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,GACxC,eAAe,CAGjB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,QAsB3D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,eAAe,WAc9D"}
@@ -1,3 +1,7 @@
1
+ function applyFilterExtensions(filter, extensions) {
2
+ if (!extensions || extensions.length === 0) return filter;
3
+ return extensions.reduce((current, ext) => ext(current), filter);
4
+ }
1
5
  function clearFilterBarFilter(filter) {
2
6
  if (filter.kind === "text" || filter.kind === "lookup" || filter.kind === "enum") {
3
7
  filter.onChange("");
@@ -31,6 +35,7 @@ function isFilterBarFilterActive(filter) {
31
35
  return Object.keys(filter.value).length > 0;
32
36
  }
33
37
  export {
38
+ applyFilterExtensions,
34
39
  clearFilterBarFilter,
35
40
  isFilterBarFilterActive
36
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar-utils.js","sources":["../../src/components/filter-bar-utils.ts"],"sourcesContent":["import type { FilterBarFilter } from \"./FilterBar\";\n\nexport function clearFilterBarFilter(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n filter.onChange(\"\");\n return;\n }\n\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n filter.onChange([]);\n return;\n }\n\n if (filter.kind === \"number\") {\n filter.onChange({});\n return;\n }\n\n if (filter.kind === \"boolean\") {\n filter.onChange(false);\n return;\n }\n\n filter.onChange({});\n}\n\nexport function isFilterBarFilterActive(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n return String(filter.value ?? \"\").trim() !== \"\";\n }\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n return filter.value.length > 0;\n }\n if (filter.kind === \"number\") {\n return (\n String(filter.value.min ?? \"\").trim() !== \"\" || String(filter.value.max ?? \"\").trim() !== \"\"\n );\n }\n if (filter.kind === \"boolean\") return filter.value;\n return Object.keys(filter.value).length > 0;\n}\n"],"names":[],"mappings":"AAEO,SAAS,qBAAqB,QAAyB;AAC5D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,SAAS,KAAK;AACrB;AAAA,EACF;AAEA,SAAO,SAAS,EAAE;AACpB;AAEO,SAAS,wBAAwB,QAAyB;AAC/D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,OAAO,OAAO,SAAS,EAAE,EAAE,WAAW;AAAA,EAC/C;AACA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,OAAO,MAAM,SAAS;AAAA,EAC/B;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WACE,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,KAAA,MAAW,MAAM,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW;AAAA,EAE9F;AACA,MAAI,OAAO,SAAS,UAAW,QAAO,OAAO;AAC7C,SAAO,OAAO,KAAK,OAAO,KAAK,EAAE,SAAS;AAC5C;"}
1
+ {"version":3,"file":"filter-bar-utils.js","sources":["../../src/components/filter-bar-utils.ts"],"sourcesContent":["import type { FilterBarFilter } from \"./FilterBar\";\n\n// FilterExtension decorates a resolved filter before it renders — the FilterBar\n// analogue of JsonSchemaForm's PreExtension. Consumers compose these in array\n// order (each sees the prior's output) to stamp domain-specific touches such as\n// an entity `icon` keyed on the filter's name, keeping FilterBar domain-agnostic.\nexport type FilterExtension = (filter: FilterBarFilter) => FilterBarFilter;\n\n// applyFilterExtensions runs a filter through the composed extension stack.\nexport function applyFilterExtensions(\n filter: FilterBarFilter,\n extensions: FilterExtension[] | undefined,\n): FilterBarFilter {\n if (!extensions || extensions.length === 0) return filter;\n return extensions.reduce((current, ext) => ext(current), filter);\n}\n\nexport function clearFilterBarFilter(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n filter.onChange(\"\");\n return;\n }\n\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n filter.onChange([]);\n return;\n }\n\n if (filter.kind === \"number\") {\n filter.onChange({});\n return;\n }\n\n if (filter.kind === \"boolean\") {\n filter.onChange(false);\n return;\n }\n\n filter.onChange({});\n}\n\nexport function isFilterBarFilterActive(filter: FilterBarFilter) {\n if (filter.kind === \"text\" || filter.kind === \"lookup\" || filter.kind === \"enum\") {\n return String(filter.value ?? \"\").trim() !== \"\";\n }\n if (filter.kind === \"lookup-multi\" || filter.kind === \"select-multi\") {\n return filter.value.length > 0;\n }\n if (filter.kind === \"number\") {\n return (\n String(filter.value.min ?? \"\").trim() !== \"\" || String(filter.value.max ?? \"\").trim() !== \"\"\n );\n }\n if (filter.kind === \"boolean\") return filter.value;\n return Object.keys(filter.value).length > 0;\n}\n"],"names":[],"mappings":"AASO,SAAS,sBACd,QACA,YACiB;AACjB,MAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO;AACnD,SAAO,WAAW,OAAO,CAAC,SAAS,QAAQ,IAAI,OAAO,GAAG,MAAM;AACjE;AAEO,SAAS,qBAAqB,QAAyB;AAC5D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,SAAS,EAAE;AAClB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,SAAS,KAAK;AACrB;AAAA,EACF;AAEA,SAAO,SAAS,EAAE;AACpB;AAEO,SAAS,wBAAwB,QAAyB;AAC/D,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ;AAChF,WAAO,OAAO,OAAO,SAAS,EAAE,EAAE,WAAW;AAAA,EAC/C;AACA,MAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,gBAAgB;AACpE,WAAO,OAAO,MAAM,SAAS;AAAA,EAC/B;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WACE,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,KAAA,MAAW,MAAM,OAAO,OAAO,MAAM,OAAO,EAAE,EAAE,WAAW;AAAA,EAE9F;AACA,MAAI,OAAO,SAAS,UAAW,QAAO,OAAO;AAC7C,SAAO,OAAO,KAAK,OAAO,KAAK,EAAE,SAAS;AAC5C;"}
@@ -135,6 +135,7 @@ function NumberControl({
135
135
  readOnly,
136
136
  size
137
137
  }) {
138
+ const coerce = field.coerceNumber !== false;
138
139
  return /* @__PURE__ */ jsxRuntime.jsx(FieldAdornmentWrapper, { prefix: field.prefix, suffix: field.suffix, children: /* @__PURE__ */ jsxRuntime.jsx(
139
140
  "input",
140
141
  {
@@ -148,12 +149,17 @@ function NumberControl({
148
149
  placeholder: jsonSchemaFormUtils.defaultPlaceholder(field.schema),
149
150
  onChange: (e) => {
150
151
  const raw = e.target.value;
151
- const coerce = field.coerceNumber !== false;
152
- if (coerce && raw.trim() !== "" && Number.isFinite(Number(raw))) {
152
+ if (coerce && raw.trim() !== "" && String(Number(raw)) === raw.trim()) {
153
153
  field.onChange(Number(raw));
154
154
  } else {
155
155
  field.onChange(raw);
156
156
  }
157
+ },
158
+ onBlur: (e) => {
159
+ const raw = e.target.value;
160
+ if (coerce && raw.trim() !== "" && Number.isFinite(Number(raw))) {
161
+ field.onChange(Number(raw));
162
+ }
157
163
  }
158
164
  }
159
165
  ) });
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-form-fields.cjs","sources":["../../src/components/json-schema-form-fields.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { LabelIcon, type LabelIconSpec } from \"../data/Icon\";\nimport { formatDateTimeRelative } from \"../data/cells/timestamp-format\";\nimport { Combobox } from \"./Combobox\";\nimport { DateTimePicker } from \"./DateTimePicker\";\nimport type { FieldControl, FieldOption, FormLayout } from \"./json-schema-form-types\";\nimport {\n defaultPlaceholder,\n inputClass,\n toText,\n withSyntheticValue,\n} from \"./json-schema-form-utils\";\nimport {\n controlHeightClass,\n controlMinHeightClass,\n fieldInnerGapClass,\n inlineRowGapClass,\n labelSizeClass,\n stackedRowGapClass,\n type FormSize,\n} from \"./json-schema-form-size\";\n\n// FieldsGrid is the container every group of field rows renders into — the\n// top-level form and each nested object/map. In inline mode it owns the single\n// 2-column track definition: `fit-content(labelMaxWidth)` for the label column,\n// `minmax(0, valueMaxWidth)` for the value column. Every field row is a\n// `subgrid` that inherits these tracks, so all labels share one column width and\n// every value lines up — a real form grid, not per-row independent grids.\n// (`fit-content()` is the only valid CSS for \"size to content, clamped to a max\"\n// — `min(w, max-content)` is rejected by the browser, which silently drops the\n// whole declaration and collapses every row to a stacked-looking column. The\n// template is an inline style because Tailwind can't interpolate runtime widths.)\n// Stacked mode is a plain single-column grid.\nexport function FieldsGrid({ layout, size, children }: { layout: FormLayout; size: FormSize; children: ReactNode }) {\n if (layout.mode === \"inline\") {\n const labelMaxWidth = layout.labelMaxWidth ?? \"40ch\";\n const valueMaxWidth = layout.valueMaxWidth ?? \"600px\";\n return (\n <div\n className={cn(\"grid\", inlineRowGapClass[size])}\n style={{ gridTemplateColumns: `fit-content(${labelMaxWidth}) minmax(0, ${valueMaxWidth})` }}\n >\n {children}\n </div>\n );\n }\n return <div className={cn(\"grid\", stackedRowGapClass[size])}>{children}</div>;\n}\n\n// FieldWrapper lays out a single label + value (+ helper/error). In inline mode\n// it is a `subgrid` row spanning the parent FieldsGrid's two columns, so its\n// label and value snap to the shared label/value tracks (helper/error sit under\n// the value column). In stacked mode the label sits tight above its control as\n// one unit, capped at valueMaxWidth so controls don't stretch edge to edge.\nexport function FieldWrapper({\n label,\n value,\n helper,\n error,\n layout,\n size,\n}: {\n label: ReactNode;\n value: ReactNode;\n helper?: ReactNode;\n error?: ReactNode;\n layout: FormLayout;\n size: FormSize;\n}) {\n if (layout.mode === \"inline\") {\n return (\n <div className=\"col-span-2 grid grid-cols-subgrid items-start gap-x-3 gap-y-0.5\">\n <div className={cn(\"flex min-w-0 items-center\", controlMinHeightClass[size])}>{label}</div>\n <div className=\"min-w-0\">{value}</div>\n {helper && <p className=\"col-start-2 text-xs text-muted-foreground\">{helper}</p>}\n {error && <p className=\"col-start-2 text-xs text-destructive\">{error}</p>}\n </div>\n );\n }\n return (\n <div\n className=\"flex w-full flex-col gap-1\"\n style={{ maxWidth: layout.valueMaxWidth ?? \"600px\" }}\n >\n {label}\n {value}\n {helper && <p className=\"text-xs text-muted-foreground\">{helper}</p>}\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n );\n}\n\nexport function FieldLabel({ field, fieldId, size }: { field: FieldControl; fieldId: string; size: FormSize }) {\n return (\n <label htmlFor={fieldId} className={cn(\"flex min-w-0 items-center gap-2 font-medium\", labelSizeClass[size])}>\n <LabelIcon icon={field.labelIcon} className=\"shrink-0 text-[15px] text-muted-foreground\" />\n <span className=\"truncate\" title={field.label !== field.key ? field.key : undefined}>\n {field.label}\n </span>\n {field.required && <span className=\"shrink-0 text-destructive\">*</span>}\n {field.badge && (\n <span className=\"shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {field.badge}\n </span>\n )}\n </label>\n );\n}\n\n// ObjectSection renders a nested object as a labelled section: a header row\n// (the field label + required/badge) above its fields, which fill the full\n// width below. It replaces the inline label + bordered box so nested objects\n// read as flat, headed groups rather than indented sub-forms. `col-span-full`\n// makes it span both tracks of an inline FieldsGrid (full width, not crammed\n// into the value column); in a stacked single-column grid it is a no-op.\nexport function ObjectSection({\n label,\n required,\n size,\n badge,\n helper,\n labelIcon,\n children,\n}: {\n label: string;\n required: boolean;\n size: FormSize;\n badge?: string;\n helper?: string;\n labelIcon?: LabelIconSpec;\n children: ReactNode;\n}) {\n return (\n <div className={cn(\"col-span-full flex flex-col\", fieldInnerGapClass[size])}>\n <div className={cn(\"flex items-center gap-2 border-b border-border pb-1 font-semibold\", labelSizeClass[size])}>\n <LabelIcon icon={labelIcon} className=\"text-[15px] text-muted-foreground\" />\n <span>{label}</span>\n {required && <span className=\"text-destructive\">*</span>}\n {badge && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {badge}\n </span>\n )}\n </div>\n {helper && <p className=\"text-xs text-muted-foreground\">{helper}</p>}\n {children}\n </div>\n );\n}\n\n// ReadOnlyValue renders a `readOnly` field's current value as static text — no\n// input, no border, just the value (date/date-time formatted human-readably).\n// An empty value shows an em-dash. Carries the same id + data-jsf-input as the\n// editable controls so layout and queries stay uniform.\nexport function ReadOnlyValue({ field, fieldId, size }: { field: FieldControl; fieldId: string; size: FormSize }) {\n const text = toText(field.value);\n const display = field.kind === \"date\" && text ? formatDateTimeRelative(text) : text;\n return (\n <span\n id={fieldId}\n data-jsf-input\n data-jsf-readonly\n className={cn(\"flex items-center text-foreground\", controlHeightClass[size], labelSizeClass[size])}\n title={text || undefined}\n >\n {display || <span className=\"text-muted-foreground\">—</span>}\n </span>\n );\n}\n\n// FieldAdornmentWrapper positions a field's leading/trailing in-field adornments\n// (FieldControl.prefix at the left edge, FieldControl.suffix at the right). The\n// container is tagged data-jsf-control so an adornment can locate its sibling\n// input[data-jsf-input] (e.g. for caret-aware insertion). With neither adornment\n// it renders the input bare, so unadorned fields are byte-for-byte unchanged.\nfunction FieldAdornmentWrapper({\n prefix,\n suffix,\n children,\n}: {\n prefix?: ReactNode;\n suffix?: ReactNode;\n children: ReactNode;\n}) {\n if (!prefix && !suffix) return <>{children}</>;\n return (\n <div data-jsf-control className=\"relative\">\n {prefix && <div className=\"absolute inset-y-0 left-1.5 flex items-center\">{prefix}</div>}\n {children}\n {suffix && <div className=\"absolute inset-y-0 right-1.5 flex items-center\">{suffix}</div>}\n </div>\n );\n}\n\nexport function StringControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n return (\n <FieldAdornmentWrapper prefix={field.prefix} suffix={field.suffix}>\n <input\n id={fieldId}\n type=\"text\"\n data-jsf-input\n className={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix && \"pr-8\")}\n value={toText(field.value)}\n disabled={readOnly}\n placeholder={defaultPlaceholder(field.schema)}\n onChange={(e) => field.onChange(e.target.value)}\n />\n </FieldAdornmentWrapper>\n );\n}\n\nexport function NumberControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n // type=\"text\" (not number) so non-numeric values a consumer permits — e.g.\n // template tokens — are not silently dropped by the browser.\n return (\n <FieldAdornmentWrapper prefix={field.prefix} suffix={field.suffix}>\n <input\n id={fieldId}\n type=\"text\"\n inputMode=\"decimal\"\n data-jsf-input\n className={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix && \"pr-8\")}\n value={toText(field.value)}\n disabled={readOnly}\n placeholder={defaultPlaceholder(field.schema)}\n onChange={(e) => {\n const raw = e.target.value;\n const coerce = field.coerceNumber !== false;\n if (coerce && raw.trim() !== \"\" && Number.isFinite(Number(raw))) {\n field.onChange(Number(raw));\n } else {\n field.onChange(raw);\n }\n }}\n />\n </FieldAdornmentWrapper>\n );\n}\n\n// DateControl edits a `format: date`/`date-time` string. Read-only, it shows the\n// human-readable absolute + relative form (e.g. \"Apr 15, 2026, 12:00 PM (2h\n// ago)\"); editable, a DateTimePicker. The raw string is committed unchanged so a\n// consumer-permitted template token in the field is preserved.\nexport function DateControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const text = toText(field.value);\n if (readOnly) {\n return (\n <div\n id={fieldId}\n data-jsf-input\n className={cn(\"flex items-center text-foreground\", controlHeightClass[size], labelSizeClass[size])}\n title={text || undefined}\n >\n {text ? formatDateTimeRelative(text) : <span className=\"text-muted-foreground\">—</span>}\n </div>\n );\n }\n return (\n <DateTimePicker\n id={fieldId}\n aria-label={field.label}\n data-jsf-input\n inputClassName={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix ? \"pr-14\" : \"pr-8\")}\n value={text}\n onChange={(next) => field.onChange(next)}\n placeholder={defaultPlaceholder(field.schema)}\n prefix={field.prefix}\n suffix={field.suffix}\n />\n );\n}\n\nexport function BooleanControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n // Only render a checkbox when the value is genuinely boolean (or unset).\n // A non-boolean value (e.g. a token a consumer left in place) renders as text\n // so it is preserved and editable.\n if (typeof field.value === \"boolean\" || field.value === undefined || field.value === null) {\n return (\n <div className={cn(\"flex items-center\", controlHeightClass[size])}>\n <input\n id={fieldId}\n type=\"checkbox\"\n className=\"h-4 w-4 accent-primary\"\n checked={field.value === true}\n disabled={readOnly}\n onChange={(e) => field.onChange(e.target.checked)}\n />\n </div>\n );\n }\n return <StringControl field={field} fieldId={fieldId} readOnly={readOnly} size={size} />;\n}\n\nexport function EnumControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const value = toText(field.value);\n const options = withSyntheticValue(field.options ?? [], value);\n if (field.display === \"radio\") {\n return (\n <RadioGroupControl field={field} fieldId={fieldId} readOnly={readOnly} options={options} value={value} size={size} />\n );\n }\n return (\n <Combobox\n id={fieldId}\n options={options}\n value={value}\n disabled={readOnly}\n size={size}\n allowCustomValue={field.allowCustomValue ?? false}\n onChange={(v) => field.onChange(v)}\n prefix={field.prefix}\n suffix={field.suffix}\n {...(defaultPlaceholder(field.schema) ? { placeholder: defaultPlaceholder(field.schema) } : {})}\n />\n );\n}\n\n// RadioGroupControl renders a small fixed enum as a segmented radio-button group\n// instead of a dropdown. It shares EnumControl's option list (any out-of-enum\n// value is already prepended, so a token still shows). One `radiogroup` role +\n// native radios keep it keyboard-navigable; the visible chip is a styled label.\nfunction RadioGroupControl({\n field,\n fieldId,\n readOnly,\n options,\n value,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n options: FieldOption[];\n value: string;\n size: FormSize;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={field.label}\n id={fieldId}\n data-jsf-input\n className=\"inline-flex flex-wrap items-center gap-1 rounded-md border border-input bg-background p-0.5\"\n >\n {options.map((opt) => {\n const checked = opt.value === value;\n return (\n <label\n key={opt.value}\n className={cn(\n \"inline-flex cursor-pointer select-none items-center rounded px-2.5 py-1\",\n labelSizeClass[size],\n checked\n ? \"bg-primary text-primary-foreground\"\n : \"text-muted-foreground hover:bg-accent hover:text-foreground\",\n readOnly && \"cursor-not-allowed opacity-60\",\n )}\n >\n <input\n type=\"radio\"\n name={fieldId}\n className=\"sr-only\"\n value={opt.value}\n checked={checked}\n disabled={readOnly}\n onChange={() => field.onChange(opt.value)}\n />\n {opt.label}\n </label>\n );\n })}\n </div>\n );\n}\n\n// HMR probe\n// HMR probe 2\n"],"names":["jsx","cn","inlineRowGapClass","stackedRowGapClass","jsxs","controlMinHeightClass","labelSizeClass","LabelIcon","fieldInnerGapClass","toText","formatDateTimeRelative","controlHeightClass","inputClass","defaultPlaceholder","DateTimePicker","withSyntheticValue","Combobox"],"mappings":"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"}
1
+ {"version":3,"file":"json-schema-form-fields.cjs","sources":["../../src/components/json-schema-form-fields.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { LabelIcon, type LabelIconSpec } from \"../data/Icon\";\nimport { formatDateTimeRelative } from \"../data/cells/timestamp-format\";\nimport { Combobox } from \"./Combobox\";\nimport { DateTimePicker } from \"./DateTimePicker\";\nimport type { FieldControl, FieldOption, FormLayout } from \"./json-schema-form-types\";\nimport {\n defaultPlaceholder,\n inputClass,\n toText,\n withSyntheticValue,\n} from \"./json-schema-form-utils\";\nimport {\n controlHeightClass,\n controlMinHeightClass,\n fieldInnerGapClass,\n inlineRowGapClass,\n labelSizeClass,\n stackedRowGapClass,\n type FormSize,\n} from \"./json-schema-form-size\";\n\n// FieldsGrid is the container every group of field rows renders into — the\n// top-level form and each nested object/map. In inline mode it owns the single\n// 2-column track definition: `fit-content(labelMaxWidth)` for the label column,\n// `minmax(0, valueMaxWidth)` for the value column. Every field row is a\n// `subgrid` that inherits these tracks, so all labels share one column width and\n// every value lines up — a real form grid, not per-row independent grids.\n// (`fit-content()` is the only valid CSS for \"size to content, clamped to a max\"\n// — `min(w, max-content)` is rejected by the browser, which silently drops the\n// whole declaration and collapses every row to a stacked-looking column. The\n// template is an inline style because Tailwind can't interpolate runtime widths.)\n// Stacked mode is a plain single-column grid.\nexport function FieldsGrid({ layout, size, children }: { layout: FormLayout; size: FormSize; children: ReactNode }) {\n if (layout.mode === \"inline\") {\n const labelMaxWidth = layout.labelMaxWidth ?? \"40ch\";\n const valueMaxWidth = layout.valueMaxWidth ?? \"600px\";\n return (\n <div\n className={cn(\"grid\", inlineRowGapClass[size])}\n style={{ gridTemplateColumns: `fit-content(${labelMaxWidth}) minmax(0, ${valueMaxWidth})` }}\n >\n {children}\n </div>\n );\n }\n return <div className={cn(\"grid\", stackedRowGapClass[size])}>{children}</div>;\n}\n\n// FieldWrapper lays out a single label + value (+ helper/error). In inline mode\n// it is a `subgrid` row spanning the parent FieldsGrid's two columns, so its\n// label and value snap to the shared label/value tracks (helper/error sit under\n// the value column). In stacked mode the label sits tight above its control as\n// one unit, capped at valueMaxWidth so controls don't stretch edge to edge.\nexport function FieldWrapper({\n label,\n value,\n helper,\n error,\n layout,\n size,\n}: {\n label: ReactNode;\n value: ReactNode;\n helper?: ReactNode;\n error?: ReactNode;\n layout: FormLayout;\n size: FormSize;\n}) {\n if (layout.mode === \"inline\") {\n return (\n <div className=\"col-span-2 grid grid-cols-subgrid items-start gap-x-3 gap-y-0.5\">\n <div className={cn(\"flex min-w-0 items-center\", controlMinHeightClass[size])}>{label}</div>\n <div className=\"min-w-0\">{value}</div>\n {helper && <p className=\"col-start-2 text-xs text-muted-foreground\">{helper}</p>}\n {error && <p className=\"col-start-2 text-xs text-destructive\">{error}</p>}\n </div>\n );\n }\n return (\n <div\n className=\"flex w-full flex-col gap-1\"\n style={{ maxWidth: layout.valueMaxWidth ?? \"600px\" }}\n >\n {label}\n {value}\n {helper && <p className=\"text-xs text-muted-foreground\">{helper}</p>}\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n );\n}\n\nexport function FieldLabel({ field, fieldId, size }: { field: FieldControl; fieldId: string; size: FormSize }) {\n return (\n <label htmlFor={fieldId} className={cn(\"flex min-w-0 items-center gap-2 font-medium\", labelSizeClass[size])}>\n <LabelIcon icon={field.labelIcon} className=\"shrink-0 text-[15px] text-muted-foreground\" />\n <span className=\"truncate\" title={field.label !== field.key ? field.key : undefined}>\n {field.label}\n </span>\n {field.required && <span className=\"shrink-0 text-destructive\">*</span>}\n {field.badge && (\n <span className=\"shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {field.badge}\n </span>\n )}\n </label>\n );\n}\n\n// ObjectSection renders a nested object as a labelled section: a header row\n// (the field label + required/badge) above its fields, which fill the full\n// width below. It replaces the inline label + bordered box so nested objects\n// read as flat, headed groups rather than indented sub-forms. `col-span-full`\n// makes it span both tracks of an inline FieldsGrid (full width, not crammed\n// into the value column); in a stacked single-column grid it is a no-op.\nexport function ObjectSection({\n label,\n required,\n size,\n badge,\n helper,\n labelIcon,\n children,\n}: {\n label: string;\n required: boolean;\n size: FormSize;\n badge?: string;\n helper?: string;\n labelIcon?: LabelIconSpec;\n children: ReactNode;\n}) {\n return (\n <div className={cn(\"col-span-full flex flex-col\", fieldInnerGapClass[size])}>\n <div className={cn(\"flex items-center gap-2 border-b border-border pb-1 font-semibold\", labelSizeClass[size])}>\n <LabelIcon icon={labelIcon} className=\"text-[15px] text-muted-foreground\" />\n <span>{label}</span>\n {required && <span className=\"text-destructive\">*</span>}\n {badge && (\n <span className=\"rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {badge}\n </span>\n )}\n </div>\n {helper && <p className=\"text-xs text-muted-foreground\">{helper}</p>}\n {children}\n </div>\n );\n}\n\n// ReadOnlyValue renders a `readOnly` field's current value as static text — no\n// input, no border, just the value (date/date-time formatted human-readably).\n// An empty value shows an em-dash. Carries the same id + data-jsf-input as the\n// editable controls so layout and queries stay uniform.\nexport function ReadOnlyValue({ field, fieldId, size }: { field: FieldControl; fieldId: string; size: FormSize }) {\n const text = toText(field.value);\n const display = field.kind === \"date\" && text ? formatDateTimeRelative(text) : text;\n return (\n <span\n id={fieldId}\n data-jsf-input\n data-jsf-readonly\n className={cn(\"flex items-center text-foreground\", controlHeightClass[size], labelSizeClass[size])}\n title={text || undefined}\n >\n {display || <span className=\"text-muted-foreground\">—</span>}\n </span>\n );\n}\n\n// FieldAdornmentWrapper positions a field's leading/trailing in-field adornments\n// (FieldControl.prefix at the left edge, FieldControl.suffix at the right). The\n// container is tagged data-jsf-control so an adornment can locate its sibling\n// input[data-jsf-input] (e.g. for caret-aware insertion). With neither adornment\n// it renders the input bare, so unadorned fields are byte-for-byte unchanged.\nfunction FieldAdornmentWrapper({\n prefix,\n suffix,\n children,\n}: {\n prefix?: ReactNode;\n suffix?: ReactNode;\n children: ReactNode;\n}) {\n if (!prefix && !suffix) return <>{children}</>;\n return (\n <div data-jsf-control className=\"relative\">\n {prefix && <div className=\"absolute inset-y-0 left-1.5 flex items-center\">{prefix}</div>}\n {children}\n {suffix && <div className=\"absolute inset-y-0 right-1.5 flex items-center\">{suffix}</div>}\n </div>\n );\n}\n\nexport function StringControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n return (\n <FieldAdornmentWrapper prefix={field.prefix} suffix={field.suffix}>\n <input\n id={fieldId}\n type=\"text\"\n data-jsf-input\n className={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix && \"pr-8\")}\n value={toText(field.value)}\n disabled={readOnly}\n placeholder={defaultPlaceholder(field.schema)}\n onChange={(e) => field.onChange(e.target.value)}\n />\n </FieldAdornmentWrapper>\n );\n}\n\nexport function NumberControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n // type=\"text\" (not number) so non-numeric values a consumer permits — e.g.\n // template tokens — are not silently dropped by the browser.\n const coerce = field.coerceNumber !== false;\n return (\n <FieldAdornmentWrapper prefix={field.prefix} suffix={field.suffix}>\n <input\n id={fieldId}\n type=\"text\"\n inputMode=\"decimal\"\n data-jsf-input\n className={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix && \"pr-8\")}\n value={toText(field.value)}\n disabled={readOnly}\n placeholder={defaultPlaceholder(field.schema)}\n onChange={(e) => {\n const raw = e.target.value;\n // Coerce mid-typing ONLY when the parse round-trips to the same text\n // (e.g. \"100\", \"33.5\") — so an in-progress decimal like \"33.\" or a\n // trailing-zero \"33.30\" keeps its raw text instead of collapsing to a\n // number and stranding the caret. Non-numeric tokens fall through to\n // the raw string. Blur finalizes any still-uncoerced numeric text.\n if (coerce && raw.trim() !== \"\" && String(Number(raw)) === raw.trim()) {\n field.onChange(Number(raw));\n } else {\n field.onChange(raw);\n }\n }}\n onBlur={(e) => {\n const raw = e.target.value;\n if (coerce && raw.trim() !== \"\" && Number.isFinite(Number(raw))) {\n field.onChange(Number(raw));\n }\n }}\n />\n </FieldAdornmentWrapper>\n );\n}\n\n// DateControl edits a `format: date`/`date-time` string. Read-only, it shows the\n// human-readable absolute + relative form (e.g. \"Apr 15, 2026, 12:00 PM (2h\n// ago)\"); editable, a DateTimePicker. The raw string is committed unchanged so a\n// consumer-permitted template token in the field is preserved.\nexport function DateControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const text = toText(field.value);\n if (readOnly) {\n return (\n <div\n id={fieldId}\n data-jsf-input\n className={cn(\"flex items-center text-foreground\", controlHeightClass[size], labelSizeClass[size])}\n title={text || undefined}\n >\n {text ? formatDateTimeRelative(text) : <span className=\"text-muted-foreground\">—</span>}\n </div>\n );\n }\n return (\n <DateTimePicker\n id={fieldId}\n aria-label={field.label}\n data-jsf-input\n inputClassName={cn(inputClass(size), field.prefix && \"pl-8\", field.suffix ? \"pr-14\" : \"pr-8\")}\n value={text}\n onChange={(next) => field.onChange(next)}\n placeholder={defaultPlaceholder(field.schema)}\n prefix={field.prefix}\n suffix={field.suffix}\n />\n );\n}\n\nexport function BooleanControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n // Only render a checkbox when the value is genuinely boolean (or unset).\n // A non-boolean value (e.g. a token a consumer left in place) renders as text\n // so it is preserved and editable.\n if (typeof field.value === \"boolean\" || field.value === undefined || field.value === null) {\n return (\n <div className={cn(\"flex items-center\", controlHeightClass[size])}>\n <input\n id={fieldId}\n type=\"checkbox\"\n className=\"h-4 w-4 accent-primary\"\n checked={field.value === true}\n disabled={readOnly}\n onChange={(e) => field.onChange(e.target.checked)}\n />\n </div>\n );\n }\n return <StringControl field={field} fieldId={fieldId} readOnly={readOnly} size={size} />;\n}\n\nexport function EnumControl({\n field,\n fieldId,\n readOnly,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n size: FormSize;\n}) {\n const value = toText(field.value);\n const options = withSyntheticValue(field.options ?? [], value);\n if (field.display === \"radio\") {\n return (\n <RadioGroupControl field={field} fieldId={fieldId} readOnly={readOnly} options={options} value={value} size={size} />\n );\n }\n return (\n <Combobox\n id={fieldId}\n options={options}\n value={value}\n disabled={readOnly}\n size={size}\n allowCustomValue={field.allowCustomValue ?? false}\n onChange={(v) => field.onChange(v)}\n prefix={field.prefix}\n suffix={field.suffix}\n {...(defaultPlaceholder(field.schema) ? { placeholder: defaultPlaceholder(field.schema) } : {})}\n />\n );\n}\n\n// RadioGroupControl renders a small fixed enum as a segmented radio-button group\n// instead of a dropdown. It shares EnumControl's option list (any out-of-enum\n// value is already prepended, so a token still shows). One `radiogroup` role +\n// native radios keep it keyboard-navigable; the visible chip is a styled label.\nfunction RadioGroupControl({\n field,\n fieldId,\n readOnly,\n options,\n value,\n size,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n options: FieldOption[];\n value: string;\n size: FormSize;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={field.label}\n id={fieldId}\n data-jsf-input\n className=\"inline-flex flex-wrap items-center gap-1 rounded-md border border-input bg-background p-0.5\"\n >\n {options.map((opt) => {\n const checked = opt.value === value;\n return (\n <label\n key={opt.value}\n className={cn(\n \"inline-flex cursor-pointer select-none items-center rounded px-2.5 py-1\",\n labelSizeClass[size],\n checked\n ? \"bg-primary text-primary-foreground\"\n : \"text-muted-foreground hover:bg-accent hover:text-foreground\",\n readOnly && \"cursor-not-allowed opacity-60\",\n )}\n >\n <input\n type=\"radio\"\n name={fieldId}\n className=\"sr-only\"\n value={opt.value}\n checked={checked}\n disabled={readOnly}\n onChange={() => field.onChange(opt.value)}\n />\n {opt.label}\n </label>\n );\n })}\n </div>\n );\n}\n\n// HMR probe\n// HMR probe 2\n"],"names":["jsx","cn","inlineRowGapClass","stackedRowGapClass","jsxs","controlMinHeightClass","labelSizeClass","LabelIcon","fieldInnerGapClass","toText","formatDateTimeRelative","controlHeightClass","inputClass","defaultPlaceholder","DateTimePicker","withSyntheticValue","Combobox"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-form-fields.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-fields.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"json-schema-form-fields.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-fields.tsx"],"names":[],"mappings":"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"}