@flanksource/clicky-ui 0.2.14 → 0.2.15

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 (461) hide show
  1. package/dist/chat.cjs +20 -0
  2. package/dist/chat.cjs.map +1 -0
  3. package/dist/chat.d.ts +2 -0
  4. package/dist/chat.d.ts.map +1 -0
  5. package/dist/chat.js +20 -0
  6. package/dist/chat.js.map +1 -0
  7. package/dist/components/Combobox.cjs +5 -3
  8. package/dist/components/Combobox.cjs.map +1 -1
  9. package/dist/components/Combobox.d.ts +2 -0
  10. package/dist/components/Combobox.d.ts.map +1 -1
  11. package/dist/components/Combobox.js +5 -3
  12. package/dist/components/Combobox.js.map +1 -1
  13. package/dist/components/DateTimePicker.cjs +3 -1
  14. package/dist/components/DateTimePicker.cjs.map +1 -1
  15. package/dist/components/DateTimePicker.d.ts +5 -1
  16. package/dist/components/DateTimePicker.d.ts.map +1 -1
  17. package/dist/components/DateTimePicker.js +3 -1
  18. package/dist/components/DateTimePicker.js.map +1 -1
  19. package/dist/components/FilterBar.cjs +8 -41
  20. package/dist/components/FilterBar.cjs.map +1 -1
  21. package/dist/components/FilterBar.d.ts +0 -2
  22. package/dist/components/FilterBar.d.ts.map +1 -1
  23. package/dist/components/FilterBar.js +3 -36
  24. package/dist/components/FilterBar.js.map +1 -1
  25. package/dist/components/FormatOptionsDropdown.cjs +2 -18
  26. package/dist/components/FormatOptionsDropdown.cjs.map +1 -1
  27. package/dist/components/FormatOptionsDropdown.d.ts +1 -17
  28. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -1
  29. package/dist/components/FormatOptionsDropdown.js +1 -17
  30. package/dist/components/FormatOptionsDropdown.js.map +1 -1
  31. package/dist/components/JsonSchemaForm.cjs +128 -12
  32. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  33. package/dist/components/JsonSchemaForm.d.ts +1 -1
  34. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  35. package/dist/components/JsonSchemaForm.js +131 -15
  36. package/dist/components/JsonSchemaForm.js.map +1 -1
  37. package/dist/components/SecretKeySelector.cjs +0 -1
  38. package/dist/components/SecretKeySelector.cjs.map +1 -1
  39. package/dist/components/SecretKeySelector.d.ts +0 -2
  40. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  41. package/dist/components/SecretKeySelector.js +1 -2
  42. package/dist/components/SecretKeySelector.js.map +1 -1
  43. package/dist/components/TreePickerField.cjs +137 -0
  44. package/dist/components/TreePickerField.cjs.map +1 -0
  45. package/dist/components/TreePickerField.d.ts +30 -0
  46. package/dist/components/TreePickerField.d.ts.map +1 -0
  47. package/dist/components/TreePickerField.js +137 -0
  48. package/dist/components/TreePickerField.js.map +1 -0
  49. package/dist/components/WorkloadPicker.cjs +6 -81
  50. package/dist/components/WorkloadPicker.cjs.map +1 -1
  51. package/dist/components/WorkloadPicker.d.ts +1 -20
  52. package/dist/components/WorkloadPicker.d.ts.map +1 -1
  53. package/dist/components/WorkloadPicker.js +3 -78
  54. package/dist/components/WorkloadPicker.js.map +1 -1
  55. package/dist/components/button-variants.cjs +30 -0
  56. package/dist/components/button-variants.cjs.map +1 -0
  57. package/dist/components/button-variants.d.ts +5 -0
  58. package/dist/components/button-variants.d.ts.map +1 -0
  59. package/dist/components/button-variants.js +30 -0
  60. package/dist/components/button-variants.js.map +1 -0
  61. package/dist/components/button.cjs +11 -82
  62. package/dist/components/button.cjs.map +1 -1
  63. package/dist/components/button.d.ts +1 -5
  64. package/dist/components/button.d.ts.map +1 -1
  65. package/dist/components/button.js +5 -76
  66. package/dist/components/button.js.map +1 -1
  67. package/dist/components/filter-bar-utils.cjs +37 -0
  68. package/dist/components/filter-bar-utils.cjs.map +1 -0
  69. package/dist/components/filter-bar-utils.d.ts +4 -0
  70. package/dist/components/filter-bar-utils.d.ts.map +1 -0
  71. package/dist/components/filter-bar-utils.js +37 -0
  72. package/dist/components/filter-bar-utils.js.map +1 -0
  73. package/dist/components/format-options.cjs +20 -0
  74. package/dist/components/format-options.cjs.map +1 -0
  75. package/dist/components/format-options.d.ts +18 -0
  76. package/dist/components/format-options.d.ts.map +1 -0
  77. package/dist/components/format-options.js +20 -0
  78. package/dist/components/format-options.js.map +1 -0
  79. package/dist/components/json-schema-form-array.cjs +13 -17
  80. package/dist/components/json-schema-form-array.cjs.map +1 -1
  81. package/dist/components/json-schema-form-array.d.ts +1 -2
  82. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  83. package/dist/components/json-schema-form-array.js +3 -7
  84. package/dist/components/json-schema-form-array.js.map +1 -1
  85. package/dist/components/json-schema-form-fields.cjs +90 -232
  86. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  87. package/dist/components/json-schema-form-fields.d.ts +51 -6
  88. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  89. package/dist/components/json-schema-form-fields.js +82 -224
  90. package/dist/components/json-schema-form-fields.js.map +1 -1
  91. package/dist/components/json-schema-form-object.cjs +149 -0
  92. package/dist/components/json-schema-form-object.cjs.map +1 -0
  93. package/dist/components/json-schema-form-object.d.ts +10 -0
  94. package/dist/components/json-schema-form-object.d.ts.map +1 -0
  95. package/dist/components/json-schema-form-object.js +149 -0
  96. package/dist/components/json-schema-form-object.js.map +1 -0
  97. package/dist/components/json-schema-form-preferences.cjs +41 -0
  98. package/dist/components/json-schema-form-preferences.cjs.map +1 -0
  99. package/dist/components/json-schema-form-preferences.d.ts +10 -0
  100. package/dist/components/json-schema-form-preferences.d.ts.map +1 -0
  101. package/dist/components/json-schema-form-preferences.js +41 -0
  102. package/dist/components/json-schema-form-preferences.js.map +1 -0
  103. package/dist/components/json-schema-form-render.cjs +43 -72
  104. package/dist/components/json-schema-form-render.cjs.map +1 -1
  105. package/dist/components/json-schema-form-render.d.ts +5 -33
  106. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  107. package/dist/components/json-schema-form-render.js +41 -70
  108. package/dist/components/json-schema-form-render.js.map +1 -1
  109. package/dist/components/json-schema-form-resolve.cjs +9 -1
  110. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  111. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  112. package/dist/components/json-schema-form-resolve.js +9 -1
  113. package/dist/components/json-schema-form-resolve.js.map +1 -1
  114. package/dist/components/json-schema-form-types.d.ts +58 -1
  115. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  116. package/dist/components/json-schema-form-utils.cjs +96 -0
  117. package/dist/components/json-schema-form-utils.cjs.map +1 -0
  118. package/dist/components/json-schema-form-utils.d.ts +17 -0
  119. package/dist/components/json-schema-form-utils.d.ts.map +1 -0
  120. package/dist/components/json-schema-form-utils.js +96 -0
  121. package/dist/components/json-schema-form-utils.js.map +1 -0
  122. package/dist/components/loading.cjs +109 -0
  123. package/dist/components/loading.cjs.map +1 -0
  124. package/dist/components/loading.d.ts +27 -0
  125. package/dist/components/loading.d.ts.map +1 -0
  126. package/dist/components/loading.js +109 -0
  127. package/dist/components/loading.js.map +1 -0
  128. package/dist/components/workload-picker-utils.cjs +88 -0
  129. package/dist/components/workload-picker-utils.cjs.map +1 -0
  130. package/dist/components/workload-picker-utils.d.ts +34 -0
  131. package/dist/components/workload-picker-utils.d.ts.map +1 -0
  132. package/dist/components/workload-picker-utils.js +88 -0
  133. package/dist/components/workload-picker-utils.js.map +1 -0
  134. package/dist/components.cjs +18 -6
  135. package/dist/components.cjs.map +1 -1
  136. package/dist/components.d.ts +10 -3
  137. package/dist/components.d.ts.map +1 -1
  138. package/dist/components.js +16 -4
  139. package/dist/components.js.map +1 -1
  140. package/dist/data/Badge.cjs +11 -91
  141. package/dist/data/Badge.cjs.map +1 -1
  142. package/dist/data/Badge.d.ts +1 -5
  143. package/dist/data/Badge.d.ts.map +1 -1
  144. package/dist/data/Badge.js +11 -91
  145. package/dist/data/Badge.js.map +1 -1
  146. package/dist/data/Clicky.cjs +4 -3
  147. package/dist/data/Clicky.cjs.map +1 -1
  148. package/dist/data/Clicky.d.ts.map +1 -1
  149. package/dist/data/Clicky.js +4 -3
  150. package/dist/data/Clicky.js.map +1 -1
  151. package/dist/data/DataTable.cjs +161 -156
  152. package/dist/data/DataTable.cjs.map +1 -1
  153. package/dist/data/DataTable.d.ts +25 -4
  154. package/dist/data/DataTable.d.ts.map +1 -1
  155. package/dist/data/DataTable.js +140 -135
  156. package/dist/data/DataTable.js.map +1 -1
  157. package/dist/data/FilterPill.cjs +3 -0
  158. package/dist/data/FilterPill.cjs.map +1 -1
  159. package/dist/data/FilterPill.d.ts.map +1 -1
  160. package/dist/data/FilterPill.js +3 -0
  161. package/dist/data/FilterPill.js.map +1 -1
  162. package/dist/data/Icon.cjs +7 -7
  163. package/dist/data/Icon.cjs.map +1 -1
  164. package/dist/data/Icon.js +7 -7
  165. package/dist/data/Icon.js.map +1 -1
  166. package/dist/data/LogDetails.cjs +5 -14
  167. package/dist/data/LogDetails.cjs.map +1 -1
  168. package/dist/data/LogDetails.d.ts +8 -4
  169. package/dist/data/LogDetails.d.ts.map +1 -1
  170. package/dist/data/LogDetails.js +4 -13
  171. package/dist/data/LogDetails.js.map +1 -1
  172. package/dist/data/LogsTable.cjs +6 -165
  173. package/dist/data/LogsTable.cjs.map +1 -1
  174. package/dist/data/LogsTable.d.ts +2 -15
  175. package/dist/data/LogsTable.d.ts.map +1 -1
  176. package/dist/data/LogsTable.js +6 -165
  177. package/dist/data/LogsTable.js.map +1 -1
  178. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  179. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  180. package/dist/data/TreeNode.cjs +13 -7
  181. package/dist/data/TreeNode.cjs.map +1 -1
  182. package/dist/data/TreeNode.d.ts.map +1 -1
  183. package/dist/data/TreeNode.js +13 -7
  184. package/dist/data/TreeNode.js.map +1 -1
  185. package/dist/data/badge-variants.cjs +85 -0
  186. package/dist/data/badge-variants.cjs.map +1 -0
  187. package/dist/data/badge-variants.d.ts +6 -0
  188. package/dist/data/badge-variants.d.ts.map +1 -0
  189. package/dist/data/badge-variants.js +85 -0
  190. package/dist/data/badge-variants.js.map +1 -0
  191. package/dist/data/cache-browser/CacheBrowser.cjs +59 -0
  192. package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -0
  193. package/dist/data/cache-browser/CacheBrowser.d.ts +26 -0
  194. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -0
  195. package/dist/data/cache-browser/CacheBrowser.js +59 -0
  196. package/dist/data/cache-browser/CacheBrowser.js.map +1 -0
  197. package/dist/data/cache-browser/CacheDetailPanel.cjs +193 -0
  198. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -0
  199. package/dist/data/cache-browser/CacheDetailPanel.d.ts +20 -0
  200. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -0
  201. package/dist/data/cache-browser/CacheDetailPanel.js +193 -0
  202. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -0
  203. package/dist/data/cache-browser/CacheStatsOverview.cjs +126 -0
  204. package/dist/data/cache-browser/CacheStatsOverview.cjs.map +1 -0
  205. package/dist/data/cache-browser/CacheStatsOverview.d.ts +17 -0
  206. package/dist/data/cache-browser/CacheStatsOverview.d.ts.map +1 -0
  207. package/dist/data/cache-browser/CacheStatsOverview.js +126 -0
  208. package/dist/data/cache-browser/CacheStatsOverview.js.map +1 -0
  209. package/dist/data/cache-browser/CacheTree.cjs +189 -0
  210. package/dist/data/cache-browser/CacheTree.cjs.map +1 -0
  211. package/dist/data/cache-browser/CacheTree.d.ts +27 -0
  212. package/dist/data/cache-browser/CacheTree.d.ts.map +1 -0
  213. package/dist/data/cache-browser/CacheTree.js +189 -0
  214. package/dist/data/cache-browser/CacheTree.js.map +1 -0
  215. package/dist/data/cache-browser/CacheValue.cjs +86 -0
  216. package/dist/data/cache-browser/CacheValue.cjs.map +1 -0
  217. package/dist/data/cache-browser/CacheValue.d.ts +11 -0
  218. package/dist/data/cache-browser/CacheValue.d.ts.map +1 -0
  219. package/dist/data/cache-browser/CacheValue.js +86 -0
  220. package/dist/data/cache-browser/CacheValue.js.map +1 -0
  221. package/dist/data/cache-browser/adapter.cjs +52 -0
  222. package/dist/data/cache-browser/adapter.cjs.map +1 -0
  223. package/dist/data/cache-browser/adapter.d.ts +48 -0
  224. package/dist/data/cache-browser/adapter.d.ts.map +1 -0
  225. package/dist/data/cache-browser/adapter.js +52 -0
  226. package/dist/data/cache-browser/adapter.js.map +1 -0
  227. package/dist/data/cache-browser/api.cjs +42 -0
  228. package/dist/data/cache-browser/api.cjs.map +1 -0
  229. package/dist/data/cache-browser/api.d.ts +33 -0
  230. package/dist/data/cache-browser/api.d.ts.map +1 -0
  231. package/dist/data/cache-browser/api.js +42 -0
  232. package/dist/data/cache-browser/api.js.map +1 -0
  233. package/dist/data/cache-browser/index.d.ts +9 -0
  234. package/dist/data/cache-browser/index.d.ts.map +1 -0
  235. package/dist/data/cache-browser/types.cjs +7 -0
  236. package/dist/data/cache-browser/types.cjs.map +1 -0
  237. package/dist/data/cache-browser/types.d.ts +78 -0
  238. package/dist/data/cache-browser/types.d.ts.map +1 -0
  239. package/dist/data/cache-browser/types.js +7 -0
  240. package/dist/data/cache-browser/types.js.map +1 -0
  241. package/dist/data/cells/TagList.cjs +4 -101
  242. package/dist/data/cells/TagList.cjs.map +1 -1
  243. package/dist/data/cells/TagList.d.ts +1 -49
  244. package/dist/data/cells/TagList.d.ts.map +1 -1
  245. package/dist/data/cells/TagList.js +3 -100
  246. package/dist/data/cells/TagList.js.map +1 -1
  247. package/dist/data/cells/Timestamp.cjs +3 -192
  248. package/dist/data/cells/Timestamp.cjs.map +1 -1
  249. package/dist/data/cells/Timestamp.d.ts +1 -50
  250. package/dist/data/cells/Timestamp.d.ts.map +1 -1
  251. package/dist/data/cells/Timestamp.js +2 -191
  252. package/dist/data/cells/Timestamp.js.map +1 -1
  253. package/dist/data/cells/tag-utils.cjs +103 -0
  254. package/dist/data/cells/tag-utils.cjs.map +1 -0
  255. package/dist/data/cells/tag-utils.d.ts +51 -0
  256. package/dist/data/cells/tag-utils.d.ts.map +1 -0
  257. package/dist/data/cells/tag-utils.js +103 -0
  258. package/dist/data/cells/tag-utils.js.map +1 -0
  259. package/dist/data/cells/timestamp-format.cjs +193 -0
  260. package/dist/data/cells/timestamp-format.cjs.map +1 -0
  261. package/dist/data/cells/timestamp-format.d.ts +51 -0
  262. package/dist/data/cells/timestamp-format.d.ts.map +1 -0
  263. package/dist/data/cells/timestamp-format.js +193 -0
  264. package/dist/data/cells/timestamp-format.js.map +1 -0
  265. package/dist/data/chat/Chat.cjs +48 -0
  266. package/dist/data/chat/Chat.cjs.map +1 -0
  267. package/dist/data/chat/Chat.d.ts +26 -0
  268. package/dist/data/chat/Chat.d.ts.map +1 -0
  269. package/dist/data/chat/Chat.fixtures.d.ts +6 -0
  270. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -0
  271. package/dist/data/chat/Chat.js +48 -0
  272. package/dist/data/chat/Chat.js.map +1 -0
  273. package/dist/data/chat/Conversation.cjs +34 -0
  274. package/dist/data/chat/Conversation.cjs.map +1 -0
  275. package/dist/data/chat/Conversation.d.ts +11 -0
  276. package/dist/data/chat/Conversation.d.ts.map +1 -0
  277. package/dist/data/chat/Conversation.js +34 -0
  278. package/dist/data/chat/Conversation.js.map +1 -0
  279. package/dist/data/chat/Message.cjs +44 -0
  280. package/dist/data/chat/Message.cjs.map +1 -0
  281. package/dist/data/chat/Message.d.ts +10 -0
  282. package/dist/data/chat/Message.d.ts.map +1 -0
  283. package/dist/data/chat/Message.js +44 -0
  284. package/dist/data/chat/Message.js.map +1 -0
  285. package/dist/data/chat/PromptInput.cjs +61 -0
  286. package/dist/data/chat/PromptInput.cjs.map +1 -0
  287. package/dist/data/chat/PromptInput.d.ts +16 -0
  288. package/dist/data/chat/PromptInput.d.ts.map +1 -0
  289. package/dist/data/chat/PromptInput.js +61 -0
  290. package/dist/data/chat/PromptInput.js.map +1 -0
  291. package/dist/data/chat/ToolCall.cjs +92 -0
  292. package/dist/data/chat/ToolCall.cjs.map +1 -0
  293. package/dist/data/chat/ToolCall.d.ts +14 -0
  294. package/dist/data/chat/ToolCall.d.ts.map +1 -0
  295. package/dist/data/chat/ToolCall.js +92 -0
  296. package/dist/data/chat/ToolCall.js.map +1 -0
  297. package/dist/data/chat/clickyOperationsToTools.cjs +73 -0
  298. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -0
  299. package/dist/data/chat/clickyOperationsToTools.d.ts +10 -0
  300. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -0
  301. package/dist/data/chat/clickyOperationsToTools.js +73 -0
  302. package/dist/data/chat/clickyOperationsToTools.js.map +1 -0
  303. package/dist/data/chat/index.d.ts +8 -0
  304. package/dist/data/chat/index.d.ts.map +1 -0
  305. package/dist/data/chat/types.cjs +18 -0
  306. package/dist/data/chat/types.cjs.map +1 -0
  307. package/dist/data/chat/types.d.ts +41 -0
  308. package/dist/data/chat/types.d.ts.map +1 -0
  309. package/dist/data/chat/types.js +18 -0
  310. package/dist/data/chat/types.js.map +1 -0
  311. package/dist/data/data-table-utils.cjs +55 -0
  312. package/dist/data/data-table-utils.cjs.map +1 -0
  313. package/dist/data/data-table-utils.d.ts +24 -0
  314. package/dist/data/data-table-utils.d.ts.map +1 -0
  315. package/dist/data/data-table-utils.js +55 -0
  316. package/dist/data/data-table-utils.js.map +1 -0
  317. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +2 -1
  318. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  319. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  320. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +3 -2
  321. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  322. package/dist/data/diagnostics/GoroutineCard.cjs +3 -22
  323. package/dist/data/diagnostics/GoroutineCard.cjs.map +1 -1
  324. package/dist/data/diagnostics/GoroutineCard.d.ts +0 -2
  325. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -1
  326. package/dist/data/diagnostics/GoroutineCard.js +2 -21
  327. package/dist/data/diagnostics/GoroutineCard.js.map +1 -1
  328. package/dist/data/diagnostics/ThreadCard.cjs +3 -38
  329. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  330. package/dist/data/diagnostics/ThreadCard.d.ts +0 -2
  331. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  332. package/dist/data/diagnostics/ThreadCard.js +2 -37
  333. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  334. package/dist/data/diagnostics/state-styles.cjs +59 -0
  335. package/dist/data/diagnostics/state-styles.cjs.map +1 -0
  336. package/dist/data/diagnostics/state-styles.d.ts +5 -0
  337. package/dist/data/diagnostics/state-styles.d.ts.map +1 -0
  338. package/dist/data/diagnostics/state-styles.js +59 -0
  339. package/dist/data/diagnostics/state-styles.js.map +1 -0
  340. package/dist/data/logs-normalize.cjs +166 -0
  341. package/dist/data/logs-normalize.cjs.map +1 -0
  342. package/dist/data/logs-normalize.d.ts +16 -0
  343. package/dist/data/logs-normalize.d.ts.map +1 -0
  344. package/dist/data/logs-normalize.js +166 -0
  345. package/dist/data/logs-normalize.js.map +1 -0
  346. package/dist/data/task-status.cjs +19 -19
  347. package/dist/data/task-status.cjs.map +1 -1
  348. package/dist/data/task-status.js +19 -19
  349. package/dist/data/task-status.js.map +1 -1
  350. package/dist/data/version-info.cjs +3 -3
  351. package/dist/data/version-info.js +3 -3
  352. package/dist/data.cjs +43 -18
  353. package/dist/data.cjs.map +1 -1
  354. package/dist/data.d.ts +11 -5
  355. package/dist/data.d.ts.map +1 -1
  356. package/dist/data.js +30 -5
  357. package/dist/data.js.map +1 -1
  358. package/dist/hooks/density-provider.cjs +38 -0
  359. package/dist/hooks/density-provider.cjs.map +1 -0
  360. package/dist/hooks/density-provider.d.ts +20 -0
  361. package/dist/hooks/density-provider.d.ts.map +1 -0
  362. package/dist/hooks/density-provider.js +38 -0
  363. package/dist/hooks/density-provider.js.map +1 -0
  364. package/dist/hooks/theme-provider.cjs +43 -0
  365. package/dist/hooks/theme-provider.cjs.map +1 -0
  366. package/dist/hooks/theme-provider.d.ts +9 -0
  367. package/dist/hooks/theme-provider.d.ts.map +1 -0
  368. package/dist/hooks/theme-provider.js +43 -0
  369. package/dist/hooks/theme-provider.js.map +1 -0
  370. package/dist/hooks/use-density.cjs +8 -37
  371. package/dist/hooks/use-density.cjs.map +1 -1
  372. package/dist/hooks/use-density.d.ts +5 -20
  373. package/dist/hooks/use-density.d.ts.map +1 -1
  374. package/dist/hooks/use-density.js +9 -38
  375. package/dist/hooks/use-density.js.map +1 -1
  376. package/dist/hooks/use-theme.cjs +10 -43
  377. package/dist/hooks/use-theme.cjs.map +1 -1
  378. package/dist/hooks/use-theme.d.ts +6 -9
  379. package/dist/hooks/use-theme.d.ts.map +1 -1
  380. package/dist/hooks/use-theme.js +11 -44
  381. package/dist/hooks/use-theme.js.map +1 -1
  382. package/dist/hooks.cjs +5 -2
  383. package/dist/hooks.cjs.map +1 -1
  384. package/dist/hooks.d.ts +4 -2
  385. package/dist/hooks.d.ts.map +1 -1
  386. package/dist/hooks.js +5 -2
  387. package/dist/hooks.js.map +1 -1
  388. package/dist/icons/changeIconAliases.cjs +13 -13
  389. package/dist/icons/changeIconAliases.cjs.map +1 -1
  390. package/dist/icons/changeIconAliases.d.ts.map +1 -1
  391. package/dist/icons/changeIconAliases.js +13 -13
  392. package/dist/icons/changeIconAliases.js.map +1 -1
  393. package/dist/index.cjs +71 -30
  394. package/dist/index.cjs.map +1 -1
  395. package/dist/index.js +53 -12
  396. package/dist/index.js.map +1 -1
  397. package/dist/overlay/DropdownMenu.cjs +2 -0
  398. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  399. package/dist/overlay/DropdownMenu.d.ts +3 -1
  400. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  401. package/dist/overlay/DropdownMenu.js +2 -0
  402. package/dist/overlay/DropdownMenu.js.map +1 -1
  403. package/dist/overlay/Modal.cjs +11 -4
  404. package/dist/overlay/Modal.cjs.map +1 -1
  405. package/dist/overlay/Modal.d.ts +1 -1
  406. package/dist/overlay/Modal.d.ts.map +1 -1
  407. package/dist/overlay/Modal.js +11 -4
  408. package/dist/overlay/Modal.js.map +1 -1
  409. package/dist/overlay/modalStack.cjs +35 -0
  410. package/dist/overlay/modalStack.cjs.map +1 -0
  411. package/dist/overlay/modalStack.d.ts +13 -0
  412. package/dist/overlay/modalStack.d.ts.map +1 -0
  413. package/dist/overlay/modalStack.js +35 -0
  414. package/dist/overlay/modalStack.js.map +1 -0
  415. package/dist/rpc/AcceptPicker.cjs +2 -18
  416. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  417. package/dist/rpc/AcceptPicker.d.ts +1 -41
  418. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  419. package/dist/rpc/AcceptPicker.js +2 -18
  420. package/dist/rpc/AcceptPicker.js.map +1 -1
  421. package/dist/rpc/CommandOutput.cjs +1 -1
  422. package/dist/rpc/CommandOutput.cjs.map +1 -1
  423. package/dist/rpc/CommandOutput.js +1 -1
  424. package/dist/rpc/CommandOutput.js.map +1 -1
  425. package/dist/rpc/EndpointList.cjs +1 -1
  426. package/dist/rpc/EndpointList.cjs.map +1 -1
  427. package/dist/rpc/EndpointList.js +1 -1
  428. package/dist/rpc/EndpointList.js.map +1 -1
  429. package/dist/rpc/OperationCatalog.cjs +23 -41
  430. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  431. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  432. package/dist/rpc/OperationCatalog.js +24 -42
  433. package/dist/rpc/OperationCatalog.js.map +1 -1
  434. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  435. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  436. package/dist/rpc/OperationCommandPage.js.map +1 -1
  437. package/dist/rpc/accept-options.cjs +20 -0
  438. package/dist/rpc/accept-options.cjs.map +1 -0
  439. package/dist/rpc/accept-options.d.ts +42 -0
  440. package/dist/rpc/accept-options.d.ts.map +1 -0
  441. package/dist/rpc/accept-options.js +20 -0
  442. package/dist/rpc/accept-options.js.map +1 -0
  443. package/dist/rpc/classify.cjs +15 -4
  444. package/dist/rpc/classify.cjs.map +1 -1
  445. package/dist/rpc/classify.d.ts.map +1 -1
  446. package/dist/rpc/classify.js +15 -4
  447. package/dist/rpc/classify.js.map +1 -1
  448. package/dist/rpc/clickyMetadata.cjs +13 -3
  449. package/dist/rpc/clickyMetadata.cjs.map +1 -1
  450. package/dist/rpc/clickyMetadata.d.ts +2 -0
  451. package/dist/rpc/clickyMetadata.d.ts.map +1 -1
  452. package/dist/rpc/clickyMetadata.js +14 -4
  453. package/dist/rpc/clickyMetadata.js.map +1 -1
  454. package/dist/rpc.cjs +3 -2
  455. package/dist/rpc.cjs.map +1 -1
  456. package/dist/rpc.d.ts +2 -1
  457. package/dist/rpc.d.ts.map +1 -1
  458. package/dist/rpc.js +2 -1
  459. package/dist/rpc.js.map +1 -1
  460. package/dist/styles.css +1 -1
  461. package/package.json +16 -1
@@ -0,0 +1,78 @@
1
+ /** One entry in a tree level: a prefix group or a leaf key. */
2
+ export type CacheTreeNode = {
3
+ /** Display segment: the next path segment for groups, the key tail for leaves. */
4
+ name: string;
5
+ /** Group nodes only: full logical prefix including the trailing separator. */
6
+ prefix?: string;
7
+ /** Leaf nodes only: the full logical key. */
8
+ key?: string;
9
+ /** Total keys under this node (1 for a leaf). */
10
+ keys: number;
11
+ /** Group nodes: number of distinct child segments. */
12
+ children?: number;
13
+ /** Leaf value type: string | hash | list | set | zset | stream. */
14
+ type?: string;
15
+ /** Leaf TTL in seconds; -1 means no expiry. */
16
+ ttlSeconds?: number;
17
+ /**
18
+ * MEMORY USAGE when the server supports it: a leaf's own size, or for a
19
+ * group the aggregated size of every key beneath it.
20
+ */
21
+ bytes?: number;
22
+ };
23
+ export type CacheTreeResponse = {
24
+ prefix: string;
25
+ nodes: CacheTreeNode[];
26
+ /** Total keys scanned under prefix, including keys inside group nodes. */
27
+ keys: number;
28
+ /** Node list or scan hit a cap; counts are lower bounds. */
29
+ truncated?: boolean;
30
+ /** Whether per-key byte sizes were available (MEMORY USAGE). */
31
+ bytesSupported: boolean;
32
+ };
33
+ export type CacheScoredMember = {
34
+ member: string;
35
+ score: number;
36
+ };
37
+ /** Full detail for one key. Exactly one value field is set, per `type`. */
38
+ export type CacheKeyDetail = {
39
+ key: string;
40
+ type: string;
41
+ ttlSeconds: number;
42
+ bytes?: number;
43
+ /** Full value length: STRLEN, HLEN, LLEN, SCARD or ZCARD. */
44
+ length: number;
45
+ value?: string;
46
+ fields?: Record<string, string>;
47
+ items?: string[];
48
+ members?: CacheScoredMember[];
49
+ /** The returned value was capped; `length` still reports the full size. */
50
+ truncated?: boolean;
51
+ };
52
+ export type CacheSearchResponse = {
53
+ keys: CacheTreeNode[];
54
+ truncated?: boolean;
55
+ };
56
+ export type CacheStats = {
57
+ keys: number;
58
+ keysTruncated?: boolean;
59
+ usedMemoryBytes?: number;
60
+ maxMemoryBytes?: number;
61
+ hits?: number;
62
+ misses?: number;
63
+ evictedKeys?: number;
64
+ expiredKeys?: number;
65
+ connectedClients?: number;
66
+ version?: string;
67
+ uptimeSeconds?: number;
68
+ /** Set when the backend's INFO failed; server fields above are then absent. */
69
+ infoError?: string;
70
+ };
71
+ export type CacheDeleteResponse = {
72
+ deleted: number;
73
+ };
74
+ /** True when the node is a leaf key (vs a prefix group). */
75
+ export declare function isLeaf(node: CacheTreeNode): node is CacheTreeNode & {
76
+ key: string;
77
+ };
78
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/data/cache-browser/types.ts"],"names":[],"mappings":"AAIA,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAC1B,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAEnF"}
@@ -0,0 +1,7 @@
1
+ function isLeaf(node) {
2
+ return node.key !== void 0 && node.key !== "";
3
+ }
4
+ export {
5
+ isLeaf
6
+ };
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":["../../../src/data/cache-browser/types.ts"],"sourcesContent":["// Wire types for clicky's generic cache-browser API\n// (github.com/flanksource/clicky/cache). Field names match the Go JSON tags\n// exactly.\n\n/** One entry in a tree level: a prefix group or a leaf key. */\nexport type CacheTreeNode = {\n /** Display segment: the next path segment for groups, the key tail for leaves. */\n name: string;\n /** Group nodes only: full logical prefix including the trailing separator. */\n prefix?: string;\n /** Leaf nodes only: the full logical key. */\n key?: string;\n /** Total keys under this node (1 for a leaf). */\n keys: number;\n /** Group nodes: number of distinct child segments. */\n children?: number;\n /** Leaf value type: string | hash | list | set | zset | stream. */\n type?: string;\n /** Leaf TTL in seconds; -1 means no expiry. */\n ttlSeconds?: number;\n /**\n * MEMORY USAGE when the server supports it: a leaf's own size, or for a\n * group the aggregated size of every key beneath it.\n */\n bytes?: number;\n};\n\nexport type CacheTreeResponse = {\n prefix: string;\n nodes: CacheTreeNode[];\n /** Total keys scanned under prefix, including keys inside group nodes. */\n keys: number;\n /** Node list or scan hit a cap; counts are lower bounds. */\n truncated?: boolean;\n /** Whether per-key byte sizes were available (MEMORY USAGE). */\n bytesSupported: boolean;\n};\n\nexport type CacheScoredMember = {\n member: string;\n score: number;\n};\n\n/** Full detail for one key. Exactly one value field is set, per `type`. */\nexport type CacheKeyDetail = {\n key: string;\n type: string;\n ttlSeconds: number;\n bytes?: number;\n /** Full value length: STRLEN, HLEN, LLEN, SCARD or ZCARD. */\n length: number;\n value?: string;\n fields?: Record<string, string>;\n items?: string[];\n members?: CacheScoredMember[];\n /** The returned value was capped; `length` still reports the full size. */\n truncated?: boolean;\n};\n\nexport type CacheSearchResponse = {\n keys: CacheTreeNode[];\n truncated?: boolean;\n};\n\nexport type CacheStats = {\n keys: number;\n keysTruncated?: boolean;\n usedMemoryBytes?: number;\n maxMemoryBytes?: number;\n hits?: number;\n misses?: number;\n evictedKeys?: number;\n expiredKeys?: number;\n connectedClients?: number;\n version?: string;\n uptimeSeconds?: number;\n /** Set when the backend's INFO failed; server fields above are then absent. */\n infoError?: string;\n};\n\nexport type CacheDeleteResponse = {\n deleted: number;\n};\n\n/** True when the node is a leaf key (vs a prefix group). */\nexport function isLeaf(node: CacheTreeNode): node is CacheTreeNode & { key: string } {\n return node.key !== undefined && node.key !== \"\";\n}\n"],"names":[],"mappings":"AAqFO,SAAS,OAAO,MAA8D;AACnF,SAAO,KAAK,QAAQ,UAAa,KAAK,QAAQ;AAChD;"}
@@ -8,86 +8,15 @@ const Icon = require("../Icon.cjs");
8
8
  const Properties = require("../Properties.cjs");
9
9
  const useDensity = require("../../hooks/use-density.cjs");
10
10
  const utils = require("../../lib/utils.cjs");
11
+ const tagUtils = require("./tag-utils.cjs");
11
12
  const UiZoomIn = require("../../icons/components/UiZoomIn.cjs");
12
13
  const UiZoomOut = require("../../icons/components/UiZoomOut.cjs");
13
14
  const UiCopy = require("../../icons/components/UiCopy.cjs");
14
- function normalizeTags(value, separator = "=") {
15
- if (value == null) return [];
16
- if (Array.isArray(value)) {
17
- return value.map((entry) => normalizeOne(entry, separator)).filter((tag) => tag.value !== "");
18
- }
19
- if (typeof value === "object") {
20
- return Object.entries(value).map(([key, raw]) => {
21
- if (raw == null) return null;
22
- const valueStr = String(raw).trim();
23
- if (!valueStr) return null;
24
- return {
25
- key,
26
- value: valueStr,
27
- display: `${key}${separator}${valueStr}`,
28
- token: `${key}${separator}${valueStr}`
29
- };
30
- }).filter((tag) => tag !== null);
31
- }
32
- return [];
33
- }
34
- function normalizeOne(entry, separator) {
35
- if (typeof entry === "string") {
36
- const trimmed = entry.trim();
37
- const eq = trimmed.indexOf("=");
38
- const colon = trimmed.indexOf(":");
39
- const splitAt = eq >= 0 && (colon < 0 || eq < colon) ? eq : colon >= 0 && colon < trimmed.length - 1 ? colon : -1;
40
- if (splitAt > 0) {
41
- const key2 = trimmed.slice(0, splitAt);
42
- const value2 = trimmed.slice(splitAt + 1);
43
- return {
44
- key: key2,
45
- value: value2,
46
- display: `${key2}${separator}${value2}`,
47
- token: `${key2}${separator}${value2}`
48
- };
49
- }
50
- return { value: trimmed, display: trimmed, token: trimmed };
51
- }
52
- const key = "key" in entry && typeof entry.key === "string" ? entry.key : "name" in entry && typeof entry.name === "string" ? entry.name : void 0;
53
- const value = String(entry.value ?? "").trim();
54
- if (key) {
55
- return {
56
- key,
57
- value,
58
- display: `${key}${separator}${value}`,
59
- token: `${key}${separator}${value}`
60
- };
61
- }
62
- return { value, display: value, token: value };
63
- }
64
- function tagFilterTokens(value, separator = "=") {
65
- return normalizeTags(value, separator).map((tag) => tag.token);
66
- }
67
- function splitTagToken(token, separator = "=") {
68
- const idx = token.indexOf(separator);
69
- if (idx <= 0) return { key: "", value: token };
70
- return {
71
- key: token.slice(0, idx),
72
- value: token.slice(idx + separator.length)
73
- };
74
- }
75
- const noop = {
76
- getMode: () => "neutral",
77
- toggleInclude: () => {
78
- },
79
- toggleExclude: () => {
80
- }
81
- };
82
- const TagActionsContext = react.createContext(noop);
83
15
  function TagActionsProvider({
84
16
  value,
85
17
  children
86
18
  }) {
87
- return /* @__PURE__ */ jsxRuntime.jsx(TagActionsContext.Provider, { value, children });
88
- }
89
- function useTagActions() {
90
- return react.useContext(TagActionsContext);
19
+ return /* @__PURE__ */ jsxRuntime.jsx(tagUtils.TagActionsContext.Provider, { value, children });
91
20
  }
92
21
  function copyToClipboard(text) {
93
22
  var _a;
@@ -100,7 +29,7 @@ function TagBadge({
100
29
  actions: actionMode,
101
30
  compact = false
102
31
  }) {
103
- const actions = useTagActions();
32
+ const actions = tagUtils.useTagActions();
104
33
  const mode = actions.getMode(tag.token);
105
34
  const onPlus = react.useCallback(
106
35
  (event) => {
@@ -279,7 +208,7 @@ function TagPropertiesList({
279
208
  tags,
280
209
  rowClassName = "grid-cols-[minmax(4rem,8rem)_minmax(0,1fr)]"
281
210
  }) {
282
- const tagActions = useTagActions();
211
+ const tagActions = tagUtils.useTagActions();
283
212
  const items = react.useMemo(
284
213
  () => tags.map((tag, index) => ({ key: `${tag.token}-${index}`, value: tag })),
285
214
  [tags]
@@ -316,33 +245,7 @@ function TagPropertiesList({
316
245
  }
317
246
  );
318
247
  }
319
- function tagActionsFromRecord(value, onChange) {
320
- return {
321
- getMode: (token) => value[token] ?? "neutral",
322
- toggleInclude: (token) => {
323
- const next = { ...value };
324
- if (next[token] === "include") delete next[token];
325
- else next[token] = "include";
326
- onChange(next);
327
- },
328
- toggleExclude: (token) => {
329
- const next = { ...value };
330
- if (next[token] === "exclude") delete next[token];
331
- else next[token] = "exclude";
332
- onChange(next);
333
- }
334
- };
335
- }
336
- function useTagActionsValue(value, onChange) {
337
- return react.useMemo(() => tagActionsFromRecord(value, onChange), [value, onChange]);
338
- }
339
248
  exports.TagActionsProvider = TagActionsProvider;
340
249
  exports.TagList = TagList;
341
250
  exports.TagPropertiesList = TagPropertiesList;
342
- exports.normalizeTags = normalizeTags;
343
- exports.splitTagToken = splitTagToken;
344
- exports.tagActionsFromRecord = tagActionsFromRecord;
345
- exports.tagFilterTokens = tagFilterTokens;
346
- exports.useTagActions = useTagActions;
347
- exports.useTagActionsValue = useTagActionsValue;
348
251
  //# sourceMappingURL=TagList.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TagList.cjs","sources":["../../../src/data/cells/TagList.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo } from \"react\";\nimport { Badge } from \"../Badge\";\nimport { HoverCard } from \"../../overlay/HoverCard\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport { Properties, type PropertiesItem } from \"../Properties\";\nimport { UiCopy, UiZoomIn, UiZoomOut } from \"../../icons\";\nimport { useDensityValue } from \"../../hooks/use-density\";\nimport { cn } from \"../../lib/utils\";\nimport type { FilterMode } from \"../FilterPill\";\n\nexport type TagInput = string | { key: string; value: string } | { name: string; value: string };\n\nexport type NormalizedTag = {\n key?: string;\n value: string;\n display: string;\n token: string;\n};\n\nexport type TagsValue =\n | TagInput[]\n | Record<string, string | number | boolean | null>\n | null\n | undefined;\n\nexport type TagsOptions = {\n /** Number of tags to show inline before using the `+N` overflow popover. */\n maxVisible?: number;\n /** Separator between tag keys and values. Defaults to `=`. */\n separator?: string;\n};\n\nexport function normalizeTags(value: TagsValue, separator = \"=\"): NormalizedTag[] {\n if (value == null) return [];\n\n if (Array.isArray(value)) {\n return value.map((entry) => normalizeOne(entry, separator)).filter((tag) => tag.value !== \"\");\n }\n\n if (typeof value === \"object\") {\n return Object.entries(value)\n .map(([key, raw]): NormalizedTag | null => {\n if (raw == null) return null;\n const valueStr = String(raw).trim();\n if (!valueStr) return null;\n return {\n key,\n value: valueStr,\n display: `${key}${separator}${valueStr}`,\n token: `${key}${separator}${valueStr}`,\n } satisfies NormalizedTag;\n })\n .filter((tag): tag is NormalizedTag => tag !== null);\n }\n\n return [];\n}\n\nfunction normalizeOne(entry: TagInput, separator: string): NormalizedTag {\n if (typeof entry === \"string\") {\n const trimmed = entry.trim();\n const eq = trimmed.indexOf(\"=\");\n const colon = trimmed.indexOf(\":\");\n const splitAt =\n eq >= 0 && (colon < 0 || eq < colon)\n ? eq\n : colon >= 0 && colon < trimmed.length - 1\n ? colon\n : -1;\n\n if (splitAt > 0) {\n const key = trimmed.slice(0, splitAt);\n const value = trimmed.slice(splitAt + 1);\n return {\n key,\n value,\n display: `${key}${separator}${value}`,\n token: `${key}${separator}${value}`,\n };\n }\n\n return { value: trimmed, display: trimmed, token: trimmed };\n }\n\n const key =\n \"key\" in entry && typeof entry.key === \"string\"\n ? entry.key\n : \"name\" in entry && typeof entry.name === \"string\"\n ? entry.name\n : undefined;\n const value = String(entry.value ?? \"\").trim();\n\n if (key) {\n return {\n key,\n value,\n display: `${key}${separator}${value}`,\n token: `${key}${separator}${value}`,\n };\n }\n return { value, display: value, token: value };\n}\n\nexport function tagFilterTokens(value: TagsValue, separator = \"=\"): string[] {\n return normalizeTags(value, separator).map((tag) => tag.token);\n}\n\n/**\n * Splits a token previously produced by `normalizeTags`/`tagFilterTokens`\n * back into its key and value parts using the same separator. Tokens\n * without a separator (bare tags) return `{ key: \"\", value: token }`.\n */\nexport function splitTagToken(token: string, separator = \"=\"): { key: string; value: string } {\n const idx = token.indexOf(separator);\n if (idx <= 0) return { key: \"\", value: token };\n return {\n key: token.slice(0, idx),\n value: token.slice(idx + separator.length),\n };\n}\n\n// Filter mode mapping (re-using FilterPill's tri-state vocabulary so the wire\n// shape matches DataTable's existing multiFilters state).\nexport type TagFilterMode = Extract<FilterMode, \"include\" | \"exclude\">;\n\nexport type TagActionsContextValue = {\n /** Returns the current mode for a token; \"neutral\" if the user hasn't acted on it. */\n getMode: (token: string) => FilterMode;\n /** Toggle include for this token (off → include → off). */\n toggleInclude: (token: string) => void;\n /** Toggle exclude for this token (off → exclude → off). */\n toggleExclude: (token: string) => void;\n};\n\nconst noop: TagActionsContextValue = {\n getMode: () => \"neutral\",\n toggleInclude: () => {},\n toggleExclude: () => {},\n};\n\nconst TagActionsContext = createContext<TagActionsContextValue>(noop);\n\nexport function TagActionsProvider({\n value,\n children,\n}: {\n value: TagActionsContextValue;\n children: React.ReactNode;\n}) {\n return <TagActionsContext.Provider value={value}>{children}</TagActionsContext.Provider>;\n}\n\nexport function useTagActions(): TagActionsContextValue {\n return useContext(TagActionsContext);\n}\n\nexport type TagListProps = {\n /** Normalized tags to render. */\n tags: NormalizedTag[];\n /** Number of tags to show inline before the overflow popover. */\n maxVisible?: number;\n /** Classes applied to the tag row. */\n className?: string;\n /** Whether copy/zoom actions appear on hover or inline. */\n actions?: \"hover\" | \"inline\";\n /**\n * When `true`, visible tag badges render only their value — the key is\n * dropped from the inline display. The full `key=value` text is still\n * available in `tag.display` (used for tooltips, copy actions, and the\n * overflow `+N` popover). Defaults to whether the surrounding density\n * (via {@link useDensityValue}) is `\"compact\"`.\n */\n compact?: boolean;\n /**\n * When `true`, tag badges wrap onto multiple lines instead of staying on a\n * single row with a `+N` overflow popover. Used by detail/expanded views\n * (e.g. LogsTable row details) where vertical space is available.\n */\n wrap?: boolean;\n};\n\nfunction copyToClipboard(text: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(text).catch(() => undefined);\n }\n}\n\nfunction TagBadge({\n tag,\n actions: actionMode,\n compact = false,\n}: {\n tag: NormalizedTag;\n actions: \"hover\" | \"inline\";\n compact?: boolean;\n}) {\n const actions = useTagActions();\n const mode = actions.getMode(tag.token);\n\n const onPlus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleInclude(tag.token);\n },\n [actions, tag.token],\n );\n const onMinus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleExclude(tag.token);\n },\n [actions, tag.token],\n );\n const onCopy = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n copyToClipboard(tag.value);\n },\n [tag.value],\n );\n\n // Active state colors mirror FilterPill: include = green, exclude = red.\n const includeActive = mode === \"include\";\n const excludeActive = mode === \"exclude\";\n\n const showTooltip = compact && !!tag.key;\n const badge = (\n <span\n {...(showTooltip ? { title: tag.display } : {})}\n className={cn(\n \"inline-flex items-center rounded-md border bg-background align-middle\",\n includeActive\n ? \"border-green-500/50 bg-green-500/5\"\n : excludeActive\n ? \"border-red-500/50 bg-red-500/5\"\n : \"border-border\",\n )}\n >\n {tag.key && !compact ? (\n <Badge\n size=\"xs\"\n variant=\"label\"\n tone=\"neutral\"\n label={tag.key}\n value={tag.value}\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n className=\"border-transparent shadow-none\"\n />\n ) : (\n <Badge\n size=\"xs\"\n variant=\"soft\"\n tone=\"neutral\"\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n >\n {tag.value}\n </Badge>\n )}\n </span>\n );\n\n const toolbar = (\n <span className=\"inline-flex items-center gap-0.5\">\n <TagActionButton\n ariaLabel={`Include ${tag.display}`}\n onClick={onPlus}\n active={includeActive}\n activeClassName=\"bg-green-500/20 text-green-700 dark:text-green-400\"\n icon={UiZoomIn}\n />\n <TagActionButton\n ariaLabel={`Exclude ${tag.display}`}\n onClick={onMinus}\n active={excludeActive}\n activeClassName=\"bg-red-500/20 text-red-700 dark:text-red-400\"\n icon={UiZoomOut}\n />\n <TagActionButton ariaLabel={`Copy ${tag.display}`} onClick={onCopy} icon={UiCopy} />\n </span>\n );\n\n if (actionMode === \"inline\") {\n return (\n <span className=\"inline-flex items-center gap-0.5 rounded-md border border-border bg-background pr-0.5\">\n {badge}\n {toolbar}\n </span>\n );\n }\n\n // Action icons live in a hover popover above the tag — the cell stays\n // clean, and hovering reveals the magnifier-plus / magnifier-minus / copy\n // toolbar.\n return (\n <HoverCard placement=\"top\" delay={120} arrow={false} trigger={badge} cardClassName=\"!p-1\">\n {toolbar}\n </HoverCard>\n );\n}\n\nfunction TagActionButton({\n ariaLabel,\n onClick,\n active,\n activeClassName,\n icon,\n}: {\n ariaLabel: string;\n onClick: (event: React.MouseEvent) => void;\n active?: boolean;\n activeClassName?: string;\n icon: StaticIconComponent;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={onClick}\n className={cn(\n \"inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground\",\n \"hover:bg-accent hover:text-foreground\",\n active && activeClassName,\n )}\n >\n <Icon icon={icon} className=\"text-xs\" />\n </button>\n );\n}\n\nexport function TagList({\n tags,\n maxVisible = 3,\n className,\n actions = \"hover\",\n compact,\n wrap = false,\n}: TagListProps) {\n const density = useDensityValue();\n const isCompact = compact ?? density === \"compact\";\n\n if (tags.length === 0) {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n if (wrap) {\n return (\n <span className={cn(\"flex min-w-0 flex-wrap items-center gap-1\", className)}>\n {tags.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n );\n }\n\n const visible = tags.slice(0, maxVisible);\n const overflow = tags.slice(maxVisible);\n\n return (\n <span className={cn(\"flex min-w-0 items-center gap-1\", className)}>\n <span className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-hidden\">\n {visible.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n {overflow.length > 0 && (\n <HoverCard\n placement=\"top\"\n trigger={\n <Badge\n size=\"xs\"\n variant=\"outlined\"\n tone=\"neutral\"\n clickToCopy={false}\n className=\"shrink-0\"\n >\n +{overflow.length}\n </Badge>\n }\n cardClassName=\"min-w-72 max-w-[90vw] whitespace-normal !p-0\"\n >\n <TagPropertiesList tags={overflow} />\n </HoverCard>\n )}\n </span>\n );\n}\n\nexport function TagPropertiesList({\n tags,\n rowClassName = \"grid-cols-[minmax(4rem,8rem)_minmax(0,1fr)]\",\n}: {\n tags: NormalizedTag[];\n rowClassName?: string;\n}) {\n const tagActions = useTagActions();\n const items = useMemo<PropertiesItem<NormalizedTag>[]>(\n () => tags.map((tag, index) => ({ key: `${tag.token}-${index}`, value: tag })),\n [tags],\n );\n\n return (\n <Properties<NormalizedTag>\n items={items}\n density=\"compact\"\n className=\"border-0 bg-transparent\"\n rowClassName={rowClassName}\n renderLabel={(_key, tag) =>\n tag.key ? (\n <span className=\"font-mono\">{tag.key}</span>\n ) : (\n <span className=\"italic text-muted-foreground\">tag</span>\n )\n }\n renderValue={(_key, tag) => (\n <span className=\"block truncate font-mono\" title={tag.value}>\n {tag.value}\n </span>\n )}\n suffixActions={[\n {\n id: \"include\",\n icon: UiZoomIn,\n label: (_key, tag) => `Include ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleInclude(tag.token),\n },\n {\n id: \"exclude\",\n icon: UiZoomOut,\n label: (_key, tag) => `Exclude ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleExclude(tag.token),\n },\n {\n id: \"copy\",\n icon: UiCopy,\n label: (_key, tag) => `Copy ${tag.display}`,\n onClick: (_key, tag) => copyToClipboard(tag.value),\n },\n ]}\n />\n );\n}\n\n/**\n * Builds a TagActionsContextValue from a flat record-of-modes (the same\n * shape used by FilterBar's multi/nested-multi filters). Useful when\n * connecting DataTable's multiFilters state to the in-cell + / − buttons.\n */\nexport function tagActionsFromRecord(\n value: Record<string, TagFilterMode>,\n onChange: (next: Record<string, TagFilterMode>) => void,\n): TagActionsContextValue {\n return {\n getMode: (token) => value[token] ?? \"neutral\",\n toggleInclude: (token) => {\n const next = { ...value };\n if (next[token] === \"include\") delete next[token];\n else next[token] = \"include\";\n onChange(next);\n },\n toggleExclude: (token) => {\n const next = { ...value };\n if (next[token] === \"exclude\") delete next[token];\n else next[token] = \"exclude\";\n onChange(next);\n },\n };\n}\n\n// Memoizing the context value avoids re-rendering every TagList cell on\n// unrelated state changes.\nexport function useTagActionsValue(\n value: Record<string, TagFilterMode>,\n onChange: (next: Record<string, TagFilterMode>) => void,\n): TagActionsContextValue {\n return useMemo(() => tagActionsFromRecord(value, onChange), [value, onChange]);\n}\n"],"names":["key","value","createContext","jsx","useContext","useCallback","cn","Badge","jsxs","UiZoomIn","UiZoomOut","UiCopy","HoverCard","Icon","useDensityValue","useMemo","Properties"],"mappings":"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"}
1
+ {"version":3,"file":"TagList.cjs","sources":["../../../src/data/cells/TagList.tsx"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { Badge } from \"../Badge\";\nimport { HoverCard } from \"../../overlay/HoverCard\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport { Properties, type PropertiesItem } from \"../Properties\";\nimport { UiCopy, UiZoomIn, UiZoomOut } from \"../../icons\";\nimport { useDensityValue } from \"../../hooks/use-density\";\nimport { cn } from \"../../lib/utils\";\nimport {\n TagActionsContext,\n useTagActions,\n type NormalizedTag,\n type TagActionsContextValue,\n} from \"./tag-utils\";\n\nexport function TagActionsProvider({\n value,\n children,\n}: {\n value: TagActionsContextValue;\n children: React.ReactNode;\n}) {\n return <TagActionsContext.Provider value={value}>{children}</TagActionsContext.Provider>;\n}\n\nexport type TagListProps = {\n /** Normalized tags to render. */\n tags: NormalizedTag[];\n /** Number of tags to show inline before the overflow popover. */\n maxVisible?: number;\n /** Classes applied to the tag row. */\n className?: string;\n /** Whether copy/zoom actions appear on hover or inline. */\n actions?: \"hover\" | \"inline\";\n /**\n * When `true`, visible tag badges render only their value — the key is\n * dropped from the inline display. The full `key=value` text is still\n * available in `tag.display` (used for tooltips, copy actions, and the\n * overflow `+N` popover). Defaults to whether the surrounding density\n * (via {@link useDensityValue}) is `\"compact\"`.\n */\n compact?: boolean;\n /**\n * When `true`, tag badges wrap onto multiple lines instead of staying on a\n * single row with a `+N` overflow popover. Used by detail/expanded views\n * (e.g. LogsTable row details) where vertical space is available.\n */\n wrap?: boolean;\n};\n\nfunction copyToClipboard(text: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(text).catch(() => undefined);\n }\n}\n\nfunction TagBadge({\n tag,\n actions: actionMode,\n compact = false,\n}: {\n tag: NormalizedTag;\n actions: \"hover\" | \"inline\";\n compact?: boolean;\n}) {\n const actions = useTagActions();\n const mode = actions.getMode(tag.token);\n\n const onPlus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleInclude(tag.token);\n },\n [actions, tag.token],\n );\n const onMinus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleExclude(tag.token);\n },\n [actions, tag.token],\n );\n const onCopy = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n copyToClipboard(tag.value);\n },\n [tag.value],\n );\n\n // Active state colors mirror FilterPill: include = green, exclude = red.\n const includeActive = mode === \"include\";\n const excludeActive = mode === \"exclude\";\n\n const showTooltip = compact && !!tag.key;\n const badge = (\n <span\n {...(showTooltip ? { title: tag.display } : {})}\n className={cn(\n \"inline-flex items-center rounded-md border bg-background align-middle\",\n includeActive\n ? \"border-green-500/50 bg-green-500/5\"\n : excludeActive\n ? \"border-red-500/50 bg-red-500/5\"\n : \"border-border\",\n )}\n >\n {tag.key && !compact ? (\n <Badge\n size=\"xs\"\n variant=\"label\"\n tone=\"neutral\"\n label={tag.key}\n value={tag.value}\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n className=\"border-transparent shadow-none\"\n />\n ) : (\n <Badge\n size=\"xs\"\n variant=\"soft\"\n tone=\"neutral\"\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n >\n {tag.value}\n </Badge>\n )}\n </span>\n );\n\n const toolbar = (\n <span className=\"inline-flex items-center gap-0.5\">\n <TagActionButton\n ariaLabel={`Include ${tag.display}`}\n onClick={onPlus}\n active={includeActive}\n activeClassName=\"bg-green-500/20 text-green-700 dark:text-green-400\"\n icon={UiZoomIn}\n />\n <TagActionButton\n ariaLabel={`Exclude ${tag.display}`}\n onClick={onMinus}\n active={excludeActive}\n activeClassName=\"bg-red-500/20 text-red-700 dark:text-red-400\"\n icon={UiZoomOut}\n />\n <TagActionButton ariaLabel={`Copy ${tag.display}`} onClick={onCopy} icon={UiCopy} />\n </span>\n );\n\n if (actionMode === \"inline\") {\n return (\n <span className=\"inline-flex items-center gap-0.5 rounded-md border border-border bg-background pr-0.5\">\n {badge}\n {toolbar}\n </span>\n );\n }\n\n // Action icons live in a hover popover above the tag — the cell stays\n // clean, and hovering reveals the magnifier-plus / magnifier-minus / copy\n // toolbar.\n return (\n <HoverCard placement=\"top\" delay={120} arrow={false} trigger={badge} cardClassName=\"!p-1\">\n {toolbar}\n </HoverCard>\n );\n}\n\nfunction TagActionButton({\n ariaLabel,\n onClick,\n active,\n activeClassName,\n icon,\n}: {\n ariaLabel: string;\n onClick: (event: React.MouseEvent) => void;\n active?: boolean;\n activeClassName?: string;\n icon: StaticIconComponent;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={onClick}\n className={cn(\n \"inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground\",\n \"hover:bg-accent hover:text-foreground\",\n active && activeClassName,\n )}\n >\n <Icon icon={icon} className=\"text-xs\" />\n </button>\n );\n}\n\nexport function TagList({\n tags,\n maxVisible = 3,\n className,\n actions = \"hover\",\n compact,\n wrap = false,\n}: TagListProps) {\n const density = useDensityValue();\n const isCompact = compact ?? density === \"compact\";\n\n if (tags.length === 0) {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n if (wrap) {\n return (\n <span className={cn(\"flex min-w-0 flex-wrap items-center gap-1\", className)}>\n {tags.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n );\n }\n\n const visible = tags.slice(0, maxVisible);\n const overflow = tags.slice(maxVisible);\n\n return (\n <span className={cn(\"flex min-w-0 items-center gap-1\", className)}>\n <span className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-hidden\">\n {visible.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n {overflow.length > 0 && (\n <HoverCard\n placement=\"top\"\n trigger={\n <Badge\n size=\"xs\"\n variant=\"outlined\"\n tone=\"neutral\"\n clickToCopy={false}\n className=\"shrink-0\"\n >\n +{overflow.length}\n </Badge>\n }\n cardClassName=\"min-w-72 max-w-[90vw] whitespace-normal !p-0\"\n >\n <TagPropertiesList tags={overflow} />\n </HoverCard>\n )}\n </span>\n );\n}\n\nexport function TagPropertiesList({\n tags,\n rowClassName = \"grid-cols-[minmax(4rem,8rem)_minmax(0,1fr)]\",\n}: {\n tags: NormalizedTag[];\n rowClassName?: string;\n}) {\n const tagActions = useTagActions();\n const items = useMemo<PropertiesItem<NormalizedTag>[]>(\n () => tags.map((tag, index) => ({ key: `${tag.token}-${index}`, value: tag })),\n [tags],\n );\n\n return (\n <Properties<NormalizedTag>\n items={items}\n density=\"compact\"\n className=\"border-0 bg-transparent\"\n rowClassName={rowClassName}\n renderLabel={(_key, tag) =>\n tag.key ? (\n <span className=\"font-mono\">{tag.key}</span>\n ) : (\n <span className=\"italic text-muted-foreground\">tag</span>\n )\n }\n renderValue={(_key, tag) => (\n <span className=\"block truncate font-mono\" title={tag.value}>\n {tag.value}\n </span>\n )}\n suffixActions={[\n {\n id: \"include\",\n icon: UiZoomIn,\n label: (_key, tag) => `Include ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleInclude(tag.token),\n },\n {\n id: \"exclude\",\n icon: UiZoomOut,\n label: (_key, tag) => `Exclude ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleExclude(tag.token),\n },\n {\n id: \"copy\",\n icon: UiCopy,\n label: (_key, tag) => `Copy ${tag.display}`,\n onClick: (_key, tag) => copyToClipboard(tag.value),\n },\n ]}\n />\n );\n}\n\n"],"names":["jsx","TagActionsContext","useTagActions","useCallback","cn","Badge","jsxs","UiZoomIn","UiZoomOut","UiCopy","HoverCard","Icon","useDensityValue","useMemo","Properties"],"mappings":"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"}
@@ -1,49 +1,8 @@
1
- import { FilterMode } from '../FilterPill';
2
- export type TagInput = string | {
3
- key: string;
4
- value: string;
5
- } | {
6
- name: string;
7
- value: string;
8
- };
9
- export type NormalizedTag = {
10
- key?: string;
11
- value: string;
12
- display: string;
13
- token: string;
14
- };
15
- export type TagsValue = TagInput[] | Record<string, string | number | boolean | null> | null | undefined;
16
- export type TagsOptions = {
17
- /** Number of tags to show inline before using the `+N` overflow popover. */
18
- maxVisible?: number;
19
- /** Separator between tag keys and values. Defaults to `=`. */
20
- separator?: string;
21
- };
22
- export declare function normalizeTags(value: TagsValue, separator?: string): NormalizedTag[];
23
- export declare function tagFilterTokens(value: TagsValue, separator?: string): string[];
24
- /**
25
- * Splits a token previously produced by `normalizeTags`/`tagFilterTokens`
26
- * back into its key and value parts using the same separator. Tokens
27
- * without a separator (bare tags) return `{ key: "", value: token }`.
28
- */
29
- export declare function splitTagToken(token: string, separator?: string): {
30
- key: string;
31
- value: string;
32
- };
33
- export type TagFilterMode = Extract<FilterMode, "include" | "exclude">;
34
- export type TagActionsContextValue = {
35
- /** Returns the current mode for a token; "neutral" if the user hasn't acted on it. */
36
- getMode: (token: string) => FilterMode;
37
- /** Toggle include for this token (off → include → off). */
38
- toggleInclude: (token: string) => void;
39
- /** Toggle exclude for this token (off → exclude → off). */
40
- toggleExclude: (token: string) => void;
41
- };
1
+ import { NormalizedTag, TagActionsContextValue } from './tag-utils';
42
2
  export declare function TagActionsProvider({ value, children, }: {
43
3
  value: TagActionsContextValue;
44
4
  children: React.ReactNode;
45
5
  }): import("react/jsx-runtime").JSX.Element;
46
- export declare function useTagActions(): TagActionsContextValue;
47
6
  export type TagListProps = {
48
7
  /** Normalized tags to render. */
49
8
  tags: NormalizedTag[];
@@ -73,11 +32,4 @@ export declare function TagPropertiesList({ tags, rowClassName, }: {
73
32
  tags: NormalizedTag[];
74
33
  rowClassName?: string;
75
34
  }): import("react/jsx-runtime").JSX.Element;
76
- /**
77
- * Builds a TagActionsContextValue from a flat record-of-modes (the same
78
- * shape used by FilterBar's multi/nested-multi filters). Useful when
79
- * connecting DataTable's multiFilters state to the in-cell + / − buttons.
80
- */
81
- export declare function tagActionsFromRecord(value: Record<string, TagFilterMode>, onChange: (next: Record<string, TagFilterMode>) => void): TagActionsContextValue;
82
- export declare function useTagActionsValue(value: Record<string, TagFilterMode>, onChange: (next: Record<string, TagFilterMode>) => void): TagActionsContextValue;
83
35
  //# sourceMappingURL=TagList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TagList.d.ts","sourceRoot":"","sources":["../../../src/data/cells/TagList.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TagList.d.ts","sourceRoot":"","sources":["../../../src/data/cells/TagList.tsx"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AAErB,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAEA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,iCAAiC;IACjC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC7B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AA2JF,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,UAAc,EACd,SAAS,EACT,OAAiB,EACjB,OAAO,EACP,IAAY,GACb,EAAE,YAAY,2CA2Dd;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAA4D,GAC7D,EAAE;IACD,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,2CA+CA"}
@@ -1,92 +1,21 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useContext, useMemo, createContext, useCallback } from "react";
2
+ import { useCallback, useMemo } from "react";
3
3
  import { Badge } from "../Badge.js";
4
4
  import { HoverCard } from "../../overlay/HoverCard.js";
5
5
  import { Icon } from "../Icon.js";
6
6
  import { Properties } from "../Properties.js";
7
7
  import { useDensityValue } from "../../hooks/use-density.js";
8
8
  import { cn } from "../../lib/utils.js";
9
+ import { TagActionsContext, useTagActions } from "./tag-utils.js";
9
10
  import { UiZoomIn } from "../../icons/components/UiZoomIn.js";
10
11
  import { UiZoomOut } from "../../icons/components/UiZoomOut.js";
11
12
  import { UiCopy } from "../../icons/components/UiCopy.js";
12
- function normalizeTags(value, separator = "=") {
13
- if (value == null) return [];
14
- if (Array.isArray(value)) {
15
- return value.map((entry) => normalizeOne(entry, separator)).filter((tag) => tag.value !== "");
16
- }
17
- if (typeof value === "object") {
18
- return Object.entries(value).map(([key, raw]) => {
19
- if (raw == null) return null;
20
- const valueStr = String(raw).trim();
21
- if (!valueStr) return null;
22
- return {
23
- key,
24
- value: valueStr,
25
- display: `${key}${separator}${valueStr}`,
26
- token: `${key}${separator}${valueStr}`
27
- };
28
- }).filter((tag) => tag !== null);
29
- }
30
- return [];
31
- }
32
- function normalizeOne(entry, separator) {
33
- if (typeof entry === "string") {
34
- const trimmed = entry.trim();
35
- const eq = trimmed.indexOf("=");
36
- const colon = trimmed.indexOf(":");
37
- const splitAt = eq >= 0 && (colon < 0 || eq < colon) ? eq : colon >= 0 && colon < trimmed.length - 1 ? colon : -1;
38
- if (splitAt > 0) {
39
- const key2 = trimmed.slice(0, splitAt);
40
- const value2 = trimmed.slice(splitAt + 1);
41
- return {
42
- key: key2,
43
- value: value2,
44
- display: `${key2}${separator}${value2}`,
45
- token: `${key2}${separator}${value2}`
46
- };
47
- }
48
- return { value: trimmed, display: trimmed, token: trimmed };
49
- }
50
- const key = "key" in entry && typeof entry.key === "string" ? entry.key : "name" in entry && typeof entry.name === "string" ? entry.name : void 0;
51
- const value = String(entry.value ?? "").trim();
52
- if (key) {
53
- return {
54
- key,
55
- value,
56
- display: `${key}${separator}${value}`,
57
- token: `${key}${separator}${value}`
58
- };
59
- }
60
- return { value, display: value, token: value };
61
- }
62
- function tagFilterTokens(value, separator = "=") {
63
- return normalizeTags(value, separator).map((tag) => tag.token);
64
- }
65
- function splitTagToken(token, separator = "=") {
66
- const idx = token.indexOf(separator);
67
- if (idx <= 0) return { key: "", value: token };
68
- return {
69
- key: token.slice(0, idx),
70
- value: token.slice(idx + separator.length)
71
- };
72
- }
73
- const noop = {
74
- getMode: () => "neutral",
75
- toggleInclude: () => {
76
- },
77
- toggleExclude: () => {
78
- }
79
- };
80
- const TagActionsContext = createContext(noop);
81
13
  function TagActionsProvider({
82
14
  value,
83
15
  children
84
16
  }) {
85
17
  return /* @__PURE__ */ jsx(TagActionsContext.Provider, { value, children });
86
18
  }
87
- function useTagActions() {
88
- return useContext(TagActionsContext);
89
- }
90
19
  function copyToClipboard(text) {
91
20
  var _a;
92
21
  if (typeof navigator !== "undefined" && ((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
@@ -314,35 +243,9 @@ function TagPropertiesList({
314
243
  }
315
244
  );
316
245
  }
317
- function tagActionsFromRecord(value, onChange) {
318
- return {
319
- getMode: (token) => value[token] ?? "neutral",
320
- toggleInclude: (token) => {
321
- const next = { ...value };
322
- if (next[token] === "include") delete next[token];
323
- else next[token] = "include";
324
- onChange(next);
325
- },
326
- toggleExclude: (token) => {
327
- const next = { ...value };
328
- if (next[token] === "exclude") delete next[token];
329
- else next[token] = "exclude";
330
- onChange(next);
331
- }
332
- };
333
- }
334
- function useTagActionsValue(value, onChange) {
335
- return useMemo(() => tagActionsFromRecord(value, onChange), [value, onChange]);
336
- }
337
246
  export {
338
247
  TagActionsProvider,
339
248
  TagList,
340
- TagPropertiesList,
341
- normalizeTags,
342
- splitTagToken,
343
- tagActionsFromRecord,
344
- tagFilterTokens,
345
- useTagActions,
346
- useTagActionsValue
249
+ TagPropertiesList
347
250
  };
348
251
  //# sourceMappingURL=TagList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TagList.js","sources":["../../../src/data/cells/TagList.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo } from \"react\";\nimport { Badge } from \"../Badge\";\nimport { HoverCard } from \"../../overlay/HoverCard\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport { Properties, type PropertiesItem } from \"../Properties\";\nimport { UiCopy, UiZoomIn, UiZoomOut } from \"../../icons\";\nimport { useDensityValue } from \"../../hooks/use-density\";\nimport { cn } from \"../../lib/utils\";\nimport type { FilterMode } from \"../FilterPill\";\n\nexport type TagInput = string | { key: string; value: string } | { name: string; value: string };\n\nexport type NormalizedTag = {\n key?: string;\n value: string;\n display: string;\n token: string;\n};\n\nexport type TagsValue =\n | TagInput[]\n | Record<string, string | number | boolean | null>\n | null\n | undefined;\n\nexport type TagsOptions = {\n /** Number of tags to show inline before using the `+N` overflow popover. */\n maxVisible?: number;\n /** Separator between tag keys and values. Defaults to `=`. */\n separator?: string;\n};\n\nexport function normalizeTags(value: TagsValue, separator = \"=\"): NormalizedTag[] {\n if (value == null) return [];\n\n if (Array.isArray(value)) {\n return value.map((entry) => normalizeOne(entry, separator)).filter((tag) => tag.value !== \"\");\n }\n\n if (typeof value === \"object\") {\n return Object.entries(value)\n .map(([key, raw]): NormalizedTag | null => {\n if (raw == null) return null;\n const valueStr = String(raw).trim();\n if (!valueStr) return null;\n return {\n key,\n value: valueStr,\n display: `${key}${separator}${valueStr}`,\n token: `${key}${separator}${valueStr}`,\n } satisfies NormalizedTag;\n })\n .filter((tag): tag is NormalizedTag => tag !== null);\n }\n\n return [];\n}\n\nfunction normalizeOne(entry: TagInput, separator: string): NormalizedTag {\n if (typeof entry === \"string\") {\n const trimmed = entry.trim();\n const eq = trimmed.indexOf(\"=\");\n const colon = trimmed.indexOf(\":\");\n const splitAt =\n eq >= 0 && (colon < 0 || eq < colon)\n ? eq\n : colon >= 0 && colon < trimmed.length - 1\n ? colon\n : -1;\n\n if (splitAt > 0) {\n const key = trimmed.slice(0, splitAt);\n const value = trimmed.slice(splitAt + 1);\n return {\n key,\n value,\n display: `${key}${separator}${value}`,\n token: `${key}${separator}${value}`,\n };\n }\n\n return { value: trimmed, display: trimmed, token: trimmed };\n }\n\n const key =\n \"key\" in entry && typeof entry.key === \"string\"\n ? entry.key\n : \"name\" in entry && typeof entry.name === \"string\"\n ? entry.name\n : undefined;\n const value = String(entry.value ?? \"\").trim();\n\n if (key) {\n return {\n key,\n value,\n display: `${key}${separator}${value}`,\n token: `${key}${separator}${value}`,\n };\n }\n return { value, display: value, token: value };\n}\n\nexport function tagFilterTokens(value: TagsValue, separator = \"=\"): string[] {\n return normalizeTags(value, separator).map((tag) => tag.token);\n}\n\n/**\n * Splits a token previously produced by `normalizeTags`/`tagFilterTokens`\n * back into its key and value parts using the same separator. Tokens\n * without a separator (bare tags) return `{ key: \"\", value: token }`.\n */\nexport function splitTagToken(token: string, separator = \"=\"): { key: string; value: string } {\n const idx = token.indexOf(separator);\n if (idx <= 0) return { key: \"\", value: token };\n return {\n key: token.slice(0, idx),\n value: token.slice(idx + separator.length),\n };\n}\n\n// Filter mode mapping (re-using FilterPill's tri-state vocabulary so the wire\n// shape matches DataTable's existing multiFilters state).\nexport type TagFilterMode = Extract<FilterMode, \"include\" | \"exclude\">;\n\nexport type TagActionsContextValue = {\n /** Returns the current mode for a token; \"neutral\" if the user hasn't acted on it. */\n getMode: (token: string) => FilterMode;\n /** Toggle include for this token (off → include → off). */\n toggleInclude: (token: string) => void;\n /** Toggle exclude for this token (off → exclude → off). */\n toggleExclude: (token: string) => void;\n};\n\nconst noop: TagActionsContextValue = {\n getMode: () => \"neutral\",\n toggleInclude: () => {},\n toggleExclude: () => {},\n};\n\nconst TagActionsContext = createContext<TagActionsContextValue>(noop);\n\nexport function TagActionsProvider({\n value,\n children,\n}: {\n value: TagActionsContextValue;\n children: React.ReactNode;\n}) {\n return <TagActionsContext.Provider value={value}>{children}</TagActionsContext.Provider>;\n}\n\nexport function useTagActions(): TagActionsContextValue {\n return useContext(TagActionsContext);\n}\n\nexport type TagListProps = {\n /** Normalized tags to render. */\n tags: NormalizedTag[];\n /** Number of tags to show inline before the overflow popover. */\n maxVisible?: number;\n /** Classes applied to the tag row. */\n className?: string;\n /** Whether copy/zoom actions appear on hover or inline. */\n actions?: \"hover\" | \"inline\";\n /**\n * When `true`, visible tag badges render only their value — the key is\n * dropped from the inline display. The full `key=value` text is still\n * available in `tag.display` (used for tooltips, copy actions, and the\n * overflow `+N` popover). Defaults to whether the surrounding density\n * (via {@link useDensityValue}) is `\"compact\"`.\n */\n compact?: boolean;\n /**\n * When `true`, tag badges wrap onto multiple lines instead of staying on a\n * single row with a `+N` overflow popover. Used by detail/expanded views\n * (e.g. LogsTable row details) where vertical space is available.\n */\n wrap?: boolean;\n};\n\nfunction copyToClipboard(text: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(text).catch(() => undefined);\n }\n}\n\nfunction TagBadge({\n tag,\n actions: actionMode,\n compact = false,\n}: {\n tag: NormalizedTag;\n actions: \"hover\" | \"inline\";\n compact?: boolean;\n}) {\n const actions = useTagActions();\n const mode = actions.getMode(tag.token);\n\n const onPlus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleInclude(tag.token);\n },\n [actions, tag.token],\n );\n const onMinus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleExclude(tag.token);\n },\n [actions, tag.token],\n );\n const onCopy = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n copyToClipboard(tag.value);\n },\n [tag.value],\n );\n\n // Active state colors mirror FilterPill: include = green, exclude = red.\n const includeActive = mode === \"include\";\n const excludeActive = mode === \"exclude\";\n\n const showTooltip = compact && !!tag.key;\n const badge = (\n <span\n {...(showTooltip ? { title: tag.display } : {})}\n className={cn(\n \"inline-flex items-center rounded-md border bg-background align-middle\",\n includeActive\n ? \"border-green-500/50 bg-green-500/5\"\n : excludeActive\n ? \"border-red-500/50 bg-red-500/5\"\n : \"border-border\",\n )}\n >\n {tag.key && !compact ? (\n <Badge\n size=\"xs\"\n variant=\"label\"\n tone=\"neutral\"\n label={tag.key}\n value={tag.value}\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n className=\"border-transparent shadow-none\"\n />\n ) : (\n <Badge\n size=\"xs\"\n variant=\"soft\"\n tone=\"neutral\"\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n >\n {tag.value}\n </Badge>\n )}\n </span>\n );\n\n const toolbar = (\n <span className=\"inline-flex items-center gap-0.5\">\n <TagActionButton\n ariaLabel={`Include ${tag.display}`}\n onClick={onPlus}\n active={includeActive}\n activeClassName=\"bg-green-500/20 text-green-700 dark:text-green-400\"\n icon={UiZoomIn}\n />\n <TagActionButton\n ariaLabel={`Exclude ${tag.display}`}\n onClick={onMinus}\n active={excludeActive}\n activeClassName=\"bg-red-500/20 text-red-700 dark:text-red-400\"\n icon={UiZoomOut}\n />\n <TagActionButton ariaLabel={`Copy ${tag.display}`} onClick={onCopy} icon={UiCopy} />\n </span>\n );\n\n if (actionMode === \"inline\") {\n return (\n <span className=\"inline-flex items-center gap-0.5 rounded-md border border-border bg-background pr-0.5\">\n {badge}\n {toolbar}\n </span>\n );\n }\n\n // Action icons live in a hover popover above the tag — the cell stays\n // clean, and hovering reveals the magnifier-plus / magnifier-minus / copy\n // toolbar.\n return (\n <HoverCard placement=\"top\" delay={120} arrow={false} trigger={badge} cardClassName=\"!p-1\">\n {toolbar}\n </HoverCard>\n );\n}\n\nfunction TagActionButton({\n ariaLabel,\n onClick,\n active,\n activeClassName,\n icon,\n}: {\n ariaLabel: string;\n onClick: (event: React.MouseEvent) => void;\n active?: boolean;\n activeClassName?: string;\n icon: StaticIconComponent;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={onClick}\n className={cn(\n \"inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground\",\n \"hover:bg-accent hover:text-foreground\",\n active && activeClassName,\n )}\n >\n <Icon icon={icon} className=\"text-xs\" />\n </button>\n );\n}\n\nexport function TagList({\n tags,\n maxVisible = 3,\n className,\n actions = \"hover\",\n compact,\n wrap = false,\n}: TagListProps) {\n const density = useDensityValue();\n const isCompact = compact ?? density === \"compact\";\n\n if (tags.length === 0) {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n if (wrap) {\n return (\n <span className={cn(\"flex min-w-0 flex-wrap items-center gap-1\", className)}>\n {tags.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n );\n }\n\n const visible = tags.slice(0, maxVisible);\n const overflow = tags.slice(maxVisible);\n\n return (\n <span className={cn(\"flex min-w-0 items-center gap-1\", className)}>\n <span className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-hidden\">\n {visible.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n {overflow.length > 0 && (\n <HoverCard\n placement=\"top\"\n trigger={\n <Badge\n size=\"xs\"\n variant=\"outlined\"\n tone=\"neutral\"\n clickToCopy={false}\n className=\"shrink-0\"\n >\n +{overflow.length}\n </Badge>\n }\n cardClassName=\"min-w-72 max-w-[90vw] whitespace-normal !p-0\"\n >\n <TagPropertiesList tags={overflow} />\n </HoverCard>\n )}\n </span>\n );\n}\n\nexport function TagPropertiesList({\n tags,\n rowClassName = \"grid-cols-[minmax(4rem,8rem)_minmax(0,1fr)]\",\n}: {\n tags: NormalizedTag[];\n rowClassName?: string;\n}) {\n const tagActions = useTagActions();\n const items = useMemo<PropertiesItem<NormalizedTag>[]>(\n () => tags.map((tag, index) => ({ key: `${tag.token}-${index}`, value: tag })),\n [tags],\n );\n\n return (\n <Properties<NormalizedTag>\n items={items}\n density=\"compact\"\n className=\"border-0 bg-transparent\"\n rowClassName={rowClassName}\n renderLabel={(_key, tag) =>\n tag.key ? (\n <span className=\"font-mono\">{tag.key}</span>\n ) : (\n <span className=\"italic text-muted-foreground\">tag</span>\n )\n }\n renderValue={(_key, tag) => (\n <span className=\"block truncate font-mono\" title={tag.value}>\n {tag.value}\n </span>\n )}\n suffixActions={[\n {\n id: \"include\",\n icon: UiZoomIn,\n label: (_key, tag) => `Include ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleInclude(tag.token),\n },\n {\n id: \"exclude\",\n icon: UiZoomOut,\n label: (_key, tag) => `Exclude ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleExclude(tag.token),\n },\n {\n id: \"copy\",\n icon: UiCopy,\n label: (_key, tag) => `Copy ${tag.display}`,\n onClick: (_key, tag) => copyToClipboard(tag.value),\n },\n ]}\n />\n );\n}\n\n/**\n * Builds a TagActionsContextValue from a flat record-of-modes (the same\n * shape used by FilterBar's multi/nested-multi filters). Useful when\n * connecting DataTable's multiFilters state to the in-cell + / − buttons.\n */\nexport function tagActionsFromRecord(\n value: Record<string, TagFilterMode>,\n onChange: (next: Record<string, TagFilterMode>) => void,\n): TagActionsContextValue {\n return {\n getMode: (token) => value[token] ?? \"neutral\",\n toggleInclude: (token) => {\n const next = { ...value };\n if (next[token] === \"include\") delete next[token];\n else next[token] = \"include\";\n onChange(next);\n },\n toggleExclude: (token) => {\n const next = { ...value };\n if (next[token] === \"exclude\") delete next[token];\n else next[token] = \"exclude\";\n onChange(next);\n },\n };\n}\n\n// Memoizing the context value avoids re-rendering every TagList cell on\n// unrelated state changes.\nexport function useTagActionsValue(\n value: Record<string, TagFilterMode>,\n onChange: (next: Record<string, TagFilterMode>) => void,\n): TagActionsContextValue {\n return useMemo(() => tagActionsFromRecord(value, onChange), [value, onChange]);\n}\n"],"names":["key","value"],"mappings":"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"}
1
+ {"version":3,"file":"TagList.js","sources":["../../../src/data/cells/TagList.tsx"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { Badge } from \"../Badge\";\nimport { HoverCard } from \"../../overlay/HoverCard\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport { Properties, type PropertiesItem } from \"../Properties\";\nimport { UiCopy, UiZoomIn, UiZoomOut } from \"../../icons\";\nimport { useDensityValue } from \"../../hooks/use-density\";\nimport { cn } from \"../../lib/utils\";\nimport {\n TagActionsContext,\n useTagActions,\n type NormalizedTag,\n type TagActionsContextValue,\n} from \"./tag-utils\";\n\nexport function TagActionsProvider({\n value,\n children,\n}: {\n value: TagActionsContextValue;\n children: React.ReactNode;\n}) {\n return <TagActionsContext.Provider value={value}>{children}</TagActionsContext.Provider>;\n}\n\nexport type TagListProps = {\n /** Normalized tags to render. */\n tags: NormalizedTag[];\n /** Number of tags to show inline before the overflow popover. */\n maxVisible?: number;\n /** Classes applied to the tag row. */\n className?: string;\n /** Whether copy/zoom actions appear on hover or inline. */\n actions?: \"hover\" | \"inline\";\n /**\n * When `true`, visible tag badges render only their value — the key is\n * dropped from the inline display. The full `key=value` text is still\n * available in `tag.display` (used for tooltips, copy actions, and the\n * overflow `+N` popover). Defaults to whether the surrounding density\n * (via {@link useDensityValue}) is `\"compact\"`.\n */\n compact?: boolean;\n /**\n * When `true`, tag badges wrap onto multiple lines instead of staying on a\n * single row with a `+N` overflow popover. Used by detail/expanded views\n * (e.g. LogsTable row details) where vertical space is available.\n */\n wrap?: boolean;\n};\n\nfunction copyToClipboard(text: string) {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(text).catch(() => undefined);\n }\n}\n\nfunction TagBadge({\n tag,\n actions: actionMode,\n compact = false,\n}: {\n tag: NormalizedTag;\n actions: \"hover\" | \"inline\";\n compact?: boolean;\n}) {\n const actions = useTagActions();\n const mode = actions.getMode(tag.token);\n\n const onPlus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleInclude(tag.token);\n },\n [actions, tag.token],\n );\n const onMinus = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n actions.toggleExclude(tag.token);\n },\n [actions, tag.token],\n );\n const onCopy = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n copyToClipboard(tag.value);\n },\n [tag.value],\n );\n\n // Active state colors mirror FilterPill: include = green, exclude = red.\n const includeActive = mode === \"include\";\n const excludeActive = mode === \"exclude\";\n\n const showTooltip = compact && !!tag.key;\n const badge = (\n <span\n {...(showTooltip ? { title: tag.display } : {})}\n className={cn(\n \"inline-flex items-center rounded-md border bg-background align-middle\",\n includeActive\n ? \"border-green-500/50 bg-green-500/5\"\n : excludeActive\n ? \"border-red-500/50 bg-red-500/5\"\n : \"border-border\",\n )}\n >\n {tag.key && !compact ? (\n <Badge\n size=\"xs\"\n variant=\"label\"\n tone=\"neutral\"\n label={tag.key}\n value={tag.value}\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n className=\"border-transparent shadow-none\"\n />\n ) : (\n <Badge\n size=\"xs\"\n variant=\"soft\"\n tone=\"neutral\"\n maxWidth={32}\n truncate=\"auto\"\n clickToCopy={false}\n >\n {tag.value}\n </Badge>\n )}\n </span>\n );\n\n const toolbar = (\n <span className=\"inline-flex items-center gap-0.5\">\n <TagActionButton\n ariaLabel={`Include ${tag.display}`}\n onClick={onPlus}\n active={includeActive}\n activeClassName=\"bg-green-500/20 text-green-700 dark:text-green-400\"\n icon={UiZoomIn}\n />\n <TagActionButton\n ariaLabel={`Exclude ${tag.display}`}\n onClick={onMinus}\n active={excludeActive}\n activeClassName=\"bg-red-500/20 text-red-700 dark:text-red-400\"\n icon={UiZoomOut}\n />\n <TagActionButton ariaLabel={`Copy ${tag.display}`} onClick={onCopy} icon={UiCopy} />\n </span>\n );\n\n if (actionMode === \"inline\") {\n return (\n <span className=\"inline-flex items-center gap-0.5 rounded-md border border-border bg-background pr-0.5\">\n {badge}\n {toolbar}\n </span>\n );\n }\n\n // Action icons live in a hover popover above the tag — the cell stays\n // clean, and hovering reveals the magnifier-plus / magnifier-minus / copy\n // toolbar.\n return (\n <HoverCard placement=\"top\" delay={120} arrow={false} trigger={badge} cardClassName=\"!p-1\">\n {toolbar}\n </HoverCard>\n );\n}\n\nfunction TagActionButton({\n ariaLabel,\n onClick,\n active,\n activeClassName,\n icon,\n}: {\n ariaLabel: string;\n onClick: (event: React.MouseEvent) => void;\n active?: boolean;\n activeClassName?: string;\n icon: StaticIconComponent;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n title={ariaLabel}\n onClick={onClick}\n className={cn(\n \"inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground\",\n \"hover:bg-accent hover:text-foreground\",\n active && activeClassName,\n )}\n >\n <Icon icon={icon} className=\"text-xs\" />\n </button>\n );\n}\n\nexport function TagList({\n tags,\n maxVisible = 3,\n className,\n actions = \"hover\",\n compact,\n wrap = false,\n}: TagListProps) {\n const density = useDensityValue();\n const isCompact = compact ?? density === \"compact\";\n\n if (tags.length === 0) {\n return <span className=\"text-muted-foreground\">—</span>;\n }\n\n if (wrap) {\n return (\n <span className={cn(\"flex min-w-0 flex-wrap items-center gap-1\", className)}>\n {tags.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n );\n }\n\n const visible = tags.slice(0, maxVisible);\n const overflow = tags.slice(maxVisible);\n\n return (\n <span className={cn(\"flex min-w-0 items-center gap-1\", className)}>\n <span className=\"flex min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-hidden\">\n {visible.map((tag, index) => (\n <TagBadge\n key={`${tag.display}-${index}`}\n tag={tag}\n actions={actions}\n compact={isCompact}\n />\n ))}\n </span>\n {overflow.length > 0 && (\n <HoverCard\n placement=\"top\"\n trigger={\n <Badge\n size=\"xs\"\n variant=\"outlined\"\n tone=\"neutral\"\n clickToCopy={false}\n className=\"shrink-0\"\n >\n +{overflow.length}\n </Badge>\n }\n cardClassName=\"min-w-72 max-w-[90vw] whitespace-normal !p-0\"\n >\n <TagPropertiesList tags={overflow} />\n </HoverCard>\n )}\n </span>\n );\n}\n\nexport function TagPropertiesList({\n tags,\n rowClassName = \"grid-cols-[minmax(4rem,8rem)_minmax(0,1fr)]\",\n}: {\n tags: NormalizedTag[];\n rowClassName?: string;\n}) {\n const tagActions = useTagActions();\n const items = useMemo<PropertiesItem<NormalizedTag>[]>(\n () => tags.map((tag, index) => ({ key: `${tag.token}-${index}`, value: tag })),\n [tags],\n );\n\n return (\n <Properties<NormalizedTag>\n items={items}\n density=\"compact\"\n className=\"border-0 bg-transparent\"\n rowClassName={rowClassName}\n renderLabel={(_key, tag) =>\n tag.key ? (\n <span className=\"font-mono\">{tag.key}</span>\n ) : (\n <span className=\"italic text-muted-foreground\">tag</span>\n )\n }\n renderValue={(_key, tag) => (\n <span className=\"block truncate font-mono\" title={tag.value}>\n {tag.value}\n </span>\n )}\n suffixActions={[\n {\n id: \"include\",\n icon: UiZoomIn,\n label: (_key, tag) => `Include ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleInclude(tag.token),\n },\n {\n id: \"exclude\",\n icon: UiZoomOut,\n label: (_key, tag) => `Exclude ${tag.display}`,\n onClick: (_key, tag) => tagActions.toggleExclude(tag.token),\n },\n {\n id: \"copy\",\n icon: UiCopy,\n label: (_key, tag) => `Copy ${tag.display}`,\n onClick: (_key, tag) => copyToClipboard(tag.value),\n },\n ]}\n />\n );\n}\n\n"],"names":[],"mappings":"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"}