@flanksource/clicky-ui 0.3.55 → 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 (991) 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 +19 -29
  628. package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
  629. package/dist/data/test-runner/MatrixMarks.d.ts +4 -4
  630. package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
  631. package/dist/data/test-runner/MatrixMarks.js +19 -29
  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/types.d.ts +2 -0
  656. package/dist/data/test-runner/types.d.ts.map +1 -1
  657. package/dist/data/timeseries-query.cjs +98 -2
  658. package/dist/data/timeseries-query.cjs.map +1 -1
  659. package/dist/data/timeseries-query.d.ts +31 -5
  660. package/dist/data/timeseries-query.d.ts.map +1 -1
  661. package/dist/data/timeseries-query.js +98 -3
  662. package/dist/data/timeseries-query.js.map +1 -1
  663. package/dist/data/timeseries-stream-provider.cjs +38 -0
  664. package/dist/data/timeseries-stream-provider.cjs.map +1 -0
  665. package/dist/data/timeseries-stream-provider.d.ts +26 -0
  666. package/dist/data/timeseries-stream-provider.d.ts.map +1 -0
  667. package/dist/data/timeseries-stream-provider.js +38 -0
  668. package/dist/data/timeseries-stream-provider.js.map +1 -0
  669. package/dist/data/timeseries-stream.cjs +304 -0
  670. package/dist/data/timeseries-stream.cjs.map +1 -0
  671. package/dist/data/timeseries-stream.d.ts +81 -0
  672. package/dist/data/timeseries-stream.d.ts.map +1 -0
  673. package/dist/data/timeseries-stream.fixtures.d.ts +36 -0
  674. package/dist/data/timeseries-stream.fixtures.d.ts.map +1 -0
  675. package/dist/data/timeseries-stream.js +296 -0
  676. package/dist/data/timeseries-stream.js.map +1 -0
  677. package/dist/data/token-style.cjs +13 -0
  678. package/dist/data/token-style.cjs.map +1 -0
  679. package/dist/data/token-style.d.ts +4 -0
  680. package/dist/data/token-style.d.ts.map +1 -0
  681. package/dist/data/token-style.js +13 -0
  682. package/dist/data/token-style.js.map +1 -0
  683. package/dist/data/traces/ProcessTraceDetail.cjs +1 -1
  684. package/dist/data/traces/ProcessTraceDetail.js +1 -1
  685. package/dist/data/traces/index.d.ts +1 -1
  686. package/dist/data/traces/index.d.ts.map +1 -1
  687. package/dist/data/use-data-table-virtual.d.ts +1 -1
  688. package/dist/data/version-info.cjs +3 -3
  689. package/dist/data/version-info.js +3 -3
  690. package/dist/data/workload-panel/MemoryStack.cjs +49 -0
  691. package/dist/data/workload-panel/MemoryStack.cjs.map +1 -0
  692. package/dist/data/workload-panel/MemoryStack.d.ts +11 -0
  693. package/dist/data/workload-panel/MemoryStack.d.ts.map +1 -0
  694. package/dist/data/workload-panel/MemoryStack.js +48 -0
  695. package/dist/data/workload-panel/MemoryStack.js.map +1 -0
  696. package/dist/data/workload-panel/Metrics.cjs +197 -0
  697. package/dist/data/workload-panel/Metrics.cjs.map +1 -0
  698. package/dist/data/workload-panel/Metrics.d.ts +11 -0
  699. package/dist/data/workload-panel/Metrics.d.ts.map +1 -0
  700. package/dist/data/workload-panel/Metrics.js +196 -0
  701. package/dist/data/workload-panel/Metrics.js.map +1 -0
  702. package/dist/data/workload-panel/WorkloadPanel.cjs +66 -0
  703. package/dist/data/workload-panel/WorkloadPanel.cjs.map +1 -0
  704. package/dist/data/workload-panel/WorkloadPanel.d.ts +3 -0
  705. package/dist/data/workload-panel/WorkloadPanel.d.ts.map +1 -0
  706. package/dist/data/workload-panel/WorkloadPanel.js +66 -0
  707. package/dist/data/workload-panel/WorkloadPanel.js.map +1 -0
  708. package/dist/data/workload-panel/fixtures.d.ts +60 -0
  709. package/dist/data/workload-panel/fixtures.d.ts.map +1 -0
  710. package/dist/data/workload-panel/model.cjs +137 -0
  711. package/dist/data/workload-panel/model.cjs.map +1 -0
  712. package/dist/data/workload-panel/model.d.ts +53 -0
  713. package/dist/data/workload-panel/model.d.ts.map +1 -0
  714. package/dist/data/workload-panel/model.js +133 -0
  715. package/dist/data/workload-panel/model.js.map +1 -0
  716. package/dist/data/workload-panel/types.d.ts +56 -0
  717. package/dist/data/workload-panel/types.d.ts.map +1 -0
  718. package/dist/data.cjs +57 -6
  719. package/dist/data.d.ts +9 -1
  720. package/dist/data.d.ts.map +1 -1
  721. package/dist/data.js +27 -10
  722. package/dist/file-findings/AnnotatedCode.cjs +243 -0
  723. package/dist/file-findings/AnnotatedCode.cjs.map +1 -0
  724. package/dist/file-findings/AnnotatedCode.d.ts +30 -0
  725. package/dist/file-findings/AnnotatedCode.d.ts.map +1 -0
  726. package/dist/file-findings/AnnotatedCode.js +243 -0
  727. package/dist/file-findings/AnnotatedCode.js.map +1 -0
  728. package/dist/file-findings/FileFindingsView.cjs +213 -0
  729. package/dist/file-findings/FileFindingsView.cjs.map +1 -0
  730. package/dist/file-findings/FileFindingsView.d.ts +35 -0
  731. package/dist/file-findings/FileFindingsView.d.ts.map +1 -0
  732. package/dist/file-findings/FileFindingsView.js +213 -0
  733. package/dist/file-findings/FileFindingsView.js.map +1 -0
  734. package/dist/file-findings/LazyAnnotatedCode.cjs +22 -0
  735. package/dist/file-findings/LazyAnnotatedCode.cjs.map +1 -0
  736. package/dist/file-findings/LazyAnnotatedCode.d.ts +5 -0
  737. package/dist/file-findings/LazyAnnotatedCode.d.ts.map +1 -0
  738. package/dist/file-findings/LazyAnnotatedCode.js +22 -0
  739. package/dist/file-findings/LazyAnnotatedCode.js.map +1 -0
  740. package/dist/file-findings/adapters.cjs +155 -0
  741. package/dist/file-findings/adapters.cjs.map +1 -0
  742. package/dist/file-findings/adapters.d.ts +24 -0
  743. package/dist/file-findings/adapters.d.ts.map +1 -0
  744. package/dist/file-findings/adapters.js +153 -0
  745. package/dist/file-findings/adapters.js.map +1 -0
  746. package/dist/file-findings/file-review/CommentDraft.cjs +97 -0
  747. package/dist/file-findings/file-review/CommentDraft.cjs.map +1 -0
  748. package/dist/file-findings/file-review/CommentDraft.d.ts +25 -0
  749. package/dist/file-findings/file-review/CommentDraft.d.ts.map +1 -0
  750. package/dist/file-findings/file-review/CommentDraft.js +97 -0
  751. package/dist/file-findings/file-review/CommentDraft.js.map +1 -0
  752. package/dist/file-findings/file-review/FileReview.cjs +863 -0
  753. package/dist/file-findings/file-review/FileReview.cjs.map +1 -0
  754. package/dist/file-findings/file-review/FileReview.d.ts +79 -0
  755. package/dist/file-findings/file-review/FileReview.d.ts.map +1 -0
  756. package/dist/file-findings/file-review/FileReview.fixtures.d.ts +25 -0
  757. package/dist/file-findings/file-review/FileReview.fixtures.d.ts.map +1 -0
  758. package/dist/file-findings/file-review/FileReview.js +863 -0
  759. package/dist/file-findings/file-review/FileReview.js.map +1 -0
  760. package/dist/file-findings/file-review/InlineAuthors.cjs +77 -0
  761. package/dist/file-findings/file-review/InlineAuthors.cjs.map +1 -0
  762. package/dist/file-findings/file-review/InlineAuthors.d.ts +9 -0
  763. package/dist/file-findings/file-review/InlineAuthors.d.ts.map +1 -0
  764. package/dist/file-findings/file-review/InlineAuthors.js +77 -0
  765. package/dist/file-findings/file-review/InlineAuthors.js.map +1 -0
  766. package/dist/file-findings/file-review/InlineThread.cjs +77 -0
  767. package/dist/file-findings/file-review/InlineThread.cjs.map +1 -0
  768. package/dist/file-findings/file-review/InlineThread.d.ts +27 -0
  769. package/dist/file-findings/file-review/InlineThread.d.ts.map +1 -0
  770. package/dist/file-findings/file-review/InlineThread.js +77 -0
  771. package/dist/file-findings/file-review/InlineThread.js.map +1 -0
  772. package/dist/file-findings/file-review/ProblemsList.cjs +164 -0
  773. package/dist/file-findings/file-review/ProblemsList.cjs.map +1 -0
  774. package/dist/file-findings/file-review/ProblemsList.d.ts +15 -0
  775. package/dist/file-findings/file-review/ProblemsList.d.ts.map +1 -0
  776. package/dist/file-findings/file-review/ProblemsList.js +164 -0
  777. package/dist/file-findings/file-review/ProblemsList.js.map +1 -0
  778. package/dist/file-findings/file-review/SourceView.cjs +179 -0
  779. package/dist/file-findings/file-review/SourceView.cjs.map +1 -0
  780. package/dist/file-findings/file-review/SourceView.d.ts +29 -0
  781. package/dist/file-findings/file-review/SourceView.d.ts.map +1 -0
  782. package/dist/file-findings/file-review/SourceView.js +179 -0
  783. package/dist/file-findings/file-review/SourceView.js.map +1 -0
  784. package/dist/file-findings/file-review/blame.cjs +35 -0
  785. package/dist/file-findings/file-review/blame.cjs.map +1 -0
  786. package/dist/file-findings/file-review/blame.d.ts +28 -0
  787. package/dist/file-findings/file-review/blame.d.ts.map +1 -0
  788. package/dist/file-findings/file-review/blame.js +33 -0
  789. package/dist/file-findings/file-review/blame.js.map +1 -0
  790. package/dist/file-findings/file-review/geometry.cjs +101 -0
  791. package/dist/file-findings/file-review/geometry.cjs.map +1 -0
  792. package/dist/file-findings/file-review/geometry.d.ts +45 -0
  793. package/dist/file-findings/file-review/geometry.d.ts.map +1 -0
  794. package/dist/file-findings/file-review/geometry.js +98 -0
  795. package/dist/file-findings/file-review/geometry.js.map +1 -0
  796. package/dist/file-findings/file-review/hooks.cjs +101 -0
  797. package/dist/file-findings/file-review/hooks.cjs.map +1 -0
  798. package/dist/file-findings/file-review/hooks.d.ts +22 -0
  799. package/dist/file-findings/file-review/hooks.d.ts.map +1 -0
  800. package/dist/file-findings/file-review/hooks.js +99 -0
  801. package/dist/file-findings/file-review/hooks.js.map +1 -0
  802. package/dist/file-findings/file-review/marks.cjs +52 -0
  803. package/dist/file-findings/file-review/marks.cjs.map +1 -0
  804. package/dist/file-findings/file-review/marks.d.ts +23 -0
  805. package/dist/file-findings/file-review/marks.d.ts.map +1 -0
  806. package/dist/file-findings/file-review/marks.js +47 -0
  807. package/dist/file-findings/file-review/marks.js.map +1 -0
  808. package/dist/file-findings/file-review/problem-filters.cjs +14 -0
  809. package/dist/file-findings/file-review/problem-filters.cjs.map +1 -0
  810. package/dist/file-findings/file-review/problem-filters.d.ts +10 -0
  811. package/dist/file-findings/file-review/problem-filters.d.ts.map +1 -0
  812. package/dist/file-findings/file-review/problem-filters.js +13 -0
  813. package/dist/file-findings/file-review/problem-filters.js.map +1 -0
  814. package/dist/file-findings/file-review/quote-anchor.cjs +234 -0
  815. package/dist/file-findings/file-review/quote-anchor.cjs.map +1 -0
  816. package/dist/file-findings/file-review/quote-anchor.d.ts +54 -0
  817. package/dist/file-findings/file-review/quote-anchor.d.ts.map +1 -0
  818. package/dist/file-findings/file-review/quote-anchor.js +226 -0
  819. package/dist/file-findings/file-review/quote-anchor.js.map +1 -0
  820. package/dist/file-findings/file-review/source-anchor.cjs +104 -0
  821. package/dist/file-findings/file-review/source-anchor.cjs.map +1 -0
  822. package/dist/file-findings/file-review/source-anchor.d.ts +27 -0
  823. package/dist/file-findings/file-review/source-anchor.d.ts.map +1 -0
  824. package/dist/file-findings/file-review/source-anchor.js +99 -0
  825. package/dist/file-findings/file-review/source-anchor.js.map +1 -0
  826. package/dist/file-findings/file-review/source-marks.cjs +71 -0
  827. package/dist/file-findings/file-review/source-marks.cjs.map +1 -0
  828. package/dist/file-findings/file-review/source-marks.d.ts +27 -0
  829. package/dist/file-findings/file-review/source-marks.d.ts.map +1 -0
  830. package/dist/file-findings/file-review/source-marks.js +68 -0
  831. package/dist/file-findings/file-review/source-marks.js.map +1 -0
  832. package/dist/file-findings/findings-comments.cjs +136 -0
  833. package/dist/file-findings/findings-comments.cjs.map +1 -0
  834. package/dist/file-findings/findings-comments.d.ts +28 -0
  835. package/dist/file-findings/findings-comments.d.ts.map +1 -0
  836. package/dist/file-findings/findings-comments.js +131 -0
  837. package/dist/file-findings/findings-comments.js.map +1 -0
  838. package/dist/file-findings/findings-languages.cjs +53 -0
  839. package/dist/file-findings/findings-languages.cjs.map +1 -0
  840. package/dist/file-findings/findings-languages.d.ts +11 -0
  841. package/dist/file-findings/findings-languages.d.ts.map +1 -0
  842. package/dist/file-findings/findings-languages.js +53 -0
  843. package/dist/file-findings/findings-languages.js.map +1 -0
  844. package/dist/file-findings/mdx-source.cjs +48 -0
  845. package/dist/file-findings/mdx-source.cjs.map +1 -0
  846. package/dist/file-findings/mdx-source.d.ts +7 -0
  847. package/dist/file-findings/mdx-source.d.ts.map +1 -0
  848. package/dist/file-findings/mdx-source.js +48 -0
  849. package/dist/file-findings/mdx-source.js.map +1 -0
  850. package/dist/file-findings/monaco-language.cjs +73 -0
  851. package/dist/file-findings/monaco-language.cjs.map +1 -0
  852. package/dist/file-findings/monaco-language.d.ts +11 -0
  853. package/dist/file-findings/monaco-language.d.ts.map +1 -0
  854. package/dist/file-findings/monaco-language.js +72 -0
  855. package/dist/file-findings/monaco-language.js.map +1 -0
  856. package/dist/file-findings/severity-counts.cjs +20 -0
  857. package/dist/file-findings/severity-counts.cjs.map +1 -0
  858. package/dist/file-findings/severity-counts.d.ts +5 -0
  859. package/dist/file-findings/severity-counts.d.ts.map +1 -0
  860. package/dist/file-findings/severity-counts.js +19 -0
  861. package/dist/file-findings/severity-counts.js.map +1 -0
  862. package/dist/file-findings/types.cjs +12 -0
  863. package/dist/file-findings/types.cjs.map +1 -0
  864. package/dist/file-findings/types.d.ts +43 -0
  865. package/dist/file-findings/types.d.ts.map +1 -0
  866. package/dist/file-findings/types.js +11 -0
  867. package/dist/file-findings/types.js.map +1 -0
  868. package/dist/file-findings.cjs +47 -0
  869. package/dist/file-findings.d.ts +15 -0
  870. package/dist/file-findings.d.ts.map +1 -0
  871. package/dist/file-findings.js +15 -0
  872. package/dist/hooks/event-hub.cjs +22 -8
  873. package/dist/hooks/event-hub.cjs.map +1 -1
  874. package/dist/hooks/event-hub.d.ts.map +1 -1
  875. package/dist/hooks/event-hub.js +22 -8
  876. package/dist/hooks/event-hub.js.map +1 -1
  877. package/dist/icons/components/UiBrowser.cjs +51 -0
  878. package/dist/icons/components/UiBrowser.cjs.map +1 -0
  879. package/dist/icons/components/UiBrowser.d.ts +15 -0
  880. package/dist/icons/components/UiBrowser.d.ts.map +1 -0
  881. package/dist/icons/components/UiBrowser.js +48 -0
  882. package/dist/icons/components/UiBrowser.js.map +1 -0
  883. package/dist/icons/components/UiCreditCard.cjs +51 -0
  884. package/dist/icons/components/UiCreditCard.cjs.map +1 -0
  885. package/dist/icons/components/UiCreditCard.d.ts +15 -0
  886. package/dist/icons/components/UiCreditCard.d.ts.map +1 -0
  887. package/dist/icons/components/UiCreditCard.js +48 -0
  888. package/dist/icons/components/UiCreditCard.js.map +1 -0
  889. package/dist/icons/components/UiShoppingCart.cjs +51 -0
  890. package/dist/icons/components/UiShoppingCart.cjs.map +1 -0
  891. package/dist/icons/components/UiShoppingCart.d.ts +15 -0
  892. package/dist/icons/components/UiShoppingCart.d.ts.map +1 -0
  893. package/dist/icons/components/UiShoppingCart.js +48 -0
  894. package/dist/icons/components/UiShoppingCart.js.map +1 -0
  895. package/dist/icons/index.d.ts +6 -0
  896. package/dist/icons/index.d.ts.map +1 -1
  897. package/dist/icons/registry.cjs +6 -0
  898. package/dist/icons/registry.cjs.map +1 -1
  899. package/dist/icons/registry.d.ts.map +1 -1
  900. package/dist/icons/registry.js +6 -0
  901. package/dist/icons/registry.js.map +1 -1
  902. package/dist/icons.cjs +9 -0
  903. package/dist/icons.js +4 -1
  904. package/dist/index.cjs +75 -7
  905. package/dist/index.d.ts +1 -0
  906. package/dist/index.d.ts.map +1 -1
  907. package/dist/index.js +35 -12
  908. package/dist/layout/AppShell.cjs +37 -21
  909. package/dist/layout/AppShell.cjs.map +1 -1
  910. package/dist/layout/AppShell.d.ts +13 -2
  911. package/dist/layout/AppShell.d.ts.map +1 -1
  912. package/dist/layout/AppShell.js +37 -21
  913. package/dist/layout/AppShell.js.map +1 -1
  914. package/dist/layout/AppShell.nav.cjs +7 -6
  915. package/dist/layout/AppShell.nav.cjs.map +1 -1
  916. package/dist/layout/AppShell.nav.d.ts.map +1 -1
  917. package/dist/layout/AppShell.nav.js +7 -6
  918. package/dist/layout/AppShell.nav.js.map +1 -1
  919. package/dist/layout/SplitPane.cjs +16 -6
  920. package/dist/layout/SplitPane.cjs.map +1 -1
  921. package/dist/layout/SplitPane.d.ts +12 -2
  922. package/dist/layout/SplitPane.d.ts.map +1 -1
  923. package/dist/layout/SplitPane.js +16 -6
  924. package/dist/layout/SplitPane.js.map +1 -1
  925. package/dist/layout/Workspace.cjs +37 -33
  926. package/dist/layout/Workspace.cjs.map +1 -1
  927. package/dist/layout/Workspace.d.ts.map +1 -1
  928. package/dist/layout/Workspace.js +37 -33
  929. package/dist/layout/Workspace.js.map +1 -1
  930. package/dist/layout/Workspace.regions.cjs +3 -3
  931. package/dist/layout/Workspace.regions.cjs.map +1 -1
  932. package/dist/layout/Workspace.regions.js +3 -3
  933. package/dist/layout/Workspace.regions.js.map +1 -1
  934. package/dist/lib/breakpoints.cjs +102 -0
  935. package/dist/lib/breakpoints.cjs.map +1 -0
  936. package/dist/lib/breakpoints.d.ts +36 -0
  937. package/dist/lib/breakpoints.d.ts.map +1 -0
  938. package/dist/lib/breakpoints.js +99 -0
  939. package/dist/lib/breakpoints.js.map +1 -0
  940. package/dist/lib/combobox.cjs +2 -1
  941. package/dist/lib/combobox.cjs.map +1 -1
  942. package/dist/lib/combobox.d.ts +1 -1
  943. package/dist/lib/combobox.d.ts.map +1 -1
  944. package/dist/lib/combobox.js +2 -1
  945. package/dist/lib/combobox.js.map +1 -1
  946. package/dist/lib/path-tree.cjs +21 -0
  947. package/dist/lib/path-tree.cjs.map +1 -1
  948. package/dist/lib/path-tree.d.ts +15 -0
  949. package/dist/lib/path-tree.d.ts.map +1 -1
  950. package/dist/lib/path-tree.js +21 -1
  951. package/dist/lib/path-tree.js.map +1 -1
  952. package/dist/overlay/Modal.cjs +2 -1
  953. package/dist/overlay/Modal.cjs.map +1 -1
  954. package/dist/overlay/Modal.d.ts.map +1 -1
  955. package/dist/overlay/Modal.js +2 -1
  956. package/dist/overlay/Modal.js.map +1 -1
  957. package/dist/overlay/dropdownMenuContext.d.ts +1 -1
  958. package/dist/profiles/editor/profileEditor.cjs +1 -1
  959. package/dist/profiles/editor/profileEditor.cjs.map +1 -1
  960. package/dist/profiles/editor/profileEditor.js +1 -1
  961. package/dist/profiles/editor/profileEditor.js.map +1 -1
  962. package/dist/profiles/editor/profileEditorSections.cjs +2 -2
  963. package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
  964. package/dist/profiles/editor/profileEditorSections.js +2 -2
  965. package/dist/profiles/editor/profileEditorSections.js.map +1 -1
  966. package/dist/profiles/query/prometheusResults.cjs +24 -36
  967. package/dist/profiles/query/prometheusResults.cjs.map +1 -1
  968. package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
  969. package/dist/profiles/query/prometheusResults.js +24 -36
  970. package/dist/profiles/query/prometheusResults.js.map +1 -1
  971. package/dist/rpc/CommandForm.cjs +1 -1
  972. package/dist/rpc/CommandForm.cjs.map +1 -1
  973. package/dist/rpc/CommandForm.js +1 -1
  974. package/dist/rpc/CommandForm.js.map +1 -1
  975. package/dist/rpc/classify.cjs +1 -1
  976. package/dist/rpc/classify.cjs.map +1 -1
  977. package/dist/rpc/classify.d.ts.map +1 -1
  978. package/dist/rpc/classify.js +1 -1
  979. package/dist/rpc/classify.js.map +1 -1
  980. package/dist/rpc/useOperations.d.ts +24 -24
  981. package/dist/rpc.cjs +0 -2
  982. package/dist/rpc.d.ts +0 -1
  983. package/dist/rpc.d.ts.map +1 -1
  984. package/dist/rpc.js +1 -2
  985. package/dist/styles.css +1 -1
  986. package/dist/utils.cjs +6 -0
  987. package/dist/utils.d.ts +2 -1
  988. package/dist/utils.d.ts.map +1 -1
  989. package/dist/utils.js +3 -2
  990. package/package.json +9 -3
  991. package/schemas/json-schema-form.schema.json +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CommentSidePanel.js","names":[],"sources":["../../src/comments/CommentSidePanel.tsx"],"sourcesContent":["import {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiComment } from \"../icons\";\nimport { CommentThread } from \"./CommentThread\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport {\n useCommentContextOptional,\n type CommentContextValue,\n} from \"./comment-context\";\nimport {\n buildThreadListHandlers,\n getRoots,\n selectAnchorThreads,\n sortReplies,\n buildReplyMap,\n} from \"./comment-utils\";\nimport {\n resolveCommentStage,\n selectCommentThreadsByStage,\n} from \"../lib/comment-stage\";\nimport {\n DOCUMENT_ANCHOR,\n type Comment,\n type CommentAnchor,\n type CommentCreateAction,\n type CommentStatusStage,\n} from \"./comment-types\";\n\nexport type CommentSidePanelProps = {\n /** Explicit label per anchor key. */\n anchorLabels?: Record<CommentAnchor, string>;\n /** Fallback label formatter for anchors without an explicit label. */\n formatAnchorLabel?: (anchor: CommentAnchor) => string;\n compact?: boolean;\n /** Position the focused thread beside its registered content anchor. */\n focusedAlignment?: \"flow\" | \"anchor\";\n className?: string;\n /** Serialize one whole thread for Copy and its maximized Markdown tab. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n createActions?: readonly CommentCreateAction[];\n};\n\nfunction defaultAnchorLabel(anchor: CommentAnchor): string {\n if (anchor === DOCUMENT_ANCHOR) return \"General\";\n return anchor\n .replace(/\\[\\d+\\]/g, \"\")\n .replaceAll(\".\", \" › \")\n .replaceAll(\"_\", \" \")\n .trim();\n}\n\nfunction useAnchorLabel(props: CommentSidePanelProps) {\n return (anchor: CommentAnchor): string =>\n props.anchorLabels?.[anchor] ??\n props.formatAnchorLabel?.(anchor) ??\n defaultAnchorLabel(anchor);\n}\n\nfunction LocationMeta({ label }: { label: string }) {\n return (\n <span\n data-testid=\"comment-location-meta\"\n className=\"inline-flex items-center rounded-full bg-muted px-2 py-1 text-[10px] font-medium text-muted-foreground\"\n >\n {label}\n </span>\n );\n}\n\nfunction RailToggle({\n active,\n onClick,\n children,\n testId,\n}: {\n active?: boolean;\n onClick: () => void;\n children: React.ReactNode;\n testId?: string;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testId}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium shadow-sm transition-colors\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n <Icon icon={UiComment} className=\"text-xs\" />\n {children}\n </button>\n );\n}\n\nfunction orderedAnchors(ctx: CommentContextValue): string[] {\n return Object.keys(ctx.commentMeta).sort((a, b) => {\n if (a === DOCUMENT_ANCHOR) return -1;\n if (b === DOCUMENT_ANCHOR) return 1;\n const at = ctx.getAnchorTop(a);\n const bt = ctx.getAnchorTop(b);\n if (at == null && bt == null) return a.localeCompare(b);\n if (at == null) return 1;\n if (bt == null) return -1;\n if (at !== bt) return at - bt;\n return a.localeCompare(b);\n });\n}\n\nfunction orderComments(\n comments: Comment[],\n anchorOrder: Map<string, number>,\n): Comment[] {\n const replyMap = buildReplyMap(comments);\n const roots = getRoots(comments).sort((a, b) => {\n const ai =\n anchorOrder.get(a.anchor ?? DOCUMENT_ANCHOR) ?? Number.MAX_SAFE_INTEGER;\n const bi =\n anchorOrder.get(b.anchor ?? DOCUMENT_ANCHOR) ?? Number.MAX_SAFE_INTEGER;\n if (ai !== bi) return ai - bi;\n if (a.createdAt !== b.createdAt)\n return a.createdAt.localeCompare(b.createdAt);\n return String(a.id).localeCompare(String(b.id));\n });\n return roots.flatMap((root) => [\n root,\n ...sortReplies(replyMap.get(root.id) ?? []),\n ]);\n}\n\nfunction AllComments({\n ctx,\n comments,\n label,\n emptyLabel,\n threadToMarkdown,\n renderRootDetails,\n}: {\n ctx: CommentContextValue;\n comments: Comment[];\n label: (a: CommentAnchor) => string;\n emptyLabel: string;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n}) {\n const ordered = useMemo(() => {\n const anchorOrder = new Map(orderedAnchors(ctx).map((a, i) => [a, i]));\n return orderComments(comments, anchorOrder);\n }, [ctx, comments]);\n const handlers = buildThreadListHandlers(ordered, ctx.config, ctx.callbacks);\n\n function activateThread(\n event: MouseEvent<HTMLDivElement>,\n anchor: CommentAnchor,\n ) {\n const target = event.target as Element;\n if (\n target.closest(\n 'button, a, details, input, textarea, select, [contenteditable=\"true\"]',\n )\n )\n return;\n const roleButton = target.closest('[role=\"button\"]');\n if (roleButton && roleButton !== target.closest(\"[data-comment-kind]\"))\n return;\n if (anchor !== DOCUMENT_ANCHOR) {\n const found = ctx.scrollToAnchor(anchor, {\n behavior: \"smooth\",\n block: \"start\",\n offset: 12,\n });\n if (!found) return;\n }\n ctx.focusAnchor(anchor);\n }\n\n if (ordered.length === 0) {\n return (\n <p className=\"rounded-lg bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n {emptyLabel}\n </p>\n );\n }\n\n return (\n <div\n data-testid=\"comment-all-rail\"\n className=\"space-y-3 overflow-y-auto pr-1\"\n >\n <CommentThreadList\n comments={ordered}\n config={ctx.config}\n compact\n renderRootMeta={(c) => {\n const anchor = c.anchor ?? DOCUMENT_ANCHOR;\n const available =\n anchor === DOCUMENT_ANCHOR || ctx.getAnchorTop(anchor) != null;\n return (\n <LocationMeta\n label={`${label(anchor)}${available ? \"\" : \" · Unavailable\"}`}\n />\n );\n }}\n getThreadProps={(c) => ({\n \"data-testid\": \"comment-feed-item\",\n onMouseEnter: () =>\n ctx.setHighlightAnchor(c.anchor ?? DOCUMENT_ANCHOR),\n onMouseLeave: () => ctx.setHighlightAnchor(null),\n onClick: (event) =>\n activateThread(event, c.anchor ?? DOCUMENT_ANCHOR),\n })}\n {...handlers}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n />\n </div>\n );\n}\n\nfunction FocusedComments({\n ctx,\n comments: visible,\n anchor,\n label,\n compact,\n threadToMarkdown,\n renderRootDetails,\n createActions,\n}: {\n ctx: CommentContextValue;\n comments: Comment[];\n anchor: CommentAnchor;\n label: string;\n compact?: boolean;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n createActions?: readonly CommentCreateAction[];\n}) {\n const comments = selectAnchorThreads(visible, anchor);\n const hasComments = comments.length > 0;\n return (\n <div className=\"space-y-3\" data-comment-anchor={anchor}>\n <LocationMeta\n label={\n anchor === DOCUMENT_ANCHOR\n ? \"Whole-page comment\"\n : `Attached to ${label}`\n }\n />\n <CommentThread\n comments={comments}\n config={ctx.config}\n anchor={anchor}\n compact={compact ?? false}\n autoFocusComposer={!hasComments}\n defaultExpanded={hasComments}\n composerPlaceholder={\n hasComments ? \"Add another top-level comment…\" : \"Add a comment…\"\n }\n {...ctx.callbacks}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(createActions ? { createActions } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n />\n </div>\n );\n}\n\n/**\n * A controlled comment rail driven by {@link CommentProvider}. Shows a focused\n * thread for the active anchor, the full document feed in anchor order, or a\n * toggle when collapsed. Renders nothing outside a provider or when empty.\n */\nexport function CommentSidePanel(props: CommentSidePanelProps) {\n const ctx = useCommentContextOptional();\n const label = useAnchorLabel(props);\n const railRef = useRef<HTMLElement>(null);\n const focusedRef = useRef<HTMLDivElement>(null);\n const [focusedOffset, setFocusedOffset] = useState<number | null>(null);\n const [stage, setStage] = useState<CommentStatusStage>(\"active\");\n const focusedAnchor = ctx?.railMode === \"focused\" ? ctx.focusedAnchor : null;\n\n useEffect(() => {\n if (!ctx || props.focusedAlignment !== \"anchor\" || !focusedAnchor) {\n setFocusedOffset(null);\n return;\n }\n const content = ctx.contentRef.current;\n const rail = railRef.current;\n const focused = focusedRef.current;\n if (!content || !rail || !focused) return;\n\n const update = () => {\n const anchorTop = ctx.getAnchorTop(focusedAnchor);\n if (anchorTop == null) {\n setFocusedOffset(null);\n return;\n }\n const desiredTop = anchorTop + content.getBoundingClientRect().top;\n const currentOffset = Number.parseFloat(focused.style.top) || 0;\n const nextOffset =\n currentOffset + desiredTop - focused.getBoundingClientRect().top;\n setFocusedOffset(Math.max(0, nextOffset));\n };\n update();\n content.addEventListener(\"scroll\", update, { passive: true });\n window.addEventListener(\"resize\", update);\n const observer =\n typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(update);\n observer?.observe(content);\n observer?.observe(rail);\n return () => {\n content.removeEventListener(\"scroll\", update);\n window.removeEventListener(\"resize\", update);\n observer?.disconnect();\n };\n }, [ctx, focusedAnchor, props.focusedAlignment]);\n\n if (!ctx) return null;\n\n // Threads, not cards: a reply is part of its root, never a separate entry.\n const counts = getRoots(ctx.comments).reduce(\n (result, root) => {\n const rootStage = resolveCommentStage(ctx.config, root.status);\n if (rootStage) result[rootStage] += 1;\n return result;\n },\n { active: 0, resolved: 0, closed: 0 },\n );\n const visible = selectCommentThreadsByStage(ctx.comments, ctx.config, stage);\n if (\n ctx.railMode === \"closed\" &&\n counts.active + counts.resolved + counts.closed === 0\n )\n return null;\n\n function selectStage(next: CommentStatusStage) {\n setStage(next);\n if (ctx?.railMode !== \"all\") ctx?.openCommentList();\n }\n\n return (\n <aside\n ref={railRef}\n data-testid=\"comment-side-panel\"\n className={cn(\"relative w-[320px] space-y-3\", props.className)}\n >\n <div\n data-testid=\"comment-rail-header\"\n className=\"sticky top-0 z-20 flex items-center gap-2 bg-background py-2\"\n >\n {(counts.active > 0 || ctx.railMode === \"all\") && (\n <RailToggle\n active={ctx.railMode === \"all\" && stage === \"active\"}\n onClick={() => selectStage(\"active\")}\n testId=\"comment-open-all\"\n >\n {ctx.railMode === \"closed\"\n ? `Open comments (${counts.active})`\n : ctx.railMode === \"focused\"\n ? `All comments (${counts.active})`\n : `Open (${counts.active})`}\n </RailToggle>\n )}\n {counts.resolved > 0 && (\n <button\n type=\"button\"\n aria-pressed={ctx.railMode === \"all\" && stage === \"resolved\"}\n onClick={() => selectStage(\"resolved\")}\n className={cn(\n \"rounded-full border px-2 py-1 text-xs font-medium transition-colors\",\n ctx.railMode === \"all\" && stage === \"resolved\"\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n Resolved ({counts.resolved})\n </button>\n )}\n {counts.closed > 0 && (\n <button\n type=\"button\"\n aria-pressed={ctx.railMode === \"all\" && stage === \"closed\"}\n onClick={() => selectStage(\"closed\")}\n className={cn(\n \"rounded-full border px-2 py-1 text-xs font-medium transition-colors\",\n ctx.railMode === \"all\" && stage === \"closed\"\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n Closed ({counts.closed})\n </button>\n )}\n {ctx.railMode !== \"closed\" && (\n <button\n type=\"button\"\n onClick={ctx.closeRail}\n className=\"ml-auto rounded-md px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n {ctx.railMode === \"all\" ? \"Close\" : \"Hide\"}\n </button>\n )}\n </div>\n {ctx.railMode === \"all\" ? (\n <AllComments\n ctx={ctx}\n comments={visible}\n label={label}\n emptyLabel={\n stage === \"active\"\n ? \"No open comments.\"\n : stage === \"resolved\"\n ? \"No resolved comments.\"\n : \"No closed comments.\"\n }\n {...(props.threadToMarkdown\n ? { threadToMarkdown: props.threadToMarkdown }\n : {})}\n {...(props.renderRootDetails\n ? { renderRootDetails: props.renderRootDetails }\n : {})}\n />\n ) : ctx.railMode === \"focused\" && ctx.focusedAnchor ? (\n <div\n ref={focusedRef}\n data-testid=\"comment-focused-rail\"\n className=\"relative space-y-3\"\n style={focusedOffset == null ? undefined : { top: focusedOffset }}\n >\n <FocusedComments\n ctx={ctx}\n comments={ctx.comments}\n anchor={ctx.focusedAnchor}\n {...(props.createActions\n ? { createActions: props.createActions }\n : {})}\n label={label(ctx.focusedAnchor)}\n {...(props.compact !== undefined ? { compact: props.compact } : {})}\n {...(props.threadToMarkdown\n ? { threadToMarkdown: props.threadToMarkdown }\n : {})}\n {...(props.renderRootDetails\n ? { renderRootDetails: props.renderRootDetails }\n : {})}\n />\n </div>\n ) : null}\n </aside>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentSidePanel.js","names":[],"sources":["../../src/comments/CommentSidePanel.tsx"],"sourcesContent":["import {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MouseEvent,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiComment } from \"../icons\";\nimport type { DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport { CommentThread } from \"./CommentThread\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport {\n useCommentContextOptional,\n type CommentContextValue,\n} from \"./comment-context\";\nimport {\n buildThreadListHandlers,\n getRoots,\n selectAnchorThreads,\n sortReplies,\n buildReplyMap,\n} from \"./comment-utils\";\nimport {\n resolveCommentStage,\n selectCommentThreadsByStage,\n} from \"../lib/comment-stage\";\nimport {\n DOCUMENT_ANCHOR,\n type Comment,\n type CommentAnchor,\n type CommentCreateAction,\n type CommentStatusStage,\n} from \"./comment-types\";\n\nexport type CommentSidePanelProps = {\n /** Explicit label per anchor key. */\n anchorLabels?: Record<CommentAnchor, string>;\n /** Fallback label formatter for anchors without an explicit label. */\n formatAnchorLabel?: (anchor: CommentAnchor) => string;\n compact?: boolean;\n /** Position the focused thread beside its registered content anchor. */\n focusedAlignment?: \"flow\" | \"anchor\";\n className?: string;\n /** Serialize one whole thread for Copy and its maximized Markdown tab. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n createActions?: readonly CommentCreateAction[];\n /**\n * Entries appended to each root's \"Assign…\" submenu — the seam for host\n * actions that start from an assignment, such as running an agent.\n */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n};\n\nfunction defaultAnchorLabel(anchor: CommentAnchor): string {\n if (anchor === DOCUMENT_ANCHOR) return \"General\";\n return anchor\n .replace(/\\[\\d+\\]/g, \"\")\n .replaceAll(\".\", \" › \")\n .replaceAll(\"_\", \" \")\n .trim();\n}\n\nfunction useAnchorLabel(props: CommentSidePanelProps) {\n return (anchor: CommentAnchor): string =>\n props.anchorLabels?.[anchor] ??\n props.formatAnchorLabel?.(anchor) ??\n defaultAnchorLabel(anchor);\n}\n\nfunction LocationMeta({ label }: { label: string }) {\n return (\n <span\n data-testid=\"comment-location-meta\"\n className=\"inline-flex items-center rounded-full bg-muted px-2 py-1 text-[10px] font-medium text-muted-foreground\"\n >\n {label}\n </span>\n );\n}\n\nfunction RailToggle({\n active,\n onClick,\n children,\n testId,\n}: {\n active?: boolean;\n onClick: () => void;\n children: React.ReactNode;\n testId?: string;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testId}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium shadow-sm transition-colors [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:text-sm\",\n active\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n <Icon icon={UiComment} className=\"text-xs\" />\n {children}\n </button>\n );\n}\n\nfunction orderedAnchors(ctx: CommentContextValue): string[] {\n return Object.keys(ctx.commentMeta).sort((a, b) => {\n if (a === DOCUMENT_ANCHOR) return -1;\n if (b === DOCUMENT_ANCHOR) return 1;\n const at = ctx.getAnchorTop(a);\n const bt = ctx.getAnchorTop(b);\n if (at == null && bt == null) return a.localeCompare(b);\n if (at == null) return 1;\n if (bt == null) return -1;\n if (at !== bt) return at - bt;\n return a.localeCompare(b);\n });\n}\n\nfunction orderComments(\n comments: Comment[],\n anchorOrder: Map<string, number>,\n): Comment[] {\n const replyMap = buildReplyMap(comments);\n const roots = getRoots(comments).sort((a, b) => {\n const ai =\n anchorOrder.get(a.anchor ?? DOCUMENT_ANCHOR) ?? Number.MAX_SAFE_INTEGER;\n const bi =\n anchorOrder.get(b.anchor ?? DOCUMENT_ANCHOR) ?? Number.MAX_SAFE_INTEGER;\n if (ai !== bi) return ai - bi;\n if (a.createdAt !== b.createdAt)\n return a.createdAt.localeCompare(b.createdAt);\n return String(a.id).localeCompare(String(b.id));\n });\n return roots.flatMap((root) => [\n root,\n ...sortReplies(replyMap.get(root.id) ?? []),\n ]);\n}\n\nfunction AllComments({\n ctx,\n comments,\n label,\n emptyLabel,\n threadToMarkdown,\n renderRootDetails,\n extraAssignItems,\n}: {\n ctx: CommentContextValue;\n comments: Comment[];\n label: (a: CommentAnchor) => string;\n emptyLabel: string;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n}) {\n const ordered = useMemo(() => {\n const anchorOrder = new Map(orderedAnchors(ctx).map((a, i) => [a, i]));\n return orderComments(comments, anchorOrder);\n }, [ctx, comments]);\n const handlers = buildThreadListHandlers(ordered, ctx.config, ctx.callbacks);\n\n function activateThread(\n event: MouseEvent<HTMLDivElement>,\n anchor: CommentAnchor,\n ) {\n const target = event.target as Element;\n if (\n target.closest(\n 'button, a, details, input, textarea, select, [contenteditable=\"true\"]',\n )\n )\n return;\n const roleButton = target.closest('[role=\"button\"]');\n if (roleButton && roleButton !== target.closest(\"[data-comment-kind]\"))\n return;\n if (anchor !== DOCUMENT_ANCHOR) {\n const found = ctx.scrollToAnchor(anchor, {\n behavior: \"smooth\",\n block: \"start\",\n offset: 12,\n });\n if (!found) return;\n }\n ctx.focusAnchor(anchor);\n }\n\n if (ordered.length === 0) {\n return (\n <p className=\"rounded-lg bg-muted/40 px-3 py-2 text-xs text-muted-foreground\">\n {emptyLabel}\n </p>\n );\n }\n\n return (\n <div\n data-testid=\"comment-all-rail\"\n className=\"space-y-3 overflow-y-auto pr-1\"\n >\n <CommentThreadList\n comments={ordered}\n config={ctx.config}\n compact\n renderRootMeta={(c) => {\n const anchor = c.anchor ?? DOCUMENT_ANCHOR;\n const available =\n anchor === DOCUMENT_ANCHOR || ctx.getAnchorTop(anchor) != null;\n return (\n <LocationMeta\n label={`${label(anchor)}${available ? \"\" : \" · Unavailable\"}`}\n />\n );\n }}\n getThreadProps={(c) => ({\n \"data-testid\": \"comment-feed-item\",\n onMouseEnter: () =>\n ctx.setHighlightAnchor(c.anchor ?? DOCUMENT_ANCHOR),\n onMouseLeave: () => ctx.setHighlightAnchor(null),\n onClick: (event) =>\n activateThread(event, c.anchor ?? DOCUMENT_ANCHOR),\n })}\n {...handlers}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(extraAssignItems ? { extraAssignItems } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n />\n </div>\n );\n}\n\nfunction FocusedComments({\n ctx,\n comments: visible,\n anchor,\n label,\n compact,\n threadToMarkdown,\n renderRootDetails,\n createActions,\n extraAssignItems,\n}: {\n ctx: CommentContextValue;\n comments: Comment[];\n anchor: CommentAnchor;\n label: string;\n compact?: boolean;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n renderRootDetails?: (comment: Comment) => ReactNode;\n createActions?: readonly CommentCreateAction[];\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n}) {\n const comments = selectAnchorThreads(visible, anchor);\n const hasComments = comments.length > 0;\n return (\n <div className=\"space-y-3\" data-comment-anchor={anchor}>\n <LocationMeta\n label={\n anchor === DOCUMENT_ANCHOR\n ? \"Whole-page comment\"\n : `Attached to ${label}`\n }\n />\n <CommentThread\n comments={comments}\n config={ctx.config}\n anchor={anchor}\n compact={compact ?? false}\n autoFocusComposer={!hasComments}\n defaultExpanded={hasComments}\n composerPlaceholder={\n hasComments ? \"Add another top-level comment…\" : \"Add a comment…\"\n }\n {...ctx.callbacks}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(createActions ? { createActions } : {})}\n {...(extraAssignItems ? { extraAssignItems } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n />\n </div>\n );\n}\n\n/**\n * A controlled comment rail driven by {@link CommentProvider}. Shows a focused\n * thread for the active anchor, the full document feed in anchor order, or a\n * toggle when collapsed. Renders nothing outside a provider or when empty.\n */\nexport function CommentSidePanel(props: CommentSidePanelProps) {\n const ctx = useCommentContextOptional();\n const label = useAnchorLabel(props);\n const railRef = useRef<HTMLElement>(null);\n const focusedRef = useRef<HTMLDivElement>(null);\n const [focusedOffset, setFocusedOffset] = useState<number | null>(null);\n const [stage, setStage] = useState<CommentStatusStage>(\"active\");\n const focusedAnchor = ctx?.railMode === \"focused\" ? ctx.focusedAnchor : null;\n\n useEffect(() => {\n if (!ctx || props.focusedAlignment !== \"anchor\" || !focusedAnchor) {\n setFocusedOffset(null);\n return;\n }\n const content = ctx.contentRef.current;\n const rail = railRef.current;\n const focused = focusedRef.current;\n if (!content || !rail || !focused) return;\n\n const update = () => {\n const anchorTop = ctx.getAnchorTop(focusedAnchor);\n // A rail stacked under the content (narrow screens) has no anchor row to\n // line up with; offsetting it only pushes the thread out of view.\n const contentBox = content.getBoundingClientRect();\n const stacked =\n contentBox.height > 0 &&\n rail.getBoundingClientRect().top >= contentBox.bottom;\n if (anchorTop == null || stacked) {\n setFocusedOffset(null);\n return;\n }\n const desiredTop = anchorTop + content.getBoundingClientRect().top;\n const currentOffset = Number.parseFloat(focused.style.top) || 0;\n const nextOffset =\n currentOffset + desiredTop - focused.getBoundingClientRect().top;\n setFocusedOffset(Math.max(0, nextOffset));\n };\n update();\n content.addEventListener(\"scroll\", update, { passive: true });\n window.addEventListener(\"resize\", update);\n const observer =\n typeof ResizeObserver === \"undefined\" ? null : new ResizeObserver(update);\n observer?.observe(content);\n observer?.observe(rail);\n return () => {\n content.removeEventListener(\"scroll\", update);\n window.removeEventListener(\"resize\", update);\n observer?.disconnect();\n };\n }, [ctx, focusedAnchor, props.focusedAlignment]);\n\n if (!ctx) return null;\n\n // Threads, not cards: a reply is part of its root, never a separate entry.\n const counts = getRoots(ctx.comments).reduce(\n (result, root) => {\n const rootStage = resolveCommentStage(ctx.config, root.status);\n if (rootStage) result[rootStage] += 1;\n return result;\n },\n { active: 0, resolved: 0, closed: 0 },\n );\n const visible = selectCommentThreadsByStage(ctx.comments, ctx.config, stage);\n if (\n ctx.railMode === \"closed\" &&\n counts.active + counts.resolved + counts.closed === 0\n )\n return null;\n\n function selectStage(next: CommentStatusStage) {\n setStage(next);\n if (ctx?.railMode !== \"all\") ctx?.openCommentList();\n }\n\n return (\n <aside\n ref={railRef}\n data-testid=\"comment-side-panel\"\n className={cn(\"relative w-[320px] max-w-full space-y-3\", props.className)}\n >\n <div\n data-testid=\"comment-rail-header\"\n className=\"sticky top-0 z-20 flex flex-wrap items-center gap-2 bg-background py-2\"\n >\n {(counts.active > 0 || ctx.railMode === \"all\") && (\n <RailToggle\n active={ctx.railMode === \"all\" && stage === \"active\"}\n onClick={() => selectStage(\"active\")}\n testId=\"comment-open-all\"\n >\n {ctx.railMode === \"closed\"\n ? `Open comments (${counts.active})`\n : ctx.railMode === \"focused\"\n ? `All comments (${counts.active})`\n : `Open (${counts.active})`}\n </RailToggle>\n )}\n {counts.resolved > 0 && (\n <button\n type=\"button\"\n aria-pressed={ctx.railMode === \"all\" && stage === \"resolved\"}\n onClick={() => selectStage(\"resolved\")}\n className={cn(\n \"rounded-full border px-2 py-1 text-xs font-medium transition-colors [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\",\n ctx.railMode === \"all\" && stage === \"resolved\"\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n Resolved ({counts.resolved})\n </button>\n )}\n {counts.closed > 0 && (\n <button\n type=\"button\"\n aria-pressed={ctx.railMode === \"all\" && stage === \"closed\"}\n onClick={() => selectStage(\"closed\")}\n className={cn(\n \"rounded-full border px-2 py-1 text-xs font-medium transition-colors [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\",\n ctx.railMode === \"all\" && stage === \"closed\"\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border bg-background text-muted-foreground hover:text-foreground\",\n )}\n >\n Closed ({counts.closed})\n </button>\n )}\n {ctx.railMode !== \"closed\" && (\n <button\n type=\"button\"\n onClick={ctx.closeRail}\n className=\"ml-auto rounded-md px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground [@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:px-3 [@media(pointer:coarse)]:text-sm\"\n >\n {ctx.railMode === \"all\" ? \"Close\" : \"Hide\"}\n </button>\n )}\n </div>\n {ctx.railMode === \"all\" ? (\n <AllComments\n ctx={ctx}\n comments={visible}\n label={label}\n emptyLabel={\n stage === \"active\"\n ? \"No open comments.\"\n : stage === \"resolved\"\n ? \"No resolved comments.\"\n : \"No closed comments.\"\n }\n {...(props.threadToMarkdown\n ? { threadToMarkdown: props.threadToMarkdown }\n : {})}\n {...(props.renderRootDetails\n ? { renderRootDetails: props.renderRootDetails }\n : {})}\n {...(props.extraAssignItems\n ? { extraAssignItems: props.extraAssignItems }\n : {})}\n />\n ) : ctx.railMode === \"focused\" && ctx.focusedAnchor ? (\n <div\n ref={focusedRef}\n data-testid=\"comment-focused-rail\"\n className=\"relative space-y-3\"\n style={focusedOffset == null ? undefined : { top: focusedOffset }}\n >\n <FocusedComments\n ctx={ctx}\n comments={ctx.comments}\n anchor={ctx.focusedAnchor}\n {...(props.createActions\n ? { createActions: props.createActions }\n : {})}\n label={label(ctx.focusedAnchor)}\n {...(props.compact !== undefined ? { compact: props.compact } : {})}\n {...(props.threadToMarkdown\n ? { threadToMarkdown: props.threadToMarkdown }\n : {})}\n {...(props.renderRootDetails\n ? { renderRootDetails: props.renderRootDetails }\n : {})}\n {...(props.extraAssignItems\n ? { extraAssignItems: props.extraAssignItems }\n : {})}\n />\n </div>\n ) : null}\n </aside>\n );\n}\n"],"mappings":"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"}
@@ -11,10 +11,12 @@ let react_jsx_runtime = require("react/jsx-runtime");
11
11
  * the supplied callbacks, translating list-level events (checklist index, reply
12
12
  * target) into the callback contract.
13
13
  */
14
- function CommentThread({ comments, config, anchor, compact = false, autoFocusComposer = false, defaultExpanded = false, composerPlaceholder, hideComposer = false, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, onCreate, onReply, onUpdateStatus, onClose, onDelete, onChecklistToggle, onMention }) {
14
+ function CommentThread({ comments, config, anchor, compact = false, autoFocusComposer = false, defaultExpanded = false, composerPlaceholder, hideComposer = false, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, extraAssignItems, onCreate, onReply, onUpdateStatus, onClose, onAcknowledge, onAssign, onDelete, onChecklistToggle, onMention }) {
15
15
  const listHandlers = require_comment_utils.buildThreadListHandlers(comments, config, {
16
16
  ...onUpdateStatus ? { onUpdateStatus } : {},
17
17
  ...onClose ? { onClose } : {},
18
+ ...onAcknowledge ? { onAcknowledge } : {},
19
+ ...onAssign ? { onAssign } : {},
18
20
  ...onDelete ? { onDelete } : {},
19
21
  ...onChecklistToggle ? { onChecklistToggle } : {},
20
22
  ...onReply ? { onReply } : {},
@@ -31,6 +33,7 @@ function CommentThread({ comments, config, anchor, compact = false, autoFocusCom
31
33
  ...renderRootDetails ? { renderRootDetails } : {},
32
34
  ...renderBody ? { renderBody } : {},
33
35
  ...threadToMarkdown ? { threadToMarkdown } : {},
36
+ ...extraAssignItems ? { extraAssignItems } : {},
34
37
  ...listHandlers
35
38
  }), !hideComposer && onCreate && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
36
39
  className: "pt-1",
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThread.cjs","names":["buildThreadListHandlers","cn","CommentThreadList","CommentComposer"],"sources":["../../src/comments/CommentThread.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { CommentComposer } from \"./CommentComposer\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport { buildThreadListHandlers } from \"./comment-utils\";\nimport type {\n Comment,\n CommentAnchor,\n CommentCallbacks,\n CommentConfig,\n CommentCreateAction,\n} from \"./comment-types\";\n\nexport type CommentThreadProps = CommentCallbacks & {\n /** Comments for this thread (typically pre-filtered to one anchor). */\n comments: Comment[];\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n compact?: boolean;\n /** Auto-open and focus the composer on mount. */\n autoFocusComposer?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Label for creating a separate root comment. */\n composerPlaceholder?: string;\n /** Hide the composer (read-only thread). */\n hideComposer?: boolean;\n createActions?: readonly CommentCreateAction[];\n renderRootMeta?: (comment: Comment) => ReactNode;\n renderRootDetails?: (comment: Comment) => ReactNode;\n renderBody?: (body: string) => ReactNode;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n};\n\n/**\n * Top-level controlled comment thread: a threaded list plus a mention-aware\n * composer. Owns no data — it renders `comments` and forwards every mutation to\n * the supplied callbacks, translating list-level events (checklist index, reply\n * target) into the callback contract.\n */\nexport function CommentThread({\n comments,\n config,\n anchor,\n compact = false,\n autoFocusComposer = false,\n defaultExpanded = false,\n composerPlaceholder,\n hideComposer = false,\n createActions,\n renderRootMeta,\n renderRootDetails,\n renderBody,\n threadToMarkdown,\n onCreate,\n onReply,\n onUpdateStatus,\n onClose,\n onDelete,\n onChecklistToggle,\n onMention,\n}: CommentThreadProps) {\n const listHandlers = buildThreadListHandlers(comments, config, {\n ...(onUpdateStatus ? { onUpdateStatus } : {}),\n ...(onClose ? { onClose } : {}),\n ...(onDelete ? { onDelete } : {}),\n ...(onChecklistToggle ? { onChecklistToggle } : {}),\n ...(onReply ? { onReply } : {}),\n ...(onMention ? { onMention } : {}),\n });\n\n return (\n <div className={cn(compact && \"p-2\")}>\n <CommentThreadList\n comments={comments}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n {...(renderRootMeta ? { renderRootMeta } : {})}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(renderBody ? { renderBody } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n {...listHandlers}\n />\n {!hideComposer && onCreate && (\n <div className=\"pt-1\">\n <CommentComposer\n config={config}\n anchor={anchor ?? null}\n autoFocus={autoFocusComposer}\n {...(composerPlaceholder\n ? { placeholder: composerPlaceholder }\n : {})}\n onCreate={onCreate}\n {...(createActions ? { createActions } : {})}\n {...(onMention ? { onMention } : {})}\n />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAyCA,SAAgB,cAAc,EAC5B,UACA,QACA,QACA,UAAU,OACV,oBAAoB,OACpB,kBAAkB,OAClB,qBACA,eAAe,OACf,eACA,gBACA,mBACA,YACA,kBACA,UACA,SACA,gBACA,SACA,UACA,mBACA,aACqB;CACrB,MAAM,eAAeA,sBAAAA,wBAAwB,UAAU,QAAQ;EAC7D,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC3C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;EACjD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;CACnC,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,WAAW,KAAK;EAAnC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,0BAAAA,mBAAD;GACY;GACF;GACC;GACQ;GACjB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC5C,GAAK,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;GAClD,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;GACpC,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAI;EACL,CAAA,GACA,CAAC,gBAAgB,YAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,wBAAAA,iBAAD;IACU;IACR,QAAQ,UAAU;IAClB,WAAW;IACX,GAAK,sBACD,EAAE,aAAa,oBAAoB,IACnC,CAAC;IACK;IACV,GAAK,gBAAgB,EAAE,cAAc,IAAI,CAAC;IAC1C,GAAK,YAAY,EAAE,UAAU,IAAI,CAAC;GACnC,CAAA;EACE,CAAA,CAEJ;;AAET"}
1
+ {"version":3,"file":"CommentThread.cjs","names":["buildThreadListHandlers","cn","CommentThreadList","CommentComposer"],"sources":["../../src/comments/CommentThread.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport type { DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport { CommentComposer } from \"./CommentComposer\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport { buildThreadListHandlers } from \"./comment-utils\";\nimport type {\n Comment,\n CommentAnchor,\n CommentCallbacks,\n CommentConfig,\n CommentCreateAction,\n} from \"./comment-types\";\n\nexport type CommentThreadProps = CommentCallbacks & {\n /** Comments for this thread (typically pre-filtered to one anchor). */\n comments: Comment[];\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n compact?: boolean;\n /** Auto-open and focus the composer on mount. */\n autoFocusComposer?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Label for creating a separate root comment. */\n composerPlaceholder?: string;\n /** Hide the composer (read-only thread). */\n hideComposer?: boolean;\n createActions?: readonly CommentCreateAction[];\n renderRootMeta?: (comment: Comment) => ReactNode;\n renderRootDetails?: (comment: Comment) => ReactNode;\n renderBody?: (body: string) => ReactNode;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n /** Caller-owned entries appended to each root's \"Assign…\" submenu. */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n};\n\n/**\n * Top-level controlled comment thread: a threaded list plus a mention-aware\n * composer. Owns no data — it renders `comments` and forwards every mutation to\n * the supplied callbacks, translating list-level events (checklist index, reply\n * target) into the callback contract.\n */\nexport function CommentThread({\n comments,\n config,\n anchor,\n compact = false,\n autoFocusComposer = false,\n defaultExpanded = false,\n composerPlaceholder,\n hideComposer = false,\n createActions,\n renderRootMeta,\n renderRootDetails,\n renderBody,\n threadToMarkdown,\n extraAssignItems,\n onCreate,\n onReply,\n onUpdateStatus,\n onClose,\n onAcknowledge,\n onAssign,\n onDelete,\n onChecklistToggle,\n onMention,\n}: CommentThreadProps) {\n const listHandlers = buildThreadListHandlers(comments, config, {\n ...(onUpdateStatus ? { onUpdateStatus } : {}),\n ...(onClose ? { onClose } : {}),\n ...(onAcknowledge ? { onAcknowledge } : {}),\n ...(onAssign ? { onAssign } : {}),\n ...(onDelete ? { onDelete } : {}),\n ...(onChecklistToggle ? { onChecklistToggle } : {}),\n ...(onReply ? { onReply } : {}),\n ...(onMention ? { onMention } : {}),\n });\n\n return (\n <div className={cn(compact && \"p-2\")}>\n <CommentThreadList\n comments={comments}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n {...(renderRootMeta ? { renderRootMeta } : {})}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(renderBody ? { renderBody } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n {...(extraAssignItems ? { extraAssignItems } : {})}\n {...listHandlers}\n />\n {!hideComposer && onCreate && (\n <div className=\"pt-1\">\n <CommentComposer\n config={config}\n anchor={anchor ?? null}\n autoFocus={autoFocusComposer}\n {...(composerPlaceholder\n ? { placeholder: composerPlaceholder }\n : {})}\n onCreate={onCreate}\n {...(createActions ? { createActions } : {})}\n {...(onMention ? { onMention } : {})}\n />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA4CA,SAAgB,cAAc,EAC5B,UACA,QACA,QACA,UAAU,OACV,oBAAoB,OACpB,kBAAkB,OAClB,qBACA,eAAe,OACf,eACA,gBACA,mBACA,YACA,kBACA,kBACA,UACA,SACA,gBACA,SACA,eACA,UACA,UACA,mBACA,aACqB;CACrB,MAAM,eAAeA,sBAAAA,wBAAwB,UAAU,QAAQ;EAC7D,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC3C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;EACzC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;EACjD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;CACnC,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,WAAW,KAAK;EAAnC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,0BAAAA,mBAAD;GACY;GACF;GACC;GACQ;GACjB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC5C,GAAK,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;GAClD,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;GACpC,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAI;EACL,CAAA,GACA,CAAC,gBAAgB,YAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACb,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,wBAAAA,iBAAD;IACU;IACR,QAAQ,UAAU;IAClB,WAAW;IACX,GAAK,sBACD,EAAE,aAAa,oBAAoB,IACnC,CAAC;IACK;IACV,GAAK,gBAAgB,EAAE,cAAc,IAAI,CAAC;IAC1C,GAAK,YAAY,EAAE,UAAU,IAAI,CAAC;GACnC,CAAA;EACE,CAAA,CAEJ;;AAET"}
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
+ import { DropdownMenuItem } from '../overlay/DropdownMenu.js';
2
3
  import { Comment, CommentAnchor, CommentCallbacks, CommentConfig, CommentCreateAction } from './comment-types.js';
3
4
  export type CommentThreadProps = CommentCallbacks & {
4
5
  /** Comments for this thread (typically pre-filtered to one anchor). */
@@ -20,6 +21,8 @@ export type CommentThreadProps = CommentCallbacks & {
20
21
  renderRootDetails?: (comment: Comment) => ReactNode;
21
22
  renderBody?: (body: string) => ReactNode;
22
23
  threadToMarkdown?: (thread: readonly Comment[]) => string;
24
+ /** Caller-owned entries appended to each root's "Assign…" submenu. */
25
+ extraAssignItems?: (comment: Comment) => DropdownMenuItem[];
23
26
  };
24
27
  /**
25
28
  * Top-level controlled comment thread: a threaded list plus a mention-aware
@@ -27,5 +30,5 @@ export type CommentThreadProps = CommentCallbacks & {
27
30
  * the supplied callbacks, translating list-level events (checklist index, reply
28
31
  * target) into the callback contract.
29
32
  */
30
- export declare function CommentThread({ comments, config, anchor, compact, autoFocusComposer, defaultExpanded, composerPlaceholder, hideComposer, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, onCreate, onReply, onUpdateStatus, onClose, onDelete, onChecklistToggle, onMention, }: CommentThreadProps): import("react").JSX.Element;
33
+ export declare function CommentThread({ comments, config, anchor, compact, autoFocusComposer, defaultExpanded, composerPlaceholder, hideComposer, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, extraAssignItems, onCreate, onReply, onUpdateStatus, onClose, onAcknowledge, onAssign, onDelete, onChecklistToggle, onMention, }: CommentThreadProps): import("react").JSX.Element;
31
34
  //# sourceMappingURL=CommentThread.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThread.d.ts","sourceRoot":"","sources":["../../src/comments/CommentThread.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG;IAClD,uEAAuE;IACvE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kDAAkD;IAClD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACjD,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACpD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK,MAAM,CAAC;CAC3D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAe,EACf,iBAAyB,EACzB,eAAuB,EACvB,mBAAmB,EACnB,YAAoB,EACpB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,cAAc,EACd,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,SAAS,GACV,EAAE,kBAAkB,+BAwCpB"}
1
+ {"version":3,"file":"CommentThread.d.ts","sourceRoot":"","sources":["../../src/comments/CommentThread.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG;IAClD,uEAAuE;IACvE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kDAAkD;IAClD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACjD,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACpD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK,MAAM,CAAC;IAC1D,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,gBAAgB,EAAE,CAAC;CAC7D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAe,EACf,iBAAyB,EACzB,eAAuB,EACvB,mBAAmB,EACnB,YAAoB,EACpB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,cAAc,EACd,OAAO,EACP,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,SAAS,GACV,EAAE,kBAAkB,+BA2CpB"}
@@ -11,10 +11,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
11
11
  * the supplied callbacks, translating list-level events (checklist index, reply
12
12
  * target) into the callback contract.
13
13
  */
14
- function CommentThread({ comments, config, anchor, compact = false, autoFocusComposer = false, defaultExpanded = false, composerPlaceholder, hideComposer = false, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, onCreate, onReply, onUpdateStatus, onClose, onDelete, onChecklistToggle, onMention }) {
14
+ function CommentThread({ comments, config, anchor, compact = false, autoFocusComposer = false, defaultExpanded = false, composerPlaceholder, hideComposer = false, createActions, renderRootMeta, renderRootDetails, renderBody, threadToMarkdown, extraAssignItems, onCreate, onReply, onUpdateStatus, onClose, onAcknowledge, onAssign, onDelete, onChecklistToggle, onMention }) {
15
15
  const listHandlers = buildThreadListHandlers(comments, config, {
16
16
  ...onUpdateStatus ? { onUpdateStatus } : {},
17
17
  ...onClose ? { onClose } : {},
18
+ ...onAcknowledge ? { onAcknowledge } : {},
19
+ ...onAssign ? { onAssign } : {},
18
20
  ...onDelete ? { onDelete } : {},
19
21
  ...onChecklistToggle ? { onChecklistToggle } : {},
20
22
  ...onReply ? { onReply } : {},
@@ -31,6 +33,7 @@ function CommentThread({ comments, config, anchor, compact = false, autoFocusCom
31
33
  ...renderRootDetails ? { renderRootDetails } : {},
32
34
  ...renderBody ? { renderBody } : {},
33
35
  ...threadToMarkdown ? { threadToMarkdown } : {},
36
+ ...extraAssignItems ? { extraAssignItems } : {},
34
37
  ...listHandlers
35
38
  }), !hideComposer && onCreate && /* @__PURE__ */ jsx("div", {
36
39
  className: "pt-1",
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThread.js","names":[],"sources":["../../src/comments/CommentThread.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { CommentComposer } from \"./CommentComposer\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport { buildThreadListHandlers } from \"./comment-utils\";\nimport type {\n Comment,\n CommentAnchor,\n CommentCallbacks,\n CommentConfig,\n CommentCreateAction,\n} from \"./comment-types\";\n\nexport type CommentThreadProps = CommentCallbacks & {\n /** Comments for this thread (typically pre-filtered to one anchor). */\n comments: Comment[];\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n compact?: boolean;\n /** Auto-open and focus the composer on mount. */\n autoFocusComposer?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Label for creating a separate root comment. */\n composerPlaceholder?: string;\n /** Hide the composer (read-only thread). */\n hideComposer?: boolean;\n createActions?: readonly CommentCreateAction[];\n renderRootMeta?: (comment: Comment) => ReactNode;\n renderRootDetails?: (comment: Comment) => ReactNode;\n renderBody?: (body: string) => ReactNode;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n};\n\n/**\n * Top-level controlled comment thread: a threaded list plus a mention-aware\n * composer. Owns no data — it renders `comments` and forwards every mutation to\n * the supplied callbacks, translating list-level events (checklist index, reply\n * target) into the callback contract.\n */\nexport function CommentThread({\n comments,\n config,\n anchor,\n compact = false,\n autoFocusComposer = false,\n defaultExpanded = false,\n composerPlaceholder,\n hideComposer = false,\n createActions,\n renderRootMeta,\n renderRootDetails,\n renderBody,\n threadToMarkdown,\n onCreate,\n onReply,\n onUpdateStatus,\n onClose,\n onDelete,\n onChecklistToggle,\n onMention,\n}: CommentThreadProps) {\n const listHandlers = buildThreadListHandlers(comments, config, {\n ...(onUpdateStatus ? { onUpdateStatus } : {}),\n ...(onClose ? { onClose } : {}),\n ...(onDelete ? { onDelete } : {}),\n ...(onChecklistToggle ? { onChecklistToggle } : {}),\n ...(onReply ? { onReply } : {}),\n ...(onMention ? { onMention } : {}),\n });\n\n return (\n <div className={cn(compact && \"p-2\")}>\n <CommentThreadList\n comments={comments}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n {...(renderRootMeta ? { renderRootMeta } : {})}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(renderBody ? { renderBody } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n {...listHandlers}\n />\n {!hideComposer && onCreate && (\n <div className=\"pt-1\">\n <CommentComposer\n config={config}\n anchor={anchor ?? null}\n autoFocus={autoFocusComposer}\n {...(composerPlaceholder\n ? { placeholder: composerPlaceholder }\n : {})}\n onCreate={onCreate}\n {...(createActions ? { createActions } : {})}\n {...(onMention ? { onMention } : {})}\n />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAyCA,SAAgB,cAAc,EAC5B,UACA,QACA,QACA,UAAU,OACV,oBAAoB,OACpB,kBAAkB,OAClB,qBACA,eAAe,OACf,eACA,gBACA,mBACA,YACA,kBACA,UACA,SACA,gBACA,SACA,UACA,mBACA,aACqB;CACrB,MAAM,eAAe,wBAAwB,UAAU,QAAQ;EAC7D,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC3C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;EACjD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;CACnC,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,KAAK;EAAnC,UAAA,CACE,oBAAC,mBAAD;GACY;GACF;GACC;GACQ;GACjB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC5C,GAAK,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;GAClD,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;GACpC,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAI;EACL,CAAA,GACA,CAAC,gBAAgB,YAChB,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,iBAAD;IACU;IACR,QAAQ,UAAU;IAClB,WAAW;IACX,GAAK,sBACD,EAAE,aAAa,oBAAoB,IACnC,CAAC;IACK;IACV,GAAK,gBAAgB,EAAE,cAAc,IAAI,CAAC;IAC1C,GAAK,YAAY,EAAE,UAAU,IAAI,CAAC;GACnC,CAAA;EACE,CAAA,CAEJ;;AAET"}
1
+ {"version":3,"file":"CommentThread.js","names":[],"sources":["../../src/comments/CommentThread.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport type { DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport { CommentComposer } from \"./CommentComposer\";\nimport { CommentThreadList } from \"./CommentThreadList\";\nimport { buildThreadListHandlers } from \"./comment-utils\";\nimport type {\n Comment,\n CommentAnchor,\n CommentCallbacks,\n CommentConfig,\n CommentCreateAction,\n} from \"./comment-types\";\n\nexport type CommentThreadProps = CommentCallbacks & {\n /** Comments for this thread (typically pre-filtered to one anchor). */\n comments: Comment[];\n config: CommentConfig;\n /** Anchor stamped onto created comments. */\n anchor?: CommentAnchor | null;\n compact?: boolean;\n /** Auto-open and focus the composer on mount. */\n autoFocusComposer?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Label for creating a separate root comment. */\n composerPlaceholder?: string;\n /** Hide the composer (read-only thread). */\n hideComposer?: boolean;\n createActions?: readonly CommentCreateAction[];\n renderRootMeta?: (comment: Comment) => ReactNode;\n renderRootDetails?: (comment: Comment) => ReactNode;\n renderBody?: (body: string) => ReactNode;\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n /** Caller-owned entries appended to each root's \"Assign…\" submenu. */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n};\n\n/**\n * Top-level controlled comment thread: a threaded list plus a mention-aware\n * composer. Owns no data — it renders `comments` and forwards every mutation to\n * the supplied callbacks, translating list-level events (checklist index, reply\n * target) into the callback contract.\n */\nexport function CommentThread({\n comments,\n config,\n anchor,\n compact = false,\n autoFocusComposer = false,\n defaultExpanded = false,\n composerPlaceholder,\n hideComposer = false,\n createActions,\n renderRootMeta,\n renderRootDetails,\n renderBody,\n threadToMarkdown,\n extraAssignItems,\n onCreate,\n onReply,\n onUpdateStatus,\n onClose,\n onAcknowledge,\n onAssign,\n onDelete,\n onChecklistToggle,\n onMention,\n}: CommentThreadProps) {\n const listHandlers = buildThreadListHandlers(comments, config, {\n ...(onUpdateStatus ? { onUpdateStatus } : {}),\n ...(onClose ? { onClose } : {}),\n ...(onAcknowledge ? { onAcknowledge } : {}),\n ...(onAssign ? { onAssign } : {}),\n ...(onDelete ? { onDelete } : {}),\n ...(onChecklistToggle ? { onChecklistToggle } : {}),\n ...(onReply ? { onReply } : {}),\n ...(onMention ? { onMention } : {}),\n });\n\n return (\n <div className={cn(compact && \"p-2\")}>\n <CommentThreadList\n comments={comments}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n {...(renderRootMeta ? { renderRootMeta } : {})}\n {...(renderRootDetails ? { renderRootDetails } : {})}\n {...(renderBody ? { renderBody } : {})}\n {...(threadToMarkdown ? { threadToMarkdown } : {})}\n {...(extraAssignItems ? { extraAssignItems } : {})}\n {...listHandlers}\n />\n {!hideComposer && onCreate && (\n <div className=\"pt-1\">\n <CommentComposer\n config={config}\n anchor={anchor ?? null}\n autoFocus={autoFocusComposer}\n {...(composerPlaceholder\n ? { placeholder: composerPlaceholder }\n : {})}\n onCreate={onCreate}\n {...(createActions ? { createActions } : {})}\n {...(onMention ? { onMention } : {})}\n />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA4CA,SAAgB,cAAc,EAC5B,UACA,QACA,QACA,UAAU,OACV,oBAAoB,OACpB,kBAAkB,OAClB,qBACA,eAAe,OACf,eACA,gBACA,mBACA,YACA,kBACA,kBACA,UACA,SACA,gBACA,SACA,eACA,UACA,UACA,mBACA,aACqB;CACrB,MAAM,eAAe,wBAAwB,UAAU,QAAQ;EAC7D,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC3C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;EACzC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;EACjD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;CACnC,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,KAAK;EAAnC,UAAA,CACE,oBAAC,mBAAD;GACY;GACF;GACC;GACQ;GACjB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC5C,GAAK,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;GAClD,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;GACpC,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;GAChD,GAAI;EACL,CAAA,GACA,CAAC,gBAAgB,YAChB,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,iBAAD;IACU;IACR,QAAQ,UAAU;IAClB,WAAW;IACX,GAAK,sBACD,EAAE,aAAa,oBAAoB,IACnC,CAAC;IACK;IACV,GAAK,gBAAgB,EAAE,cAAc,IAAI,CAAC;IAC1C,GAAK,YAAY,EAAE,UAAU,IAAI,CAAC;GACnC,CAAA;EACE,CAAA,CAEJ;;AAET"}
@@ -42,10 +42,10 @@ function ReplyInput({ onSubmit, onCancel }) {
42
42
  },
43
43
  placeholder: "Write a reply…",
44
44
  "data-testid": "comment-reply-input",
45
- className: "h-7 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40"
45
+ className: "h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:text-base"
46
46
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_button.Button, {
47
47
  size: "sm",
48
- className: "h-7 text-xs",
48
+ className: "h-7 text-xs [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:px-4 [@media(pointer:coarse)]:text-sm",
49
49
  disabled: submitting || !body.trim(),
50
50
  onClick: () => void send(),
51
51
  children: "Send"
@@ -57,7 +57,7 @@ function ReplyInput({ onSubmit, onCancel }) {
57
57
  * optional inline reply box. Fully controlled — mutations route through the
58
58
  * id-keyed callbacks.
59
59
  */
60
- function CommentThreadList({ comments, config, compact = false, defaultExpanded = false, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onChecklistToggle, onDelete, onReply }) {
60
+ function CommentThreadList({ comments, config, compact = false, defaultExpanded = false, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onAcknowledge, onAssign, extraAssignItems, onChecklistToggle, onDelete, onReply }) {
61
61
  const [replyingTo, setReplyingTo] = (0, react.useState)(null);
62
62
  const [maximizedRootId, setMaximizedRootId] = (0, react.useState)(null);
63
63
  const [maximizedTab, setMaximizedTab] = (0, react.useState)("thread");
@@ -76,6 +76,9 @@ function CommentThreadList({ comments, config, compact = false, defaultExpanded
76
76
  return {
77
77
  ...onUpdateStatus ? { onUpdateStatus: (status) => onUpdateStatus(id, status) } : {},
78
78
  ...onClose ? { onClose: () => onClose(id) } : {},
79
+ ...onAcknowledge ? { onAcknowledge: () => onAcknowledge(id) } : {},
80
+ ...onAssign ? { onAssign: (assignee) => onAssign(id, assignee) } : {},
81
+ ...extraAssignItems ? { extraAssignItems } : {},
79
82
  ...onChecklistToggle ? { onChecklistToggle: (index) => onChecklistToggle(id, index) } : {},
80
83
  ...onDelete ? { onDelete: () => onDelete(id) } : {}
81
84
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThreadList.cjs","names":["useState","useRef","Button","getRoots","buildReplyMap","sortReplies","_Fragment","cn","CommentCard","copyText","Modal","Tabs","Markdown"],"sources":["../../src/comments/CommentThreadList.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\nimport { copyText } from \"../components/clipboard\";\nimport { Markdown } from \"../data/Markdown\";\nimport { Tabs } from \"../layout/Tabs\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommentCard } from \"./CommentCard\";\nimport { buildReplyMap, getRoots, sortReplies } from \"./comment-utils\";\nimport type { Comment, CommentConfig } from \"./comment-types\";\n\nexport type CommentThreadListProps = {\n comments: Comment[];\n config: CommentConfig;\n compact?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Extra content rendered above each root card (e.g. an anchor label). */\n renderRootMeta?: (comment: Comment) => ReactNode;\n /** Extra content rendered with each root thread, including its maximized view. */\n renderRootDetails?: (comment: Comment) => ReactNode;\n /** Props merged onto each thread wrapper (e.g. for scroll anchoring). */\n getThreadProps?: (comment: Comment) => HTMLAttributes<HTMLDivElement>;\n /** Custom body renderer forwarded to each card. */\n renderBody?: (body: string) => ReactNode;\n /** Serialize a root and its replies for Copy and the Markdown preview. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n onUpdateStatus?: (id: string, status: string) => void | Promise<void>;\n onClose?: (id: string) => void | Promise<void>;\n onChecklistToggle?: (id: string, index: number) => void;\n onDelete?: (id: string) => void;\n /** Submit a reply to `parent`. Presence enables the inline reply affordance. */\n onReply?: (parent: Comment, body: string) => void | Promise<void>;\n};\n\nfunction ReplyInput({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: string) => void | Promise<void>;\n onCancel: () => void;\n}) {\n const [body, setBody] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n async function send() {\n if (!body.trim() || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n try {\n await onSubmit(body.trim());\n setBody(\"\");\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n return (\n <div className=\"ml-6 flex gap-1.5 py-1\" aria-busy={submitting}>\n <input\n autoFocus\n value={body}\n disabled={submitting}\n onChange={(e) => setBody(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void send();\n }\n if (e.key === \"Escape\") onCancel();\n }}\n placeholder=\"Write a reply…\"\n data-testid=\"comment-reply-input\"\n className=\"h-7 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40\"\n />\n <Button\n size=\"sm\"\n className=\"h-7 text-xs\"\n disabled={submitting || !body.trim()}\n onClick={() => void send()}\n >\n Send\n </Button>\n </div>\n );\n}\n\n/**\n * Renders a list of threaded comments: each root with its sorted replies and an\n * optional inline reply box. Fully controlled — mutations route through the\n * id-keyed callbacks.\n */\nexport function CommentThreadList({\n comments,\n config,\n compact = false,\n defaultExpanded = false,\n renderRootMeta,\n renderRootDetails,\n getThreadProps,\n renderBody,\n threadToMarkdown,\n onUpdateStatus,\n onClose,\n onChecklistToggle,\n onDelete,\n onReply,\n}: CommentThreadListProps) {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n // Maximizing is owned here, not by the card: a thread is the unit a reader\n // wants enlarged, and only this list knows a root's replies.\n const [maximizedRootId, setMaximizedRootId] = useState<string | null>(null);\n const [maximizedTab, setMaximizedTab] = useState<\"thread\" | \"markdown\">(\n \"thread\",\n );\n // Which message in the maximized thread has its reply composer open.\n const [modalReplyTo, setModalReplyTo] = useState<string | null>(null);\n const roots = getRoots(comments);\n const replyMap = buildReplyMap(comments);\n\n if (roots.length === 0) return null;\n\n const maximizedRoot = roots.find((root) => root.id === maximizedRootId);\n const maximizedThread = maximizedRoot\n ? [maximizedRoot, ...sortReplies(replyMap.get(maximizedRoot.id) ?? [])]\n : [];\n\n function closeMaximized() {\n setMaximizedRootId(null);\n setModalReplyTo(null);\n setMaximizedTab(\"thread\");\n }\n\n function cardHandlers(id: string) {\n return {\n ...(onUpdateStatus\n ? { onUpdateStatus: (status: string) => onUpdateStatus(id, status) }\n : {}),\n ...(onClose ? { onClose: () => onClose(id) } : {}),\n ...(onChecklistToggle\n ? { onChecklistToggle: (index: number) => onChecklistToggle(id, index) }\n : {}),\n ...(onDelete ? { onDelete: () => onDelete(id) } : {}),\n };\n }\n\n return (\n <>\n <div className=\"space-y-2\">\n {roots.map((root) => {\n const replies = sortReplies(replyMap.get(root.id) ?? []);\n const thread = [root, ...replies];\n const threadProps = getThreadProps?.(root) ?? {};\n return (\n <div\n key={root.id}\n data-testid=\"comment-thread-block\"\n data-comment-id={root.id}\n {...threadProps}\n className={cn(\"space-y-1.5 p-1\", threadProps.className)}\n >\n {renderRootMeta ? (\n <div className=\"px-1\">{renderRootMeta(root)}</div>\n ) : null}\n <CommentCard\n comment={root}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(root.id)}\n {...(onReply ? { onReply: () => setReplyingTo(root.id) } : {})}\n />\n {renderRootDetails?.(root)}\n {replies.length > 0 && (\n <div className=\"space-y-1.5\">\n {replies.map((reply) => (\n <CommentCard\n key={reply.id}\n comment={reply}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(reply.id)}\n />\n ))}\n </div>\n )}\n {onReply && replyingTo === root.id && (\n <ReplyInput\n onCancel={() => setReplyingTo(null)}\n onSubmit={async (body) => {\n await onReply(root, body);\n setReplyingTo(null);\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n {maximizedRoot && (\n <Modal open onClose={closeMaximized} title=\"Comment thread\" size=\"lg\">\n <div className=\"space-y-3\" data-testid=\"comment-thread-modal\">\n {threadToMarkdown && (\n <Tabs\n tabs={[\n { id: \"thread\", label: \"Thread\" },\n { id: \"markdown\", label: \"Markdown\" },\n ]}\n value={maximizedTab}\n onChange={(tab) =>\n setMaximizedTab(tab === \"markdown\" ? \"markdown\" : \"thread\")\n }\n />\n )}\n {maximizedTab === \"markdown\" && threadToMarkdown ? (\n <Markdown text={threadToMarkdown(maximizedThread)} />\n ) : (\n <div className=\"space-y-2\">\n {/* No onMaximize inside: the thread is already maximized. */}\n {maximizedThread.map((message) => (\n <div key={message.id} className=\"space-y-1.5\">\n <CommentCard\n comment={message}\n config={config}\n defaultExpanded\n {...(threadToMarkdown\n ? {\n onCopy: () =>\n copyText(threadToMarkdown(maximizedThread)),\n }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(message.id)}\n {...(onReply\n ? { onReply: () => setModalReplyTo(message.id) }\n : {})}\n />\n {message.id === maximizedRoot.id &&\n renderRootDetails?.(maximizedRoot)}\n {onReply && modalReplyTo === message.id && (\n <ReplyInput\n onCancel={() => setModalReplyTo(null)}\n onSubmit={async (body) => {\n await onReply(maximizedRoot, body);\n setModalReplyTo(null);\n }}\n />\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentThreadList.cjs","names":["useState","useRef","Button","getRoots","buildReplyMap","sortReplies","_Fragment","cn","CommentCard","copyText","Modal","Tabs","Markdown"],"sources":["../../src/comments/CommentThreadList.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\nimport { copyText } from \"../components/clipboard\";\nimport { Markdown } from \"../data/Markdown\";\nimport { Tabs } from \"../layout/Tabs\";\nimport type { DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommentCard } from \"./CommentCard\";\nimport { buildReplyMap, getRoots, sortReplies } from \"./comment-utils\";\nimport type { Comment, CommentAuthor, CommentConfig } from \"./comment-types\";\n\nexport type CommentThreadListProps = {\n comments: Comment[];\n config: CommentConfig;\n compact?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Extra content rendered above each root card (e.g. an anchor label). */\n renderRootMeta?: (comment: Comment) => ReactNode;\n /** Extra content rendered with each root thread, including its maximized view. */\n renderRootDetails?: (comment: Comment) => ReactNode;\n /** Props merged onto each thread wrapper (e.g. for scroll anchoring). */\n getThreadProps?: (comment: Comment) => HTMLAttributes<HTMLDivElement>;\n /** Custom body renderer forwarded to each card. */\n renderBody?: (body: string) => ReactNode;\n /** Serialize a root and its replies for Copy and the Markdown preview. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n onUpdateStatus?: (id: string, status: string) => void | Promise<void>;\n onClose?: (id: string) => void | Promise<void>;\n onAcknowledge?: (id: string) => void | Promise<void>;\n onAssign?: (\n id: string,\n assignee: CommentAuthor | null,\n ) => void | Promise<void>;\n /** Caller-owned entries appended to each root's \"Assign…\" submenu. */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n onChecklistToggle?: (id: string, index: number) => void;\n onDelete?: (id: string) => void;\n /** Submit a reply to `parent`. Presence enables the inline reply affordance. */\n onReply?: (parent: Comment, body: string) => void | Promise<void>;\n};\n\nfunction ReplyInput({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: string) => void | Promise<void>;\n onCancel: () => void;\n}) {\n const [body, setBody] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n async function send() {\n if (!body.trim() || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n try {\n await onSubmit(body.trim());\n setBody(\"\");\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n return (\n <div className=\"ml-6 flex gap-1.5 py-1\" aria-busy={submitting}>\n <input\n autoFocus\n value={body}\n disabled={submitting}\n onChange={(e) => setBody(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void send();\n }\n if (e.key === \"Escape\") onCancel();\n }}\n placeholder=\"Write a reply…\"\n data-testid=\"comment-reply-input\"\n className=\"h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:text-base\"\n />\n <Button\n size=\"sm\"\n className=\"h-7 text-xs [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:px-4 [@media(pointer:coarse)]:text-sm\"\n disabled={submitting || !body.trim()}\n onClick={() => void send()}\n >\n Send\n </Button>\n </div>\n );\n}\n\n/**\n * Renders a list of threaded comments: each root with its sorted replies and an\n * optional inline reply box. Fully controlled — mutations route through the\n * id-keyed callbacks.\n */\nexport function CommentThreadList({\n comments,\n config,\n compact = false,\n defaultExpanded = false,\n renderRootMeta,\n renderRootDetails,\n getThreadProps,\n renderBody,\n threadToMarkdown,\n onUpdateStatus,\n onClose,\n onAcknowledge,\n onAssign,\n extraAssignItems,\n onChecklistToggle,\n onDelete,\n onReply,\n}: CommentThreadListProps) {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n // Maximizing is owned here, not by the card: a thread is the unit a reader\n // wants enlarged, and only this list knows a root's replies.\n const [maximizedRootId, setMaximizedRootId] = useState<string | null>(null);\n const [maximizedTab, setMaximizedTab] = useState<\"thread\" | \"markdown\">(\n \"thread\",\n );\n // Which message in the maximized thread has its reply composer open.\n const [modalReplyTo, setModalReplyTo] = useState<string | null>(null);\n const roots = getRoots(comments);\n const replyMap = buildReplyMap(comments);\n\n if (roots.length === 0) return null;\n\n const maximizedRoot = roots.find((root) => root.id === maximizedRootId);\n const maximizedThread = maximizedRoot\n ? [maximizedRoot, ...sortReplies(replyMap.get(maximizedRoot.id) ?? [])]\n : [];\n\n function closeMaximized() {\n setMaximizedRootId(null);\n setModalReplyTo(null);\n setMaximizedTab(\"thread\");\n }\n\n function cardHandlers(id: string) {\n return {\n ...(onUpdateStatus\n ? { onUpdateStatus: (status: string) => onUpdateStatus(id, status) }\n : {}),\n ...(onClose ? { onClose: () => onClose(id) } : {}),\n ...(onAcknowledge ? { onAcknowledge: () => onAcknowledge(id) } : {}),\n ...(onAssign\n ? {\n onAssign: (assignee: CommentAuthor | null) =>\n onAssign(id, assignee),\n }\n : {}),\n ...(extraAssignItems ? { extraAssignItems } : {}),\n ...(onChecklistToggle\n ? { onChecklistToggle: (index: number) => onChecklistToggle(id, index) }\n : {}),\n ...(onDelete ? { onDelete: () => onDelete(id) } : {}),\n };\n }\n\n return (\n <>\n <div className=\"space-y-2\">\n {roots.map((root) => {\n const replies = sortReplies(replyMap.get(root.id) ?? []);\n const thread = [root, ...replies];\n const threadProps = getThreadProps?.(root) ?? {};\n return (\n <div\n key={root.id}\n data-testid=\"comment-thread-block\"\n data-comment-id={root.id}\n {...threadProps}\n className={cn(\"space-y-1.5 p-1\", threadProps.className)}\n >\n {renderRootMeta ? (\n <div className=\"px-1\">{renderRootMeta(root)}</div>\n ) : null}\n <CommentCard\n comment={root}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(root.id)}\n {...(onReply ? { onReply: () => setReplyingTo(root.id) } : {})}\n />\n {renderRootDetails?.(root)}\n {replies.length > 0 && (\n <div className=\"space-y-1.5\">\n {replies.map((reply) => (\n <CommentCard\n key={reply.id}\n comment={reply}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(reply.id)}\n />\n ))}\n </div>\n )}\n {onReply && replyingTo === root.id && (\n <ReplyInput\n onCancel={() => setReplyingTo(null)}\n onSubmit={async (body) => {\n await onReply(root, body);\n setReplyingTo(null);\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n {maximizedRoot && (\n <Modal open onClose={closeMaximized} title=\"Comment thread\" size=\"lg\">\n <div className=\"space-y-3\" data-testid=\"comment-thread-modal\">\n {threadToMarkdown && (\n <Tabs\n tabs={[\n { id: \"thread\", label: \"Thread\" },\n { id: \"markdown\", label: \"Markdown\" },\n ]}\n value={maximizedTab}\n onChange={(tab) =>\n setMaximizedTab(tab === \"markdown\" ? \"markdown\" : \"thread\")\n }\n />\n )}\n {maximizedTab === \"markdown\" && threadToMarkdown ? (\n <Markdown text={threadToMarkdown(maximizedThread)} />\n ) : (\n <div className=\"space-y-2\">\n {/* No onMaximize inside: the thread is already maximized. */}\n {maximizedThread.map((message) => (\n <div key={message.id} className=\"space-y-1.5\">\n <CommentCard\n comment={message}\n config={config}\n defaultExpanded\n {...(threadToMarkdown\n ? {\n onCopy: () =>\n copyText(threadToMarkdown(maximizedThread)),\n }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(message.id)}\n {...(onReply\n ? { onReply: () => setModalReplyTo(message.id) }\n : {})}\n />\n {message.id === maximizedRoot.id &&\n renderRootDetails?.(maximizedRoot)}\n {onReply && modalReplyTo === message.id && (\n <ReplyInput\n onCancel={() => setModalReplyTo(null)}\n onSubmit={async (body) => {\n await onReply(maximizedRoot, body);\n setModalReplyTo(null);\n }}\n />\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { HTMLAttributes, ReactNode } from 'react';
2
- import { Comment, CommentConfig } from './comment-types.js';
2
+ import { DropdownMenuItem } from '../overlay/DropdownMenu.js';
3
+ import { Comment, CommentAuthor, CommentConfig } from './comment-types.js';
3
4
  export type CommentThreadListProps = {
4
5
  comments: Comment[];
5
6
  config: CommentConfig;
@@ -18,6 +19,10 @@ export type CommentThreadListProps = {
18
19
  threadToMarkdown?: (thread: readonly Comment[]) => string;
19
20
  onUpdateStatus?: (id: string, status: string) => void | Promise<void>;
20
21
  onClose?: (id: string) => void | Promise<void>;
22
+ onAcknowledge?: (id: string) => void | Promise<void>;
23
+ onAssign?: (id: string, assignee: CommentAuthor | null) => void | Promise<void>;
24
+ /** Caller-owned entries appended to each root's "Assign…" submenu. */
25
+ extraAssignItems?: (comment: Comment) => DropdownMenuItem[];
21
26
  onChecklistToggle?: (id: string, index: number) => void;
22
27
  onDelete?: (id: string) => void;
23
28
  /** Submit a reply to `parent`. Presence enables the inline reply affordance. */
@@ -28,5 +33,5 @@ export type CommentThreadListProps = {
28
33
  * optional inline reply box. Fully controlled — mutations route through the
29
34
  * id-keyed callbacks.
30
35
  */
31
- export declare function CommentThreadList({ comments, config, compact, defaultExpanded, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onChecklistToggle, onDelete, onReply, }: CommentThreadListProps): import("react").JSX.Element | null;
36
+ export declare function CommentThreadList({ comments, config, compact, defaultExpanded, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onAcknowledge, onAssign, extraAssignItems, onChecklistToggle, onDelete, onReply, }: CommentThreadListProps): import("react").JSX.Element | null;
32
37
  //# sourceMappingURL=CommentThreadList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThreadList.d.ts","sourceRoot":"","sources":["../../src/comments/CommentThreadList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAS9E,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACjD,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACpD,yEAAyE;IACzE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,cAAc,CAAC,cAAc,CAAC,CAAC;IACtE,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACzC,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK,MAAM,CAAC;IAC1D,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,gFAAgF;IAChF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC;AAsDF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,MAAM,EACN,OAAe,EACf,eAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,OAAO,GACR,EAAE,sBAAsB,sCAiKxB"}
1
+ {"version":3,"file":"CommentThreadList.d.ts","sourceRoot":"","sources":["../../src/comments/CommentThreadList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7E,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gGAAgG;IAChG,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACjD,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACpD,yEAAyE;IACzE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,cAAc,CAAC,cAAc,CAAC,CAAC;IACtE,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACzC,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK,MAAM,CAAC;IAC1D,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,CACT,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,aAAa,GAAG,IAAI,KAC3B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,gBAAgB,EAAE,CAAC;IAC5D,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,gFAAgF;IAChF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC;AAsDF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,MAAM,EACN,OAAe,EACf,eAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,aAAa,EACb,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,OAAO,GACR,EAAE,sBAAsB,sCAyKxB"}
@@ -42,10 +42,10 @@ function ReplyInput({ onSubmit, onCancel }) {
42
42
  },
43
43
  placeholder: "Write a reply…",
44
44
  "data-testid": "comment-reply-input",
45
- className: "h-7 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40"
45
+ className: "h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:text-base"
46
46
  }), /* @__PURE__ */ jsx(Button, {
47
47
  size: "sm",
48
- className: "h-7 text-xs",
48
+ className: "h-7 text-xs [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:px-4 [@media(pointer:coarse)]:text-sm",
49
49
  disabled: submitting || !body.trim(),
50
50
  onClick: () => void send(),
51
51
  children: "Send"
@@ -57,7 +57,7 @@ function ReplyInput({ onSubmit, onCancel }) {
57
57
  * optional inline reply box. Fully controlled — mutations route through the
58
58
  * id-keyed callbacks.
59
59
  */
60
- function CommentThreadList({ comments, config, compact = false, defaultExpanded = false, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onChecklistToggle, onDelete, onReply }) {
60
+ function CommentThreadList({ comments, config, compact = false, defaultExpanded = false, renderRootMeta, renderRootDetails, getThreadProps, renderBody, threadToMarkdown, onUpdateStatus, onClose, onAcknowledge, onAssign, extraAssignItems, onChecklistToggle, onDelete, onReply }) {
61
61
  const [replyingTo, setReplyingTo] = useState(null);
62
62
  const [maximizedRootId, setMaximizedRootId] = useState(null);
63
63
  const [maximizedTab, setMaximizedTab] = useState("thread");
@@ -76,6 +76,9 @@ function CommentThreadList({ comments, config, compact = false, defaultExpanded
76
76
  return {
77
77
  ...onUpdateStatus ? { onUpdateStatus: (status) => onUpdateStatus(id, status) } : {},
78
78
  ...onClose ? { onClose: () => onClose(id) } : {},
79
+ ...onAcknowledge ? { onAcknowledge: () => onAcknowledge(id) } : {},
80
+ ...onAssign ? { onAssign: (assignee) => onAssign(id, assignee) } : {},
81
+ ...extraAssignItems ? { extraAssignItems } : {},
79
82
  ...onChecklistToggle ? { onChecklistToggle: (index) => onChecklistToggle(id, index) } : {},
80
83
  ...onDelete ? { onDelete: () => onDelete(id) } : {}
81
84
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CommentThreadList.js","names":["_Fragment"],"sources":["../../src/comments/CommentThreadList.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\nimport { copyText } from \"../components/clipboard\";\nimport { Markdown } from \"../data/Markdown\";\nimport { Tabs } from \"../layout/Tabs\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommentCard } from \"./CommentCard\";\nimport { buildReplyMap, getRoots, sortReplies } from \"./comment-utils\";\nimport type { Comment, CommentConfig } from \"./comment-types\";\n\nexport type CommentThreadListProps = {\n comments: Comment[];\n config: CommentConfig;\n compact?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Extra content rendered above each root card (e.g. an anchor label). */\n renderRootMeta?: (comment: Comment) => ReactNode;\n /** Extra content rendered with each root thread, including its maximized view. */\n renderRootDetails?: (comment: Comment) => ReactNode;\n /** Props merged onto each thread wrapper (e.g. for scroll anchoring). */\n getThreadProps?: (comment: Comment) => HTMLAttributes<HTMLDivElement>;\n /** Custom body renderer forwarded to each card. */\n renderBody?: (body: string) => ReactNode;\n /** Serialize a root and its replies for Copy and the Markdown preview. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n onUpdateStatus?: (id: string, status: string) => void | Promise<void>;\n onClose?: (id: string) => void | Promise<void>;\n onChecklistToggle?: (id: string, index: number) => void;\n onDelete?: (id: string) => void;\n /** Submit a reply to `parent`. Presence enables the inline reply affordance. */\n onReply?: (parent: Comment, body: string) => void | Promise<void>;\n};\n\nfunction ReplyInput({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: string) => void | Promise<void>;\n onCancel: () => void;\n}) {\n const [body, setBody] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n async function send() {\n if (!body.trim() || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n try {\n await onSubmit(body.trim());\n setBody(\"\");\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n return (\n <div className=\"ml-6 flex gap-1.5 py-1\" aria-busy={submitting}>\n <input\n autoFocus\n value={body}\n disabled={submitting}\n onChange={(e) => setBody(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void send();\n }\n if (e.key === \"Escape\") onCancel();\n }}\n placeholder=\"Write a reply…\"\n data-testid=\"comment-reply-input\"\n className=\"h-7 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40\"\n />\n <Button\n size=\"sm\"\n className=\"h-7 text-xs\"\n disabled={submitting || !body.trim()}\n onClick={() => void send()}\n >\n Send\n </Button>\n </div>\n );\n}\n\n/**\n * Renders a list of threaded comments: each root with its sorted replies and an\n * optional inline reply box. Fully controlled — mutations route through the\n * id-keyed callbacks.\n */\nexport function CommentThreadList({\n comments,\n config,\n compact = false,\n defaultExpanded = false,\n renderRootMeta,\n renderRootDetails,\n getThreadProps,\n renderBody,\n threadToMarkdown,\n onUpdateStatus,\n onClose,\n onChecklistToggle,\n onDelete,\n onReply,\n}: CommentThreadListProps) {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n // Maximizing is owned here, not by the card: a thread is the unit a reader\n // wants enlarged, and only this list knows a root's replies.\n const [maximizedRootId, setMaximizedRootId] = useState<string | null>(null);\n const [maximizedTab, setMaximizedTab] = useState<\"thread\" | \"markdown\">(\n \"thread\",\n );\n // Which message in the maximized thread has its reply composer open.\n const [modalReplyTo, setModalReplyTo] = useState<string | null>(null);\n const roots = getRoots(comments);\n const replyMap = buildReplyMap(comments);\n\n if (roots.length === 0) return null;\n\n const maximizedRoot = roots.find((root) => root.id === maximizedRootId);\n const maximizedThread = maximizedRoot\n ? [maximizedRoot, ...sortReplies(replyMap.get(maximizedRoot.id) ?? [])]\n : [];\n\n function closeMaximized() {\n setMaximizedRootId(null);\n setModalReplyTo(null);\n setMaximizedTab(\"thread\");\n }\n\n function cardHandlers(id: string) {\n return {\n ...(onUpdateStatus\n ? { onUpdateStatus: (status: string) => onUpdateStatus(id, status) }\n : {}),\n ...(onClose ? { onClose: () => onClose(id) } : {}),\n ...(onChecklistToggle\n ? { onChecklistToggle: (index: number) => onChecklistToggle(id, index) }\n : {}),\n ...(onDelete ? { onDelete: () => onDelete(id) } : {}),\n };\n }\n\n return (\n <>\n <div className=\"space-y-2\">\n {roots.map((root) => {\n const replies = sortReplies(replyMap.get(root.id) ?? []);\n const thread = [root, ...replies];\n const threadProps = getThreadProps?.(root) ?? {};\n return (\n <div\n key={root.id}\n data-testid=\"comment-thread-block\"\n data-comment-id={root.id}\n {...threadProps}\n className={cn(\"space-y-1.5 p-1\", threadProps.className)}\n >\n {renderRootMeta ? (\n <div className=\"px-1\">{renderRootMeta(root)}</div>\n ) : null}\n <CommentCard\n comment={root}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(root.id)}\n {...(onReply ? { onReply: () => setReplyingTo(root.id) } : {})}\n />\n {renderRootDetails?.(root)}\n {replies.length > 0 && (\n <div className=\"space-y-1.5\">\n {replies.map((reply) => (\n <CommentCard\n key={reply.id}\n comment={reply}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(reply.id)}\n />\n ))}\n </div>\n )}\n {onReply && replyingTo === root.id && (\n <ReplyInput\n onCancel={() => setReplyingTo(null)}\n onSubmit={async (body) => {\n await onReply(root, body);\n setReplyingTo(null);\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n {maximizedRoot && (\n <Modal open onClose={closeMaximized} title=\"Comment thread\" size=\"lg\">\n <div className=\"space-y-3\" data-testid=\"comment-thread-modal\">\n {threadToMarkdown && (\n <Tabs\n tabs={[\n { id: \"thread\", label: \"Thread\" },\n { id: \"markdown\", label: \"Markdown\" },\n ]}\n value={maximizedTab}\n onChange={(tab) =>\n setMaximizedTab(tab === \"markdown\" ? \"markdown\" : \"thread\")\n }\n />\n )}\n {maximizedTab === \"markdown\" && threadToMarkdown ? (\n <Markdown text={threadToMarkdown(maximizedThread)} />\n ) : (\n <div className=\"space-y-2\">\n {/* No onMaximize inside: the thread is already maximized. */}\n {maximizedThread.map((message) => (\n <div key={message.id} className=\"space-y-1.5\">\n <CommentCard\n comment={message}\n config={config}\n defaultExpanded\n {...(threadToMarkdown\n ? {\n onCopy: () =>\n copyText(threadToMarkdown(maximizedThread)),\n }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(message.id)}\n {...(onReply\n ? { onReply: () => setModalReplyTo(message.id) }\n : {})}\n />\n {message.id === maximizedRoot.id &&\n renderRootDetails?.(maximizedRoot)}\n {onReply && modalReplyTo === message.id && (\n <ReplyInput\n onCancel={() => setModalReplyTo(null)}\n onSubmit={async (body) => {\n await onReply(maximizedRoot, body);\n setModalReplyTo(null);\n }}\n />\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;AAmCA,SAAS,WAAW,EAClB,UACA,YAIC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CACnC,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,gBAAgB,OAAO,KAAK;CAClC,eAAe,OAAO;EACpB,IAAI,CAAC,KAAK,KAAK,KAAK,cAAc,SAAS;EAC3C,cAAc,UAAU;EACxB,cAAc,IAAI;EAClB,IAAI;GACF,MAAM,SAAS,KAAK,KAAK,CAAC;GAC1B,QAAQ,EAAE;EACZ,UAAU;GACR,cAAc,UAAU;GACxB,cAAc,KAAK;EACrB;CACF;CACA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAyB,aAAW;EAAnD,UAAA,CACE,oBAAC,SAAD;GACE,WAAA;GACA,OAAO;GACP,UAAU;GACV,WAAW,MAAM,QAAQ,EAAE,OAAO,KAAK;GACvC,YAAY,MAAM;IAChB,IAAI,EAAE,QAAQ,SAAS;KACrB,EAAE,eAAe;KACjB,KAAU;IACZ;IACA,IAAI,EAAE,QAAQ,UAAU,SAAS;GACnC;GACA,aAAY;GACZ,eAAY;GACZ,WAAU;EACX,CAAA,GACD,oBAAC,QAAD;GACE,MAAK;GACL,WAAU;GACV,UAAU,cAAc,CAAC,KAAK,KAAK;GACnC,eAAe,KAAK,KAAK;GAC1B,UAAA;EAEO,CAAA,CACL;;AAET;;;;;;AAOA,SAAgB,kBAAkB,EAChC,UACA,QACA,UAAU,OACV,kBAAkB,OAClB,gBACA,mBACA,gBACA,YACA,kBACA,gBACA,SACA,mBACA,UACA,WACyB;CACzB,MAAM,CAAC,YAAY,iBAAiB,SAAwB,IAAI;CAGhE,MAAM,CAAC,iBAAiB,sBAAsB,SAAwB,IAAI;CAC1E,MAAM,CAAC,cAAc,mBAAmB,SACtC,QACF;CAEA,MAAM,CAAC,cAAc,mBAAmB,SAAwB,IAAI;CACpE,MAAM,QAAQ,SAAS,QAAQ;CAC/B,MAAM,WAAW,cAAc,QAAQ;CAEvC,IAAI,MAAM,WAAW,GAAG,OAAO;CAE/B,MAAM,gBAAgB,MAAM,MAAM,SAAS,KAAK,OAAO,eAAe;CACtE,MAAM,kBAAkB,gBACpB,CAAC,eAAe,GAAG,YAAY,SAAS,IAAI,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,IACpE,CAAC;CAEL,SAAS,iBAAiB;EACxB,mBAAmB,IAAI;EACvB,gBAAgB,IAAI;EACpB,gBAAgB,QAAQ;CAC1B;CAEA,SAAS,aAAa,IAAY;EAChC,OAAO;GACL,GAAI,iBACA,EAAE,iBAAiB,WAAmB,eAAe,IAAI,MAAM,EAAE,IACjE,CAAC;GACL,GAAI,UAAU,EAAE,eAAe,QAAQ,EAAE,EAAE,IAAI,CAAC;GAChD,GAAI,oBACA,EAAE,oBAAoB,UAAkB,kBAAkB,IAAI,KAAK,EAAE,IACrE,CAAC;GACL,GAAI,WAAW,EAAE,gBAAgB,SAAS,EAAE,EAAE,IAAI,CAAC;EACrD;CACF;CAEA,OACE,qBAAAA,YAAA,EAAA,UAAA,CACE,oBAAC,OAAD;EAAK,WAAU;EACZ,UAAA,MAAM,KAAK,SAAS;GACnB,MAAM,UAAU,YAAY,SAAS,IAAI,KAAK,EAAE,KAAK,CAAC,CAAC;GACvD,MAAM,SAAS,CAAC,MAAM,GAAG,OAAO;GAChC,MAAM,cAAc,iBAAiB,IAAI,KAAK,CAAC;GAC/C,OACE,qBAAC,OAAD;IAEE,eAAY;IACZ,mBAAiB,KAAK;IACtB,GAAI;IACJ,WAAW,GAAG,mBAAmB,YAAY,SAAS;IALxD,UAAA;KAOG,iBACC,oBAAC,OAAD;MAAK,WAAU;MAAQ,UAAA,eAAe,IAAI;KAAO,CAAA,IAC/C;KACJ,oBAAC,aAAD;MACE,SAAS;MACD;MACC;MACQ;MACjB,kBAAkB,mBAAmB,KAAK,EAAE;MAC5C,GAAK,mBACD,EAAE,cAAc,SAAS,iBAAiB,MAAM,CAAC,EAAE,IACnD,CAAC;MACL,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;MACpC,GAAI,aAAa,KAAK,EAAE;MACxB,GAAK,UAAU,EAAE,eAAe,cAAc,KAAK,EAAE,EAAE,IAAI,CAAC;KAC7D,CAAA;KACA,oBAAoB,IAAI;KACxB,QAAQ,SAAS,KAChB,oBAAC,OAAD;MAAK,WAAU;MACZ,UAAA,QAAQ,KAAK,UACZ,oBAAC,aAAD;OAEE,SAAS;OACD;OACC;OACQ;OACjB,kBAAkB,mBAAmB,KAAK,EAAE;OAC5C,GAAK,mBACD,EAAE,cAAc,SAAS,iBAAiB,MAAM,CAAC,EAAE,IACnD,CAAC;OACL,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;OACpC,GAAI,aAAa,MAAM,EAAE;MAC1B,GAXM,MAAM,EAWZ,CACF;KACE,CAAA;KAEN,WAAW,eAAe,KAAK,MAC9B,oBAAC,YAAD;MACE,gBAAgB,cAAc,IAAI;MAClC,UAAU,OAAO,SAAS;OACxB,MAAM,QAAQ,MAAM,IAAI;OACxB,cAAc,IAAI;MACpB;KACD,CAAA;IAEA;GAnDE,GAAA,KAAK,EAmDP;EAET,CAAC;CACE,CAAA,GACJ,iBACC,oBAAC,OAAD;EAAO,MAAA;EAAK,SAAS;EAAgB,OAAM;EAAiB,MAAK;EAC/D,UAAA,qBAAC,OAAD;GAAK,WAAU;GAAY,eAAY;GAAvC,UAAA,CACG,oBACC,oBAAC,MAAD;IACE,MAAM,CACJ;KAAE,IAAI;KAAU,OAAO;IAAS,GAChC;KAAE,IAAI;KAAY,OAAO;IAAW,CACtC;IACA,OAAO;IACP,WAAW,QACT,gBAAgB,QAAQ,aAAa,aAAa,QAAQ;GAE7D,CAAA,GAEF,iBAAiB,cAAc,mBAC9B,oBAAC,UAAD,EAAU,MAAM,iBAAiB,eAAe,EAAI,CAAA,IAEpD,oBAAC,OAAD;IAAK,WAAU;IAEZ,UAAA,gBAAgB,KAAK,YACpB,qBAAC,OAAD;KAAsB,WAAU;KAAhC,UAAA;MACE,oBAAC,aAAD;OACE,SAAS;OACD;OACR,iBAAA;OACA,GAAK,mBACD,EACE,cACE,SAAS,iBAAiB,eAAe,CAAC,EAC9C,IACA,CAAC;OACL,GAAK,aAAa,EAAE,WAAW,IAAI,CAAC;OACpC,GAAI,aAAa,QAAQ,EAAE;OAC3B,GAAK,UACD,EAAE,eAAe,gBAAgB,QAAQ,EAAE,EAAE,IAC7C,CAAC;MACN,CAAA;MACA,QAAQ,OAAO,cAAc,MAC5B,oBAAoB,aAAa;MAClC,WAAW,iBAAiB,QAAQ,MACnC,oBAAC,YAAD;OACE,gBAAgB,gBAAgB,IAAI;OACpC,UAAU,OAAO,SAAS;QACxB,MAAM,QAAQ,eAAe,IAAI;QACjC,gBAAgB,IAAI;OACtB;MACD,CAAA;KAEA;IA5BK,GAAA,QAAQ,EA4Bb,CACN;GACE,CAAA,CAEJ;;CACA,CAAA,CAET,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"CommentThreadList.js","names":["_Fragment"],"sources":["../../src/comments/CommentThreadList.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"../components/button\";\nimport { copyText } from \"../components/clipboard\";\nimport { Markdown } from \"../data/Markdown\";\nimport { Tabs } from \"../layout/Tabs\";\nimport type { DropdownMenuItem } from \"../overlay/DropdownMenu\";\nimport { Modal } from \"../overlay/Modal\";\nimport { CommentCard } from \"./CommentCard\";\nimport { buildReplyMap, getRoots, sortReplies } from \"./comment-utils\";\nimport type { Comment, CommentAuthor, CommentConfig } from \"./comment-types\";\n\nexport type CommentThreadListProps = {\n comments: Comment[];\n config: CommentConfig;\n compact?: boolean;\n /** Expand each thread immediately (roots and their replies), exposing actions such as Reply. */\n defaultExpanded?: boolean;\n /** Extra content rendered above each root card (e.g. an anchor label). */\n renderRootMeta?: (comment: Comment) => ReactNode;\n /** Extra content rendered with each root thread, including its maximized view. */\n renderRootDetails?: (comment: Comment) => ReactNode;\n /** Props merged onto each thread wrapper (e.g. for scroll anchoring). */\n getThreadProps?: (comment: Comment) => HTMLAttributes<HTMLDivElement>;\n /** Custom body renderer forwarded to each card. */\n renderBody?: (body: string) => ReactNode;\n /** Serialize a root and its replies for Copy and the Markdown preview. */\n threadToMarkdown?: (thread: readonly Comment[]) => string;\n onUpdateStatus?: (id: string, status: string) => void | Promise<void>;\n onClose?: (id: string) => void | Promise<void>;\n onAcknowledge?: (id: string) => void | Promise<void>;\n onAssign?: (\n id: string,\n assignee: CommentAuthor | null,\n ) => void | Promise<void>;\n /** Caller-owned entries appended to each root's \"Assign…\" submenu. */\n extraAssignItems?: (comment: Comment) => DropdownMenuItem[];\n onChecklistToggle?: (id: string, index: number) => void;\n onDelete?: (id: string) => void;\n /** Submit a reply to `parent`. Presence enables the inline reply affordance. */\n onReply?: (parent: Comment, body: string) => void | Promise<void>;\n};\n\nfunction ReplyInput({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: string) => void | Promise<void>;\n onCancel: () => void;\n}) {\n const [body, setBody] = useState(\"\");\n const [submitting, setSubmitting] = useState(false);\n const submittingRef = useRef(false);\n async function send() {\n if (!body.trim() || submittingRef.current) return;\n submittingRef.current = true;\n setSubmitting(true);\n try {\n await onSubmit(body.trim());\n setBody(\"\");\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }\n return (\n <div className=\"ml-6 flex gap-1.5 py-1\" aria-busy={submitting}>\n <input\n autoFocus\n value={body}\n disabled={submitting}\n onChange={(e) => setBody(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void send();\n }\n if (e.key === \"Escape\") onCancel();\n }}\n placeholder=\"Write a reply…\"\n data-testid=\"comment-reply-input\"\n className=\"h-7 min-w-0 flex-1 rounded-md border border-border bg-background px-2 py-1 text-xs outline-none focus:border-primary/40 [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:text-base\"\n />\n <Button\n size=\"sm\"\n className=\"h-7 text-xs [@media(pointer:coarse)]:h-11 [@media(pointer:coarse)]:px-4 [@media(pointer:coarse)]:text-sm\"\n disabled={submitting || !body.trim()}\n onClick={() => void send()}\n >\n Send\n </Button>\n </div>\n );\n}\n\n/**\n * Renders a list of threaded comments: each root with its sorted replies and an\n * optional inline reply box. Fully controlled — mutations route through the\n * id-keyed callbacks.\n */\nexport function CommentThreadList({\n comments,\n config,\n compact = false,\n defaultExpanded = false,\n renderRootMeta,\n renderRootDetails,\n getThreadProps,\n renderBody,\n threadToMarkdown,\n onUpdateStatus,\n onClose,\n onAcknowledge,\n onAssign,\n extraAssignItems,\n onChecklistToggle,\n onDelete,\n onReply,\n}: CommentThreadListProps) {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n // Maximizing is owned here, not by the card: a thread is the unit a reader\n // wants enlarged, and only this list knows a root's replies.\n const [maximizedRootId, setMaximizedRootId] = useState<string | null>(null);\n const [maximizedTab, setMaximizedTab] = useState<\"thread\" | \"markdown\">(\n \"thread\",\n );\n // Which message in the maximized thread has its reply composer open.\n const [modalReplyTo, setModalReplyTo] = useState<string | null>(null);\n const roots = getRoots(comments);\n const replyMap = buildReplyMap(comments);\n\n if (roots.length === 0) return null;\n\n const maximizedRoot = roots.find((root) => root.id === maximizedRootId);\n const maximizedThread = maximizedRoot\n ? [maximizedRoot, ...sortReplies(replyMap.get(maximizedRoot.id) ?? [])]\n : [];\n\n function closeMaximized() {\n setMaximizedRootId(null);\n setModalReplyTo(null);\n setMaximizedTab(\"thread\");\n }\n\n function cardHandlers(id: string) {\n return {\n ...(onUpdateStatus\n ? { onUpdateStatus: (status: string) => onUpdateStatus(id, status) }\n : {}),\n ...(onClose ? { onClose: () => onClose(id) } : {}),\n ...(onAcknowledge ? { onAcknowledge: () => onAcknowledge(id) } : {}),\n ...(onAssign\n ? {\n onAssign: (assignee: CommentAuthor | null) =>\n onAssign(id, assignee),\n }\n : {}),\n ...(extraAssignItems ? { extraAssignItems } : {}),\n ...(onChecklistToggle\n ? { onChecklistToggle: (index: number) => onChecklistToggle(id, index) }\n : {}),\n ...(onDelete ? { onDelete: () => onDelete(id) } : {}),\n };\n }\n\n return (\n <>\n <div className=\"space-y-2\">\n {roots.map((root) => {\n const replies = sortReplies(replyMap.get(root.id) ?? []);\n const thread = [root, ...replies];\n const threadProps = getThreadProps?.(root) ?? {};\n return (\n <div\n key={root.id}\n data-testid=\"comment-thread-block\"\n data-comment-id={root.id}\n {...threadProps}\n className={cn(\"space-y-1.5 p-1\", threadProps.className)}\n >\n {renderRootMeta ? (\n <div className=\"px-1\">{renderRootMeta(root)}</div>\n ) : null}\n <CommentCard\n comment={root}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(root.id)}\n {...(onReply ? { onReply: () => setReplyingTo(root.id) } : {})}\n />\n {renderRootDetails?.(root)}\n {replies.length > 0 && (\n <div className=\"space-y-1.5\">\n {replies.map((reply) => (\n <CommentCard\n key={reply.id}\n comment={reply}\n config={config}\n compact={compact}\n defaultExpanded={defaultExpanded}\n onMaximize={() => setMaximizedRootId(root.id)}\n {...(threadToMarkdown\n ? { onCopy: () => copyText(threadToMarkdown(thread)) }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(reply.id)}\n />\n ))}\n </div>\n )}\n {onReply && replyingTo === root.id && (\n <ReplyInput\n onCancel={() => setReplyingTo(null)}\n onSubmit={async (body) => {\n await onReply(root, body);\n setReplyingTo(null);\n }}\n />\n )}\n </div>\n );\n })}\n </div>\n {maximizedRoot && (\n <Modal open onClose={closeMaximized} title=\"Comment thread\" size=\"lg\">\n <div className=\"space-y-3\" data-testid=\"comment-thread-modal\">\n {threadToMarkdown && (\n <Tabs\n tabs={[\n { id: \"thread\", label: \"Thread\" },\n { id: \"markdown\", label: \"Markdown\" },\n ]}\n value={maximizedTab}\n onChange={(tab) =>\n setMaximizedTab(tab === \"markdown\" ? \"markdown\" : \"thread\")\n }\n />\n )}\n {maximizedTab === \"markdown\" && threadToMarkdown ? (\n <Markdown text={threadToMarkdown(maximizedThread)} />\n ) : (\n <div className=\"space-y-2\">\n {/* No onMaximize inside: the thread is already maximized. */}\n {maximizedThread.map((message) => (\n <div key={message.id} className=\"space-y-1.5\">\n <CommentCard\n comment={message}\n config={config}\n defaultExpanded\n {...(threadToMarkdown\n ? {\n onCopy: () =>\n copyText(threadToMarkdown(maximizedThread)),\n }\n : {})}\n {...(renderBody ? { renderBody } : {})}\n {...cardHandlers(message.id)}\n {...(onReply\n ? { onReply: () => setModalReplyTo(message.id) }\n : {})}\n />\n {message.id === maximizedRoot.id &&\n renderRootDetails?.(maximizedRoot)}\n {onReply && modalReplyTo === message.id && (\n <ReplyInput\n onCancel={() => setModalReplyTo(null)}\n onSubmit={async (body) => {\n await onReply(maximizedRoot, body);\n setModalReplyTo(null);\n }}\n />\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
@@ -173,7 +173,7 @@ var MentionTextarea = (0, react.forwardRef)(function MentionTextarea({ value, on
173
173
  value,
174
174
  placeholder,
175
175
  "data-testid": dataTestId,
176
- className: require_utils.cn("w-full resize-none bg-transparent text-sm leading-snug outline-none placeholder:text-placeholder", className),
176
+ className: require_utils.cn("w-full resize-none bg-transparent text-sm leading-snug outline-none placeholder:text-placeholder [@media(pointer:coarse)]:text-base", className),
177
177
  onChange: (e) => {
178
178
  onChange(e.target.value);
179
179
  refreshMention(e.target);
@@ -1 +1 @@
1
- {"version":3,"file":"MentionTextarea.cjs","names":["forwardRef","useRef","useState","useFloatingZIndex","_Fragment","cn","createPortal","CommentAuthorAvatar"],"sources":["../../src/comments/MentionTextarea.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"../overlay/modalStack\";\nimport { CommentAuthorAvatar } from \"./CommentAuthor\";\nimport type { CommentMention, CommentMentionable } from \"./comment-types\";\n\nexport type MentionTextareaProps = {\n /** Controlled value. */\n value: string;\n /** Called with the next value on edit or mention insertion. */\n onChange: (value: string) => void;\n /** People/agents offered in the @-mention popover. */\n mentionables: CommentMentionable[];\n /** Fired when a mention is inserted via the popover. */\n onMentionSelect?: (mention: CommentMention) => void;\n /** Enter (without Shift) while the popover is closed. */\n onSubmit?: () => void;\n /** Escape while the popover is closed. */\n onCancel?: () => void;\n placeholder?: string;\n autoFocus?: boolean;\n rows?: number;\n className?: string;\n \"data-testid\"?: string;\n};\n\nconst MENTION_QUERY = /(^|\\s)@([\\w.-]*)$/;\nconst MAX_RESULTS = 8;\n\ntype ActiveMention = { atIndex: number; query: string };\ntype CaretRect = { top: number; left: number; height: number };\n\nfunction detectMention(value: string, caret: number): ActiveMention | null {\n const match = value.slice(0, caret).match(MENTION_QUERY);\n if (!match) return null;\n const query = match[2] ?? \"\";\n const atIndex = caret - query.length - 1;\n return { atIndex, query };\n}\n\nfunction filterMentionables(\n mentionables: CommentMentionable[],\n query: string,\n): CommentMentionable[] {\n const q = query.toLowerCase();\n const matches = q\n ? mentionables.filter(\n (m) =>\n m.name.toLowerCase().includes(q) || m.id.toLowerCase().includes(q),\n )\n : mentionables;\n return matches.slice(0, MAX_RESULTS);\n}\n\nconst MIRROR_PROPS = [\n \"boxSizing\",\n \"width\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontWeight\",\n \"fontStretch\",\n \"fontSize\",\n \"lineHeight\",\n \"fontFamily\",\n \"textAlign\",\n \"textTransform\",\n \"textIndent\",\n \"letterSpacing\",\n \"wordSpacing\",\n \"tabSize\",\n \"whiteSpace\",\n \"wordWrap\",\n \"overflowWrap\",\n] as const;\n\n// Measures the caret pixel position with an off-screen mirror div that copies the\n// textarea's box metrics — the dependency-free way to anchor a popover at the caret.\nfunction caretViewportRect(\n el: HTMLTextAreaElement,\n position: number,\n): CaretRect {\n if (\n typeof document === \"undefined\" ||\n typeof getComputedStyle !== \"function\"\n ) {\n const r = el.getBoundingClientRect();\n return { top: r.top, left: r.left, height: 16 };\n }\n const style = getComputedStyle(el);\n const mirror = document.createElement(\"div\");\n for (const prop of MIRROR_PROPS) mirror.style[prop] = style[prop];\n mirror.style.position = \"absolute\";\n mirror.style.visibility = \"hidden\";\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.overflowWrap = \"break-word\";\n mirror.style.top = \"0\";\n mirror.style.left = \"-9999px\";\n mirror.textContent = el.value.slice(0, position);\n\n const marker = document.createElement(\"span\");\n marker.textContent = el.value.slice(position) || \".\";\n mirror.appendChild(marker);\n document.body.appendChild(mirror);\n\n const lineHeight =\n parseInt(style.lineHeight, 10) || parseInt(style.fontSize, 10) || 16;\n const offsetTop = marker.offsetTop;\n const offsetLeft = marker.offsetLeft;\n document.body.removeChild(mirror);\n\n const rect = el.getBoundingClientRect();\n return {\n top: rect.top + offsetTop - el.scrollTop,\n left: rect.left + offsetLeft - el.scrollLeft,\n height: lineHeight,\n };\n}\n\n/**\n * A textarea with an @-mention autocomplete. Typing `@` opens a caret-anchored\n * popover filtered against `mentionables`; selecting one inserts the name and\n * fires `onMentionSelect`. Enter submits and Escape cancels only when the\n * popover is closed.\n */\nexport const MentionTextarea = forwardRef<\n HTMLTextAreaElement,\n MentionTextareaProps\n>(function MentionTextarea(\n {\n value,\n onChange,\n mentionables,\n onMentionSelect,\n onSubmit,\n onCancel,\n placeholder,\n autoFocus,\n rows = 2,\n className,\n \"data-testid\": dataTestId,\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(\n forwardedRef,\n () => innerRef.current as HTMLTextAreaElement,\n );\n\n const [active, setActive] = useState<ActiveMention | null>(null);\n const [caretRect, setCaretRect] = useState<CaretRect | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const floatingZ = useFloatingZIndex();\n\n const results = active ? filterMentionables(mentionables, active.query) : [];\n const open = active != null && results.length > 0;\n\n function refreshMention(el: HTMLTextAreaElement) {\n const next = detectMention(el.value, el.selectionStart ?? el.value.length);\n setActive(next);\n setActiveIndex(0);\n setCaretRect(next ? caretViewportRect(el, el.selectionStart ?? 0) : null);\n }\n\n function insertMention(m: CommentMentionable) {\n const el = innerRef.current;\n if (!el || !active) return;\n const caret = el.selectionStart ?? value.length;\n const next = `${value.slice(0, active.atIndex)}@${m.name} ${value.slice(caret)}`;\n const nextCaret = active.atIndex + m.name.length + 2;\n onChange(next);\n onMentionSelect?.({ id: m.id, name: m.name, kind: m.kind });\n setActive(null);\n setCaretRect(null);\n requestAnimationFrame(() => {\n el.focus();\n el.setSelectionRange(nextCaret, nextCaret);\n });\n }\n\n function onKeyDown(e: KeyboardEvent<HTMLTextAreaElement>) {\n if (open) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => (i + 1) % results.length);\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => (i - 1 + results.length) % results.length);\n return;\n }\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n const choice = results[activeIndex];\n if (choice) insertMention(choice);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setActive(null);\n setCaretRect(null);\n return;\n }\n }\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onSubmit?.();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }\n\n useEffect(() => {\n if (!autoFocus) return;\n const el = innerRef.current;\n const raf = requestAnimationFrame(() => {\n el?.focus();\n const len = el?.value.length ?? 0;\n el?.setSelectionRange(len, len);\n });\n return () => cancelAnimationFrame(raf);\n }, [autoFocus]);\n\n return (\n <>\n <textarea\n ref={innerRef}\n rows={rows}\n value={value}\n placeholder={placeholder}\n data-testid={dataTestId}\n className={cn(\n \"w-full resize-none bg-transparent text-sm leading-snug outline-none placeholder:text-placeholder\",\n className,\n )}\n onChange={(e) => {\n onChange(e.target.value);\n refreshMention(e.target);\n }}\n onKeyUp={(e) => refreshMention(e.currentTarget)}\n onClick={(e) => refreshMention(e.currentTarget)}\n onKeyDown={onKeyDown}\n onBlur={() => {\n setActive(null);\n setCaretRect(null);\n }}\n />\n {open &&\n typeof document !== \"undefined\" &&\n createPortal(\n <ul\n role=\"listbox\"\n data-testid=\"mention-popover\"\n style={{\n position: \"fixed\",\n top: (caretRect?.top ?? 0) + (caretRect?.height ?? 16) + 2,\n left: caretRect?.left ?? 0,\n zIndex: floatingZ,\n }}\n className=\"max-h-56 min-w-[12rem] overflow-auto rounded-md border border-border bg-popover py-1 shadow-md\"\n >\n {results.map((m, i) => (\n <li key={m.id}>\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n // Use mousedown so selection runs before the textarea blur closes the popover.\n onMouseDown={(e) => {\n e.preventDefault();\n insertMention(m);\n }}\n onMouseEnter={() => setActiveIndex(i)}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground\",\n i === activeIndex && \"bg-accent text-accent-foreground\",\n )}\n >\n <CommentAuthorAvatar\n author={{\n name: m.name,\n kind: m.kind,\n ...(m.avatar ? { avatar: m.avatar } : {}),\n ...(m.icon ? { icon: m.icon } : {}),\n }}\n size=\"xs\"\n bare\n />\n <span className=\"truncate\">{m.name}</span>\n {m.kind === \"agent\" && (\n <span className=\"ml-auto text-[10px] text-muted-foreground\">\n agent\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>,\n document.body,\n )}\n </>\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"MentionTextarea.cjs","names":["forwardRef","useRef","useState","useFloatingZIndex","_Fragment","cn","createPortal","CommentAuthorAvatar"],"sources":["../../src/comments/MentionTextarea.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { useFloatingZIndex } from \"../overlay/modalStack\";\nimport { CommentAuthorAvatar } from \"./CommentAuthor\";\nimport type { CommentMention, CommentMentionable } from \"./comment-types\";\n\nexport type MentionTextareaProps = {\n /** Controlled value. */\n value: string;\n /** Called with the next value on edit or mention insertion. */\n onChange: (value: string) => void;\n /** People/agents offered in the @-mention popover. */\n mentionables: CommentMentionable[];\n /** Fired when a mention is inserted via the popover. */\n onMentionSelect?: (mention: CommentMention) => void;\n /** Enter (without Shift) while the popover is closed. */\n onSubmit?: () => void;\n /** Escape while the popover is closed. */\n onCancel?: () => void;\n placeholder?: string;\n autoFocus?: boolean;\n rows?: number;\n className?: string;\n \"data-testid\"?: string;\n};\n\nconst MENTION_QUERY = /(^|\\s)@([\\w.-]*)$/;\nconst MAX_RESULTS = 8;\n\ntype ActiveMention = { atIndex: number; query: string };\ntype CaretRect = { top: number; left: number; height: number };\n\nfunction detectMention(value: string, caret: number): ActiveMention | null {\n const match = value.slice(0, caret).match(MENTION_QUERY);\n if (!match) return null;\n const query = match[2] ?? \"\";\n const atIndex = caret - query.length - 1;\n return { atIndex, query };\n}\n\nfunction filterMentionables(\n mentionables: CommentMentionable[],\n query: string,\n): CommentMentionable[] {\n const q = query.toLowerCase();\n const matches = q\n ? mentionables.filter(\n (m) =>\n m.name.toLowerCase().includes(q) || m.id.toLowerCase().includes(q),\n )\n : mentionables;\n return matches.slice(0, MAX_RESULTS);\n}\n\nconst MIRROR_PROPS = [\n \"boxSizing\",\n \"width\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontWeight\",\n \"fontStretch\",\n \"fontSize\",\n \"lineHeight\",\n \"fontFamily\",\n \"textAlign\",\n \"textTransform\",\n \"textIndent\",\n \"letterSpacing\",\n \"wordSpacing\",\n \"tabSize\",\n \"whiteSpace\",\n \"wordWrap\",\n \"overflowWrap\",\n] as const;\n\n// Measures the caret pixel position with an off-screen mirror div that copies the\n// textarea's box metrics — the dependency-free way to anchor a popover at the caret.\nfunction caretViewportRect(\n el: HTMLTextAreaElement,\n position: number,\n): CaretRect {\n if (\n typeof document === \"undefined\" ||\n typeof getComputedStyle !== \"function\"\n ) {\n const r = el.getBoundingClientRect();\n return { top: r.top, left: r.left, height: 16 };\n }\n const style = getComputedStyle(el);\n const mirror = document.createElement(\"div\");\n for (const prop of MIRROR_PROPS) mirror.style[prop] = style[prop];\n mirror.style.position = \"absolute\";\n mirror.style.visibility = \"hidden\";\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.overflowWrap = \"break-word\";\n mirror.style.top = \"0\";\n mirror.style.left = \"-9999px\";\n mirror.textContent = el.value.slice(0, position);\n\n const marker = document.createElement(\"span\");\n marker.textContent = el.value.slice(position) || \".\";\n mirror.appendChild(marker);\n document.body.appendChild(mirror);\n\n const lineHeight =\n parseInt(style.lineHeight, 10) || parseInt(style.fontSize, 10) || 16;\n const offsetTop = marker.offsetTop;\n const offsetLeft = marker.offsetLeft;\n document.body.removeChild(mirror);\n\n const rect = el.getBoundingClientRect();\n return {\n top: rect.top + offsetTop - el.scrollTop,\n left: rect.left + offsetLeft - el.scrollLeft,\n height: lineHeight,\n };\n}\n\n/**\n * A textarea with an @-mention autocomplete. Typing `@` opens a caret-anchored\n * popover filtered against `mentionables`; selecting one inserts the name and\n * fires `onMentionSelect`. Enter submits and Escape cancels only when the\n * popover is closed.\n */\nexport const MentionTextarea = forwardRef<\n HTMLTextAreaElement,\n MentionTextareaProps\n>(function MentionTextarea(\n {\n value,\n onChange,\n mentionables,\n onMentionSelect,\n onSubmit,\n onCancel,\n placeholder,\n autoFocus,\n rows = 2,\n className,\n \"data-testid\": dataTestId,\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLTextAreaElement>(null);\n useImperativeHandle(\n forwardedRef,\n () => innerRef.current as HTMLTextAreaElement,\n );\n\n const [active, setActive] = useState<ActiveMention | null>(null);\n const [caretRect, setCaretRect] = useState<CaretRect | null>(null);\n const [activeIndex, setActiveIndex] = useState(0);\n const floatingZ = useFloatingZIndex();\n\n const results = active ? filterMentionables(mentionables, active.query) : [];\n const open = active != null && results.length > 0;\n\n function refreshMention(el: HTMLTextAreaElement) {\n const next = detectMention(el.value, el.selectionStart ?? el.value.length);\n setActive(next);\n setActiveIndex(0);\n setCaretRect(next ? caretViewportRect(el, el.selectionStart ?? 0) : null);\n }\n\n function insertMention(m: CommentMentionable) {\n const el = innerRef.current;\n if (!el || !active) return;\n const caret = el.selectionStart ?? value.length;\n const next = `${value.slice(0, active.atIndex)}@${m.name} ${value.slice(caret)}`;\n const nextCaret = active.atIndex + m.name.length + 2;\n onChange(next);\n onMentionSelect?.({ id: m.id, name: m.name, kind: m.kind });\n setActive(null);\n setCaretRect(null);\n requestAnimationFrame(() => {\n el.focus();\n el.setSelectionRange(nextCaret, nextCaret);\n });\n }\n\n function onKeyDown(e: KeyboardEvent<HTMLTextAreaElement>) {\n if (open) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => (i + 1) % results.length);\n return;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => (i - 1 + results.length) % results.length);\n return;\n }\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n const choice = results[activeIndex];\n if (choice) insertMention(choice);\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n setActive(null);\n setCaretRect(null);\n return;\n }\n }\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onSubmit?.();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }\n\n useEffect(() => {\n if (!autoFocus) return;\n const el = innerRef.current;\n const raf = requestAnimationFrame(() => {\n el?.focus();\n const len = el?.value.length ?? 0;\n el?.setSelectionRange(len, len);\n });\n return () => cancelAnimationFrame(raf);\n }, [autoFocus]);\n\n return (\n <>\n <textarea\n ref={innerRef}\n rows={rows}\n value={value}\n placeholder={placeholder}\n data-testid={dataTestId}\n className={cn(\n // iOS zooms the page into any focused field under 16px.\n \"w-full resize-none bg-transparent text-sm leading-snug outline-none placeholder:text-placeholder [@media(pointer:coarse)]:text-base\",\n className,\n )}\n onChange={(e) => {\n onChange(e.target.value);\n refreshMention(e.target);\n }}\n onKeyUp={(e) => refreshMention(e.currentTarget)}\n onClick={(e) => refreshMention(e.currentTarget)}\n onKeyDown={onKeyDown}\n onBlur={() => {\n setActive(null);\n setCaretRect(null);\n }}\n />\n {open &&\n typeof document !== \"undefined\" &&\n createPortal(\n <ul\n role=\"listbox\"\n data-testid=\"mention-popover\"\n style={{\n position: \"fixed\",\n top: (caretRect?.top ?? 0) + (caretRect?.height ?? 16) + 2,\n left: caretRect?.left ?? 0,\n zIndex: floatingZ,\n }}\n className=\"max-h-56 min-w-[12rem] overflow-auto rounded-md border border-border bg-popover py-1 shadow-md\"\n >\n {results.map((m, i) => (\n <li key={m.id}>\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={i === activeIndex}\n // Use mousedown so selection runs before the textarea blur closes the popover.\n onMouseDown={(e) => {\n e.preventDefault();\n insertMention(m);\n }}\n onMouseEnter={() => setActiveIndex(i)}\n className={cn(\n \"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground\",\n i === activeIndex && \"bg-accent text-accent-foreground\",\n )}\n >\n <CommentAuthorAvatar\n author={{\n name: m.name,\n kind: m.kind,\n ...(m.avatar ? { avatar: m.avatar } : {}),\n ...(m.icon ? { icon: m.icon } : {}),\n }}\n size=\"xs\"\n bare\n />\n <span className=\"truncate\">{m.name}</span>\n {m.kind === \"agent\" && (\n <span className=\"ml-auto text-[10px] text-muted-foreground\">\n agent\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>,\n document.body,\n )}\n </>\n );\n});\n"],"mappings":"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"}