@flanksource/clicky-ui 0.3.54 → 0.3.56

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 (999) hide show
  1. package/NOTICE.md +6 -0
  2. package/dist/ai.cjs +6 -0
  3. package/dist/ai.js +3 -1
  4. package/dist/chat.cjs +2 -0
  5. package/dist/chat.d.ts +1 -0
  6. package/dist/chat.d.ts.map +1 -1
  7. package/dist/chat.js +2 -1
  8. package/dist/comments/CommentCard.cjs +37 -7
  9. package/dist/comments/CommentCard.cjs.map +1 -1
  10. package/dist/comments/CommentCard.d.ts +11 -1
  11. package/dist/comments/CommentCard.d.ts.map +1 -1
  12. package/dist/comments/CommentCard.js +37 -7
  13. package/dist/comments/CommentCard.js.map +1 -1
  14. package/dist/comments/CommentCardParts.cjs +9 -4
  15. package/dist/comments/CommentCardParts.cjs.map +1 -1
  16. package/dist/comments/CommentCardParts.d.ts.map +1 -1
  17. package/dist/comments/CommentCardParts.js +9 -4
  18. package/dist/comments/CommentCardParts.js.map +1 -1
  19. package/dist/comments/CommentComposer.cjs +8 -8
  20. package/dist/comments/CommentComposer.cjs.map +1 -1
  21. package/dist/comments/CommentComposer.d.ts.map +1 -1
  22. package/dist/comments/CommentComposer.js +8 -8
  23. package/dist/comments/CommentComposer.js.map +1 -1
  24. package/dist/comments/CommentProvider.cjs +5 -1
  25. package/dist/comments/CommentProvider.cjs.map +1 -1
  26. package/dist/comments/CommentProvider.d.ts +1 -1
  27. package/dist/comments/CommentProvider.d.ts.map +1 -1
  28. package/dist/comments/CommentProvider.js +5 -1
  29. package/dist/comments/CommentProvider.js.map +1 -1
  30. package/dist/comments/CommentSidePanel.cjs +17 -11
  31. package/dist/comments/CommentSidePanel.cjs.map +1 -1
  32. package/dist/comments/CommentSidePanel.d.ts +6 -0
  33. package/dist/comments/CommentSidePanel.d.ts.map +1 -1
  34. package/dist/comments/CommentSidePanel.js +17 -11
  35. package/dist/comments/CommentSidePanel.js.map +1 -1
  36. package/dist/comments/CommentThread.cjs +4 -1
  37. package/dist/comments/CommentThread.cjs.map +1 -1
  38. package/dist/comments/CommentThread.d.ts +4 -1
  39. package/dist/comments/CommentThread.d.ts.map +1 -1
  40. package/dist/comments/CommentThread.js +4 -1
  41. package/dist/comments/CommentThread.js.map +1 -1
  42. package/dist/comments/CommentThreadList.cjs +6 -3
  43. package/dist/comments/CommentThreadList.cjs.map +1 -1
  44. package/dist/comments/CommentThreadList.d.ts +7 -2
  45. package/dist/comments/CommentThreadList.d.ts.map +1 -1
  46. package/dist/comments/CommentThreadList.js +6 -3
  47. package/dist/comments/CommentThreadList.js.map +1 -1
  48. package/dist/comments/MentionTextarea.cjs +1 -1
  49. package/dist/comments/MentionTextarea.cjs.map +1 -1
  50. package/dist/comments/MentionTextarea.d.ts.map +1 -1
  51. package/dist/comments/MentionTextarea.js +1 -1
  52. package/dist/comments/MentionTextarea.js.map +1 -1
  53. package/dist/comments/comment-assign.cjs +68 -0
  54. package/dist/comments/comment-assign.cjs.map +1 -0
  55. package/dist/comments/comment-assign.d.ts +31 -0
  56. package/dist/comments/comment-assign.d.ts.map +1 -0
  57. package/dist/comments/comment-assign.js +67 -0
  58. package/dist/comments/comment-assign.js.map +1 -0
  59. package/dist/comments/comment-types.cjs.map +1 -1
  60. package/dist/comments/comment-types.d.ts +39 -0
  61. package/dist/comments/comment-types.d.ts.map +1 -1
  62. package/dist/comments/comment-types.js.map +1 -1
  63. package/dist/comments/comment-utils.cjs +2 -0
  64. package/dist/comments/comment-utils.cjs.map +1 -1
  65. package/dist/comments/comment-utils.d.ts +2 -0
  66. package/dist/comments/comment-utils.d.ts.map +1 -1
  67. package/dist/comments/comment-utils.js +2 -0
  68. package/dist/comments/comment-utils.js.map +1 -1
  69. package/dist/comments.cjs +3 -0
  70. package/dist/comments.d.ts +1 -0
  71. package/dist/comments.d.ts.map +1 -1
  72. package/dist/comments.js +2 -1
  73. package/dist/components/ComboboxMenu.cjs +23 -13
  74. package/dist/components/ComboboxMenu.cjs.map +1 -1
  75. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  76. package/dist/components/ComboboxMenu.js +23 -13
  77. package/dist/components/ComboboxMenu.js.map +1 -1
  78. package/dist/components/FilterBar.cjs +29 -6
  79. package/dist/components/FilterBar.cjs.map +1 -1
  80. package/dist/components/FilterBar.d.ts +3 -1
  81. package/dist/components/FilterBar.d.ts.map +1 -1
  82. package/dist/components/FilterBar.js +29 -6
  83. package/dist/components/FilterBar.js.map +1 -1
  84. package/dist/components/ItemActions.cjs +1 -1
  85. package/dist/components/ItemActions.cjs.map +1 -1
  86. package/dist/components/ItemActions.js +1 -1
  87. package/dist/components/ItemActions.js.map +1 -1
  88. package/dist/components/ListMenu.cjs +33 -3
  89. package/dist/components/ListMenu.cjs.map +1 -1
  90. package/dist/components/ListMenu.d.ts +4 -1
  91. package/dist/components/ListMenu.d.ts.map +1 -1
  92. package/dist/components/ListMenu.js +33 -3
  93. package/dist/components/ListMenu.js.map +1 -1
  94. package/dist/components/ListMenuItems.cjs +80 -0
  95. package/dist/components/ListMenuItems.cjs.map +1 -0
  96. package/dist/components/ListMenuItems.d.ts +8 -0
  97. package/dist/components/ListMenuItems.d.ts.map +1 -0
  98. package/dist/components/ListMenuItems.js +80 -0
  99. package/dist/components/ListMenuItems.js.map +1 -0
  100. package/dist/components/LocalPathPicker.cjs +182 -0
  101. package/dist/components/LocalPathPicker.cjs.map +1 -0
  102. package/dist/components/LocalPathPicker.d.ts +11 -0
  103. package/dist/components/LocalPathPicker.d.ts.map +1 -0
  104. package/dist/components/LocalPathPicker.js +182 -0
  105. package/dist/components/LocalPathPicker.js.map +1 -0
  106. package/dist/components/LocalPathTree.cjs +89 -0
  107. package/dist/components/LocalPathTree.cjs.map +1 -0
  108. package/dist/components/LocalPathTree.d.ts +9 -0
  109. package/dist/components/LocalPathTree.d.ts.map +1 -0
  110. package/dist/components/LocalPathTree.js +89 -0
  111. package/dist/components/LocalPathTree.js.map +1 -0
  112. package/dist/components/RangeSlider.cjs +10 -30
  113. package/dist/components/RangeSlider.cjs.map +1 -1
  114. package/dist/components/RangeSlider.d.ts.map +1 -1
  115. package/dist/components/RangeSlider.js +4 -24
  116. package/dist/components/RangeSlider.js.map +1 -1
  117. package/dist/components/Slider.cjs +79 -0
  118. package/dist/components/Slider.cjs.map +1 -0
  119. package/dist/components/Slider.d.ts +23 -0
  120. package/dist/components/Slider.d.ts.map +1 -0
  121. package/dist/components/Slider.js +79 -0
  122. package/dist/components/Slider.js.map +1 -0
  123. package/dist/components/combobox-types.d.ts +4 -1
  124. package/dist/components/combobox-types.d.ts.map +1 -1
  125. package/dist/components/filter-bar-field-utils.cjs +3 -5
  126. package/dist/components/filter-bar-field-utils.cjs.map +1 -1
  127. package/dist/components/filter-bar-field-utils.d.ts.map +1 -1
  128. package/dist/components/filter-bar-field-utils.js +3 -5
  129. package/dist/components/filter-bar-field-utils.js.map +1 -1
  130. package/dist/components/filter-bar-tree-model.cjs +22 -0
  131. package/dist/components/filter-bar-tree-model.cjs.map +1 -0
  132. package/dist/components/filter-bar-tree-model.d.ts +33 -0
  133. package/dist/components/filter-bar-tree-model.d.ts.map +1 -0
  134. package/dist/components/filter-bar-tree-model.js +21 -0
  135. package/dist/components/filter-bar-tree-model.js.map +1 -0
  136. package/dist/components/filter-bar-tree.cjs +84 -0
  137. package/dist/components/filter-bar-tree.cjs.map +1 -0
  138. package/dist/components/filter-bar-tree.d.ts +7 -0
  139. package/dist/components/filter-bar-tree.d.ts.map +1 -0
  140. package/dist/components/filter-bar-tree.js +84 -0
  141. package/dist/components/filter-bar-tree.js.map +1 -0
  142. package/dist/components/json-schema-form-debug-glyph-map.cjs +2 -0
  143. package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -1
  144. package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -1
  145. package/dist/components/json-schema-form-debug-glyph-map.js +2 -0
  146. package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -1
  147. package/dist/components/json-schema-form-help-links.cjs +18 -0
  148. package/dist/components/json-schema-form-help-links.cjs.map +1 -0
  149. package/dist/components/json-schema-form-help-links.d.ts +5 -0
  150. package/dist/components/json-schema-form-help-links.d.ts.map +1 -0
  151. package/dist/components/json-schema-form-help-links.js +18 -0
  152. package/dist/components/json-schema-form-help-links.js.map +1 -0
  153. package/dist/components/json-schema-form-help-model.cjs +7 -0
  154. package/dist/components/json-schema-form-help-model.cjs.map +1 -0
  155. package/dist/components/json-schema-form-help-model.d.ts +3 -0
  156. package/dist/components/json-schema-form-help-model.d.ts.map +1 -0
  157. package/dist/components/json-schema-form-help-model.js +7 -0
  158. package/dist/components/json-schema-form-help-model.js.map +1 -0
  159. package/dist/components/json-schema-form-json.cjs +48 -0
  160. package/dist/components/json-schema-form-json.cjs.map +1 -0
  161. package/dist/components/json-schema-form-json.d.ts +7 -0
  162. package/dist/components/json-schema-form-json.d.ts.map +1 -0
  163. package/dist/components/json-schema-form-json.js +48 -0
  164. package/dist/components/json-schema-form-json.js.map +1 -0
  165. package/dist/components/json-schema-form-layout.cjs +7 -5
  166. package/dist/components/json-schema-form-layout.cjs.map +1 -1
  167. package/dist/components/json-schema-form-layout.d.ts +2 -2
  168. package/dist/components/json-schema-form-layout.d.ts.map +1 -1
  169. package/dist/components/json-schema-form-layout.js +7 -5
  170. package/dist/components/json-schema-form-layout.js.map +1 -1
  171. package/dist/components/json-schema-form-object.cjs +2 -13
  172. package/dist/components/json-schema-form-object.cjs.map +1 -1
  173. package/dist/components/json-schema-form-object.d.ts.map +1 -1
  174. package/dist/components/json-schema-form-object.js +2 -13
  175. package/dist/components/json-schema-form-object.js.map +1 -1
  176. package/dist/components/json-schema-form-refs.cjs +1 -1
  177. package/dist/components/json-schema-form-refs.cjs.map +1 -1
  178. package/dist/components/json-schema-form-refs.d.ts.map +1 -1
  179. package/dist/components/json-schema-form-refs.js +1 -1
  180. package/dist/components/json-schema-form-refs.js.map +1 -1
  181. package/dist/components/json-schema-form-render.cjs +20 -6
  182. package/dist/components/json-schema-form-render.cjs.map +1 -1
  183. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  184. package/dist/components/json-schema-form-render.js +20 -6
  185. package/dist/components/json-schema-form-render.js.map +1 -1
  186. package/dist/components/json-schema-form-resolve.cjs +22 -2
  187. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  188. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  189. package/dist/components/json-schema-form-resolve.js +22 -2
  190. package/dist/components/json-schema-form-resolve.js.map +1 -1
  191. package/dist/components/json-schema-form-types.d.ts +5 -1
  192. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  193. package/dist/components/json-schema-form-union-model.cjs +46 -0
  194. package/dist/components/json-schema-form-union-model.cjs.map +1 -0
  195. package/dist/components/json-schema-form-union-model.d.ts +6 -0
  196. package/dist/components/json-schema-form-union-model.d.ts.map +1 -0
  197. package/dist/components/json-schema-form-union-model.js +43 -0
  198. package/dist/components/json-schema-form-union-model.js.map +1 -0
  199. package/dist/components/json-schema-form-union.cjs +52 -0
  200. package/dist/components/json-schema-form-union.cjs.map +1 -0
  201. package/dist/components/json-schema-form-union.d.ts +7 -0
  202. package/dist/components/json-schema-form-union.d.ts.map +1 -0
  203. package/dist/components/json-schema-form-union.js +52 -0
  204. package/dist/components/json-schema-form-union.js.map +1 -0
  205. package/dist/components/list-menu-virtual.cjs +5 -0
  206. package/dist/components/list-menu-virtual.cjs.map +1 -0
  207. package/dist/components/list-menu-virtual.d.ts +12 -0
  208. package/dist/components/list-menu-virtual.d.ts.map +1 -0
  209. package/dist/components/list-menu-virtual.js +6 -0
  210. package/dist/components/list-menu-virtual.js.map +1 -0
  211. package/dist/components/local-path.cjs +12 -0
  212. package/dist/components/local-path.cjs.map +1 -0
  213. package/dist/components/local-path.d.ts +14 -0
  214. package/dist/components/local-path.d.ts.map +1 -0
  215. package/dist/components/local-path.js +12 -0
  216. package/dist/components/local-path.js.map +1 -0
  217. package/dist/components/slider-shared.cjs +32 -0
  218. package/dist/components/slider-shared.cjs.map +1 -0
  219. package/dist/components/slider-shared.d.ts +18 -0
  220. package/dist/components/slider-shared.d.ts.map +1 -0
  221. package/dist/components/slider-shared.js +27 -0
  222. package/dist/components/slider-shared.js.map +1 -0
  223. package/dist/components.cjs +8 -0
  224. package/dist/components.d.ts +6 -1
  225. package/dist/components.d.ts.map +1 -1
  226. package/dist/components.js +5 -1
  227. package/dist/connections/ConnectionsPage.cjs +51 -19
  228. package/dist/connections/ConnectionsPage.cjs.map +1 -1
  229. package/dist/connections/ConnectionsPage.d.ts +9 -1
  230. package/dist/connections/ConnectionsPage.d.ts.map +1 -1
  231. package/dist/connections/ConnectionsPage.js +52 -20
  232. package/dist/connections/ConnectionsPage.js.map +1 -1
  233. package/dist/connections/connectionDashboard.cjs +13 -8
  234. package/dist/connections/connectionDashboard.cjs.map +1 -1
  235. package/dist/connections/connectionDashboard.d.ts +8 -3
  236. package/dist/connections/connectionDashboard.d.ts.map +1 -1
  237. package/dist/connections/connectionDashboard.js +14 -9
  238. package/dist/connections/connectionDashboard.js.map +1 -1
  239. package/dist/connections/connectionDashboardModel.cjs.map +1 -1
  240. package/dist/connections/connectionDashboardModel.d.ts +4 -0
  241. package/dist/connections/connectionDashboardModel.d.ts.map +1 -1
  242. package/dist/connections/connectionDashboardModel.js.map +1 -1
  243. package/dist/connections/connectionDashboardRow.cjs +75 -55
  244. package/dist/connections/connectionDashboardRow.cjs.map +1 -1
  245. package/dist/connections/connectionDashboardRow.d.ts +3 -2
  246. package/dist/connections/connectionDashboardRow.d.ts.map +1 -1
  247. package/dist/connections/connectionDashboardRow.js +75 -55
  248. package/dist/connections/connectionDashboardRow.js.map +1 -1
  249. package/dist/connections/connectionNamespaceField.cjs +17 -0
  250. package/dist/connections/connectionNamespaceField.cjs.map +1 -0
  251. package/dist/connections/connectionNamespaceField.d.ts +10 -0
  252. package/dist/connections/connectionNamespaceField.d.ts.map +1 -0
  253. package/dist/connections/connectionNamespaceField.js +17 -0
  254. package/dist/connections/connectionNamespaceField.js.map +1 -0
  255. package/dist/connections/connectionSchemaFormExtensions.cjs +98 -0
  256. package/dist/connections/connectionSchemaFormExtensions.cjs.map +1 -0
  257. package/dist/connections/connectionSchemaFormExtensions.d.ts +41 -0
  258. package/dist/connections/connectionSchemaFormExtensions.d.ts.map +1 -0
  259. package/dist/connections/connectionSchemaFormExtensions.js +96 -0
  260. package/dist/connections/connectionSchemaFormExtensions.js.map +1 -0
  261. package/dist/connections/connectionsPageModel.cjs +11 -0
  262. package/dist/connections/connectionsPageModel.cjs.map +1 -1
  263. package/dist/connections/connectionsPageModel.d.ts +5 -0
  264. package/dist/connections/connectionsPageModel.d.ts.map +1 -1
  265. package/dist/connections/connectionsPageModel.js +11 -1
  266. package/dist/connections/connectionsPageModel.js.map +1 -1
  267. package/dist/connections.cjs +5 -0
  268. package/dist/connections.d.ts +2 -1
  269. package/dist/connections.d.ts.map +1 -1
  270. package/dist/connections.js +3 -2
  271. package/dist/data/AvatarBadge.cjs +3 -3
  272. package/dist/data/AvatarBadge.cjs.map +1 -1
  273. package/dist/data/AvatarBadge.js +3 -3
  274. package/dist/data/AvatarBadge.js.map +1 -1
  275. package/dist/data/CodeDiff.cjs +2 -0
  276. package/dist/data/CodeDiff.cjs.map +1 -1
  277. package/dist/data/CodeDiff.js +2 -0
  278. package/dist/data/CodeDiff.js.map +1 -1
  279. package/dist/data/DataTable.cjs +3 -2
  280. package/dist/data/DataTable.cjs.map +1 -1
  281. package/dist/data/DataTable.d.ts.map +1 -1
  282. package/dist/data/DataTable.js +3 -2
  283. package/dist/data/DataTable.js.map +1 -1
  284. package/dist/data/Gauge.cjs +1 -1
  285. package/dist/data/Gauge.cjs.map +1 -1
  286. package/dist/data/Gauge.js +1 -1
  287. package/dist/data/Gauge.js.map +1 -1
  288. package/dist/data/HighlightedTokens.cjs +2 -10
  289. package/dist/data/HighlightedTokens.cjs.map +1 -1
  290. package/dist/data/HighlightedTokens.d.ts.map +1 -1
  291. package/dist/data/HighlightedTokens.js +1 -9
  292. package/dist/data/HighlightedTokens.js.map +1 -1
  293. package/dist/data/Markdown.cjs +38 -11
  294. package/dist/data/Markdown.cjs.map +1 -1
  295. package/dist/data/Markdown.d.ts +9 -1
  296. package/dist/data/Markdown.d.ts.map +1 -1
  297. package/dist/data/Markdown.js +39 -12
  298. package/dist/data/Markdown.js.map +1 -1
  299. package/dist/data/MultiGaugeBar.cjs +157 -0
  300. package/dist/data/MultiGaugeBar.cjs.map +1 -0
  301. package/dist/data/MultiGaugeBar.d.ts +29 -0
  302. package/dist/data/MultiGaugeBar.d.ts.map +1 -0
  303. package/dist/data/MultiGaugeBar.js +157 -0
  304. package/dist/data/MultiGaugeBar.js.map +1 -0
  305. package/dist/data/OpenInFilesLink.cjs +27 -0
  306. package/dist/data/OpenInFilesLink.cjs.map +1 -0
  307. package/dist/data/OpenInFilesLink.d.ts +15 -0
  308. package/dist/data/OpenInFilesLink.d.ts.map +1 -0
  309. package/dist/data/OpenInFilesLink.js +27 -0
  310. package/dist/data/OpenInFilesLink.js.map +1 -0
  311. package/dist/data/ProgressBar.cjs +5 -3
  312. package/dist/data/ProgressBar.cjs.map +1 -1
  313. package/dist/data/ProgressBar.d.ts +5 -1
  314. package/dist/data/ProgressBar.d.ts.map +1 -1
  315. package/dist/data/ProgressBar.js +5 -3
  316. package/dist/data/ProgressBar.js.map +1 -1
  317. package/dist/data/ProgressBars.cjs +13 -5
  318. package/dist/data/ProgressBars.cjs.map +1 -1
  319. package/dist/data/ProgressBars.d.ts +6 -1
  320. package/dist/data/ProgressBars.d.ts.map +1 -1
  321. package/dist/data/ProgressBars.js +13 -5
  322. package/dist/data/ProgressBars.js.map +1 -1
  323. package/dist/data/Properties.cjs +3 -3
  324. package/dist/data/Properties.cjs.map +1 -1
  325. package/dist/data/Properties.js +3 -3
  326. package/dist/data/Properties.js.map +1 -1
  327. package/dist/data/TaskProgress.cjs +14 -6
  328. package/dist/data/TaskProgress.cjs.map +1 -1
  329. package/dist/data/TaskProgress.d.ts +3 -1
  330. package/dist/data/TaskProgress.d.ts.map +1 -1
  331. package/dist/data/TaskProgress.js +14 -6
  332. package/dist/data/TaskProgress.js.map +1 -1
  333. package/dist/data/TaskPrompts.cjs +96 -0
  334. package/dist/data/TaskPrompts.cjs.map +1 -0
  335. package/dist/data/TaskPrompts.d.ts +6 -0
  336. package/dist/data/TaskPrompts.d.ts.map +1 -0
  337. package/dist/data/TaskPrompts.js +96 -0
  338. package/dist/data/TaskPrompts.js.map +1 -0
  339. package/dist/data/TaskSnapshot.cjs.map +1 -1
  340. package/dist/data/TaskSnapshot.d.ts +3 -0
  341. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  342. package/dist/data/TaskSnapshot.js.map +1 -1
  343. package/dist/data/TimeseriesCoreBars.cjs +7 -3
  344. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  345. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  346. package/dist/data/TimeseriesCoreBars.js +8 -4
  347. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  348. package/dist/data/TimeseriesGauge.cjs +12 -5
  349. package/dist/data/TimeseriesGauge.cjs.map +1 -1
  350. package/dist/data/TimeseriesGauge.d.ts.map +1 -1
  351. package/dist/data/TimeseriesGauge.js +13 -6
  352. package/dist/data/TimeseriesGauge.js.map +1 -1
  353. package/dist/data/TimeseriesPanel.cjs +10 -9
  354. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  355. package/dist/data/TimeseriesPanel.d.ts +1 -1
  356. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  357. package/dist/data/TimeseriesPanel.js +11 -10
  358. package/dist/data/TimeseriesPanel.js.map +1 -1
  359. package/dist/data/TimeseriesPanel.model.cjs +62 -10
  360. package/dist/data/TimeseriesPanel.model.cjs.map +1 -1
  361. package/dist/data/TimeseriesPanel.model.d.ts +40 -1
  362. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -1
  363. package/dist/data/TimeseriesPanel.model.js +62 -11
  364. package/dist/data/TimeseriesPanel.model.js.map +1 -1
  365. package/dist/data/WorkloadCard.cjs +7 -3
  366. package/dist/data/WorkloadCard.cjs.map +1 -1
  367. package/dist/data/WorkloadCard.d.ts +3 -1
  368. package/dist/data/WorkloadCard.d.ts.map +1 -1
  369. package/dist/data/WorkloadCard.js +7 -3
  370. package/dist/data/WorkloadCard.js.map +1 -1
  371. package/dist/data/WorkloadCard.model.cjs.map +1 -1
  372. package/dist/data/WorkloadCard.model.d.ts +2 -0
  373. package/dist/data/WorkloadCard.model.d.ts.map +1 -1
  374. package/dist/data/WorkloadCard.model.js.map +1 -1
  375. package/dist/data/ai/ChatWindow.placement.cjs +2 -1
  376. package/dist/data/ai/ChatWindow.placement.cjs.map +1 -1
  377. package/dist/data/ai/ChatWindow.placement.d.ts +1 -1
  378. package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -1
  379. package/dist/data/ai/ChatWindow.placement.js +2 -1
  380. package/dist/data/ai/ChatWindow.placement.js.map +1 -1
  381. package/dist/data/ai/SpecRuntimeBar.cjs +2 -2
  382. package/dist/data/ai/SpecRuntimeBar.cjs.map +1 -1
  383. package/dist/data/ai/SpecRuntimeBar.d.ts +4 -1
  384. package/dist/data/ai/SpecRuntimeBar.d.ts.map +1 -1
  385. package/dist/data/ai/SpecRuntimeBar.js +2 -2
  386. package/dist/data/ai/SpecRuntimeBar.js.map +1 -1
  387. package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +1 -1
  388. package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
  389. package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +1 -1
  390. package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
  391. package/dist/data/ai/SpecRuntimeEditor.model.cjs +2 -2
  392. package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
  393. package/dist/data/ai/SpecRuntimeEditor.model.d.ts +2 -2
  394. package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
  395. package/dist/data/ai/SpecRuntimeEditor.model.js +2 -2
  396. package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
  397. package/dist/data/ai/ThreadPicker.cjs +2 -2
  398. package/dist/data/ai/ThreadPicker.cjs.map +1 -1
  399. package/dist/data/ai/ThreadPicker.js +2 -2
  400. package/dist/data/ai/ThreadPicker.js.map +1 -1
  401. package/dist/data/ai/index.d.ts +2 -0
  402. package/dist/data/ai/index.d.ts.map +1 -1
  403. package/dist/data/ai/use-prompt-run-stream.cjs +126 -0
  404. package/dist/data/ai/use-prompt-run-stream.cjs.map +1 -0
  405. package/dist/data/ai/use-prompt-run-stream.d.ts +52 -0
  406. package/dist/data/ai/use-prompt-run-stream.d.ts.map +1 -0
  407. package/dist/data/ai/use-prompt-run-stream.js +126 -0
  408. package/dist/data/ai/use-prompt-run-stream.js.map +1 -0
  409. package/dist/data/cache-browser/CacheBrowser.cjs +1 -0
  410. package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -1
  411. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -1
  412. package/dist/data/cache-browser/CacheBrowser.js +1 -0
  413. package/dist/data/cache-browser/CacheBrowser.js.map +1 -1
  414. package/dist/data/charts/BarChart.cjs +194 -0
  415. package/dist/data/charts/BarChart.cjs.map +1 -0
  416. package/dist/data/charts/BarChart.d.ts +19 -0
  417. package/dist/data/charts/BarChart.d.ts.map +1 -0
  418. package/dist/data/charts/BarChart.js +194 -0
  419. package/dist/data/charts/BarChart.js.map +1 -0
  420. package/dist/data/charts/ChartLegend.cjs +54 -0
  421. package/dist/data/charts/ChartLegend.cjs.map +1 -0
  422. package/dist/data/charts/ChartLegend.d.ts +17 -0
  423. package/dist/data/charts/ChartLegend.d.ts.map +1 -0
  424. package/dist/data/charts/ChartLegend.js +54 -0
  425. package/dist/data/charts/ChartLegend.js.map +1 -0
  426. package/dist/data/charts/Sparkline.cjs +56 -0
  427. package/dist/data/charts/Sparkline.cjs.map +1 -0
  428. package/dist/data/charts/Sparkline.d.ts +15 -0
  429. package/dist/data/charts/Sparkline.d.ts.map +1 -0
  430. package/dist/data/charts/Sparkline.js +56 -0
  431. package/dist/data/charts/Sparkline.js.map +1 -0
  432. package/dist/data/charts/StackedBarChart.cjs +241 -0
  433. package/dist/data/charts/StackedBarChart.cjs.map +1 -0
  434. package/dist/data/charts/StackedBarChart.d.ts +20 -0
  435. package/dist/data/charts/StackedBarChart.d.ts.map +1 -0
  436. package/dist/data/charts/StackedBarChart.js +241 -0
  437. package/dist/data/charts/StackedBarChart.js.map +1 -0
  438. package/dist/data/charts/TrendChart.cjs +157 -0
  439. package/dist/data/charts/TrendChart.cjs.map +1 -0
  440. package/dist/data/charts/TrendChart.d.ts +20 -0
  441. package/dist/data/charts/TrendChart.d.ts.map +1 -0
  442. package/dist/data/charts/TrendChart.js +157 -0
  443. package/dist/data/charts/TrendChart.js.map +1 -0
  444. package/dist/data/charts/chart-marks.cjs +115 -0
  445. package/dist/data/charts/chart-marks.cjs.map +1 -0
  446. package/dist/data/charts/chart-marks.d.ts +39 -0
  447. package/dist/data/charts/chart-marks.d.ts.map +1 -0
  448. package/dist/data/charts/chart-marks.js +112 -0
  449. package/dist/data/charts/chart-marks.js.map +1 -0
  450. package/dist/data/charts/chart-palette.cjs +74 -0
  451. package/dist/data/charts/chart-palette.cjs.map +1 -0
  452. package/dist/data/charts/chart-palette.d.ts +58 -0
  453. package/dist/data/charts/chart-palette.d.ts.map +1 -0
  454. package/dist/data/charts/chart-palette.js +72 -0
  455. package/dist/data/charts/chart-palette.js.map +1 -0
  456. package/dist/data/charts/chart-scale.cjs +115 -0
  457. package/dist/data/charts/chart-scale.cjs.map +1 -0
  458. package/dist/data/charts/chart-scale.d.ts +41 -0
  459. package/dist/data/charts/chart-scale.d.ts.map +1 -0
  460. package/dist/data/charts/chart-scale.js +104 -0
  461. package/dist/data/charts/chart-scale.js.map +1 -0
  462. package/dist/data/charts/chart.test-utils.d.ts +7 -0
  463. package/dist/data/charts/chart.test-utils.d.ts.map +1 -0
  464. package/dist/data/charts/index.d.ts +7 -0
  465. package/dist/data/charts/index.d.ts.map +1 -0
  466. package/dist/data/chat/MessageActions.cjs +1 -1
  467. package/dist/data/chat/MessageActions.cjs.map +1 -1
  468. package/dist/data/chat/MessageActions.js +1 -1
  469. package/dist/data/chat/MessageActions.js.map +1 -1
  470. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +1 -1
  471. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +1 -1
  472. package/dist/data/diagnostics/DiagnosticsTree.cjs +1 -1
  473. package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
  474. package/dist/data/diagnostics/DiagnosticsTree.js +1 -1
  475. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
  476. package/dist/data/diagnostics/FrameSourceWindow.cjs +9 -2
  477. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  478. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -1
  479. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  480. package/dist/data/diagnostics/FrameSourceWindow.js +9 -2
  481. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  482. package/dist/data/diagnostics/ProblemActions.cjs +37 -0
  483. package/dist/data/diagnostics/ProblemActions.cjs.map +1 -0
  484. package/dist/data/diagnostics/ProblemActions.d.ts +6 -0
  485. package/dist/data/diagnostics/ProblemActions.d.ts.map +1 -0
  486. package/dist/data/diagnostics/ProblemActions.js +37 -0
  487. package/dist/data/diagnostics/ProblemActions.js.map +1 -0
  488. package/dist/data/diagnostics/ProblemFacet.cjs +33 -0
  489. package/dist/data/diagnostics/ProblemFacet.cjs.map +1 -0
  490. package/dist/data/diagnostics/ProblemFacet.d.ts +9 -0
  491. package/dist/data/diagnostics/ProblemFacet.d.ts.map +1 -0
  492. package/dist/data/diagnostics/ProblemFacet.js +33 -0
  493. package/dist/data/diagnostics/ProblemFacet.js.map +1 -0
  494. package/dist/data/diagnostics/ProblemRow.cjs +62 -0
  495. package/dist/data/diagnostics/ProblemRow.cjs.map +1 -0
  496. package/dist/data/diagnostics/ProblemRow.d.ts +14 -0
  497. package/dist/data/diagnostics/ProblemRow.d.ts.map +1 -0
  498. package/dist/data/diagnostics/ProblemRow.js +62 -0
  499. package/dist/data/diagnostics/ProblemRow.js.map +1 -0
  500. package/dist/data/diagnostics/ProblemViewOptions.cjs +18 -0
  501. package/dist/data/diagnostics/ProblemViewOptions.cjs.map +1 -0
  502. package/dist/data/diagnostics/ProblemViewOptions.d.ts +6 -0
  503. package/dist/data/diagnostics/ProblemViewOptions.d.ts.map +1 -0
  504. package/dist/data/diagnostics/ProblemViewOptions.js +18 -0
  505. package/dist/data/diagnostics/ProblemViewOptions.js.map +1 -0
  506. package/dist/data/diagnostics/StackFrameRow.cjs +1 -1
  507. package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
  508. package/dist/data/diagnostics/StackFrameRow.js +1 -1
  509. package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
  510. package/dist/data/diagnostics/diagnostic-identity.cjs +14 -0
  511. package/dist/data/diagnostics/diagnostic-identity.cjs.map +1 -0
  512. package/dist/data/diagnostics/diagnostic-identity.d.ts +3 -0
  513. package/dist/data/diagnostics/diagnostic-identity.d.ts.map +1 -0
  514. package/dist/data/diagnostics/diagnostic-identity.js +14 -0
  515. package/dist/data/diagnostics/diagnostic-identity.js.map +1 -0
  516. package/dist/data/diagnostics/use-problem-expansion.cjs +16 -0
  517. package/dist/data/diagnostics/use-problem-expansion.cjs.map +1 -0
  518. package/dist/data/diagnostics/use-problem-expansion.d.ts +3 -0
  519. package/dist/data/diagnostics/use-problem-expansion.d.ts.map +1 -0
  520. package/dist/data/diagnostics/use-problem-expansion.js +16 -0
  521. package/dist/data/diagnostics/use-problem-expansion.js.map +1 -0
  522. package/dist/data/git/GitChangeList.cjs +9 -6
  523. package/dist/data/git/GitChangeList.cjs.map +1 -1
  524. package/dist/data/git/GitChangeList.d.ts +6 -0
  525. package/dist/data/git/GitChangeList.d.ts.map +1 -1
  526. package/dist/data/git/GitChangeList.js +9 -6
  527. package/dist/data/git/GitChangeList.js.map +1 -1
  528. package/dist/data/git/pickers/GitPickersDemo.d.ts.map +1 -1
  529. package/dist/data/git/pickers/ReferencePicker.cjs +1 -0
  530. package/dist/data/git/pickers/ReferencePicker.cjs.map +1 -1
  531. package/dist/data/git/pickers/ReferencePicker.js +1 -0
  532. package/dist/data/git/pickers/ReferencePicker.js.map +1 -1
  533. package/dist/data/lint/LintDetail.cjs +230 -189
  534. package/dist/data/lint/LintDetail.cjs.map +1 -1
  535. package/dist/data/lint/LintDetail.d.ts +25 -3
  536. package/dist/data/lint/LintDetail.d.ts.map +1 -1
  537. package/dist/data/lint/LintDetail.js +231 -192
  538. package/dist/data/lint/LintDetail.js.map +1 -1
  539. package/dist/data/lint/LintFilterBar.cjs +78 -83
  540. package/dist/data/lint/LintFilterBar.cjs.map +1 -1
  541. package/dist/data/lint/LintFilterBar.d.ts +23 -6
  542. package/dist/data/lint/LintFilterBar.d.ts.map +1 -1
  543. package/dist/data/lint/LintFilterBar.js +78 -85
  544. package/dist/data/lint/LintFilterBar.js.map +1 -1
  545. package/dist/data/lint/LintIgnoreMenu.cjs +59 -0
  546. package/dist/data/lint/LintIgnoreMenu.cjs.map +1 -0
  547. package/dist/data/lint/LintIgnoreMenu.d.ts +20 -0
  548. package/dist/data/lint/LintIgnoreMenu.d.ts.map +1 -0
  549. package/dist/data/lint/LintIgnoreMenu.js +58 -0
  550. package/dist/data/lint/LintIgnoreMenu.js.map +1 -0
  551. package/dist/data/lint/LintResults.cjs +59 -14
  552. package/dist/data/lint/LintResults.cjs.map +1 -1
  553. package/dist/data/lint/LintResults.d.ts +25 -1
  554. package/dist/data/lint/LintResults.d.ts.map +1 -1
  555. package/dist/data/lint/LintResults.fixtures.d.ts +19 -0
  556. package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -1
  557. package/dist/data/lint/LintResults.js +60 -15
  558. package/dist/data/lint/LintResults.js.map +1 -1
  559. package/dist/data/lint/LintTable.cjs +156 -0
  560. package/dist/data/lint/LintTable.cjs.map +1 -0
  561. package/dist/data/lint/LintTable.d.ts +13 -0
  562. package/dist/data/lint/LintTable.d.ts.map +1 -0
  563. package/dist/data/lint/LintTable.js +156 -0
  564. package/dist/data/lint/LintTable.js.map +1 -0
  565. package/dist/data/lint/LintTreeNode.cjs +42 -19
  566. package/dist/data/lint/LintTreeNode.cjs.map +1 -1
  567. package/dist/data/lint/LintTreeNode.d.ts +7 -2
  568. package/dist/data/lint/LintTreeNode.d.ts.map +1 -1
  569. package/dist/data/lint/LintTreeNode.js +44 -21
  570. package/dist/data/lint/LintTreeNode.js.map +1 -1
  571. package/dist/data/lint/ViolationSnippet.cjs +113 -0
  572. package/dist/data/lint/ViolationSnippet.cjs.map +1 -0
  573. package/dist/data/lint/ViolationSnippet.d.ts +20 -0
  574. package/dist/data/lint/ViolationSnippet.d.ts.map +1 -0
  575. package/dist/data/lint/ViolationSnippet.js +112 -0
  576. package/dist/data/lint/ViolationSnippet.js.map +1 -0
  577. package/dist/data/lint/actions.cjs +44 -16
  578. package/dist/data/lint/actions.cjs.map +1 -1
  579. package/dist/data/lint/actions.d.ts +7 -3
  580. package/dist/data/lint/actions.d.ts.map +1 -1
  581. package/dist/data/lint/actions.js +44 -16
  582. package/dist/data/lint/actions.js.map +1 -1
  583. package/dist/data/lint/grouping.cjs +105 -8
  584. package/dist/data/lint/grouping.cjs.map +1 -1
  585. package/dist/data/lint/grouping.d.ts +21 -1
  586. package/dist/data/lint/grouping.d.ts.map +1 -1
  587. package/dist/data/lint/grouping.js +105 -10
  588. package/dist/data/lint/grouping.js.map +1 -1
  589. package/dist/data/lint/ignore-menu-items.cjs +18 -0
  590. package/dist/data/lint/ignore-menu-items.cjs.map +1 -0
  591. package/dist/data/lint/ignore-menu-items.d.ts +6 -0
  592. package/dist/data/lint/ignore-menu-items.d.ts.map +1 -0
  593. package/dist/data/lint/ignore-menu-items.js +17 -0
  594. package/dist/data/lint/ignore-menu-items.js.map +1 -0
  595. package/dist/data/lint/index.d.ts +7 -5
  596. package/dist/data/lint/index.d.ts.map +1 -1
  597. package/dist/data/lint/stats.cjs +19 -4
  598. package/dist/data/lint/stats.cjs.map +1 -1
  599. package/dist/data/lint/stats.d.ts +13 -3
  600. package/dist/data/lint/stats.d.ts.map +1 -1
  601. package/dist/data/lint/stats.js +17 -5
  602. package/dist/data/lint/stats.js.map +1 -1
  603. package/dist/data/lint/types.cjs +8 -0
  604. package/dist/data/lint/types.cjs.map +1 -1
  605. package/dist/data/lint/types.d.ts +47 -0
  606. package/dist/data/lint/types.d.ts.map +1 -1
  607. package/dist/data/lint/types.js +8 -1
  608. package/dist/data/lint/types.js.map +1 -1
  609. package/dist/data/lint/violation-menu-items.cjs +31 -0
  610. package/dist/data/lint/violation-menu-items.cjs.map +1 -0
  611. package/dist/data/lint/violation-menu-items.d.ts +12 -0
  612. package/dist/data/lint/violation-menu-items.d.ts.map +1 -0
  613. package/dist/data/lint/violation-menu-items.js +31 -0
  614. package/dist/data/lint/violation-menu-items.js.map +1 -0
  615. package/dist/data/markdown-source-blocks.cjs +38 -0
  616. package/dist/data/markdown-source-blocks.cjs.map +1 -0
  617. package/dist/data/markdown-source-blocks.d.ts +32 -0
  618. package/dist/data/markdown-source-blocks.d.ts.map +1 -0
  619. package/dist/data/markdown-source-blocks.js +35 -0
  620. package/dist/data/markdown-source-blocks.js.map +1 -0
  621. package/dist/data/test-runner/FilterFacet.cjs +52 -0
  622. package/dist/data/test-runner/FilterFacet.cjs.map +1 -0
  623. package/dist/data/test-runner/FilterFacet.d.ts +13 -0
  624. package/dist/data/test-runner/FilterFacet.d.ts.map +1 -0
  625. package/dist/data/test-runner/FilterFacet.js +52 -0
  626. package/dist/data/test-runner/FilterFacet.js.map +1 -0
  627. package/dist/data/test-runner/MatrixMarks.cjs +42 -40
  628. package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
  629. package/dist/data/test-runner/MatrixMarks.d.ts +20 -4
  630. package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
  631. package/dist/data/test-runner/MatrixMarks.js +43 -42
  632. package/dist/data/test-runner/MatrixMarks.js.map +1 -1
  633. package/dist/data/test-runner/TestAttemptDetail.cjs +1 -1
  634. package/dist/data/test-runner/TestAttemptDetail.js +1 -1
  635. package/dist/data/test-runner/TestDetailPanel.cjs +11 -0
  636. package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
  637. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
  638. package/dist/data/test-runner/TestDetailPanel.js +11 -0
  639. package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
  640. package/dist/data/test-runner/TestFilterBar.cjs +3 -44
  641. package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
  642. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
  643. package/dist/data/test-runner/TestFilterBar.js +3 -44
  644. package/dist/data/test-runner/TestFilterBar.js.map +1 -1
  645. package/dist/data/test-runner/TestRunner.cjs +3 -1
  646. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  647. package/dist/data/test-runner/TestRunner.d.ts +7 -1
  648. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  649. package/dist/data/test-runner/TestRunner.js +3 -1
  650. package/dist/data/test-runner/TestRunner.js.map +1 -1
  651. package/dist/data/test-runner/context.cjs.map +1 -1
  652. package/dist/data/test-runner/context.d.ts +3 -0
  653. package/dist/data/test-runner/context.d.ts.map +1 -1
  654. package/dist/data/test-runner/context.js.map +1 -1
  655. package/dist/data/test-runner/index.d.ts +2 -2
  656. package/dist/data/test-runner/index.d.ts.map +1 -1
  657. package/dist/data/test-runner/matrix-marks.cjs +2 -11
  658. package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
  659. package/dist/data/test-runner/matrix-marks.d.ts +2 -4
  660. package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
  661. package/dist/data/test-runner/matrix-marks.js +3 -11
  662. package/dist/data/test-runner/matrix-marks.js.map +1 -1
  663. package/dist/data/test-runner/types.d.ts +2 -0
  664. package/dist/data/test-runner/types.d.ts.map +1 -1
  665. package/dist/data/timeseries-query.cjs +98 -2
  666. package/dist/data/timeseries-query.cjs.map +1 -1
  667. package/dist/data/timeseries-query.d.ts +31 -5
  668. package/dist/data/timeseries-query.d.ts.map +1 -1
  669. package/dist/data/timeseries-query.js +98 -3
  670. package/dist/data/timeseries-query.js.map +1 -1
  671. package/dist/data/timeseries-stream-provider.cjs +38 -0
  672. package/dist/data/timeseries-stream-provider.cjs.map +1 -0
  673. package/dist/data/timeseries-stream-provider.d.ts +26 -0
  674. package/dist/data/timeseries-stream-provider.d.ts.map +1 -0
  675. package/dist/data/timeseries-stream-provider.js +38 -0
  676. package/dist/data/timeseries-stream-provider.js.map +1 -0
  677. package/dist/data/timeseries-stream.cjs +304 -0
  678. package/dist/data/timeseries-stream.cjs.map +1 -0
  679. package/dist/data/timeseries-stream.d.ts +81 -0
  680. package/dist/data/timeseries-stream.d.ts.map +1 -0
  681. package/dist/data/timeseries-stream.fixtures.d.ts +36 -0
  682. package/dist/data/timeseries-stream.fixtures.d.ts.map +1 -0
  683. package/dist/data/timeseries-stream.js +296 -0
  684. package/dist/data/timeseries-stream.js.map +1 -0
  685. package/dist/data/token-style.cjs +13 -0
  686. package/dist/data/token-style.cjs.map +1 -0
  687. package/dist/data/token-style.d.ts +4 -0
  688. package/dist/data/token-style.d.ts.map +1 -0
  689. package/dist/data/token-style.js +13 -0
  690. package/dist/data/token-style.js.map +1 -0
  691. package/dist/data/traces/ProcessTraceDetail.cjs +1 -1
  692. package/dist/data/traces/ProcessTraceDetail.js +1 -1
  693. package/dist/data/traces/index.d.ts +1 -1
  694. package/dist/data/traces/index.d.ts.map +1 -1
  695. package/dist/data/use-data-table-virtual.d.ts +1 -1
  696. package/dist/data/version-info.cjs +3 -3
  697. package/dist/data/version-info.js +3 -3
  698. package/dist/data/workload-panel/MemoryStack.cjs +49 -0
  699. package/dist/data/workload-panel/MemoryStack.cjs.map +1 -0
  700. package/dist/data/workload-panel/MemoryStack.d.ts +11 -0
  701. package/dist/data/workload-panel/MemoryStack.d.ts.map +1 -0
  702. package/dist/data/workload-panel/MemoryStack.js +48 -0
  703. package/dist/data/workload-panel/MemoryStack.js.map +1 -0
  704. package/dist/data/workload-panel/Metrics.cjs +197 -0
  705. package/dist/data/workload-panel/Metrics.cjs.map +1 -0
  706. package/dist/data/workload-panel/Metrics.d.ts +11 -0
  707. package/dist/data/workload-panel/Metrics.d.ts.map +1 -0
  708. package/dist/data/workload-panel/Metrics.js +196 -0
  709. package/dist/data/workload-panel/Metrics.js.map +1 -0
  710. package/dist/data/workload-panel/WorkloadPanel.cjs +66 -0
  711. package/dist/data/workload-panel/WorkloadPanel.cjs.map +1 -0
  712. package/dist/data/workload-panel/WorkloadPanel.d.ts +3 -0
  713. package/dist/data/workload-panel/WorkloadPanel.d.ts.map +1 -0
  714. package/dist/data/workload-panel/WorkloadPanel.js +66 -0
  715. package/dist/data/workload-panel/WorkloadPanel.js.map +1 -0
  716. package/dist/data/workload-panel/fixtures.d.ts +60 -0
  717. package/dist/data/workload-panel/fixtures.d.ts.map +1 -0
  718. package/dist/data/workload-panel/model.cjs +137 -0
  719. package/dist/data/workload-panel/model.cjs.map +1 -0
  720. package/dist/data/workload-panel/model.d.ts +53 -0
  721. package/dist/data/workload-panel/model.d.ts.map +1 -0
  722. package/dist/data/workload-panel/model.js +133 -0
  723. package/dist/data/workload-panel/model.js.map +1 -0
  724. package/dist/data/workload-panel/types.d.ts +56 -0
  725. package/dist/data/workload-panel/types.d.ts.map +1 -0
  726. package/dist/data.cjs +58 -7
  727. package/dist/data.d.ts +9 -1
  728. package/dist/data.d.ts.map +1 -1
  729. package/dist/data.js +29 -12
  730. package/dist/file-findings/AnnotatedCode.cjs +243 -0
  731. package/dist/file-findings/AnnotatedCode.cjs.map +1 -0
  732. package/dist/file-findings/AnnotatedCode.d.ts +30 -0
  733. package/dist/file-findings/AnnotatedCode.d.ts.map +1 -0
  734. package/dist/file-findings/AnnotatedCode.js +243 -0
  735. package/dist/file-findings/AnnotatedCode.js.map +1 -0
  736. package/dist/file-findings/FileFindingsView.cjs +213 -0
  737. package/dist/file-findings/FileFindingsView.cjs.map +1 -0
  738. package/dist/file-findings/FileFindingsView.d.ts +35 -0
  739. package/dist/file-findings/FileFindingsView.d.ts.map +1 -0
  740. package/dist/file-findings/FileFindingsView.js +213 -0
  741. package/dist/file-findings/FileFindingsView.js.map +1 -0
  742. package/dist/file-findings/LazyAnnotatedCode.cjs +22 -0
  743. package/dist/file-findings/LazyAnnotatedCode.cjs.map +1 -0
  744. package/dist/file-findings/LazyAnnotatedCode.d.ts +5 -0
  745. package/dist/file-findings/LazyAnnotatedCode.d.ts.map +1 -0
  746. package/dist/file-findings/LazyAnnotatedCode.js +22 -0
  747. package/dist/file-findings/LazyAnnotatedCode.js.map +1 -0
  748. package/dist/file-findings/adapters.cjs +155 -0
  749. package/dist/file-findings/adapters.cjs.map +1 -0
  750. package/dist/file-findings/adapters.d.ts +24 -0
  751. package/dist/file-findings/adapters.d.ts.map +1 -0
  752. package/dist/file-findings/adapters.js +153 -0
  753. package/dist/file-findings/adapters.js.map +1 -0
  754. package/dist/file-findings/file-review/CommentDraft.cjs +97 -0
  755. package/dist/file-findings/file-review/CommentDraft.cjs.map +1 -0
  756. package/dist/file-findings/file-review/CommentDraft.d.ts +25 -0
  757. package/dist/file-findings/file-review/CommentDraft.d.ts.map +1 -0
  758. package/dist/file-findings/file-review/CommentDraft.js +97 -0
  759. package/dist/file-findings/file-review/CommentDraft.js.map +1 -0
  760. package/dist/file-findings/file-review/FileReview.cjs +863 -0
  761. package/dist/file-findings/file-review/FileReview.cjs.map +1 -0
  762. package/dist/file-findings/file-review/FileReview.d.ts +79 -0
  763. package/dist/file-findings/file-review/FileReview.d.ts.map +1 -0
  764. package/dist/file-findings/file-review/FileReview.fixtures.d.ts +25 -0
  765. package/dist/file-findings/file-review/FileReview.fixtures.d.ts.map +1 -0
  766. package/dist/file-findings/file-review/FileReview.js +863 -0
  767. package/dist/file-findings/file-review/FileReview.js.map +1 -0
  768. package/dist/file-findings/file-review/InlineAuthors.cjs +77 -0
  769. package/dist/file-findings/file-review/InlineAuthors.cjs.map +1 -0
  770. package/dist/file-findings/file-review/InlineAuthors.d.ts +9 -0
  771. package/dist/file-findings/file-review/InlineAuthors.d.ts.map +1 -0
  772. package/dist/file-findings/file-review/InlineAuthors.js +77 -0
  773. package/dist/file-findings/file-review/InlineAuthors.js.map +1 -0
  774. package/dist/file-findings/file-review/InlineThread.cjs +77 -0
  775. package/dist/file-findings/file-review/InlineThread.cjs.map +1 -0
  776. package/dist/file-findings/file-review/InlineThread.d.ts +27 -0
  777. package/dist/file-findings/file-review/InlineThread.d.ts.map +1 -0
  778. package/dist/file-findings/file-review/InlineThread.js +77 -0
  779. package/dist/file-findings/file-review/InlineThread.js.map +1 -0
  780. package/dist/file-findings/file-review/ProblemsList.cjs +164 -0
  781. package/dist/file-findings/file-review/ProblemsList.cjs.map +1 -0
  782. package/dist/file-findings/file-review/ProblemsList.d.ts +15 -0
  783. package/dist/file-findings/file-review/ProblemsList.d.ts.map +1 -0
  784. package/dist/file-findings/file-review/ProblemsList.js +164 -0
  785. package/dist/file-findings/file-review/ProblemsList.js.map +1 -0
  786. package/dist/file-findings/file-review/SourceView.cjs +179 -0
  787. package/dist/file-findings/file-review/SourceView.cjs.map +1 -0
  788. package/dist/file-findings/file-review/SourceView.d.ts +29 -0
  789. package/dist/file-findings/file-review/SourceView.d.ts.map +1 -0
  790. package/dist/file-findings/file-review/SourceView.js +179 -0
  791. package/dist/file-findings/file-review/SourceView.js.map +1 -0
  792. package/dist/file-findings/file-review/blame.cjs +35 -0
  793. package/dist/file-findings/file-review/blame.cjs.map +1 -0
  794. package/dist/file-findings/file-review/blame.d.ts +28 -0
  795. package/dist/file-findings/file-review/blame.d.ts.map +1 -0
  796. package/dist/file-findings/file-review/blame.js +33 -0
  797. package/dist/file-findings/file-review/blame.js.map +1 -0
  798. package/dist/file-findings/file-review/geometry.cjs +101 -0
  799. package/dist/file-findings/file-review/geometry.cjs.map +1 -0
  800. package/dist/file-findings/file-review/geometry.d.ts +45 -0
  801. package/dist/file-findings/file-review/geometry.d.ts.map +1 -0
  802. package/dist/file-findings/file-review/geometry.js +98 -0
  803. package/dist/file-findings/file-review/geometry.js.map +1 -0
  804. package/dist/file-findings/file-review/hooks.cjs +101 -0
  805. package/dist/file-findings/file-review/hooks.cjs.map +1 -0
  806. package/dist/file-findings/file-review/hooks.d.ts +22 -0
  807. package/dist/file-findings/file-review/hooks.d.ts.map +1 -0
  808. package/dist/file-findings/file-review/hooks.js +99 -0
  809. package/dist/file-findings/file-review/hooks.js.map +1 -0
  810. package/dist/file-findings/file-review/marks.cjs +52 -0
  811. package/dist/file-findings/file-review/marks.cjs.map +1 -0
  812. package/dist/file-findings/file-review/marks.d.ts +23 -0
  813. package/dist/file-findings/file-review/marks.d.ts.map +1 -0
  814. package/dist/file-findings/file-review/marks.js +47 -0
  815. package/dist/file-findings/file-review/marks.js.map +1 -0
  816. package/dist/file-findings/file-review/problem-filters.cjs +14 -0
  817. package/dist/file-findings/file-review/problem-filters.cjs.map +1 -0
  818. package/dist/file-findings/file-review/problem-filters.d.ts +10 -0
  819. package/dist/file-findings/file-review/problem-filters.d.ts.map +1 -0
  820. package/dist/file-findings/file-review/problem-filters.js +13 -0
  821. package/dist/file-findings/file-review/problem-filters.js.map +1 -0
  822. package/dist/file-findings/file-review/quote-anchor.cjs +234 -0
  823. package/dist/file-findings/file-review/quote-anchor.cjs.map +1 -0
  824. package/dist/file-findings/file-review/quote-anchor.d.ts +54 -0
  825. package/dist/file-findings/file-review/quote-anchor.d.ts.map +1 -0
  826. package/dist/file-findings/file-review/quote-anchor.js +226 -0
  827. package/dist/file-findings/file-review/quote-anchor.js.map +1 -0
  828. package/dist/file-findings/file-review/source-anchor.cjs +104 -0
  829. package/dist/file-findings/file-review/source-anchor.cjs.map +1 -0
  830. package/dist/file-findings/file-review/source-anchor.d.ts +27 -0
  831. package/dist/file-findings/file-review/source-anchor.d.ts.map +1 -0
  832. package/dist/file-findings/file-review/source-anchor.js +99 -0
  833. package/dist/file-findings/file-review/source-anchor.js.map +1 -0
  834. package/dist/file-findings/file-review/source-marks.cjs +71 -0
  835. package/dist/file-findings/file-review/source-marks.cjs.map +1 -0
  836. package/dist/file-findings/file-review/source-marks.d.ts +27 -0
  837. package/dist/file-findings/file-review/source-marks.d.ts.map +1 -0
  838. package/dist/file-findings/file-review/source-marks.js +68 -0
  839. package/dist/file-findings/file-review/source-marks.js.map +1 -0
  840. package/dist/file-findings/findings-comments.cjs +136 -0
  841. package/dist/file-findings/findings-comments.cjs.map +1 -0
  842. package/dist/file-findings/findings-comments.d.ts +28 -0
  843. package/dist/file-findings/findings-comments.d.ts.map +1 -0
  844. package/dist/file-findings/findings-comments.js +131 -0
  845. package/dist/file-findings/findings-comments.js.map +1 -0
  846. package/dist/file-findings/findings-languages.cjs +53 -0
  847. package/dist/file-findings/findings-languages.cjs.map +1 -0
  848. package/dist/file-findings/findings-languages.d.ts +11 -0
  849. package/dist/file-findings/findings-languages.d.ts.map +1 -0
  850. package/dist/file-findings/findings-languages.js +53 -0
  851. package/dist/file-findings/findings-languages.js.map +1 -0
  852. package/dist/file-findings/mdx-source.cjs +48 -0
  853. package/dist/file-findings/mdx-source.cjs.map +1 -0
  854. package/dist/file-findings/mdx-source.d.ts +7 -0
  855. package/dist/file-findings/mdx-source.d.ts.map +1 -0
  856. package/dist/file-findings/mdx-source.js +48 -0
  857. package/dist/file-findings/mdx-source.js.map +1 -0
  858. package/dist/file-findings/monaco-language.cjs +73 -0
  859. package/dist/file-findings/monaco-language.cjs.map +1 -0
  860. package/dist/file-findings/monaco-language.d.ts +11 -0
  861. package/dist/file-findings/monaco-language.d.ts.map +1 -0
  862. package/dist/file-findings/monaco-language.js +72 -0
  863. package/dist/file-findings/monaco-language.js.map +1 -0
  864. package/dist/file-findings/severity-counts.cjs +20 -0
  865. package/dist/file-findings/severity-counts.cjs.map +1 -0
  866. package/dist/file-findings/severity-counts.d.ts +5 -0
  867. package/dist/file-findings/severity-counts.d.ts.map +1 -0
  868. package/dist/file-findings/severity-counts.js +19 -0
  869. package/dist/file-findings/severity-counts.js.map +1 -0
  870. package/dist/file-findings/types.cjs +12 -0
  871. package/dist/file-findings/types.cjs.map +1 -0
  872. package/dist/file-findings/types.d.ts +43 -0
  873. package/dist/file-findings/types.d.ts.map +1 -0
  874. package/dist/file-findings/types.js +11 -0
  875. package/dist/file-findings/types.js.map +1 -0
  876. package/dist/file-findings.cjs +47 -0
  877. package/dist/file-findings.d.ts +15 -0
  878. package/dist/file-findings.d.ts.map +1 -0
  879. package/dist/file-findings.js +15 -0
  880. package/dist/hooks/event-hub.cjs +22 -8
  881. package/dist/hooks/event-hub.cjs.map +1 -1
  882. package/dist/hooks/event-hub.d.ts.map +1 -1
  883. package/dist/hooks/event-hub.js +22 -8
  884. package/dist/hooks/event-hub.js.map +1 -1
  885. package/dist/icons/components/UiBrowser.cjs +51 -0
  886. package/dist/icons/components/UiBrowser.cjs.map +1 -0
  887. package/dist/icons/components/UiBrowser.d.ts +15 -0
  888. package/dist/icons/components/UiBrowser.d.ts.map +1 -0
  889. package/dist/icons/components/UiBrowser.js +48 -0
  890. package/dist/icons/components/UiBrowser.js.map +1 -0
  891. package/dist/icons/components/UiCreditCard.cjs +51 -0
  892. package/dist/icons/components/UiCreditCard.cjs.map +1 -0
  893. package/dist/icons/components/UiCreditCard.d.ts +15 -0
  894. package/dist/icons/components/UiCreditCard.d.ts.map +1 -0
  895. package/dist/icons/components/UiCreditCard.js +48 -0
  896. package/dist/icons/components/UiCreditCard.js.map +1 -0
  897. package/dist/icons/components/UiShoppingCart.cjs +51 -0
  898. package/dist/icons/components/UiShoppingCart.cjs.map +1 -0
  899. package/dist/icons/components/UiShoppingCart.d.ts +15 -0
  900. package/dist/icons/components/UiShoppingCart.d.ts.map +1 -0
  901. package/dist/icons/components/UiShoppingCart.js +48 -0
  902. package/dist/icons/components/UiShoppingCart.js.map +1 -0
  903. package/dist/icons/index.d.ts +6 -0
  904. package/dist/icons/index.d.ts.map +1 -1
  905. package/dist/icons/registry.cjs +6 -0
  906. package/dist/icons/registry.cjs.map +1 -1
  907. package/dist/icons/registry.d.ts.map +1 -1
  908. package/dist/icons/registry.js +6 -0
  909. package/dist/icons/registry.js.map +1 -1
  910. package/dist/icons.cjs +9 -0
  911. package/dist/icons.js +4 -1
  912. package/dist/index.cjs +76 -8
  913. package/dist/index.d.ts +1 -0
  914. package/dist/index.d.ts.map +1 -1
  915. package/dist/index.js +37 -14
  916. package/dist/layout/AppShell.cjs +37 -21
  917. package/dist/layout/AppShell.cjs.map +1 -1
  918. package/dist/layout/AppShell.d.ts +13 -2
  919. package/dist/layout/AppShell.d.ts.map +1 -1
  920. package/dist/layout/AppShell.js +37 -21
  921. package/dist/layout/AppShell.js.map +1 -1
  922. package/dist/layout/AppShell.nav.cjs +7 -6
  923. package/dist/layout/AppShell.nav.cjs.map +1 -1
  924. package/dist/layout/AppShell.nav.d.ts.map +1 -1
  925. package/dist/layout/AppShell.nav.js +7 -6
  926. package/dist/layout/AppShell.nav.js.map +1 -1
  927. package/dist/layout/SplitPane.cjs +16 -6
  928. package/dist/layout/SplitPane.cjs.map +1 -1
  929. package/dist/layout/SplitPane.d.ts +12 -2
  930. package/dist/layout/SplitPane.d.ts.map +1 -1
  931. package/dist/layout/SplitPane.js +16 -6
  932. package/dist/layout/SplitPane.js.map +1 -1
  933. package/dist/layout/Workspace.cjs +37 -33
  934. package/dist/layout/Workspace.cjs.map +1 -1
  935. package/dist/layout/Workspace.d.ts.map +1 -1
  936. package/dist/layout/Workspace.js +37 -33
  937. package/dist/layout/Workspace.js.map +1 -1
  938. package/dist/layout/Workspace.regions.cjs +3 -3
  939. package/dist/layout/Workspace.regions.cjs.map +1 -1
  940. package/dist/layout/Workspace.regions.js +3 -3
  941. package/dist/layout/Workspace.regions.js.map +1 -1
  942. package/dist/lib/breakpoints.cjs +102 -0
  943. package/dist/lib/breakpoints.cjs.map +1 -0
  944. package/dist/lib/breakpoints.d.ts +36 -0
  945. package/dist/lib/breakpoints.d.ts.map +1 -0
  946. package/dist/lib/breakpoints.js +99 -0
  947. package/dist/lib/breakpoints.js.map +1 -0
  948. package/dist/lib/combobox.cjs +2 -1
  949. package/dist/lib/combobox.cjs.map +1 -1
  950. package/dist/lib/combobox.d.ts +1 -1
  951. package/dist/lib/combobox.d.ts.map +1 -1
  952. package/dist/lib/combobox.js +2 -1
  953. package/dist/lib/combobox.js.map +1 -1
  954. package/dist/lib/path-tree.cjs +21 -0
  955. package/dist/lib/path-tree.cjs.map +1 -1
  956. package/dist/lib/path-tree.d.ts +15 -0
  957. package/dist/lib/path-tree.d.ts.map +1 -1
  958. package/dist/lib/path-tree.js +21 -1
  959. package/dist/lib/path-tree.js.map +1 -1
  960. package/dist/overlay/Modal.cjs +2 -1
  961. package/dist/overlay/Modal.cjs.map +1 -1
  962. package/dist/overlay/Modal.d.ts.map +1 -1
  963. package/dist/overlay/Modal.js +2 -1
  964. package/dist/overlay/Modal.js.map +1 -1
  965. package/dist/overlay/dropdownMenuContext.d.ts +1 -1
  966. package/dist/profiles/editor/profileEditor.cjs +1 -1
  967. package/dist/profiles/editor/profileEditor.cjs.map +1 -1
  968. package/dist/profiles/editor/profileEditor.js +1 -1
  969. package/dist/profiles/editor/profileEditor.js.map +1 -1
  970. package/dist/profiles/editor/profileEditorSections.cjs +2 -2
  971. package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
  972. package/dist/profiles/editor/profileEditorSections.js +2 -2
  973. package/dist/profiles/editor/profileEditorSections.js.map +1 -1
  974. package/dist/profiles/query/prometheusResults.cjs +24 -36
  975. package/dist/profiles/query/prometheusResults.cjs.map +1 -1
  976. package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
  977. package/dist/profiles/query/prometheusResults.js +24 -36
  978. package/dist/profiles/query/prometheusResults.js.map +1 -1
  979. package/dist/rpc/CommandForm.cjs +1 -1
  980. package/dist/rpc/CommandForm.cjs.map +1 -1
  981. package/dist/rpc/CommandForm.js +1 -1
  982. package/dist/rpc/CommandForm.js.map +1 -1
  983. package/dist/rpc/classify.cjs +1 -1
  984. package/dist/rpc/classify.cjs.map +1 -1
  985. package/dist/rpc/classify.d.ts.map +1 -1
  986. package/dist/rpc/classify.js +1 -1
  987. package/dist/rpc/classify.js.map +1 -1
  988. package/dist/rpc/useOperations.d.ts +24 -24
  989. package/dist/rpc.cjs +0 -2
  990. package/dist/rpc.d.ts +0 -1
  991. package/dist/rpc.d.ts.map +1 -1
  992. package/dist/rpc.js +1 -2
  993. package/dist/styles.css +1 -1
  994. package/dist/utils.cjs +6 -0
  995. package/dist/utils.d.ts +2 -1
  996. package/dist/utils.d.ts.map +1 -1
  997. package/dist/utils.js +3 -2
  998. package/package.json +9 -3
  999. package/schemas/json-schema-form.schema.json +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CommentCard.js","names":["_Fragment"],"sources":["../../src/comments/CommentCard.tsx"],"sourcesContent":["import { useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu, type DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport {\n parseTimestamp,\n formatRelativeTime,\n} from \"../data/cells/timestamp-format\";\nimport {\n UiCheck,\n UiCopy,\n UiDotsVertical,\n UiFullscreen,\n UiLock,\n UiRestart,\n UiTrash,\n} from \"../icons\";\nimport { CommentAuthorAvatar } from \"./CommentAuthor\";\nimport {\n ChecklistChips,\n FacetBadges,\n RatingChip,\n ReviewDecisionChip,\n RefChips,\n StatusChip,\n} from \"./CommentCardParts\";\nimport { CommentMarkdown } from \"./CommentMarkdown\";\nimport { authorDisplayName, truncatePlain } from \"./comment-utils\";\nimport {\n resolveCommentStage,\n statusForCommentStage,\n} from \"../lib/comment-stage\";\nimport type { Comment, CommentConfig } from \"./comment-types\";\n\nexport type CommentCardProps = {\n comment: Comment;\n config: CommentConfig;\n /** Tighter padding for dense rails. */\n compact?: boolean;\n /** Render expanded on first mount. */\n defaultExpanded?: boolean;\n /** Custom body renderer; defaults to the lightweight CommentMarkdown. */\n renderBody?: (body: string) => ReactNode;\n /** Change this comment's status (roots only). */\n onUpdateStatus?: (status: string) => void | Promise<void>;\n /** Close an active or resolved root comment. */\n onClose?: () => void | Promise<void>;\n /** Delete this comment. */\n onDelete?: () => void;\n /** Copy this comment's whole thread in the caller's canonical format. */\n onCopy?: () => void | Promise<void>;\n /** Begin a reply to this comment. */\n onReply?: () => void;\n /** Advance the checklist item at `index` to its next status. */\n onChecklistToggle?: (index: number) => void;\n /**\n * Open this card's thread in a larger view. Owned by the caller because a\n * card knows only itself, while maximizing shows the root and its replies.\n * Omit to drop the action (e.g. inside an already-maximized thread).\n */\n onMaximize?: () => void;\n};\n\nfunction actionMenuItems(\n isReply: boolean,\n opts: {\n onDelete?: () => void;\n statusActions?: DropdownMenuItem[];\n onCopy?: () => void;\n onMaximize?: () => void;\n },\n): DropdownMenuItem[] {\n const items: DropdownMenuItem[] = [];\n if (opts.onDelete) {\n items.push({ label: \"Delete\", icon: UiTrash, onSelect: opts.onDelete });\n }\n if (!isReply) items.push(...(opts.statusActions ?? []));\n if (opts.onCopy) {\n items.push({ label: \"Copy\", icon: UiCopy, onSelect: opts.onCopy });\n }\n if (opts.onMaximize) {\n items.push({\n label: \"Maximise\",\n icon: UiFullscreen,\n onSelect: opts.onMaximize,\n });\n }\n return items;\n}\n\nfunction CommentBody({\n comment,\n config,\n renderBody,\n onUpdateStatus,\n onClose,\n onDelete,\n onCopy,\n onReply,\n onChecklistToggle,\n onMaximize,\n}: CommentCardProps) {\n const [actionError, setActionError] = useState(\"\");\n const isReply = Boolean(comment.parentId);\n const date = parseTimestamp(comment.createdAt);\n const resolved = statusForCommentStage(config, \"resolved\");\n const active = statusForCommentStage(config, \"active\");\n const closed = statusForCommentStage(config, \"closed\");\n const stage = resolveCommentStage(config, comment.status);\n const updateStatus = async (status: string) => {\n setActionError(\"\");\n try {\n await onUpdateStatus?.(status);\n } catch (error) {\n setActionError(\n `Couldn't update comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const close = async () => {\n setActionError(\"\");\n try {\n await onClose?.();\n } catch (error) {\n setActionError(\n `Couldn't close comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const copy = async () => {\n setActionError(\"\");\n try {\n await onCopy?.();\n } catch (error) {\n setActionError(\n `Couldn't copy comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const menuItems = actionMenuItems(isReply, {\n ...(onDelete ? { onDelete } : {}),\n statusActions: [\n ...(stage === \"active\" && onUpdateStatus && resolved\n ? [\n {\n label: \"Resolve\",\n icon: UiCheck,\n onSelect: () => void updateStatus(resolved.value),\n },\n ]\n : []),\n ...((stage === \"active\" || stage === \"resolved\") && onClose && closed\n ? [\n {\n label: \"Close\",\n icon: UiLock,\n onSelect: () => void close(),\n },\n ]\n : []),\n ...((stage === \"resolved\" || stage === \"closed\") &&\n onUpdateStatus &&\n active\n ? [\n {\n label: \"Reopen\",\n icon: UiRestart,\n onSelect: () => void updateStatus(active.value),\n },\n ]\n : []),\n ],\n ...(onCopy ? { onCopy: () => void copy() } : {}),\n ...(onMaximize ? { onMaximize } : {}),\n });\n\n return (\n <div className=\"space-y-2.5\">\n <div className=\"flex items-start gap-2.5\">\n <CommentAuthorAvatar author={comment.author} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 items-baseline gap-1.5\">\n <span className=\"truncate text-xs font-semibold text-foreground\">\n {authorDisplayName(comment.author)}\n </span>\n {date && (\n <span\n title={date.toLocaleString()}\n className=\"shrink-0 text-[10px] text-muted-foreground\"\n >\n {formatRelativeTime(date)}\n </span>\n )}\n </div>\n {!isReply && (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n <StatusChip comment={comment} config={config} />\n <RatingChip rating={comment.rating} />\n <ReviewDecisionChip decision={comment.reviewDecision} />\n <FacetBadges comment={comment} config={config} />\n </div>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-0.5\">\n {!isReply &&\n (stage === \"active\" || stage === \"resolved\") &&\n onClose &&\n closed && (\n <button\n type=\"button\"\n aria-label=\"Close comment\"\n title=\"Close comment\"\n onClick={() => void close()}\n className=\"inline-flex rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Icon icon={UiCheck} className=\"text-sm\" />\n </button>\n )}\n {!isReply && stage === \"closed\" && onUpdateStatus && active && (\n <button\n type=\"button\"\n aria-label=\"Reopen comment\"\n title=\"Reopen comment\"\n onClick={() => void updateStatus(active.value)}\n className=\"inline-flex rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <Icon icon={UiRestart} className=\"text-sm\" />\n </button>\n )}\n {menuItems.length > 0 && (\n <DropdownMenu\n align=\"right\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n aria-label=\"Comment actions\"\n className=\"inline-flex rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n >\n <Icon icon={UiDotsVertical} className=\"text-sm\" />\n </span>\n }\n items={menuItems}\n />\n )}\n </div>\n </div>\n {comment.body.trim() && (\n <div className=\"text-[13px] leading-5 text-foreground\">\n {renderBody ? (\n renderBody(comment.body)\n ) : (\n <CommentMarkdown text={comment.body} />\n )}\n </div>\n )}\n {actionError && (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/30 bg-destructive/5 px-2.5 py-2 text-xs text-destructive\"\n >\n {actionError}\n </div>\n )}\n {!isReply && (\n <ChecklistChips\n comment={comment}\n {...(onChecklistToggle ? { onChecklistToggle } : {})}\n />\n )}\n {!isReply && <RefChips comment={comment} />}\n {onReply && (\n <button\n type=\"button\"\n onClick={onReply}\n className=\"-ml-2 rounded px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-primary/10\"\n >\n Reply\n </button>\n )}\n </div>\n );\n}\n\n/**\n * A single comment, collapsible between a compact one-line preview and a full\n * card. Offers a Maximise action when `onMaximize` is supplied — the owner\n * enlarges the whole thread. Fully controlled — all mutations are delegated to\n * the supplied callbacks.\n */\nexport function CommentCard(props: CommentCardProps) {\n const { comment, config, compact, defaultExpanded } = props;\n const [expanded, setExpanded] = useState(defaultExpanded ?? false);\n const [collapsedActionError, setCollapsedActionError] = useState(\"\");\n const isReply = Boolean(comment.parentId);\n const body = <CommentBody {...props} />;\n\n async function runCollapsedAction(action: \"resolve\" | \"close\" | \"reopen\") {\n setCollapsedActionError(\"\");\n try {\n if (action === \"close\") {\n await props.onClose?.();\n return;\n }\n const next = statusForCommentStage(\n config,\n action === \"resolve\" ? \"resolved\" : \"active\",\n );\n if (next) await props.onUpdateStatus?.(next.value);\n } catch (error) {\n setCollapsedActionError(\n `${action === \"close\" ? \"Couldn't close comment\" : \"Couldn't update comment\"}: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n }\n\n async function copyCollapsed() {\n setCollapsedActionError(\"\");\n try {\n await props.onCopy?.();\n } catch (error) {\n setCollapsedActionError(\n `Couldn't copy comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n }\n\n if (!expanded) {\n return (\n <>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => setExpanded(true)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setExpanded(true);\n }\n }}\n data-testid=\"comment-card\"\n data-comment-kind={isReply ? \"reply\" : \"root\"}\n data-comment-id={comment.id}\n className={cn(\n \"group/comment flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-xs transition-colors hover:bg-muted/50\",\n !isReply && \"border border-border bg-background shadow-sm\",\n isReply && \"ml-4 border-l-2 border-l-border bg-muted/30\",\n )}\n >\n <CommentAuthorAvatar author={comment.author} bare />\n <span className=\"shrink-0 text-[11px] font-semibold text-foreground\">\n {authorDisplayName(comment.author)}\n </span>\n {!isReply && (\n <>\n <StatusChip comment={comment} config={config} />\n <RatingChip rating={comment.rating} />\n <ReviewDecisionChip decision={comment.reviewDecision} />\n <FacetBadges comment={comment} config={config} compact />\n </>\n )}\n <span className=\"min-w-0 flex-1 truncate text-[12px] text-foreground/80\">\n {comment.body.trim()\n ? truncatePlain(comment.body)\n : comment.rating === \"positive\"\n ? \"Positive rating\"\n : comment.rating === \"negative\"\n ? \"Negative rating\"\n : comment.reviewDecision === \"approved\"\n ? \"Approved\"\n : \"Empty comment\"}\n </span>\n <span\n role=\"presentation\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <DropdownMenu\n align=\"right\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n aria-label=\"Comment actions\"\n className=\"rounded p-0.5 text-muted-foreground opacity-0 transition-opacity hover:bg-muted hover:opacity-100 group-hover/comment:opacity-70\"\n >\n <Icon icon={UiDotsVertical} className=\"text-sm\" />\n </span>\n }\n items={actionMenuItems(isReply, {\n ...(props.onDelete ? { onDelete: props.onDelete } : {}),\n statusActions: [\n ...(resolveCommentStage(config, comment.status) ===\n \"active\" &&\n props.onUpdateStatus &&\n statusForCommentStage(config, \"resolved\")\n ? [\n {\n label: \"Resolve\",\n icon: UiCheck,\n onSelect: () => void runCollapsedAction(\"resolve\"),\n },\n ]\n : []),\n ...((resolveCommentStage(config, comment.status) ===\n \"active\" ||\n resolveCommentStage(config, comment.status) ===\n \"resolved\") &&\n props.onClose &&\n statusForCommentStage(config, \"closed\")\n ? [\n {\n label: \"Close\",\n icon: UiLock,\n onSelect: () => void runCollapsedAction(\"close\"),\n },\n ]\n : []),\n ...((resolveCommentStage(config, comment.status) ===\n \"resolved\" ||\n resolveCommentStage(config, comment.status) === \"closed\") &&\n props.onUpdateStatus &&\n statusForCommentStage(config, \"active\")\n ? [\n {\n label: \"Reopen\",\n icon: UiRestart,\n onSelect: () => void runCollapsedAction(\"reopen\"),\n },\n ]\n : []),\n ],\n ...(props.onCopy ? { onCopy: () => void copyCollapsed() } : {}),\n ...(props.onMaximize ? { onMaximize: props.onMaximize } : {}),\n })}\n />\n </span>\n </div>\n {collapsedActionError && (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/30 bg-destructive/5 px-2.5 py-2 text-xs text-destructive\"\n >\n {collapsedActionError}\n </div>\n )}\n </>\n );\n }\n\n return (\n <>\n <div\n data-testid=\"comment-card\"\n data-comment-kind={isReply ? \"reply\" : \"root\"}\n data-comment-id={comment.id}\n className={cn(\n \"group/comment rounded-xl bg-background px-3.5 py-3 text-xs\",\n !isReply &&\n \"border border-border/80 shadow-sm transition-shadow hover:shadow-md\",\n compact && \"px-2.5 py-2.5\",\n isReply && \"ml-4 border-l-2 border-l-border bg-muted/20 shadow-none\",\n )}\n >\n {body}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentCard.js","names":["_Fragment"],"sources":["../../src/comments/CommentCard.tsx"],"sourcesContent":["import { useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu, type DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport {\n parseTimestamp,\n formatRelativeTime,\n} from \"../data/cells/timestamp-format\";\nimport {\n UiCheck,\n UiCopy,\n UiDotsVertical,\n UiFullscreen,\n UiLock,\n UiRestart,\n UiTrash,\n} from \"../icons\";\nimport { CommentAuthorAvatar } from \"./CommentAuthor\";\nimport {\n ChecklistChips,\n FacetBadges,\n RatingChip,\n ReviewDecisionChip,\n RefChips,\n StatusChip,\n} from \"./CommentCardParts\";\nimport { CommentMarkdown } from \"./CommentMarkdown\";\nimport {\n assignmentMenuItems,\n type CommentActionRunner,\n} from \"./comment-assign\";\nimport { authorDisplayName, truncatePlain } from \"./comment-utils\";\nimport {\n resolveCommentStage,\n statusForCommentStage,\n} from \"../lib/comment-stage\";\nimport type { Comment, CommentAuthor, CommentConfig } from \"./comment-types\";\n\nexport type CommentCardProps = {\n comment: Comment;\n config: CommentConfig;\n /** Tighter padding for dense rails. */\n compact?: boolean;\n /** Render expanded on first mount. */\n defaultExpanded?: boolean;\n /** Custom body renderer; defaults to the lightweight CommentMarkdown. */\n renderBody?: (body: string) => ReactNode;\n /** Change this comment's status (roots only). */\n onUpdateStatus?: (status: string) => void | Promise<void>;\n /** Close an active or resolved root comment. */\n onClose?: () => void | Promise<void>;\n /** Claim an unassigned active root for the current user or agent. */\n onAcknowledge?: () => void | Promise<void>;\n /** Hand an active root to an assignee, or clear it with `null`. */\n onAssign?: (assignee: CommentAuthor | null) => void | Promise<void>;\n /**\n * Caller-owned entries appended to the \"Assign…\" submenu, such as a run-agent\n * action. Computed per comment so they can reflect its state.\n */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n /** Delete this comment. */\n onDelete?: () => void;\n /** Copy this comment's whole thread in the caller's canonical format. */\n onCopy?: () => void | Promise<void>;\n /** Begin a reply to this comment. */\n onReply?: () => void;\n /** Advance the checklist item at `index` to its next status. */\n onChecklistToggle?: (index: number) => void;\n /**\n * Open this card's thread in a larger view. Owned by the caller because a\n * card knows only itself, while maximizing shows the root and its replies.\n * Omit to drop the action (e.g. inside an already-maximized thread).\n */\n onMaximize?: () => void;\n};\n\nfunction actionMenuItems(\n isReply: boolean,\n opts: {\n onDelete?: () => void;\n statusActions?: DropdownMenuItem[];\n onCopy?: () => void;\n onMaximize?: () => void;\n },\n): DropdownMenuItem[] {\n const items: DropdownMenuItem[] = [];\n if (opts.onDelete) {\n items.push({ label: \"Delete\", icon: UiTrash, onSelect: opts.onDelete });\n }\n if (!isReply) items.push(...(opts.statusActions ?? []));\n if (opts.onCopy) {\n items.push({ label: \"Copy\", icon: UiCopy, onSelect: opts.onCopy });\n }\n if (opts.onMaximize) {\n items.push({\n label: \"Maximise\",\n icon: UiFullscreen,\n onSelect: opts.onMaximize,\n });\n }\n return items;\n}\n\n/** A runner for {@link assignmentMenuItems} that shows a failure through `setError`. */\nfunction reportingRunner(setError: (message: string) => void): CommentActionRunner {\n return (verb, action) => {\n setError(\"\");\n void (async () => {\n try {\n await action();\n } catch (cause) {\n setError(\n `Couldn't ${verb} comment: ${cause instanceof Error ? cause.message : \"Unexpected error\"}`,\n );\n }\n })();\n };\n}\n\n/** The Acknowledge and Assign… entries for a root; none for replies. */\nfunction rootAssignmentItems(\n props: CommentCardProps,\n run: CommentActionRunner,\n): DropdownMenuItem[] {\n const { comment, config, onAcknowledge, onAssign, extraAssignItems } = props;\n return assignmentMenuItems({\n comment,\n config,\n run,\n ...(onAcknowledge ? { onAcknowledge } : {}),\n ...(onAssign ? { onAssign } : {}),\n ...(extraAssignItems ? { extraAssignItems } : {}),\n });\n}\n\nfunction CommentBody(props: CommentCardProps) {\n const {\n comment,\n config,\n renderBody,\n onUpdateStatus,\n onClose,\n onDelete,\n onCopy,\n onReply,\n onChecklistToggle,\n onMaximize,\n } = props;\n const [actionError, setActionError] = useState(\"\");\n const isReply = Boolean(comment.parentId);\n const date = parseTimestamp(comment.createdAt);\n const resolved = statusForCommentStage(config, \"resolved\");\n const active = statusForCommentStage(config, \"active\");\n const closed = statusForCommentStage(config, \"closed\");\n const stage = resolveCommentStage(config, comment.status);\n const updateStatus = async (status: string) => {\n setActionError(\"\");\n try {\n await onUpdateStatus?.(status);\n } catch (error) {\n setActionError(\n `Couldn't update comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const close = async () => {\n setActionError(\"\");\n try {\n await onClose?.();\n } catch (error) {\n setActionError(\n `Couldn't close comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const copy = async () => {\n setActionError(\"\");\n try {\n await onCopy?.();\n } catch (error) {\n setActionError(\n `Couldn't copy comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n };\n const menuItems = actionMenuItems(isReply, {\n ...(onDelete ? { onDelete } : {}),\n statusActions: [\n ...rootAssignmentItems(props, reportingRunner(setActionError)),\n ...(stage === \"active\" && onUpdateStatus && resolved\n ? [\n {\n label: \"Resolve\",\n icon: UiCheck,\n onSelect: () => void updateStatus(resolved.value),\n },\n ]\n : []),\n ...((stage === \"active\" || stage === \"resolved\") && onClose && closed\n ? [\n {\n label: \"Close\",\n icon: UiLock,\n onSelect: () => void close(),\n },\n ]\n : []),\n ...((stage === \"resolved\" || stage === \"closed\") &&\n onUpdateStatus &&\n active\n ? [\n {\n label: \"Reopen\",\n icon: UiRestart,\n onSelect: () => void updateStatus(active.value),\n },\n ]\n : []),\n ],\n ...(onCopy ? { onCopy: () => void copy() } : {}),\n ...(onMaximize ? { onMaximize } : {}),\n });\n\n return (\n <div className=\"space-y-2.5\">\n <div className=\"flex items-start gap-2.5\">\n <CommentAuthorAvatar author={comment.author} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex min-w-0 items-baseline gap-1.5\">\n <span className=\"truncate text-xs font-semibold text-foreground\">\n {authorDisplayName(comment.author)}\n </span>\n {date && (\n <span\n title={date.toLocaleString()}\n className=\"shrink-0 text-[10px] text-muted-foreground\"\n >\n {formatRelativeTime(date)}\n </span>\n )}\n </div>\n {!isReply && (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n <StatusChip comment={comment} config={config} />\n <RatingChip rating={comment.rating} />\n <ReviewDecisionChip decision={comment.reviewDecision} />\n <FacetBadges comment={comment} config={config} />\n </div>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-0.5\">\n {!isReply &&\n (stage === \"active\" || stage === \"resolved\") &&\n onClose &&\n closed && (\n <button\n type=\"button\"\n aria-label=\"Close comment\"\n title=\"Close comment\"\n onClick={() => void close()}\n className=\"inline-flex items-center justify-center rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiCheck} className=\"text-sm\" />\n </button>\n )}\n {!isReply && stage === \"closed\" && onUpdateStatus && active && (\n <button\n type=\"button\"\n aria-label=\"Reopen comment\"\n title=\"Reopen comment\"\n onClick={() => void updateStatus(active.value)}\n className=\"inline-flex items-center justify-center rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiRestart} className=\"text-sm\" />\n </button>\n )}\n {menuItems.length > 0 && (\n <DropdownMenu\n align=\"right\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n aria-label=\"Comment actions\"\n className=\"inline-flex items-center justify-center rounded-full p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiDotsVertical} className=\"text-sm\" />\n </span>\n }\n items={menuItems}\n />\n )}\n </div>\n </div>\n {comment.body.trim() && (\n <div className=\"text-[13px] leading-5 text-foreground\">\n {renderBody ? (\n renderBody(comment.body)\n ) : (\n <CommentMarkdown text={comment.body} />\n )}\n </div>\n )}\n {actionError && (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/30 bg-destructive/5 px-2.5 py-2 text-xs text-destructive\"\n >\n {actionError}\n </div>\n )}\n {!isReply && (\n <ChecklistChips\n comment={comment}\n {...(onChecklistToggle ? { onChecklistToggle } : {})}\n />\n )}\n {!isReply && <RefChips comment={comment} />}\n {onReply && (\n <button\n type=\"button\"\n onClick={onReply}\n className=\"-ml-2 rounded px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-primary/10 [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\"\n >\n Reply\n </button>\n )}\n </div>\n );\n}\n\n/**\n * A single comment, collapsible between a compact one-line preview and a full\n * card. Offers a Maximise action when `onMaximize` is supplied — the owner\n * enlarges the whole thread. Fully controlled — all mutations are delegated to\n * the supplied callbacks.\n */\nexport function CommentCard(props: CommentCardProps) {\n const { comment, config, compact, defaultExpanded } = props;\n const [expanded, setExpanded] = useState(defaultExpanded ?? false);\n const [collapsedActionError, setCollapsedActionError] = useState(\"\");\n const isReply = Boolean(comment.parentId);\n const body = <CommentBody {...props} />;\n\n async function runCollapsedAction(action: \"resolve\" | \"close\" | \"reopen\") {\n setCollapsedActionError(\"\");\n try {\n if (action === \"close\") {\n await props.onClose?.();\n return;\n }\n const next = statusForCommentStage(\n config,\n action === \"resolve\" ? \"resolved\" : \"active\",\n );\n if (next) await props.onUpdateStatus?.(next.value);\n } catch (error) {\n setCollapsedActionError(\n `${action === \"close\" ? \"Couldn't close comment\" : \"Couldn't update comment\"}: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n }\n\n async function copyCollapsed() {\n setCollapsedActionError(\"\");\n try {\n await props.onCopy?.();\n } catch (error) {\n setCollapsedActionError(\n `Couldn't copy comment: ${error instanceof Error ? error.message : \"Unexpected error\"}`,\n );\n }\n }\n\n if (!expanded) {\n return (\n <>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => setExpanded(true)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setExpanded(true);\n }\n }}\n data-testid=\"comment-card\"\n data-comment-kind={isReply ? \"reply\" : \"root\"}\n data-comment-id={comment.id}\n className={cn(\n \"group/comment flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-xs transition-colors hover:bg-muted/50\",\n !isReply && \"border border-border bg-background shadow-sm\",\n isReply && \"ml-4 border-l-2 border-l-border bg-muted/30\",\n )}\n >\n <CommentAuthorAvatar author={comment.author} bare />\n <span className=\"min-w-0 truncate text-[11px] font-semibold text-foreground\">\n {authorDisplayName(comment.author)}\n </span>\n {!isReply && (\n <>\n <StatusChip comment={comment} config={config} />\n <RatingChip rating={comment.rating} />\n <ReviewDecisionChip decision={comment.reviewDecision} />\n <FacetBadges comment={comment} config={config} compact />\n </>\n )}\n <span className=\"min-w-0 flex-1 truncate text-[12px] text-foreground/80\">\n {comment.body.trim()\n ? truncatePlain(comment.body)\n : comment.rating === \"positive\"\n ? \"Positive rating\"\n : comment.rating === \"negative\"\n ? \"Negative rating\"\n : comment.reviewDecision === \"approved\"\n ? \"Approved\"\n : \"Empty comment\"}\n </span>\n <span\n className=\"shrink-0\"\n role=\"presentation\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <DropdownMenu\n align=\"right\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n aria-label=\"Comment actions\"\n className=\"rounded p-0.5 text-muted-foreground opacity-0 transition-opacity hover:bg-muted hover:opacity-100 group-hover/comment:opacity-70 [@media(hover:none)]:opacity-70 [@media(pointer:coarse)]:p-2.5\"\n >\n <Icon icon={UiDotsVertical} className=\"text-sm\" />\n </span>\n }\n items={actionMenuItems(isReply, {\n ...(props.onDelete ? { onDelete: props.onDelete } : {}),\n statusActions: [\n ...rootAssignmentItems(\n props,\n reportingRunner(setCollapsedActionError),\n ),\n ...(resolveCommentStage(config, comment.status) ===\n \"active\" &&\n props.onUpdateStatus &&\n statusForCommentStage(config, \"resolved\")\n ? [\n {\n label: \"Resolve\",\n icon: UiCheck,\n onSelect: () => void runCollapsedAction(\"resolve\"),\n },\n ]\n : []),\n ...((resolveCommentStage(config, comment.status) ===\n \"active\" ||\n resolveCommentStage(config, comment.status) ===\n \"resolved\") &&\n props.onClose &&\n statusForCommentStage(config, \"closed\")\n ? [\n {\n label: \"Close\",\n icon: UiLock,\n onSelect: () => void runCollapsedAction(\"close\"),\n },\n ]\n : []),\n ...((resolveCommentStage(config, comment.status) ===\n \"resolved\" ||\n resolveCommentStage(config, comment.status) === \"closed\") &&\n props.onUpdateStatus &&\n statusForCommentStage(config, \"active\")\n ? [\n {\n label: \"Reopen\",\n icon: UiRestart,\n onSelect: () => void runCollapsedAction(\"reopen\"),\n },\n ]\n : []),\n ],\n ...(props.onCopy ? { onCopy: () => void copyCollapsed() } : {}),\n ...(props.onMaximize ? { onMaximize: props.onMaximize } : {}),\n })}\n />\n </span>\n </div>\n {collapsedActionError && (\n <div\n role=\"alert\"\n className=\"rounded-md border border-destructive/30 bg-destructive/5 px-2.5 py-2 text-xs text-destructive\"\n >\n {collapsedActionError}\n </div>\n )}\n </>\n );\n }\n\n return (\n <>\n <div\n data-testid=\"comment-card\"\n data-comment-kind={isReply ? \"reply\" : \"root\"}\n data-comment-id={comment.id}\n className={cn(\n \"group/comment rounded-xl bg-background px-3.5 py-3 text-xs\",\n !isReply &&\n \"border border-border/80 shadow-sm transition-shadow hover:shadow-md\",\n compact && \"px-2.5 py-2.5\",\n isReply && \"ml-4 border-l-2 border-l-border bg-muted/20 shadow-none\",\n )}\n >\n {body}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
@@ -3,6 +3,7 @@ const require_comment_utils = require("./comment-utils.cjs");
3
3
  const require_comment_stage = require("../lib/comment-stage.cjs");
4
4
  const require_UiThumbsUp = require("../icons/components/UiThumbsUp.cjs");
5
5
  const require_UiThumbsDown = require("../icons/components/UiThumbsDown.cjs");
6
+ const require_UiRobotAi = require("../icons/components/UiRobotAi.cjs");
6
7
  const require_Badge = require("../data/Badge.cjs");
7
8
  let react_jsx_runtime = require("react/jsx-runtime");
8
9
  // src/comments/CommentCardParts.tsx
@@ -29,14 +30,18 @@ function RatingChip({ rating }) {
29
30
  function StatusChip({ comment, config }) {
30
31
  const status = require_comment_utils.resolveStatusConfig(config, comment.status);
31
32
  if (!status) return null;
32
- const closedBy = require_comment_stage.resolveCommentStage(config, comment.status) === "closed" ? comment.closedBy : void 0;
33
+ const stage = require_comment_stage.resolveCommentStage(config, comment.status);
34
+ const closedBy = stage === "closed" ? comment.closedBy : void 0;
35
+ const assignee = stage === "active" ? comment.assignee : void 0;
36
+ const icon = assignee?.kind === "agent" ? require_UiRobotAi.UiRobotAi : status.icon;
37
+ const title = assignee ? comment.acknowledgedAt ? `Acknowledged ${new Date(comment.acknowledgedAt).toLocaleString()}` : "Assigned, not yet acknowledged" : comment.closedAt ? new Date(comment.closedAt).toLocaleString() : void 0;
33
38
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Badge.Badge, {
34
39
  variant: "soft",
35
40
  tone: require_comment_utils.toneToBadgeTone(status.tone),
36
41
  size: "xs",
37
- ...status.icon ? { icon: status.icon } : {},
38
- ...comment.closedAt ? { title: new Date(comment.closedAt).toLocaleString() } : {},
39
- children: closedBy ? `Closed by ${closedBy.name}` : status.label
42
+ ...icon ? { icon } : {},
43
+ ...title ? { title } : {},
44
+ children: assignee ? `Assigned to ${assignee.name}` : closedBy ? `Closed by ${closedBy.name}` : status.label
40
45
  });
41
46
  }
42
47
  function FacetBadges({ comment, config, compact }) {
@@ -1 +1 @@
1
- {"version":3,"file":"CommentCardParts.cjs","names":["Badge","UiThumbsUp","UiThumbsDown","resolveStatusConfig","resolveCommentStage","toneToBadgeTone","resolveFacetOption","_Fragment","cn"],"sources":["../../src/comments/CommentCardParts.tsx"],"sourcesContent":["import { Badge } from \"../data/Badge\";\nimport { cn } from \"../lib/utils\";\nimport { UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport {\n resolveFacetOption,\n resolveStatusConfig,\n toneToBadgeTone,\n} from \"./comment-utils\";\nimport { resolveCommentStage } from \"../lib/comment-stage\";\nimport type {\n Comment,\n CommentConfig,\n CommentRating,\n CommentReviewDecision,\n} from \"./comment-types\";\n\nexport function ReviewDecisionChip({\n decision,\n}: {\n decision: CommentReviewDecision | undefined;\n}) {\n if (!decision) return null;\n const label =\n decision === \"approved\"\n ? \"Approved\"\n : decision === \"rejected\"\n ? \"Rejected\"\n : \"Revision requested\";\n return (\n <Badge\n variant=\"soft\"\n tone={\n decision === \"approved\"\n ? \"success\"\n : decision === \"rejected\"\n ? \"danger\"\n : \"warning\"\n }\n size=\"xs\"\n >\n {label}\n </Badge>\n );\n}\n\nexport function RatingChip({ rating }: { rating: CommentRating | undefined }) {\n if (!rating) return null;\n const positive = rating === \"positive\";\n return (\n <Badge\n variant=\"soft\"\n tone={positive ? \"success\" : \"danger\"}\n size=\"xs\"\n icon={positive ? UiThumbsUp : UiThumbsDown}\n >\n {positive ? \"Positive rating\" : \"Negative rating\"}\n </Badge>\n );\n}\n\nexport function StatusChip({\n comment,\n config,\n}: {\n comment: Comment;\n config: CommentConfig;\n}) {\n const status = resolveStatusConfig(config, comment.status);\n if (!status) return null;\n const closedBy =\n resolveCommentStage(config, comment.status) === \"closed\"\n ? comment.closedBy\n : undefined;\n return (\n <Badge\n variant=\"soft\"\n tone={toneToBadgeTone(status.tone)}\n size=\"xs\"\n {...(status.icon ? { icon: status.icon } : {})}\n {...(comment.closedAt\n ? { title: new Date(comment.closedAt).toLocaleString() }\n : {})}\n >\n {closedBy ? `Closed by ${closedBy.name}` : status.label}\n </Badge>\n );\n}\n\nexport function FacetBadges({\n comment,\n config,\n compact,\n}: {\n comment: Comment;\n config: CommentConfig;\n compact?: boolean;\n}) {\n const chips = (config.facets ?? []).flatMap((facet) => {\n const option = resolveFacetOption(facet, comment.facets?.[facet.key]);\n if (!option) return [];\n return [\n <Badge\n key={facet.key}\n variant=\"soft\"\n tone={toneToBadgeTone(option.tone)}\n size=\"xs\"\n >\n {compact ? (option.short ?? option.label) : option.label}\n </Badge>,\n ];\n });\n return chips.length > 0 ? <>{chips}</> : null;\n}\n\nexport function ChecklistChips({\n comment,\n onChecklistToggle,\n}: {\n comment: Comment;\n onChecklistToggle?: (index: number) => void;\n}) {\n if (!comment.checklist?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {comment.checklist.map((item, index) => {\n const done = /done|complete|resolved/i.test(item.status);\n const active = /progress|doing/i.test(item.status);\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onChecklistToggle?.(index)}\n disabled={!onChecklistToggle}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] transition-opacity\",\n onChecklistToggle && \"cursor-pointer hover:opacity-80\",\n done\n ? \"bg-green-100 text-green-800 line-through dark:bg-green-500/20 dark:text-green-300\"\n : active\n ? \"bg-yellow-100 text-yellow-800 dark:bg-yellow-500/20 dark:text-yellow-300\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function RefChips({ comment }: { comment: Comment }) {\n if (!comment.refs?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {comment.refs.map((group, index) => (\n <span\n key={index}\n className=\"inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\"\n >\n <span className=\"font-medium\">{group.label}:</span>\n <span className={group.mono ? \"font-mono\" : undefined}>\n {group.items.join(\", \")}\n </span>\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentCardParts.cjs","names":["Badge","UiThumbsUp","UiThumbsDown","resolveStatusConfig","resolveCommentStage","UiRobotAi","toneToBadgeTone","resolveFacetOption","_Fragment","cn"],"sources":["../../src/comments/CommentCardParts.tsx"],"sourcesContent":["import { Badge } from \"../data/Badge\";\nimport { cn } from \"../lib/utils\";\nimport { UiRobotAi, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport {\n resolveFacetOption,\n resolveStatusConfig,\n toneToBadgeTone,\n} from \"./comment-utils\";\nimport { resolveCommentStage } from \"../lib/comment-stage\";\nimport type {\n Comment,\n CommentConfig,\n CommentRating,\n CommentReviewDecision,\n} from \"./comment-types\";\n\nexport function ReviewDecisionChip({\n decision,\n}: {\n decision: CommentReviewDecision | undefined;\n}) {\n if (!decision) return null;\n const label =\n decision === \"approved\"\n ? \"Approved\"\n : decision === \"rejected\"\n ? \"Rejected\"\n : \"Revision requested\";\n return (\n <Badge\n variant=\"soft\"\n tone={\n decision === \"approved\"\n ? \"success\"\n : decision === \"rejected\"\n ? \"danger\"\n : \"warning\"\n }\n size=\"xs\"\n >\n {label}\n </Badge>\n );\n}\n\nexport function RatingChip({ rating }: { rating: CommentRating | undefined }) {\n if (!rating) return null;\n const positive = rating === \"positive\";\n return (\n <Badge\n variant=\"soft\"\n tone={positive ? \"success\" : \"danger\"}\n size=\"xs\"\n icon={positive ? UiThumbsUp : UiThumbsDown}\n >\n {positive ? \"Positive rating\" : \"Negative rating\"}\n </Badge>\n );\n}\n\nexport function StatusChip({\n comment,\n config,\n}: {\n comment: Comment;\n config: CommentConfig;\n}) {\n const status = resolveStatusConfig(config, comment.status);\n if (!status) return null;\n const stage = resolveCommentStage(config, comment.status);\n const closedBy = stage === \"closed\" ? comment.closedBy : undefined;\n const assignee = stage === \"active\" ? comment.assignee : undefined;\n const icon = assignee?.kind === \"agent\" ? UiRobotAi : status.icon;\n const title = assignee\n ? comment.acknowledgedAt\n ? `Acknowledged ${new Date(comment.acknowledgedAt).toLocaleString()}`\n : \"Assigned, not yet acknowledged\"\n : comment.closedAt\n ? new Date(comment.closedAt).toLocaleString()\n : undefined;\n return (\n <Badge\n variant=\"soft\"\n tone={toneToBadgeTone(status.tone)}\n size=\"xs\"\n {...(icon ? { icon } : {})}\n {...(title ? { title } : {})}\n >\n {assignee\n ? `Assigned to ${assignee.name}`\n : closedBy\n ? `Closed by ${closedBy.name}`\n : status.label}\n </Badge>\n );\n}\n\nexport function FacetBadges({\n comment,\n config,\n compact,\n}: {\n comment: Comment;\n config: CommentConfig;\n compact?: boolean;\n}) {\n const chips = (config.facets ?? []).flatMap((facet) => {\n const option = resolveFacetOption(facet, comment.facets?.[facet.key]);\n if (!option) return [];\n return [\n <Badge\n key={facet.key}\n variant=\"soft\"\n tone={toneToBadgeTone(option.tone)}\n size=\"xs\"\n >\n {compact ? (option.short ?? option.label) : option.label}\n </Badge>,\n ];\n });\n return chips.length > 0 ? <>{chips}</> : null;\n}\n\nexport function ChecklistChips({\n comment,\n onChecklistToggle,\n}: {\n comment: Comment;\n onChecklistToggle?: (index: number) => void;\n}) {\n if (!comment.checklist?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {comment.checklist.map((item, index) => {\n const done = /done|complete|resolved/i.test(item.status);\n const active = /progress|doing/i.test(item.status);\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onChecklistToggle?.(index)}\n disabled={!onChecklistToggle}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] transition-opacity\",\n onChecklistToggle && \"cursor-pointer hover:opacity-80\",\n done\n ? \"bg-green-100 text-green-800 line-through dark:bg-green-500/20 dark:text-green-300\"\n : active\n ? \"bg-yellow-100 text-yellow-800 dark:bg-yellow-500/20 dark:text-yellow-300\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function RefChips({ comment }: { comment: Comment }) {\n if (!comment.refs?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {comment.refs.map((group, index) => (\n <span\n key={index}\n className=\"inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\"\n >\n <span className=\"font-medium\">{group.label}:</span>\n <span className={group.mono ? \"font-mono\" : undefined}>\n {group.items.join(\", \")}\n </span>\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,mBAAmB,EACjC,YAGC;CACD,IAAI,CAAC,UAAU,OAAO;CAOtB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,cAAAA,OAAD;EACE,SAAQ;EACR,MACE,aAAa,aACT,YACA,aAAa,aACX,WACA;EAER,MAAK;EAEJ,UAjBH,aAAa,aACT,aACA,aAAa,aACX,aACA;CAcC,CAAA;AAEX;AAEA,SAAgB,WAAW,EAAE,UAAiD;CAC5E,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,WAAW,WAAW;CAC5B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,cAAAA,OAAD;EACE,SAAQ;EACR,MAAM,WAAW,YAAY;EAC7B,MAAK;EACL,MAAM,WAAWC,mBAAAA,aAAaC,qBAAAA;EAE7B,UAAA,WAAW,oBAAoB;CAC3B,CAAA;AAEX;AAEA,SAAgB,WAAW,EACzB,SACA,UAIC;CACD,MAAM,SAASC,sBAAAA,oBAAoB,QAAQ,QAAQ,MAAM;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,QAAQC,sBAAAA,oBAAoB,QAAQ,QAAQ,MAAM;CACxD,MAAM,WAAW,UAAU,WAAW,QAAQ,WAAW,KAAA;CACzD,MAAM,WAAW,UAAU,WAAW,QAAQ,WAAW,KAAA;CACzD,MAAM,OAAO,UAAU,SAAS,UAAUC,kBAAAA,YAAY,OAAO;CAC7D,MAAM,QAAQ,WACV,QAAQ,iBACN,gBAAgB,IAAI,KAAK,QAAQ,cAAc,CAAC,CAAC,eAAe,MAChE,mCACF,QAAQ,WACN,IAAI,KAAK,QAAQ,QAAQ,CAAC,CAAC,eAAe,IAC1C,KAAA;CACN,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACL,cAAAA,OAAD;EACE,SAAQ;EACR,MAAMM,sBAAAA,gBAAgB,OAAO,IAAI;EACjC,MAAK;EACL,GAAK,OAAO,EAAE,KAAK,IAAI,CAAC;EACxB,GAAK,QAAQ,EAAE,MAAM,IAAI,CAAC;EAEzB,UAAA,WACG,eAAe,SAAS,SACxB,WACE,aAAa,SAAS,SACtB,OAAO;CACR,CAAA;AAEX;AAEA,SAAgB,YAAY,EAC1B,SACA,QACA,WAKC;CACD,MAAM,SAAS,OAAO,UAAU,CAAC,EAAA,CAAG,SAAS,UAAU;EACrD,MAAM,SAASC,sBAAAA,mBAAmB,OAAO,QAAQ,SAAS,MAAM,IAAI;EACpE,IAAI,CAAC,QAAQ,OAAO,CAAC;EACrB,OAAO,CACL,iBAAA,GAAA,kBAAA,IAAA,CAACP,cAAAA,OAAD;GAEE,SAAQ;GACR,MAAMM,sBAAAA,gBAAgB,OAAO,IAAI;GACjC,MAAK;GAEJ,UAAA,UAAW,OAAO,SAAS,OAAO,QAAS,OAAO;EAC9C,GANA,MAAM,GAMN,CACT;CACF,CAAC;CACD,OAAO,MAAM,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAAE,kBAAAA,UAAA,EAAA,UAAG,MAAQ,CAAA,IAAI;AAC3C;AAEA,SAAgB,eAAe,EAC7B,SACA,qBAIC;CACD,IAAI,CAAC,QAAQ,WAAW,QAAQ,OAAO;CACvC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACZ,UAAA,QAAQ,UAAU,KAAK,MAAM,UAAU;GACtC,MAAM,OAAO,0BAA0B,KAAK,KAAK,MAAM;GACvD,MAAM,SAAS,kBAAkB,KAAK,KAAK,MAAM;GACjD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAEE,MAAK;IACL,eAAe,oBAAoB,KAAK;IACxC,UAAU,CAAC;IACX,WAAWC,cAAAA,GACT,0FACA,qBAAqB,mCACrB,OACI,sFACA,SACE,6EACA,gCACR;IAEC,UAAA,KAAK;GACA,GAfD,KAeC;EAEZ,CAAC;CACE,CAAA;AAET;AAEA,SAAgB,SAAS,EAAE,WAAiC;CAC1D,IAAI,CAAC,QAAQ,MAAM,QAAQ,OAAO;CAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACZ,UAAA,QAAQ,KAAK,KAAK,OAAO,UACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;GAEE,WAAU;GAFZ,UAAA,CAIE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CAA+B,MAAM,OAAM,GAAO;GAClD,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAW,MAAM,OAAO,cAAc,KAAA;IACzC,UAAA,MAAM,MAAM,KAAK,IAAI;GAClB,CAAA,CACF;EAPC,GAAA,KAOD,CACP;CACE,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommentCardParts.d.ts","sourceRoot":"","sources":["../../src/comments/CommentCardParts.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,aAAa,EACb,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC7C,sCAuBA;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,GAAG,SAAS,CAAA;CAAE,sCAa3E;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,GACP,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB,sCAoBA;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,sCAgBA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,iBAAiB,GAClB,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C,sCA6BA;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,sCAiBzD"}
1
+ {"version":3,"file":"CommentCardParts.d.ts","sourceRoot":"","sources":["../../src/comments/CommentCardParts.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,aAAa,EACb,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC7C,sCAuBA;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,GAAG,SAAS,CAAA;CAAE,sCAa3E;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,MAAM,GACP,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB,sCA6BA;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,sCAgBA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,iBAAiB,GAClB,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C,sCA6BA;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,sCAiBzD"}
@@ -3,6 +3,7 @@ import { resolveFacetOption, resolveStatusConfig, toneToBadgeTone } from "./comm
3
3
  import { resolveCommentStage } from "../lib/comment-stage.js";
4
4
  import { UiThumbsUp } from "../icons/components/UiThumbsUp.js";
5
5
  import { UiThumbsDown } from "../icons/components/UiThumbsDown.js";
6
+ import { UiRobotAi } from "../icons/components/UiRobotAi.js";
6
7
  import { Badge } from "../data/Badge.js";
7
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
9
  // src/comments/CommentCardParts.tsx
@@ -29,14 +30,18 @@ function RatingChip({ rating }) {
29
30
  function StatusChip({ comment, config }) {
30
31
  const status = resolveStatusConfig(config, comment.status);
31
32
  if (!status) return null;
32
- const closedBy = resolveCommentStage(config, comment.status) === "closed" ? comment.closedBy : void 0;
33
+ const stage = resolveCommentStage(config, comment.status);
34
+ const closedBy = stage === "closed" ? comment.closedBy : void 0;
35
+ const assignee = stage === "active" ? comment.assignee : void 0;
36
+ const icon = assignee?.kind === "agent" ? UiRobotAi : status.icon;
37
+ const title = assignee ? comment.acknowledgedAt ? `Acknowledged ${new Date(comment.acknowledgedAt).toLocaleString()}` : "Assigned, not yet acknowledged" : comment.closedAt ? new Date(comment.closedAt).toLocaleString() : void 0;
33
38
  return /* @__PURE__ */ jsx(Badge, {
34
39
  variant: "soft",
35
40
  tone: toneToBadgeTone(status.tone),
36
41
  size: "xs",
37
- ...status.icon ? { icon: status.icon } : {},
38
- ...comment.closedAt ? { title: new Date(comment.closedAt).toLocaleString() } : {},
39
- children: closedBy ? `Closed by ${closedBy.name}` : status.label
42
+ ...icon ? { icon } : {},
43
+ ...title ? { title } : {},
44
+ children: assignee ? `Assigned to ${assignee.name}` : closedBy ? `Closed by ${closedBy.name}` : status.label
40
45
  });
41
46
  }
42
47
  function FacetBadges({ comment, config, compact }) {
@@ -1 +1 @@
1
- {"version":3,"file":"CommentCardParts.js","names":["_Fragment"],"sources":["../../src/comments/CommentCardParts.tsx"],"sourcesContent":["import { Badge } from \"../data/Badge\";\nimport { cn } from \"../lib/utils\";\nimport { UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport {\n resolveFacetOption,\n resolveStatusConfig,\n toneToBadgeTone,\n} from \"./comment-utils\";\nimport { resolveCommentStage } from \"../lib/comment-stage\";\nimport type {\n Comment,\n CommentConfig,\n CommentRating,\n CommentReviewDecision,\n} from \"./comment-types\";\n\nexport function ReviewDecisionChip({\n decision,\n}: {\n decision: CommentReviewDecision | undefined;\n}) {\n if (!decision) return null;\n const label =\n decision === \"approved\"\n ? \"Approved\"\n : decision === \"rejected\"\n ? \"Rejected\"\n : \"Revision requested\";\n return (\n <Badge\n variant=\"soft\"\n tone={\n decision === \"approved\"\n ? \"success\"\n : decision === \"rejected\"\n ? \"danger\"\n : \"warning\"\n }\n size=\"xs\"\n >\n {label}\n </Badge>\n );\n}\n\nexport function RatingChip({ rating }: { rating: CommentRating | undefined }) {\n if (!rating) return null;\n const positive = rating === \"positive\";\n return (\n <Badge\n variant=\"soft\"\n tone={positive ? \"success\" : \"danger\"}\n size=\"xs\"\n icon={positive ? UiThumbsUp : UiThumbsDown}\n >\n {positive ? \"Positive rating\" : \"Negative rating\"}\n </Badge>\n );\n}\n\nexport function StatusChip({\n comment,\n config,\n}: {\n comment: Comment;\n config: CommentConfig;\n}) {\n const status = resolveStatusConfig(config, comment.status);\n if (!status) return null;\n const closedBy =\n resolveCommentStage(config, comment.status) === \"closed\"\n ? comment.closedBy\n : undefined;\n return (\n <Badge\n variant=\"soft\"\n tone={toneToBadgeTone(status.tone)}\n size=\"xs\"\n {...(status.icon ? { icon: status.icon } : {})}\n {...(comment.closedAt\n ? { title: new Date(comment.closedAt).toLocaleString() }\n : {})}\n >\n {closedBy ? `Closed by ${closedBy.name}` : status.label}\n </Badge>\n );\n}\n\nexport function FacetBadges({\n comment,\n config,\n compact,\n}: {\n comment: Comment;\n config: CommentConfig;\n compact?: boolean;\n}) {\n const chips = (config.facets ?? []).flatMap((facet) => {\n const option = resolveFacetOption(facet, comment.facets?.[facet.key]);\n if (!option) return [];\n return [\n <Badge\n key={facet.key}\n variant=\"soft\"\n tone={toneToBadgeTone(option.tone)}\n size=\"xs\"\n >\n {compact ? (option.short ?? option.label) : option.label}\n </Badge>,\n ];\n });\n return chips.length > 0 ? <>{chips}</> : null;\n}\n\nexport function ChecklistChips({\n comment,\n onChecklistToggle,\n}: {\n comment: Comment;\n onChecklistToggle?: (index: number) => void;\n}) {\n if (!comment.checklist?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {comment.checklist.map((item, index) => {\n const done = /done|complete|resolved/i.test(item.status);\n const active = /progress|doing/i.test(item.status);\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onChecklistToggle?.(index)}\n disabled={!onChecklistToggle}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] transition-opacity\",\n onChecklistToggle && \"cursor-pointer hover:opacity-80\",\n done\n ? \"bg-green-100 text-green-800 line-through dark:bg-green-500/20 dark:text-green-300\"\n : active\n ? \"bg-yellow-100 text-yellow-800 dark:bg-yellow-500/20 dark:text-yellow-300\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function RefChips({ comment }: { comment: Comment }) {\n if (!comment.refs?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {comment.refs.map((group, index) => (\n <span\n key={index}\n className=\"inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\"\n >\n <span className=\"font-medium\">{group.label}:</span>\n <span className={group.mono ? \"font-mono\" : undefined}>\n {group.items.join(\", \")}\n </span>\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,mBAAmB,EACjC,YAGC;CACD,IAAI,CAAC,UAAU,OAAO;CAOtB,OACE,oBAAC,OAAD;EACE,SAAQ;EACR,MACE,aAAa,aACT,YACA,aAAa,aACX,WACA;EAER,MAAK;EAEJ,UAjBH,aAAa,aACT,aACA,aAAa,aACX,aACA;CAcC,CAAA;AAEX;AAEA,SAAgB,WAAW,EAAE,UAAiD;CAC5E,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,WAAW,WAAW;CAC5B,OACE,oBAAC,OAAD;EACE,SAAQ;EACR,MAAM,WAAW,YAAY;EAC7B,MAAK;EACL,MAAM,WAAW,aAAa;EAE7B,UAAA,WAAW,oBAAoB;CAC3B,CAAA;AAEX;AAEA,SAAgB,WAAW,EACzB,SACA,UAIC;CACD,MAAM,SAAS,oBAAoB,QAAQ,QAAQ,MAAM;CACzD,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,WACJ,oBAAoB,QAAQ,QAAQ,MAAM,MAAM,WAC5C,QAAQ,WACR,KAAA;CACN,OACE,oBAAC,OAAD;EACE,SAAQ;EACR,MAAM,gBAAgB,OAAO,IAAI;EACjC,MAAK;EACL,GAAK,OAAO,OAAO,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;EAC5C,GAAK,QAAQ,WACT,EAAE,OAAO,IAAI,KAAK,QAAQ,QAAQ,CAAC,CAAC,eAAe,EAAE,IACrD,CAAC;EAEJ,UAAA,WAAW,aAAa,SAAS,SAAS,OAAO;CAC7C,CAAA;AAEX;AAEA,SAAgB,YAAY,EAC1B,SACA,QACA,WAKC;CACD,MAAM,SAAS,OAAO,UAAU,CAAC,EAAA,CAAG,SAAS,UAAU;EACrD,MAAM,SAAS,mBAAmB,OAAO,QAAQ,SAAS,MAAM,IAAI;EACpE,IAAI,CAAC,QAAQ,OAAO,CAAC;EACrB,OAAO,CACL,oBAAC,OAAD;GAEE,SAAQ;GACR,MAAM,gBAAgB,OAAO,IAAI;GACjC,MAAK;GAEJ,UAAA,UAAW,OAAO,SAAS,OAAO,QAAS,OAAO;EAC9C,GANA,MAAM,GAMN,CACT;CACF,CAAC;CACD,OAAO,MAAM,SAAS,IAAI,oBAAAA,UAAA,EAAA,UAAG,MAAQ,CAAA,IAAI;AAC3C;AAEA,SAAgB,eAAe,EAC7B,SACA,qBAIC;CACD,IAAI,CAAC,QAAQ,WAAW,QAAQ,OAAO;CACvC,OACE,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,QAAQ,UAAU,KAAK,MAAM,UAAU;GACtC,MAAM,OAAO,0BAA0B,KAAK,KAAK,MAAM;GACvD,MAAM,SAAS,kBAAkB,KAAK,KAAK,MAAM;GACjD,OACE,oBAAC,UAAD;IAEE,MAAK;IACL,eAAe,oBAAoB,KAAK;IACxC,UAAU,CAAC;IACX,WAAW,GACT,0FACA,qBAAqB,mCACrB,OACI,sFACA,SACE,6EACA,gCACR;IAEC,UAAA,KAAK;GACA,GAfD,KAeC;EAEZ,CAAC;CACE,CAAA;AAET;AAEA,SAAgB,SAAS,EAAE,WAAiC;CAC1D,IAAI,CAAC,QAAQ,MAAM,QAAQ,OAAO;CAClC,OACE,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,QAAQ,KAAK,KAAK,OAAO,UACxB,qBAAC,QAAD;GAEE,WAAU;GAFZ,UAAA,CAIE,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CAA+B,MAAM,OAAM,GAAO;GAClD,CAAA,GAAA,oBAAC,QAAD;IAAM,WAAW,MAAM,OAAO,cAAc,KAAA;IACzC,UAAA,MAAM,MAAM,KAAK,IAAI;GAClB,CAAA,CACF;EAPC,GAAA,KAOD,CACP;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"CommentCardParts.js","names":["_Fragment"],"sources":["../../src/comments/CommentCardParts.tsx"],"sourcesContent":["import { Badge } from \"../data/Badge\";\nimport { cn } from \"../lib/utils\";\nimport { UiRobotAi, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport {\n resolveFacetOption,\n resolveStatusConfig,\n toneToBadgeTone,\n} from \"./comment-utils\";\nimport { resolveCommentStage } from \"../lib/comment-stage\";\nimport type {\n Comment,\n CommentConfig,\n CommentRating,\n CommentReviewDecision,\n} from \"./comment-types\";\n\nexport function ReviewDecisionChip({\n decision,\n}: {\n decision: CommentReviewDecision | undefined;\n}) {\n if (!decision) return null;\n const label =\n decision === \"approved\"\n ? \"Approved\"\n : decision === \"rejected\"\n ? \"Rejected\"\n : \"Revision requested\";\n return (\n <Badge\n variant=\"soft\"\n tone={\n decision === \"approved\"\n ? \"success\"\n : decision === \"rejected\"\n ? \"danger\"\n : \"warning\"\n }\n size=\"xs\"\n >\n {label}\n </Badge>\n );\n}\n\nexport function RatingChip({ rating }: { rating: CommentRating | undefined }) {\n if (!rating) return null;\n const positive = rating === \"positive\";\n return (\n <Badge\n variant=\"soft\"\n tone={positive ? \"success\" : \"danger\"}\n size=\"xs\"\n icon={positive ? UiThumbsUp : UiThumbsDown}\n >\n {positive ? \"Positive rating\" : \"Negative rating\"}\n </Badge>\n );\n}\n\nexport function StatusChip({\n comment,\n config,\n}: {\n comment: Comment;\n config: CommentConfig;\n}) {\n const status = resolveStatusConfig(config, comment.status);\n if (!status) return null;\n const stage = resolveCommentStage(config, comment.status);\n const closedBy = stage === \"closed\" ? comment.closedBy : undefined;\n const assignee = stage === \"active\" ? comment.assignee : undefined;\n const icon = assignee?.kind === \"agent\" ? UiRobotAi : status.icon;\n const title = assignee\n ? comment.acknowledgedAt\n ? `Acknowledged ${new Date(comment.acknowledgedAt).toLocaleString()}`\n : \"Assigned, not yet acknowledged\"\n : comment.closedAt\n ? new Date(comment.closedAt).toLocaleString()\n : undefined;\n return (\n <Badge\n variant=\"soft\"\n tone={toneToBadgeTone(status.tone)}\n size=\"xs\"\n {...(icon ? { icon } : {})}\n {...(title ? { title } : {})}\n >\n {assignee\n ? `Assigned to ${assignee.name}`\n : closedBy\n ? `Closed by ${closedBy.name}`\n : status.label}\n </Badge>\n );\n}\n\nexport function FacetBadges({\n comment,\n config,\n compact,\n}: {\n comment: Comment;\n config: CommentConfig;\n compact?: boolean;\n}) {\n const chips = (config.facets ?? []).flatMap((facet) => {\n const option = resolveFacetOption(facet, comment.facets?.[facet.key]);\n if (!option) return [];\n return [\n <Badge\n key={facet.key}\n variant=\"soft\"\n tone={toneToBadgeTone(option.tone)}\n size=\"xs\"\n >\n {compact ? (option.short ?? option.label) : option.label}\n </Badge>,\n ];\n });\n return chips.length > 0 ? <>{chips}</> : null;\n}\n\nexport function ChecklistChips({\n comment,\n onChecklistToggle,\n}: {\n comment: Comment;\n onChecklistToggle?: (index: number) => void;\n}) {\n if (!comment.checklist?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1\">\n {comment.checklist.map((item, index) => {\n const done = /done|complete|resolved/i.test(item.status);\n const active = /progress|doing/i.test(item.status);\n return (\n <button\n key={index}\n type=\"button\"\n onClick={() => onChecklistToggle?.(index)}\n disabled={!onChecklistToggle}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] transition-opacity\",\n onChecklistToggle && \"cursor-pointer hover:opacity-80\",\n done\n ? \"bg-green-100 text-green-800 line-through dark:bg-green-500/20 dark:text-green-300\"\n : active\n ? \"bg-yellow-100 text-yellow-800 dark:bg-yellow-500/20 dark:text-yellow-300\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {item.label}\n </button>\n );\n })}\n </div>\n );\n}\n\nexport function RefChips({ comment }: { comment: Comment }) {\n if (!comment.refs?.length) return null;\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {comment.refs.map((group, index) => (\n <span\n key={index}\n className=\"inline-flex items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground\"\n >\n <span className=\"font-medium\">{group.label}:</span>\n <span className={group.mono ? \"font-mono\" : undefined}>\n {group.items.join(\", \")}\n </span>\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -115,7 +115,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
115
115
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116
116
  "data-testid": "comment-compose-box",
117
117
  "aria-busy": submitting,
118
- className: "relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md",
118
+ className: "relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md [@media(pointer:coarse)]:pb-2",
119
119
  children: [
120
120
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_MentionTextarea.MentionTextarea, {
121
121
  ref: inputRef,
@@ -131,7 +131,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
131
131
  placeholder,
132
132
  autoFocus: autoFocus || collapsible && open,
133
133
  "data-testid": "comment-compose-input",
134
- className: "min-h-[48px] pr-10"
134
+ className: "min-h-[48px] pr-10 [@media(pointer:coarse)]:pr-12"
135
135
  }),
136
136
  collapsible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
137
137
  type: "button",
@@ -140,14 +140,14 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
140
140
  setOpen(false);
141
141
  },
142
142
  "aria-label": "Close composer",
143
- className: "absolute right-3 top-3 rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
143
+ className: "absolute right-3 top-3 inline-flex items-center justify-center rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:right-1 [@media(pointer:coarse)]:top-1 [@media(pointer:coarse)]:size-11",
144
144
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
145
145
  icon: require_UiClose.UiClose,
146
146
  className: "text-xs"
147
147
  })
148
148
  }),
149
149
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
150
- className: "absolute inset-x-3 bottom-2.5 flex items-center gap-1.5",
150
+ className: "absolute inset-x-3 bottom-2.5 flex items-center gap-1.5 [@media(pointer:coarse)]:static [@media(pointer:coarse)]:mt-2 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:gap-2",
151
151
  children: [
152
152
  [[
153
153
  "positive",
@@ -162,7 +162,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
162
162
  "aria-label": label,
163
163
  "aria-pressed": rating === value,
164
164
  onClick: () => setRating((current) => current === value ? void 0 : value),
165
- className: require_utils.cn("inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", rating === value && (value === "positive" ? "bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300" : "bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300")),
165
+ className: require_utils.cn("inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:size-11", rating === value && (value === "positive" ? "bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300" : "bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300")),
166
166
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
167
167
  icon,
168
168
  className: "text-sm"
@@ -174,12 +174,12 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
174
174
  onChange: (value) => setFacet(facet.key, value)
175
175
  }, facet.key)),
176
176
  createActions?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
177
- className: "ml-auto flex gap-1",
177
+ className: "ml-auto flex gap-1 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:justify-end [@media(pointer:coarse)]:gap-2",
178
178
  children: createActions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
179
179
  type: "button",
180
180
  onClick: () => void submit(action.id),
181
181
  disabled: submitting || !body.trim() && !rating,
182
- className: "whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground",
182
+ className: "whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm",
183
183
  children: action.label
184
184
  }, action.id))
185
185
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -188,7 +188,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
188
188
  "aria-label": "Post comment",
189
189
  onClick: () => void submit(),
190
190
  disabled: submitting || !body.trim() && !rating,
191
- className: "ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground",
191
+ className: "ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:size-11",
192
192
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
193
193
  icon: require_UiArrowUp.UiArrowUp,
194
194
  className: "text-xs"
@@ -1 +1 @@
1
- {"version":3,"file":"CommentComposer.cjs","names":["DropdownMenu","cn","toneToBadgeTone","useState","useRef","MentionTextarea","Icon","UiClose","UiThumbsUp","UiThumbsDown","UiArrowUp"],"sources":["../../src/comments/CommentComposer.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu } from \"../overlay/DropdownMenu\";\nimport { UiArrowUp, UiClose, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport type { BadgeTone } from \"../data/Badge\";\nimport { MentionTextarea } from \"./MentionTextarea\";\nimport { toneToBadgeTone } from \"./comment-utils\";\nimport type {\n CommentAnchor,\n CommentConfig,\n CommentCreateAction,\n CommentCreateInput,\n CommentFacet,\n CommentMention,\n CommentRating,\n} from \"./comment-types\";\n\n// Static literals so Tailwind's source scanner emits these utilities.\nconst FACET_DOT_CLASS: Record<BadgeTone, string> = {\n neutral: \"bg-muted-foreground\",\n success: \"bg-green-500\",\n danger: \"bg-red-500\",\n warning: \"bg-yellow-500\",\n info: \"bg-blue-500\",\n};\n\nexport type CommentComposerProps = {\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n /** Start collapsed as an \"Add a comment…\" pill until clicked. */\n collapsible?: boolean;\n /** Focus the input on mount. A collapsible composer also focuses when the user expands it. */\n autoFocus?: boolean;\n placeholder?: string;\n /** Create a new root comment. */\n onCreate?: (input: CommentCreateInput, actionId?: string) => void | Promise<void>;\n createActions?: readonly CommentCreateAction[];\n /** Fired once per mention referenced by a posted comment. */\n onMention?: (mention: CommentMention, context: { body: string }) => void;\n};\n\nfunction FacetPicker({\n facet,\n value,\n onChange,\n}: {\n facet: CommentFacet;\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n}) {\n const selected = facet.options.find((o) => o.value === value);\n return (\n <DropdownMenu\n align=\"left\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium transition-colors\",\n selected\n ? \"bg-muted text-foreground\"\n : \"text-muted-foreground hover:bg-muted/60\",\n )}\n >\n {selected ? selected.label : facet.label}\n {selected && (\n <span\n role=\"presentation\"\n className=\"ml-0.5 cursor-pointer hover:text-foreground\"\n onClick={(e) => {\n e.stopPropagation();\n onChange(undefined);\n }}\n >\n ×\n </span>\n )}\n </span>\n }\n >\n {(close) => (\n <div className=\"py-1\">\n {facet.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value === value ? undefined : option.value);\n close();\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-[11px] text-popover-foreground hover:bg-accent hover:text-accent-foreground\",\n option.value === value && \"bg-muted font-semibold\",\n )}\n >\n <span\n className={cn(\n \"inline-block size-2 rounded-full\",\n FACET_DOT_CLASS[toneToBadgeTone(option.tone)],\n )}\n />\n {option.label}\n </button>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n\n/**\n * The new-comment composer: a mention-aware textarea, one picker per configured\n * facet, and a send button. Starts as a pill when `collapsible`. Owns only its\n * own draft state; posting is delegated to `onCreate`.\n */\nexport function CommentComposer({\n config,\n anchor,\n collapsible = true,\n autoFocus = false,\n placeholder = \"Add a comment…\",\n onCreate,\n createActions,\n onMention,\n}: CommentComposerProps) {\n const [open, setOpen] = useState(!collapsible || autoFocus);\n const [body, setBody] = useState(\"\");\n const [facets, setFacets] = useState<Record<string, string>>({});\n const [rating, setRating] = useState<CommentRating | undefined>();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const mentionsRef = useRef<Map<string, CommentMention>>(new Map());\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n function reset() {\n setBody(\"\");\n setFacets({});\n setRating(undefined);\n mentionsRef.current.clear();\n }\n\n function setFacet(key: string, value: string | undefined) {\n setFacets((prev) => {\n if (value === undefined) {\n const { [key]: _drop, ...rest } = prev;\n return rest;\n }\n return { ...prev, [key]: value };\n });\n }\n\n async function submit(actionId?: string) {\n const text = body.trim();\n if ((!text && !rating) || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n const mentions = [...mentionsRef.current.values()].filter((m) =>\n body.toLowerCase().includes(`@${m.name.toLowerCase()}`),\n );\n try {\n const input: CommentCreateInput = {\n body: text,\n anchor: anchor ?? null,\n ...(rating ? { rating } : {}),\n ...(Object.keys(facets).length > 0 ? { facets } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n };\n if (actionId === undefined) await onCreate?.(input);\n else await onCreate?.(input, actionId);\n for (const mention of mentions) onMention?.(mention, { body: text });\n reset();\n if (collapsible) setOpen(false);\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n\n if (!open && body.trim().length === 0) {\n return (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"w-full rounded-full border border-border bg-muted/25 px-4 py-2 text-left text-sm text-muted-foreground/70 shadow-sm transition-colors hover:border-primary/30 hover:bg-muted/40\"\n >\n {placeholder}\n </button>\n );\n }\n\n return (\n <div\n data-testid=\"comment-compose-box\"\n aria-busy={submitting}\n className=\"relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md\"\n >\n <MentionTextarea\n ref={inputRef}\n value={body}\n onChange={setBody}\n mentionables={config.mentionables ?? []}\n onMentionSelect={(m) => mentionsRef.current.set(m.id, m)}\n onSubmit={() => void submit()}\n onCancel={() => {\n reset();\n if (collapsible) setOpen(false);\n }}\n placeholder={placeholder}\n // An always-open composer is page chrome: focusing it on mount would\n // scroll its host to it and steal the keyboard from the page.\n autoFocus={autoFocus || (collapsible && open)}\n data-testid=\"comment-compose-input\"\n className=\"min-h-[48px] pr-10\"\n />\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n reset();\n setOpen(false);\n }}\n aria-label=\"Close composer\"\n className=\"absolute right-3 top-3 rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n <div className=\"absolute inset-x-3 bottom-2.5 flex items-center gap-1.5\">\n {(\n [\n [\"positive\", \"Positive rating\", UiThumbsUp],\n [\"negative\", \"Negative rating\", UiThumbsDown],\n ] as const\n ).map(([value, label, icon]) => (\n <button\n key={value}\n type=\"button\"\n aria-label={label}\n aria-pressed={rating === value}\n onClick={() =>\n setRating((current) => (current === value ? undefined : value))\n }\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n rating === value &&\n (value === \"positive\"\n ? \"bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300\"\n : \"bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300\"),\n )}\n >\n <Icon icon={icon} className=\"text-sm\" />\n </button>\n ))}\n {(config.facets ?? []).map((facet) => (\n <FacetPicker\n key={facet.key}\n facet={facet}\n value={facets[facet.key]}\n onChange={(value) => setFacet(facet.key, value)}\n />\n ))}\n {createActions?.length ? (\n <div className=\"ml-auto flex gap-1\">\n {createActions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => void submit(action.id)}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\n >\n {action.label}\n </button>\n ))}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"comment-compose-send\"\n aria-label=\"Post comment\"\n onClick={() => void submit()}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\n >\n <Icon icon={UiArrowUp} className=\"text-xs\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentComposer.cjs","names":["DropdownMenu","cn","toneToBadgeTone","useState","useRef","MentionTextarea","Icon","UiClose","UiThumbsUp","UiThumbsDown","UiArrowUp"],"sources":["../../src/comments/CommentComposer.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu } from \"../overlay/DropdownMenu\";\nimport { UiArrowUp, UiClose, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport type { BadgeTone } from \"../data/Badge\";\nimport { MentionTextarea } from \"./MentionTextarea\";\nimport { toneToBadgeTone } from \"./comment-utils\";\nimport type {\n CommentAnchor,\n CommentConfig,\n CommentCreateAction,\n CommentCreateInput,\n CommentFacet,\n CommentMention,\n CommentRating,\n} from \"./comment-types\";\n\n// Static literals so Tailwind's source scanner emits these utilities.\nconst FACET_DOT_CLASS: Record<BadgeTone, string> = {\n neutral: \"bg-muted-foreground\",\n success: \"bg-green-500\",\n danger: \"bg-red-500\",\n warning: \"bg-yellow-500\",\n info: \"bg-blue-500\",\n};\n\nexport type CommentComposerProps = {\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n /** Start collapsed as an \"Add a comment…\" pill until clicked. */\n collapsible?: boolean;\n /** Focus the input on mount. A collapsible composer also focuses when the user expands it. */\n autoFocus?: boolean;\n placeholder?: string;\n /** Create a new root comment. */\n onCreate?: (input: CommentCreateInput, actionId?: string) => void | Promise<void>;\n createActions?: readonly CommentCreateAction[];\n /** Fired once per mention referenced by a posted comment. */\n onMention?: (mention: CommentMention, context: { body: string }) => void;\n};\n\nfunction FacetPicker({\n facet,\n value,\n onChange,\n}: {\n facet: CommentFacet;\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n}) {\n const selected = facet.options.find((o) => o.value === value);\n return (\n <DropdownMenu\n align=\"left\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium transition-colors\",\n selected\n ? \"bg-muted text-foreground\"\n : \"text-muted-foreground hover:bg-muted/60\",\n )}\n >\n {selected ? selected.label : facet.label}\n {selected && (\n <span\n role=\"presentation\"\n className=\"ml-0.5 cursor-pointer hover:text-foreground\"\n onClick={(e) => {\n e.stopPropagation();\n onChange(undefined);\n }}\n >\n ×\n </span>\n )}\n </span>\n }\n >\n {(close) => (\n <div className=\"py-1\">\n {facet.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value === value ? undefined : option.value);\n close();\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-[11px] text-popover-foreground hover:bg-accent hover:text-accent-foreground\",\n option.value === value && \"bg-muted font-semibold\",\n )}\n >\n <span\n className={cn(\n \"inline-block size-2 rounded-full\",\n FACET_DOT_CLASS[toneToBadgeTone(option.tone)],\n )}\n />\n {option.label}\n </button>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n\n/**\n * The new-comment composer: a mention-aware textarea, one picker per configured\n * facet, and a send button. Starts as a pill when `collapsible`. Owns only its\n * own draft state; posting is delegated to `onCreate`.\n */\nexport function CommentComposer({\n config,\n anchor,\n collapsible = true,\n autoFocus = false,\n placeholder = \"Add a comment…\",\n onCreate,\n createActions,\n onMention,\n}: CommentComposerProps) {\n const [open, setOpen] = useState(!collapsible || autoFocus);\n const [body, setBody] = useState(\"\");\n const [facets, setFacets] = useState<Record<string, string>>({});\n const [rating, setRating] = useState<CommentRating | undefined>();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const mentionsRef = useRef<Map<string, CommentMention>>(new Map());\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n function reset() {\n setBody(\"\");\n setFacets({});\n setRating(undefined);\n mentionsRef.current.clear();\n }\n\n function setFacet(key: string, value: string | undefined) {\n setFacets((prev) => {\n if (value === undefined) {\n const { [key]: _drop, ...rest } = prev;\n return rest;\n }\n return { ...prev, [key]: value };\n });\n }\n\n async function submit(actionId?: string) {\n const text = body.trim();\n if ((!text && !rating) || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n const mentions = [...mentionsRef.current.values()].filter((m) =>\n body.toLowerCase().includes(`@${m.name.toLowerCase()}`),\n );\n try {\n const input: CommentCreateInput = {\n body: text,\n anchor: anchor ?? null,\n ...(rating ? { rating } : {}),\n ...(Object.keys(facets).length > 0 ? { facets } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n };\n if (actionId === undefined) await onCreate?.(input);\n else await onCreate?.(input, actionId);\n for (const mention of mentions) onMention?.(mention, { body: text });\n reset();\n if (collapsible) setOpen(false);\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n\n if (!open && body.trim().length === 0) {\n return (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"w-full rounded-full border border-border bg-muted/25 px-4 py-2 text-left text-sm text-muted-foreground/70 shadow-sm transition-colors hover:border-primary/30 hover:bg-muted/40\"\n >\n {placeholder}\n </button>\n );\n }\n\n return (\n <div\n data-testid=\"comment-compose-box\"\n aria-busy={submitting}\n className=\"relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md [@media(pointer:coarse)]:pb-2\"\n >\n <MentionTextarea\n ref={inputRef}\n value={body}\n onChange={setBody}\n mentionables={config.mentionables ?? []}\n onMentionSelect={(m) => mentionsRef.current.set(m.id, m)}\n onSubmit={() => void submit()}\n onCancel={() => {\n reset();\n if (collapsible) setOpen(false);\n }}\n placeholder={placeholder}\n // An always-open composer is page chrome: focusing it on mount would\n // scroll its host to it and steal the keyboard from the page.\n autoFocus={autoFocus || (collapsible && open)}\n data-testid=\"comment-compose-input\"\n className=\"min-h-[48px] pr-10 [@media(pointer:coarse)]:pr-12\"\n />\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n reset();\n setOpen(false);\n }}\n aria-label=\"Close composer\"\n className=\"absolute right-3 top-3 inline-flex items-center justify-center rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:right-1 [@media(pointer:coarse)]:top-1 [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n {/* Touch-sized controls cannot share one absolute row with the textarea,\n so on a coarse pointer the row joins the flow and wraps. */}\n <div className=\"absolute inset-x-3 bottom-2.5 flex items-center gap-1.5 [@media(pointer:coarse)]:static [@media(pointer:coarse)]:mt-2 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:gap-2\">\n {(\n [\n [\"positive\", \"Positive rating\", UiThumbsUp],\n [\"negative\", \"Negative rating\", UiThumbsDown],\n ] as const\n ).map(([value, label, icon]) => (\n <button\n key={value}\n type=\"button\"\n aria-label={label}\n aria-pressed={rating === value}\n onClick={() =>\n setRating((current) => (current === value ? undefined : value))\n }\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:size-11\",\n rating === value &&\n (value === \"positive\"\n ? \"bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300\"\n : \"bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300\"),\n )}\n >\n <Icon icon={icon} className=\"text-sm\" />\n </button>\n ))}\n {(config.facets ?? []).map((facet) => (\n <FacetPicker\n key={facet.key}\n facet={facet}\n value={facets[facet.key]}\n onChange={(value) => setFacet(facet.key, value)}\n />\n ))}\n {createActions?.length ? (\n <div className=\"ml-auto flex gap-1 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:justify-end [@media(pointer:coarse)]:gap-2\">\n {createActions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => void submit(action.id)}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\"\n >\n {action.label}\n </button>\n ))}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"comment-compose-send\"\n aria-label=\"Post comment\"\n onClick={() => void submit()}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiArrowUp} className=\"text-xs\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommentComposer.d.ts","sourceRoot":"","sources":["../../src/comments/CommentComposer.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAElB,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAWzB,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,aAAa,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,6DAA6D;IAC7D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC1E,CAAC;AAyEF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,WAAkB,EAClB,SAAiB,EACjB,WAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,oBAAoB,+BAsKtB"}
1
+ {"version":3,"file":"CommentComposer.d.ts","sourceRoot":"","sources":["../../src/comments/CommentComposer.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAElB,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAWzB,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,aAAa,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,6DAA6D;IAC7D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC1E,CAAC;AAyEF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,WAAkB,EAClB,SAAiB,EACjB,WAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,SAAS,GACV,EAAE,oBAAoB,+BAwKtB"}
@@ -115,7 +115,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
115
115
  return /* @__PURE__ */ jsxs("div", {
116
116
  "data-testid": "comment-compose-box",
117
117
  "aria-busy": submitting,
118
- className: "relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md",
118
+ className: "relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md [@media(pointer:coarse)]:pb-2",
119
119
  children: [
120
120
  /* @__PURE__ */ jsx(MentionTextarea, {
121
121
  ref: inputRef,
@@ -131,7 +131,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
131
131
  placeholder,
132
132
  autoFocus: autoFocus || collapsible && open,
133
133
  "data-testid": "comment-compose-input",
134
- className: "min-h-[48px] pr-10"
134
+ className: "min-h-[48px] pr-10 [@media(pointer:coarse)]:pr-12"
135
135
  }),
136
136
  collapsible && /* @__PURE__ */ jsx("button", {
137
137
  type: "button",
@@ -140,14 +140,14 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
140
140
  setOpen(false);
141
141
  },
142
142
  "aria-label": "Close composer",
143
- className: "absolute right-3 top-3 rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
143
+ className: "absolute right-3 top-3 inline-flex items-center justify-center rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:right-1 [@media(pointer:coarse)]:top-1 [@media(pointer:coarse)]:size-11",
144
144
  children: /* @__PURE__ */ jsx(Icon, {
145
145
  icon: UiClose,
146
146
  className: "text-xs"
147
147
  })
148
148
  }),
149
149
  /* @__PURE__ */ jsxs("div", {
150
- className: "absolute inset-x-3 bottom-2.5 flex items-center gap-1.5",
150
+ className: "absolute inset-x-3 bottom-2.5 flex items-center gap-1.5 [@media(pointer:coarse)]:static [@media(pointer:coarse)]:mt-2 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:gap-2",
151
151
  children: [
152
152
  [[
153
153
  "positive",
@@ -162,7 +162,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
162
162
  "aria-label": label,
163
163
  "aria-pressed": rating === value,
164
164
  onClick: () => setRating((current) => current === value ? void 0 : value),
165
- className: cn("inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", rating === value && (value === "positive" ? "bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300" : "bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300")),
165
+ className: cn("inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:size-11", rating === value && (value === "positive" ? "bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300" : "bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300")),
166
166
  children: /* @__PURE__ */ jsx(Icon, {
167
167
  icon,
168
168
  className: "text-sm"
@@ -174,12 +174,12 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
174
174
  onChange: (value) => setFacet(facet.key, value)
175
175
  }, facet.key)),
176
176
  createActions?.length ? /* @__PURE__ */ jsx("div", {
177
- className: "ml-auto flex gap-1",
177
+ className: "ml-auto flex gap-1 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:justify-end [@media(pointer:coarse)]:gap-2",
178
178
  children: createActions.map((action) => /* @__PURE__ */ jsx("button", {
179
179
  type: "button",
180
180
  onClick: () => void submit(action.id),
181
181
  disabled: submitting || !body.trim() && !rating,
182
- className: "whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground",
182
+ className: "whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm",
183
183
  children: action.label
184
184
  }, action.id))
185
185
  }) : /* @__PURE__ */ jsx("button", {
@@ -188,7 +188,7 @@ function CommentComposer({ config, anchor, collapsible = true, autoFocus = false
188
188
  "aria-label": "Post comment",
189
189
  onClick: () => void submit(),
190
190
  disabled: submitting || !body.trim() && !rating,
191
- className: "ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground",
191
+ className: "ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:size-11",
192
192
  children: /* @__PURE__ */ jsx(Icon, {
193
193
  icon: UiArrowUp,
194
194
  className: "text-xs"
@@ -1 +1 @@
1
- {"version":3,"file":"CommentComposer.js","names":[],"sources":["../../src/comments/CommentComposer.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu } from \"../overlay/DropdownMenu\";\nimport { UiArrowUp, UiClose, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport type { BadgeTone } from \"../data/Badge\";\nimport { MentionTextarea } from \"./MentionTextarea\";\nimport { toneToBadgeTone } from \"./comment-utils\";\nimport type {\n CommentAnchor,\n CommentConfig,\n CommentCreateAction,\n CommentCreateInput,\n CommentFacet,\n CommentMention,\n CommentRating,\n} from \"./comment-types\";\n\n// Static literals so Tailwind's source scanner emits these utilities.\nconst FACET_DOT_CLASS: Record<BadgeTone, string> = {\n neutral: \"bg-muted-foreground\",\n success: \"bg-green-500\",\n danger: \"bg-red-500\",\n warning: \"bg-yellow-500\",\n info: \"bg-blue-500\",\n};\n\nexport type CommentComposerProps = {\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n /** Start collapsed as an \"Add a comment…\" pill until clicked. */\n collapsible?: boolean;\n /** Focus the input on mount. A collapsible composer also focuses when the user expands it. */\n autoFocus?: boolean;\n placeholder?: string;\n /** Create a new root comment. */\n onCreate?: (input: CommentCreateInput, actionId?: string) => void | Promise<void>;\n createActions?: readonly CommentCreateAction[];\n /** Fired once per mention referenced by a posted comment. */\n onMention?: (mention: CommentMention, context: { body: string }) => void;\n};\n\nfunction FacetPicker({\n facet,\n value,\n onChange,\n}: {\n facet: CommentFacet;\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n}) {\n const selected = facet.options.find((o) => o.value === value);\n return (\n <DropdownMenu\n align=\"left\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium transition-colors\",\n selected\n ? \"bg-muted text-foreground\"\n : \"text-muted-foreground hover:bg-muted/60\",\n )}\n >\n {selected ? selected.label : facet.label}\n {selected && (\n <span\n role=\"presentation\"\n className=\"ml-0.5 cursor-pointer hover:text-foreground\"\n onClick={(e) => {\n e.stopPropagation();\n onChange(undefined);\n }}\n >\n ×\n </span>\n )}\n </span>\n }\n >\n {(close) => (\n <div className=\"py-1\">\n {facet.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value === value ? undefined : option.value);\n close();\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-[11px] text-popover-foreground hover:bg-accent hover:text-accent-foreground\",\n option.value === value && \"bg-muted font-semibold\",\n )}\n >\n <span\n className={cn(\n \"inline-block size-2 rounded-full\",\n FACET_DOT_CLASS[toneToBadgeTone(option.tone)],\n )}\n />\n {option.label}\n </button>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n\n/**\n * The new-comment composer: a mention-aware textarea, one picker per configured\n * facet, and a send button. Starts as a pill when `collapsible`. Owns only its\n * own draft state; posting is delegated to `onCreate`.\n */\nexport function CommentComposer({\n config,\n anchor,\n collapsible = true,\n autoFocus = false,\n placeholder = \"Add a comment…\",\n onCreate,\n createActions,\n onMention,\n}: CommentComposerProps) {\n const [open, setOpen] = useState(!collapsible || autoFocus);\n const [body, setBody] = useState(\"\");\n const [facets, setFacets] = useState<Record<string, string>>({});\n const [rating, setRating] = useState<CommentRating | undefined>();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const mentionsRef = useRef<Map<string, CommentMention>>(new Map());\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n function reset() {\n setBody(\"\");\n setFacets({});\n setRating(undefined);\n mentionsRef.current.clear();\n }\n\n function setFacet(key: string, value: string | undefined) {\n setFacets((prev) => {\n if (value === undefined) {\n const { [key]: _drop, ...rest } = prev;\n return rest;\n }\n return { ...prev, [key]: value };\n });\n }\n\n async function submit(actionId?: string) {\n const text = body.trim();\n if ((!text && !rating) || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n const mentions = [...mentionsRef.current.values()].filter((m) =>\n body.toLowerCase().includes(`@${m.name.toLowerCase()}`),\n );\n try {\n const input: CommentCreateInput = {\n body: text,\n anchor: anchor ?? null,\n ...(rating ? { rating } : {}),\n ...(Object.keys(facets).length > 0 ? { facets } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n };\n if (actionId === undefined) await onCreate?.(input);\n else await onCreate?.(input, actionId);\n for (const mention of mentions) onMention?.(mention, { body: text });\n reset();\n if (collapsible) setOpen(false);\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n\n if (!open && body.trim().length === 0) {\n return (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"w-full rounded-full border border-border bg-muted/25 px-4 py-2 text-left text-sm text-muted-foreground/70 shadow-sm transition-colors hover:border-primary/30 hover:bg-muted/40\"\n >\n {placeholder}\n </button>\n );\n }\n\n return (\n <div\n data-testid=\"comment-compose-box\"\n aria-busy={submitting}\n className=\"relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md\"\n >\n <MentionTextarea\n ref={inputRef}\n value={body}\n onChange={setBody}\n mentionables={config.mentionables ?? []}\n onMentionSelect={(m) => mentionsRef.current.set(m.id, m)}\n onSubmit={() => void submit()}\n onCancel={() => {\n reset();\n if (collapsible) setOpen(false);\n }}\n placeholder={placeholder}\n // An always-open composer is page chrome: focusing it on mount would\n // scroll its host to it and steal the keyboard from the page.\n autoFocus={autoFocus || (collapsible && open)}\n data-testid=\"comment-compose-input\"\n className=\"min-h-[48px] pr-10\"\n />\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n reset();\n setOpen(false);\n }}\n aria-label=\"Close composer\"\n className=\"absolute right-3 top-3 rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n <div className=\"absolute inset-x-3 bottom-2.5 flex items-center gap-1.5\">\n {(\n [\n [\"positive\", \"Positive rating\", UiThumbsUp],\n [\"negative\", \"Negative rating\", UiThumbsDown],\n ] as const\n ).map(([value, label, icon]) => (\n <button\n key={value}\n type=\"button\"\n aria-label={label}\n aria-pressed={rating === value}\n onClick={() =>\n setRating((current) => (current === value ? undefined : value))\n }\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n rating === value &&\n (value === \"positive\"\n ? \"bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300\"\n : \"bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300\"),\n )}\n >\n <Icon icon={icon} className=\"text-sm\" />\n </button>\n ))}\n {(config.facets ?? []).map((facet) => (\n <FacetPicker\n key={facet.key}\n facet={facet}\n value={facets[facet.key]}\n onChange={(value) => setFacet(facet.key, value)}\n />\n ))}\n {createActions?.length ? (\n <div className=\"ml-auto flex gap-1\">\n {createActions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => void submit(action.id)}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\n >\n {action.label}\n </button>\n ))}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"comment-compose-send\"\n aria-label=\"Post comment\"\n onClick={() => void submit()}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\"\n >\n <Icon icon={UiArrowUp} className=\"text-xs\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentComposer.js","names":[],"sources":["../../src/comments/CommentComposer.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { DropdownMenu } from \"../overlay/DropdownMenu\";\nimport { UiArrowUp, UiClose, UiThumbsDown, UiThumbsUp } from \"../icons\";\nimport type { BadgeTone } from \"../data/Badge\";\nimport { MentionTextarea } from \"./MentionTextarea\";\nimport { toneToBadgeTone } from \"./comment-utils\";\nimport type {\n CommentAnchor,\n CommentConfig,\n CommentCreateAction,\n CommentCreateInput,\n CommentFacet,\n CommentMention,\n CommentRating,\n} from \"./comment-types\";\n\n// Static literals so Tailwind's source scanner emits these utilities.\nconst FACET_DOT_CLASS: Record<BadgeTone, string> = {\n neutral: \"bg-muted-foreground\",\n success: \"bg-green-500\",\n danger: \"bg-red-500\",\n warning: \"bg-yellow-500\",\n info: \"bg-blue-500\",\n};\n\nexport type CommentComposerProps = {\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n /** Start collapsed as an \"Add a comment…\" pill until clicked. */\n collapsible?: boolean;\n /** Focus the input on mount. A collapsible composer also focuses when the user expands it. */\n autoFocus?: boolean;\n placeholder?: string;\n /** Create a new root comment. */\n onCreate?: (input: CommentCreateInput, actionId?: string) => void | Promise<void>;\n createActions?: readonly CommentCreateAction[];\n /** Fired once per mention referenced by a posted comment. */\n onMention?: (mention: CommentMention, context: { body: string }) => void;\n};\n\nfunction FacetPicker({\n facet,\n value,\n onChange,\n}: {\n facet: CommentFacet;\n value: string | undefined;\n onChange: (value: string | undefined) => void;\n}) {\n const selected = facet.options.find((o) => o.value === value);\n return (\n <DropdownMenu\n align=\"left\"\n menuClassName=\"min-w-[150px]\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium transition-colors\",\n selected\n ? \"bg-muted text-foreground\"\n : \"text-muted-foreground hover:bg-muted/60\",\n )}\n >\n {selected ? selected.label : facet.label}\n {selected && (\n <span\n role=\"presentation\"\n className=\"ml-0.5 cursor-pointer hover:text-foreground\"\n onClick={(e) => {\n e.stopPropagation();\n onChange(undefined);\n }}\n >\n ×\n </span>\n )}\n </span>\n }\n >\n {(close) => (\n <div className=\"py-1\">\n {facet.options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => {\n onChange(option.value === value ? undefined : option.value);\n close();\n }}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-[11px] text-popover-foreground hover:bg-accent hover:text-accent-foreground\",\n option.value === value && \"bg-muted font-semibold\",\n )}\n >\n <span\n className={cn(\n \"inline-block size-2 rounded-full\",\n FACET_DOT_CLASS[toneToBadgeTone(option.tone)],\n )}\n />\n {option.label}\n </button>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n\n/**\n * The new-comment composer: a mention-aware textarea, one picker per configured\n * facet, and a send button. Starts as a pill when `collapsible`. Owns only its\n * own draft state; posting is delegated to `onCreate`.\n */\nexport function CommentComposer({\n config,\n anchor,\n collapsible = true,\n autoFocus = false,\n placeholder = \"Add a comment…\",\n onCreate,\n createActions,\n onMention,\n}: CommentComposerProps) {\n const [open, setOpen] = useState(!collapsible || autoFocus);\n const [body, setBody] = useState(\"\");\n const [facets, setFacets] = useState<Record<string, string>>({});\n const [rating, setRating] = useState<CommentRating | undefined>();\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n const mentionsRef = useRef<Map<string, CommentMention>>(new Map());\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n function reset() {\n setBody(\"\");\n setFacets({});\n setRating(undefined);\n mentionsRef.current.clear();\n }\n\n function setFacet(key: string, value: string | undefined) {\n setFacets((prev) => {\n if (value === undefined) {\n const { [key]: _drop, ...rest } = prev;\n return rest;\n }\n return { ...prev, [key]: value };\n });\n }\n\n async function submit(actionId?: string) {\n const text = body.trim();\n if ((!text && !rating) || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n const mentions = [...mentionsRef.current.values()].filter((m) =>\n body.toLowerCase().includes(`@${m.name.toLowerCase()}`),\n );\n try {\n const input: CommentCreateInput = {\n body: text,\n anchor: anchor ?? null,\n ...(rating ? { rating } : {}),\n ...(Object.keys(facets).length > 0 ? { facets } : {}),\n ...(mentions.length > 0 ? { mentions } : {}),\n };\n if (actionId === undefined) await onCreate?.(input);\n else await onCreate?.(input, actionId);\n for (const mention of mentions) onMention?.(mention, { body: text });\n reset();\n if (collapsible) setOpen(false);\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n\n if (!open && body.trim().length === 0) {\n return (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"w-full rounded-full border border-border bg-muted/25 px-4 py-2 text-left text-sm text-muted-foreground/70 shadow-sm transition-colors hover:border-primary/30 hover:bg-muted/40\"\n >\n {placeholder}\n </button>\n );\n }\n\n return (\n <div\n data-testid=\"comment-compose-box\"\n aria-busy={submitting}\n className=\"relative rounded-2xl border border-border bg-muted/25 px-3 pt-3 pb-10 shadow-sm transition-[border-color,box-shadow] focus-within:border-primary/40 focus-within:shadow-md [@media(pointer:coarse)]:pb-2\"\n >\n <MentionTextarea\n ref={inputRef}\n value={body}\n onChange={setBody}\n mentionables={config.mentionables ?? []}\n onMentionSelect={(m) => mentionsRef.current.set(m.id, m)}\n onSubmit={() => void submit()}\n onCancel={() => {\n reset();\n if (collapsible) setOpen(false);\n }}\n placeholder={placeholder}\n // An always-open composer is page chrome: focusing it on mount would\n // scroll its host to it and steal the keyboard from the page.\n autoFocus={autoFocus || (collapsible && open)}\n data-testid=\"comment-compose-input\"\n className=\"min-h-[48px] pr-10 [@media(pointer:coarse)]:pr-12\"\n />\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n reset();\n setOpen(false);\n }}\n aria-label=\"Close composer\"\n className=\"absolute right-3 top-3 inline-flex items-center justify-center rounded-full p-1 text-muted-foreground hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:right-1 [@media(pointer:coarse)]:top-1 [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n {/* Touch-sized controls cannot share one absolute row with the textarea,\n so on a coarse pointer the row joins the flow and wraps. */}\n <div className=\"absolute inset-x-3 bottom-2.5 flex items-center gap-1.5 [@media(pointer:coarse)]:static [@media(pointer:coarse)]:mt-2 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:gap-2\">\n {(\n [\n [\"positive\", \"Positive rating\", UiThumbsUp],\n [\"negative\", \"Negative rating\", UiThumbsDown],\n ] as const\n ).map(([value, label, icon]) => (\n <button\n key={value}\n type=\"button\"\n aria-label={label}\n aria-pressed={rating === value}\n onClick={() =>\n setRating((current) => (current === value ? undefined : value))\n }\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:size-11\",\n rating === value &&\n (value === \"positive\"\n ? \"bg-green-100 text-green-700 [[data-theme=dark]_&]:bg-green-500/20 [[data-theme=dark]_&]:text-green-300\"\n : \"bg-red-100 text-red-700 [[data-theme=dark]_&]:bg-red-500/20 [[data-theme=dark]_&]:text-red-300\"),\n )}\n >\n <Icon icon={icon} className=\"text-sm\" />\n </button>\n ))}\n {(config.facets ?? []).map((facet) => (\n <FacetPicker\n key={facet.key}\n facet={facet}\n value={facets[facet.key]}\n onChange={(value) => setFacet(facet.key, value)}\n />\n ))}\n {createActions?.length ? (\n <div className=\"ml-auto flex gap-1 [@media(pointer:coarse)]:flex-wrap [@media(pointer:coarse)]:justify-end [@media(pointer:coarse)]:gap-2\">\n {createActions.map((action) => (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => void submit(action.id)}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"whitespace-nowrap rounded-md bg-primary px-1.5 py-1 text-[10px] font-medium text-primary-foreground hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\"\n >\n {action.label}\n </button>\n ))}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"comment-compose-send\"\n aria-label=\"Post comment\"\n onClick={() => void submit()}\n disabled={submitting || (!body.trim() && !rating)}\n className=\"ml-auto inline-flex size-7 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground [@media(pointer:coarse)]:size-11\"\n >\n <Icon icon={UiArrowUp} className=\"text-xs\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}