themelia-react-ui 2.0.0 → 2.0.2

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 (707) hide show
  1. package/CHANGELOG.md +527 -0
  2. package/README.md +47 -14
  3. package/THIRD_PARTY_NOTICES.md +13 -0
  4. package/dist/accordion-Cjb6sx0G.js +208 -0
  5. package/dist/accordion-Cjb6sx0G.js.map +1 -0
  6. package/dist/action-menu-CllU52Mm.js +280 -0
  7. package/dist/action-menu-CllU52Mm.js.map +1 -0
  8. package/dist/affordance-geometry.generated-tF36bREk.js +140 -0
  9. package/dist/affordance-geometry.generated-tF36bREk.js.map +1 -0
  10. package/dist/ai-artifact-DvTwDVyL.js +1148 -0
  11. package/dist/ai-artifact-DvTwDVyL.js.map +1 -0
  12. package/dist/{app-shell-BE_j8-AT.js → app-shell-C4FhvCqF.js} +5 -5
  13. package/dist/{app-shell-BE_j8-AT.js.map → app-shell-C4FhvCqF.js.map} +1 -1
  14. package/dist/attachment-BxDfL2mw.js +246 -0
  15. package/dist/attachment-BxDfL2mw.js.map +1 -0
  16. package/dist/{auth-M3vGMgDR.js → auth-ax2BqjrI.js} +241 -235
  17. package/dist/auth-ax2BqjrI.js.map +1 -0
  18. package/dist/{avatar-djdaaQ_s.js → avatar-DAPlDvhJ.js} +67 -66
  19. package/dist/avatar-DAPlDvhJ.js.map +1 -0
  20. package/dist/badge-HpFqoqSY.js +93 -0
  21. package/dist/badge-HpFqoqSY.js.map +1 -0
  22. package/dist/base/accordion.js +1 -1
  23. package/dist/base/action-menu.js +1 -1
  24. package/dist/base/attachment.js +1 -1
  25. package/dist/base/avatar.js +1 -1
  26. package/dist/base/badge.js +1 -1
  27. package/dist/base/batch-action-bar.js +3 -0
  28. package/dist/base/buttons.js +2 -3
  29. package/dist/base/cards.js +2 -2
  30. package/dist/base/carousel.js +50 -46
  31. package/dist/base/carousel.js.map +1 -1
  32. package/dist/base/cascader.js +69 -81
  33. package/dist/base/cascader.js.map +1 -1
  34. package/dist/base/chart.js +1 -1
  35. package/dist/base/choice-inputs.js +3 -3
  36. package/dist/base/code-block.js +1 -1
  37. package/dist/base/combobox.js +2 -2
  38. package/dist/base/command.js +1 -1
  39. package/dist/base/copyable.js +1 -1
  40. package/dist/base/date-pickers.js +2 -2
  41. package/dist/base/display.js +7 -7
  42. package/dist/base/feedback.js +3 -3
  43. package/dist/base/forms-numeric.js +1 -1
  44. package/dist/base/forms.js +2 -2
  45. package/dist/base/inline-edit.js +20 -20
  46. package/dist/base/inline-edit.js.map +1 -1
  47. package/dist/base/item.js +1 -1
  48. package/dist/base/media-gallery.js +1 -1
  49. package/dist/base/metadata-list.js +3 -0
  50. package/dist/base/navigation.js +7 -7
  51. package/dist/base/popover-menu.js +1 -1
  52. package/dist/base/popover.js +1 -1
  53. package/dist/base/qr-code.js +1 -1
  54. package/dist/base/repeaters.js +216 -220
  55. package/dist/base/repeaters.js.map +1 -1
  56. package/dist/base/sheet.js +1 -1
  57. package/dist/base/sidebar.js +1 -1
  58. package/dist/base/signature-pad.js +147 -137
  59. package/dist/base/signature-pad.js.map +1 -1
  60. package/dist/base/skeleton.js +1 -1
  61. package/dist/base/spinner.js +79 -2
  62. package/dist/base/spinner.js.map +1 -0
  63. package/dist/base/structure.js +1 -1
  64. package/dist/base/table.js +1 -1
  65. package/dist/base/text-inputs.js +2 -2
  66. package/dist/base/toaster.js +46 -45
  67. package/dist/base/toaster.js.map +1 -1
  68. package/dist/base/tree.js +1 -1
  69. package/dist/base/upload-queue.js +1 -1
  70. package/dist/base/upload.js +3 -3
  71. package/dist/base/value-inputs.js +2 -2
  72. package/dist/batch-action-bar-DnUJ21NQ.js +105 -0
  73. package/dist/batch-action-bar-DnUJ21NQ.js.map +1 -0
  74. package/dist/blocks/admin.js +171 -169
  75. package/dist/blocks/admin.js.map +1 -1
  76. package/dist/blocks/ai.js +308 -285
  77. package/dist/blocks/ai.js.map +1 -1
  78. package/dist/blocks/analytics/usage-card.js +1 -1
  79. package/dist/blocks/analytics.js +626 -589
  80. package/dist/blocks/analytics.js.map +1 -1
  81. package/dist/blocks/collaboration.js +1 -1
  82. package/dist/blocks/commerce/receipt.js +1 -1
  83. package/dist/blocks/commerce.js +2051 -1329
  84. package/dist/blocks/commerce.js.map +1 -1
  85. package/dist/blocks/data-display.js +3 -2
  86. package/dist/blocks/onboarding.js +68 -58
  87. package/dist/blocks/onboarding.js.map +1 -1
  88. package/dist/blocks/planning.js +27 -26
  89. package/dist/blocks/planning.js.map +1 -1
  90. package/dist/blocks/timelines.js +1 -1
  91. package/dist/breadcrumbs-C-oqs1sQ.js +129 -0
  92. package/dist/breadcrumbs-C-oqs1sQ.js.map +1 -0
  93. package/dist/{button-R9CCoH7A.js → button-DVzspB_G.js} +15 -14
  94. package/dist/button-DVzspB_G.js.map +1 -0
  95. package/dist/{button-BS3KDg00.js → buttons-DPZekJFu.js} +208 -216
  96. package/dist/buttons-DPZekJFu.js.map +1 -0
  97. package/dist/cards-BaBZR-AU.js +68 -0
  98. package/dist/cards-BaBZR-AU.js.map +1 -0
  99. package/dist/{chart-DwYRKKc-.js → chart-ZOYyK2xG.js} +58 -55
  100. package/dist/chart-ZOYyK2xG.js.map +1 -0
  101. package/dist/checkbox-AWIhNhmo.js +36 -0
  102. package/dist/checkbox-AWIhNhmo.js.map +1 -0
  103. package/dist/choice-inputs-CNHvARCJ.js +770 -0
  104. package/dist/choice-inputs-CNHvARCJ.js.map +1 -0
  105. package/dist/code-block-DeneBJR_.js +185 -0
  106. package/dist/code-block-DeneBJR_.js.map +1 -0
  107. package/dist/{collapsible-oMUGM4tr.js → collapsible-C-_l4hpy.js} +4 -4
  108. package/dist/{collapsible-oMUGM4tr.js.map → collapsible-C-_l4hpy.js.map} +1 -1
  109. package/dist/{collection-content-Ys-OZOkY.js → collection-content-By56pLog.js} +3 -3
  110. package/dist/{collection-content-Ys-OZOkY.js.map → collection-content-By56pLog.js.map} +1 -1
  111. package/dist/combobox-C0EQW6dr.js +875 -0
  112. package/dist/combobox-C0EQW6dr.js.map +1 -0
  113. package/dist/combobox-xCQ2RMNE.js +309 -0
  114. package/dist/combobox-xCQ2RMNE.js.map +1 -0
  115. package/dist/{command-kPMPjIxJ.js → command-C25VMRII.js} +7 -7
  116. package/dist/{command-kPMPjIxJ.js.map → command-C25VMRII.js.map} +1 -1
  117. package/dist/{comments-You0Bzbr.js → comments-BYYlTA8E.js} +390 -379
  118. package/dist/comments-BYYlTA8E.js.map +1 -0
  119. package/dist/components/base/action-menu/action-menu.d.ts +21 -4
  120. package/dist/components/base/action-menu/action-menu.recipes.d.ts +21 -0
  121. package/dist/components/base/action-menu/index.d.ts +1 -0
  122. package/dist/components/base/badge/badge.recipes.d.ts +5 -5
  123. package/dist/components/base/batch-action-bar/batch-action-bar.d.ts +50 -0
  124. package/dist/components/base/batch-action-bar/batch-action-bar.strings.d.ts +20 -0
  125. package/dist/components/base/batch-action-bar/index.d.ts +8 -0
  126. package/dist/components/base/buttons/button-group.recipes.d.ts +1 -1
  127. package/dist/components/base/buttons/button.recipes.d.ts +2 -2
  128. package/dist/components/base/buttons/loader-button.d.ts +2 -1
  129. package/dist/components/base/cards/card.recipes.d.ts +2 -3
  130. package/dist/components/base/cards/partials/smart-card-skeleton.d.ts +3 -13
  131. package/dist/components/base/cards/smart-card.types.d.ts +11 -4
  132. package/dist/components/base/chart/chart.d.ts +2 -5
  133. package/dist/components/base/choice-inputs/checkbox.d.ts +2 -2
  134. package/dist/components/base/choice-inputs/choice-types.d.ts +18 -6
  135. package/dist/components/base/combobox/combobox.strings.d.ts +7 -0
  136. package/dist/components/base/combobox/index.d.ts +30 -4
  137. package/dist/components/base/display/alert-dialog.d.ts +6 -5
  138. package/dist/components/base/display/dialog.d.ts +4 -8
  139. package/dist/components/base/display/icon-badge/icon-badge.d.ts +1 -1
  140. package/dist/components/base/forms/form-sizing.d.ts +26 -15
  141. package/dist/components/base/metadata-list/index.d.ts +12 -0
  142. package/dist/components/{blocks/data-display/metadata → base/metadata-list}/metadata-list.d.ts +28 -25
  143. package/dist/components/{blocks/data-display/metadata → base/metadata-list}/metadata-value.d.ts +2 -2
  144. package/dist/components/base/navigation/index.d.ts +1 -1
  145. package/dist/components/base/navigation/page-header/index.d.ts +1 -0
  146. package/dist/components/base/navigation/page-header/page-header-commands.d.ts +73 -0
  147. package/dist/components/base/navigation/page-header/page-header.d.ts +26 -3
  148. package/dist/components/base/navigation/pagination.d.ts +5 -2
  149. package/dist/components/base/popover/popover.recipes.d.ts +15 -1
  150. package/dist/components/base/sheet/sheet.d.ts +4 -8
  151. package/dist/components/base/signature-pad/signature-pad.types.d.ts +5 -1
  152. package/dist/components/base/signature-pad/signature-pad.utils.d.ts +11 -3
  153. package/dist/components/base/table/index.d.ts +9 -2
  154. package/dist/components/base/text-inputs/field-clear-button.d.ts +6 -0
  155. package/dist/components/base/text-inputs/input-group.d.ts +2 -2
  156. package/dist/components/base/upload/upload.recipes.d.ts +25 -3
  157. package/dist/components/base/value-inputs/index.d.ts +5 -5
  158. package/dist/components/base/value-inputs/tags-input.d.ts +36 -12
  159. package/dist/components/blocks/ai/ai-shimmer/ai-shimmer.d.ts +1 -1
  160. package/dist/components/blocks/ai/ai-shimmer/types.d.ts +3 -0
  161. package/dist/components/blocks/commerce/address-card/address-card.d.ts +1 -1
  162. package/dist/components/blocks/commerce/address-card/types.d.ts +2 -1
  163. package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +3 -1
  164. package/dist/components/blocks/commerce/cart-summary/index.d.ts +2 -2
  165. package/dist/components/blocks/commerce/cart-summary/types.d.ts +6 -1
  166. package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +3 -1
  167. package/dist/components/blocks/commerce/discount-stack/index.d.ts +2 -2
  168. package/dist/components/blocks/commerce/discount-stack/types.d.ts +16 -4
  169. package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +5 -0
  170. package/dist/components/blocks/commerce/fulfillment-group/index.d.ts +2 -0
  171. package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +45 -0
  172. package/dist/components/blocks/commerce/index.d.ts +13 -5
  173. package/dist/components/blocks/commerce/invoice-header/invoice-header.d.ts +1 -1
  174. package/dist/components/blocks/commerce/invoice-header/types.d.ts +4 -2
  175. package/dist/components/blocks/commerce/invoice-mini/invoice-mini.d.ts +1 -1
  176. package/dist/components/blocks/commerce/invoice-mini/types.d.ts +2 -1
  177. package/dist/components/blocks/commerce/order-customer/index.d.ts +2 -0
  178. package/dist/components/blocks/commerce/order-customer/order-customer.d.ts +5 -0
  179. package/dist/components/blocks/commerce/order-customer/types.d.ts +48 -0
  180. package/dist/components/blocks/commerce/order-header/index.d.ts +2 -0
  181. package/dist/components/blocks/commerce/order-header/order-header.d.ts +5 -0
  182. package/dist/components/blocks/commerce/order-header/types.d.ts +37 -0
  183. package/dist/components/blocks/commerce/order-line-item/index.d.ts +2 -0
  184. package/dist/components/blocks/commerce/order-line-item/order-line-item.d.ts +5 -0
  185. package/dist/components/blocks/commerce/order-line-item/types.d.ts +46 -0
  186. package/dist/components/blocks/commerce/order-summary/index.d.ts +2 -0
  187. package/dist/components/blocks/commerce/order-summary/order-summary.d.ts +5 -0
  188. package/dist/components/blocks/commerce/order-summary/types.d.ts +42 -0
  189. package/dist/components/blocks/commerce/order-transactions/index.d.ts +2 -0
  190. package/dist/components/blocks/commerce/order-transactions/order-transactions.d.ts +5 -0
  191. package/dist/components/blocks/commerce/order-transactions/types.d.ts +46 -0
  192. package/dist/components/blocks/commerce/payment-method/index.d.ts +2 -2
  193. package/dist/components/blocks/commerce/payment-method/payment-method.d.ts +9 -1
  194. package/dist/components/blocks/commerce/payment-method/types.d.ts +12 -1
  195. package/dist/components/blocks/commerce/refund-status/index.d.ts +2 -2
  196. package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +3 -1
  197. package/dist/components/blocks/commerce/refund-status/types.d.ts +6 -3
  198. package/dist/components/blocks/commerce/shared/address-lines.d.ts +21 -0
  199. package/dist/components/blocks/commerce/shared/line-thumbnail.d.ts +9 -0
  200. package/dist/components/blocks/commerce/shared/order-status.d.ts +51 -0
  201. package/dist/components/blocks/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
  202. package/dist/components/blocks/commerce/shipment-tracking/types.d.ts +27 -6
  203. package/dist/components/blocks/commerce/summary-panel/amount-row.d.ts +2 -0
  204. package/dist/components/blocks/commerce/summary-panel/index.d.ts +3 -0
  205. package/dist/components/blocks/commerce/summary-panel/summary-panel.d.ts +2 -0
  206. package/dist/components/blocks/commerce/summary-panel/types.d.ts +26 -0
  207. package/dist/components/blocks/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
  208. package/dist/components/blocks/commerce/tax-breakdown/types.d.ts +2 -1
  209. package/dist/components/blocks/data-display/inline-stat/inline-stat.d.ts +16 -8
  210. package/dist/components/blocks/data-display/metadata/index.d.ts +30 -4
  211. package/dist/components/features/activities/partials/activity-marker.d.ts +6 -3
  212. package/dist/components/features/activities/partials/activity-row.d.ts +6 -2
  213. package/dist/components/features/activities/partials/tone-tokens.d.ts +0 -6
  214. package/dist/components/features/appointment-calendar/appointment-calendar.d.ts +5 -0
  215. package/dist/components/features/appointment-calendar/appointment-calendar.types.d.ts +220 -0
  216. package/dist/components/features/appointment-calendar/appointment-calendar.utils.d.ts +41 -0
  217. package/dist/components/features/appointment-calendar/index.d.ts +3 -0
  218. package/dist/components/features/appointment-calendar/partials/appointment-agenda.d.ts +32 -0
  219. package/dist/components/features/appointment-calendar/partials/appointment-month.d.ts +13 -0
  220. package/dist/components/features/combobox/combobox.strings.d.ts +15 -1
  221. package/dist/components/features/combobox/types.d.ts +4 -0
  222. package/dist/components/features/global-search/partials/global-search-group-heading.d.ts +15 -0
  223. package/dist/components/features/global-search/partials/tone-palettes.d.ts +0 -5
  224. package/dist/components/features/kanban/kanban.d.ts +1 -1
  225. package/dist/components/features/kanban/kanban.strings.d.ts +1 -1
  226. package/dist/components/features/kanban/kanban.types.d.ts +2 -2
  227. package/dist/components/features/media-library/hooks/use-media-library.d.ts +1 -1
  228. package/dist/components/features/media-library/index.d.ts +1 -1
  229. package/dist/components/features/media-library/media-library.d.ts +1 -1
  230. package/dist/components/features/media-library/media-library.strings.d.ts +6 -0
  231. package/dist/components/features/media-library/media-library.types.d.ts +74 -1
  232. package/dist/components/features/media-library/partials/media-library-partials.d.ts +3 -3
  233. package/dist/components/features/mentions/partials/mention-kind-toggles.d.ts +16 -0
  234. package/dist/components/features/overlays/alert-dialog.d.ts +1 -1
  235. package/dist/components/features/overlays/dialog.d.ts +1 -1
  236. package/dist/components/features/overlays/index.d.ts +1 -1
  237. package/dist/components/features/overlays/overlay-tone-icon.d.ts +3 -3
  238. package/dist/components/features/overlays/overlays.types.d.ts +20 -0
  239. package/dist/components/features/products/components/product-contract-overview.d.ts +5 -0
  240. package/dist/components/features/products/components/product-details-card.d.ts +5 -0
  241. package/dist/components/features/products/components/product-operations-card.d.ts +5 -0
  242. package/dist/components/features/products/components/product-option-action-menu.d.ts +5 -0
  243. package/dist/components/features/products/components/product-options-summary.d.ts +5 -0
  244. package/dist/components/features/products/components/product-policies-card.d.ts +5 -0
  245. package/dist/components/features/products/components/product-quote-preview-card.d.ts +5 -0
  246. package/dist/components/features/products/components/product-readiness-card.d.ts +5 -0
  247. package/dist/components/features/products/components/product-structure-card.d.ts +5 -0
  248. package/dist/components/features/products/components/product-variant-action-menu.d.ts +23 -1
  249. package/dist/components/features/products/products.types.d.ts +9 -2
  250. package/dist/components/features/resource/index.d.ts +1 -1
  251. package/dist/components/features/resource/resource.d.ts +1 -1
  252. package/dist/components/features/resource/resource.types.d.ts +34 -6
  253. package/dist/components/features/rich-text-editor/index.d.ts +2 -1
  254. package/dist/components/features/rich-text-editor/partials/image-nodes.d.ts +13 -0
  255. package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +66 -0
  256. package/dist/components/features/rich-text-editor/partials/inline-reference-node.d.ts +19 -0
  257. package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +7 -1
  258. package/dist/components/features/rich-text-editor/rich-text-editor.strings.d.ts +14 -0
  259. package/dist/components/features/rich-text-editor/rich-text-editor.types.d.ts +54 -1
  260. package/dist/components/features/rich-text-editor/use-rich-text-images.d.ts +18 -0
  261. package/dist/components/features/sync/index.d.ts +26 -3
  262. package/dist/components/features/table/data-table.d.ts +1 -1
  263. package/dist/components/features/table/table-header.d.ts +1 -1
  264. package/dist/components/features/table/table.strings.d.ts +55 -1
  265. package/dist/components/features/table/table.types.d.ts +49 -11
  266. package/dist/components/features/theme-tweaker/theme-tweaker.types.d.ts +5 -0
  267. package/dist/components/layout/page/index.d.ts +1 -1
  268. package/dist/components/layout/page/page.types.d.ts +33 -36
  269. package/dist/components/layout/page/partials/page-actions.d.ts +1 -0
  270. package/dist/components/layout/page/partials/page-header.d.ts +1 -1
  271. package/dist/components/layout/settings/settings.d.ts +16 -2
  272. package/dist/components/layout/workspace/workspace.types.d.ts +21 -4
  273. package/dist/components/primitives/number.d.ts +4 -2
  274. package/dist/components/primitives/value.d.ts +3 -1
  275. package/dist/components/typography/rich-text/index.d.ts +1 -1
  276. package/dist/components/typography/rich-text/rich-text-tree.d.ts +19 -0
  277. package/dist/components/typography/rich-text/rich-text.d.ts +16 -0
  278. package/dist/components/typography/text-link.d.ts +8 -3
  279. package/dist/components/ui/checkbox.d.ts +4 -3
  280. package/dist/components/ui/combobox.d.ts +6 -2
  281. package/dist/components/ui/item.d.ts +8 -8
  282. package/dist/components/ui/overlay.recipes.d.ts +0 -9
  283. package/dist/components/ui/switch.d.ts +2 -2
  284. package/dist/components/ui/tabs.d.ts +1 -1
  285. package/dist/{containers-D_L4mTVb.js → containers-Mu1LMGV1.js} +36 -35
  286. package/dist/containers-Mu1LMGV1.js.map +1 -0
  287. package/dist/{copyable-DDjTeW_j.js → copyable-ClBuk_UK.js} +6 -6
  288. package/dist/{copyable-DDjTeW_j.js.map → copyable-ClBuk_UK.js.map} +1 -1
  289. package/dist/data-display-DT_khPl_.js +971 -0
  290. package/dist/data-display-DT_khPl_.js.map +1 -0
  291. package/dist/{date-uf3z37Nm.js → date-DCrsDTZc.js} +5 -5
  292. package/dist/{date-uf3z37Nm.js.map → date-DCrsDTZc.js.map} +1 -1
  293. package/dist/date-picker-ay0Pha_a.js +1530 -0
  294. package/dist/date-picker-ay0Pha_a.js.map +1 -0
  295. package/dist/date-pickers-Ccw8DL2b.js +175 -0
  296. package/dist/date-pickers-Ccw8DL2b.js.map +1 -0
  297. package/dist/display-hAc1HjpI.js +344 -0
  298. package/dist/display-hAc1HjpI.js.map +1 -0
  299. package/dist/dropdown-menu-Cl4X7L5S.js +193 -0
  300. package/dist/dropdown-menu-Cl4X7L5S.js.map +1 -0
  301. package/dist/editable-text-recipe-Cn61kEcv.js +10 -0
  302. package/dist/editable-text-recipe-Cn61kEcv.js.map +1 -0
  303. package/dist/features/activities.js +478 -542
  304. package/dist/features/activities.js.map +1 -1
  305. package/dist/features/ai-chat.js +209 -199
  306. package/dist/features/ai-chat.js.map +1 -1
  307. package/dist/features/appointment-calendar.js +683 -0
  308. package/dist/features/appointment-calendar.js.map +1 -0
  309. package/dist/features/async-preview.js +109 -107
  310. package/dist/features/async-preview.js.map +1 -1
  311. package/dist/features/combobox.js +1 -1
  312. package/dist/features/comments.js +1 -1
  313. package/dist/features/data-view.js +30 -29
  314. package/dist/features/data-view.js.map +1 -1
  315. package/dist/features/email-composer/engine.js +1 -1
  316. package/dist/features/email-composer.js +285 -283
  317. package/dist/features/email-composer.js.map +1 -1
  318. package/dist/features/event-calendar.js +282 -273
  319. package/dist/features/event-calendar.js.map +1 -1
  320. package/dist/features/filters.js +1 -1
  321. package/dist/features/global-search.js +318 -318
  322. package/dist/features/global-search.js.map +1 -1
  323. package/dist/features/kanban.js +146 -147
  324. package/dist/features/kanban.js.map +1 -1
  325. package/dist/features/map.js +269 -268
  326. package/dist/features/map.js.map +1 -1
  327. package/dist/features/media-library.js +970 -863
  328. package/dist/features/media-library.js.map +1 -1
  329. package/dist/features/mentions.js +1 -1
  330. package/dist/features/overlays.js +1 -1
  331. package/dist/features/products.js +1137 -1124
  332. package/dist/features/products.js.map +1 -1
  333. package/dist/features/questionnaire.js +206 -194
  334. package/dist/features/questionnaire.js.map +1 -1
  335. package/dist/features/resource-assignment.js +24 -21
  336. package/dist/features/resource-assignment.js.map +1 -1
  337. package/dist/features/resource.js +77 -69
  338. package/dist/features/resource.js.map +1 -1
  339. package/dist/features/rich-text-editor.js +30 -11
  340. package/dist/features/rich-text-editor.js.map +1 -1
  341. package/dist/features/schema-form.js +35 -33
  342. package/dist/features/schema-form.js.map +1 -1
  343. package/dist/features/suggestions.js +3 -3
  344. package/dist/features/sync.js +11 -5
  345. package/dist/features/sync.js.map +1 -1
  346. package/dist/features/table.js +1 -1
  347. package/dist/features/theme-tweaker.js +501 -496
  348. package/dist/features/theme-tweaker.js.map +1 -1
  349. package/dist/feedback-BYIhtitP.js +239 -0
  350. package/dist/feedback-BYIhtitP.js.map +1 -0
  351. package/dist/field-affordance-recipes-DZhnIL_Y.js +41 -0
  352. package/dist/field-affordance-recipes-DZhnIL_Y.js.map +1 -0
  353. package/dist/field-state-recipes-BVA2CWHo.js +12 -0
  354. package/dist/field-state-recipes-BVA2CWHo.js.map +1 -0
  355. package/dist/{filters-Da-gNPsE.js → filters-BGfvjP4d.js} +483 -472
  356. package/dist/filters-BGfvjP4d.js.map +1 -0
  357. package/dist/focus-recipes-B653VaLq.js +12 -0
  358. package/dist/focus-recipes-B653VaLq.js.map +1 -0
  359. package/dist/{form-field-VZRULhUK.js → form-field-CwH9y77i.js} +6 -5
  360. package/dist/form-field-CwH9y77i.js.map +1 -0
  361. package/dist/{form-sizing-uWP4lzVh.js → form-sizing-BdP_Mf5p.js} +45 -46
  362. package/dist/form-sizing-BdP_Mf5p.js.map +1 -0
  363. package/dist/{forms-DDeEnXSY.js → forms-B9G_xwzi.js} +22 -22
  364. package/dist/{forms-DDeEnXSY.js.map → forms-B9G_xwzi.js.map} +1 -1
  365. package/dist/forms-numeric-B_jraJaQ.js +906 -0
  366. package/dist/forms-numeric-B_jraJaQ.js.map +1 -0
  367. package/dist/{header-2ycNqGOR.js → header-CGXuhcRm.js} +164 -161
  368. package/dist/header-CGXuhcRm.js.map +1 -0
  369. package/dist/{hooks-DQ5SPwZw.js → hooks-Dkz0K2WT.js} +2 -2
  370. package/dist/{hooks-DQ5SPwZw.js.map → hooks-Dkz0K2WT.js.map} +1 -1
  371. package/dist/{http-CdEIHyQf.js → http-D_6rOnzU.js} +2 -2
  372. package/dist/{http-CdEIHyQf.js.map → http-D_6rOnzU.js.map} +1 -1
  373. package/dist/icon-badge-DYKIwvOV.js +55 -0
  374. package/dist/icon-badge-DYKIwvOV.js.map +1 -0
  375. package/dist/index.js +7 -7
  376. package/dist/input-CZw8iU99.js +21 -0
  377. package/dist/input-CZw8iU99.js.map +1 -0
  378. package/dist/input-DQdEd0YD.js +263 -0
  379. package/dist/input-DQdEd0YD.js.map +1 -0
  380. package/dist/interaction-recipes-XR9ZpVYL.js +25 -0
  381. package/dist/interaction-recipes-XR9ZpVYL.js.map +1 -0
  382. package/dist/item-K5_ghvze.js +275 -0
  383. package/dist/item-K5_ghvze.js.map +1 -0
  384. package/dist/layer-recipes-CCpklYME.js +13 -0
  385. package/dist/layer-recipes-CCpklYME.js.map +1 -0
  386. package/dist/layout/app-shell.js +1 -1
  387. package/dist/layout/auth.js +1 -1
  388. package/dist/layout/containers.js +1 -1
  389. package/dist/layout/header.js +1 -1
  390. package/dist/layout/hooks.js +1 -1
  391. package/dist/layout/navigation.js +1 -1
  392. package/dist/layout/page.js +1 -1
  393. package/dist/layout/settings.js +1 -1
  394. package/dist/layout/sidebar.js +2 -2
  395. package/dist/layout/workspace.js +1 -1
  396. package/dist/layout.js +10 -10
  397. package/dist/lib/affordance-geometry.generated.d.ts +72 -0
  398. package/dist/lib/editable-text-recipe.d.ts +4 -4
  399. package/dist/lib/field-affordance-recipes.d.ts +8 -3
  400. package/dist/lib/field-state-recipes.d.ts +9 -8
  401. package/dist/lib/focus-recipes.d.ts +24 -0
  402. package/dist/lib/interaction-recipes.d.ts +40 -0
  403. package/dist/lib/layer-recipes.d.ts +19 -0
  404. package/dist/lib/motion-recipes.d.ts +1 -0
  405. package/dist/lib/overlay-anatomy-recipes.d.ts +1 -0
  406. package/dist/lib/safe-image-src.d.ts +10 -0
  407. package/dist/lib/sanitize-html.d.ts +15 -3
  408. package/dist/lib/surface-recipes.d.ts +47 -7
  409. package/dist/lib/theme-mode-css.d.ts +7 -0
  410. package/dist/lib/token-merge.generated.d.ts +9 -6
  411. package/dist/lib/tone-recipes.d.ts +87 -0
  412. package/dist/lib/ui-provider/hooks.d.ts +2 -1
  413. package/dist/lib/ui-provider/index.d.ts +2 -2
  414. package/dist/lib/ui-provider/types.d.ts +11 -2
  415. package/dist/lib/utils.js +1 -1
  416. package/dist/media-gallery-3zIVLMWH.js +203 -0
  417. package/dist/media-gallery-3zIVLMWH.js.map +1 -0
  418. package/dist/mentions-utuUvH1K.js +570 -0
  419. package/dist/mentions-utuUvH1K.js.map +1 -0
  420. package/dist/{message-YfFmbXNP.js → message-DZ_ruyUV.js} +7 -6
  421. package/dist/message-DZ_ruyUV.js.map +1 -0
  422. package/dist/metadata-list-8N16ZMW_.js +405 -0
  423. package/dist/metadata-list-8N16ZMW_.js.map +1 -0
  424. package/dist/{motion-recipes-B6jKXEcN.js → motion-recipes-ChBg4HBq.js} +3 -2
  425. package/dist/{motion-recipes-B6jKXEcN.js.map → motion-recipes-ChBg4HBq.js.map} +1 -1
  426. package/dist/navigation-Bnotn4AQ.js +145 -0
  427. package/dist/navigation-Bnotn4AQ.js.map +1 -0
  428. package/dist/navigation-BzhHI3lo.js +269 -0
  429. package/dist/navigation-BzhHI3lo.js.map +1 -0
  430. package/dist/{navigation-row-recipes-DlU-4QYO.js → navigation-row-recipes-BFLCk_Aq.js} +2 -2
  431. package/dist/{navigation-row-recipes-DlU-4QYO.js.map → navigation-row-recipes-BFLCk_Aq.js.map} +1 -1
  432. package/dist/{number-CKRBYmZK.js → number-DbV1Dija.js} +36 -34
  433. package/dist/{number-CKRBYmZK.js.map → number-DbV1Dija.js.map} +1 -1
  434. package/dist/overflow-tab-bar-CWY7Nogn.js +282 -0
  435. package/dist/overflow-tab-bar-CWY7Nogn.js.map +1 -0
  436. package/dist/overlay.recipes-8GHqmlb4.js +6 -0
  437. package/dist/overlay.recipes-8GHqmlb4.js.map +1 -0
  438. package/dist/overlays-DNWmZrJ4.js +1001 -0
  439. package/dist/overlays-DNWmZrJ4.js.map +1 -0
  440. package/dist/page-Bgl1F560.js +224 -0
  441. package/dist/page-Bgl1F560.js.map +1 -0
  442. package/dist/page-header-commands-DOb6WsfD.js +126 -0
  443. package/dist/page-header-commands-DOb6WsfD.js.map +1 -0
  444. package/dist/pagination-BL25hu2s.js +158 -0
  445. package/dist/pagination-BL25hu2s.js.map +1 -0
  446. package/dist/{popover-Dcv_9jxr.js → popover-7_m66eYW.js} +11 -10
  447. package/dist/popover-7_m66eYW.js.map +1 -0
  448. package/dist/popover-menu-B9WWygpa.js +100 -0
  449. package/dist/popover-menu-B9WWygpa.js.map +1 -0
  450. package/dist/{popover.recipes-wmbvL8Ah.js → popover.recipes-D3j8R8Yp.js} +18 -11
  451. package/dist/popover.recipes-D3j8R8Yp.js.map +1 -0
  452. package/dist/{primitives-BHrwQXFC.js → primitives-BFK08r9M.js} +45 -44
  453. package/dist/primitives-BFK08r9M.js.map +1 -0
  454. package/dist/primitives.js +4 -4
  455. package/dist/{progress-Br9WTFya.js → progress-B1VnCT0K.js} +9 -9
  456. package/dist/{progress-Br9WTFya.js.map → progress-B1VnCT0K.js.map} +1 -1
  457. package/dist/{receipt-CV89q1fs.js → receipt-BVSOH3Xo.js} +9 -6
  458. package/dist/{receipt-CV89q1fs.js.map → receipt-BVSOH3Xo.js.map} +1 -1
  459. package/dist/rich-text-GOUyKQ-s.js +78 -0
  460. package/dist/rich-text-GOUyKQ-s.js.map +1 -0
  461. package/dist/rich-text-editor-cRLC-eBK.js +1196 -0
  462. package/dist/rich-text-editor-cRLC-eBK.js.map +1 -0
  463. package/dist/rich-text-editor-toolbar-DfXg0-VC.js +94 -0
  464. package/dist/rich-text-editor-toolbar-DfXg0-VC.js.map +1 -0
  465. package/dist/rich-text-editor.strings-CB59ekH2.js +38 -0
  466. package/dist/rich-text-editor.strings-CB59ekH2.js.map +1 -0
  467. package/dist/safe-image-src-C6kQSMBZ.js +17 -0
  468. package/dist/safe-image-src-C6kQSMBZ.js.map +1 -0
  469. package/dist/sanitize-html-DsQmI48u.js +92 -0
  470. package/dist/sanitize-html-DsQmI48u.js.map +1 -0
  471. package/dist/scroll-area-DcI-M1UT.js +48 -0
  472. package/dist/scroll-area-DcI-M1UT.js.map +1 -0
  473. package/dist/{separator-Do5GWDYi.js → separator-BDV-Y648.js} +3 -3
  474. package/dist/{separator-Do5GWDYi.js.map → separator-BDV-Y648.js.map} +1 -1
  475. package/dist/{separator-BMEvwnSX.js → separator-Bom7NsGO.js} +2 -2
  476. package/dist/{separator-BMEvwnSX.js.map → separator-Bom7NsGO.js.map} +1 -1
  477. package/dist/services/actions/action-adapters.d.ts +18 -0
  478. package/dist/services/actions/index.d.ts +1 -1
  479. package/dist/services/actions.js +16 -4
  480. package/dist/services/actions.js.map +1 -1
  481. package/dist/settings-ybnjVwbd.js +171 -0
  482. package/dist/settings-ybnjVwbd.js.map +1 -0
  483. package/dist/sheet-CGpB3omz.js +211 -0
  484. package/dist/sheet-CGpB3omz.js.map +1 -0
  485. package/dist/{sidebar-Cb8WzOvE.js → sidebar-A0ElHINE.js} +17 -16
  486. package/dist/sidebar-A0ElHINE.js.map +1 -0
  487. package/dist/{sidebar-Crc9M9JV.js → sidebar-CPx_7YBa.js} +205 -203
  488. package/dist/sidebar-CPx_7YBa.js.map +1 -0
  489. package/dist/{skeleton-DVMXr15h.js → skeleton-Byjnt7qr.js} +9 -9
  490. package/dist/{skeleton-DVMXr15h.js.map → skeleton-Byjnt7qr.js.map} +1 -1
  491. package/dist/smart-card-DiC5aac3.js +604 -0
  492. package/dist/smart-card-DiC5aac3.js.map +1 -0
  493. package/dist/{structure-hzCW-XsV.js → structure-BmisBK-3.js} +2 -2
  494. package/dist/{structure-hzCW-XsV.js.map → structure-BmisBK-3.js.map} +1 -1
  495. package/dist/style.css +1 -1
  496. package/dist/surface-recipes-BKRVW8Os.js +43 -0
  497. package/dist/surface-recipes-BKRVW8Os.js.map +1 -0
  498. package/dist/table-BweFy_P9.js +1530 -0
  499. package/dist/table-BweFy_P9.js.map +1 -0
  500. package/dist/table-DsfzoUia.js +175 -0
  501. package/dist/table-DsfzoUia.js.map +1 -0
  502. package/dist/tabs-CDocW5D1.js +191 -0
  503. package/dist/tabs-CDocW5D1.js.map +1 -0
  504. package/dist/text-inputs-f9Ia-aCi.js +353 -0
  505. package/dist/text-inputs-f9Ia-aCi.js.map +1 -0
  506. package/dist/theme-mode-css-BB-_RYab.js +14 -0
  507. package/dist/theme-mode-css-BB-_RYab.js.map +1 -0
  508. package/dist/theme-scope-BJ6eE2xt.js +50 -0
  509. package/dist/theme-scope-BJ6eE2xt.js.map +1 -0
  510. package/dist/theme.css +285 -228
  511. package/dist/themes/green.css +16 -12
  512. package/dist/timelines-CwM_9IhD.js +457 -0
  513. package/dist/timelines-CwM_9IhD.js.map +1 -0
  514. package/dist/tone-recipes-BPsRAvhu.js +73 -0
  515. package/dist/tone-recipes-BPsRAvhu.js.map +1 -0
  516. package/dist/tooltip-yiRJUFjp.js +111 -0
  517. package/dist/tooltip-yiRJUFjp.js.map +1 -0
  518. package/dist/{tree-BotPlyiD.js → tree-WnKQzwbq.js} +69 -67
  519. package/dist/tree-WnKQzwbq.js.map +1 -0
  520. package/dist/typography/rich-text.js +1 -1
  521. package/dist/typography-UTnveOEy.js +117 -0
  522. package/dist/typography-UTnveOEy.js.map +1 -0
  523. package/dist/typography.js +2 -2
  524. package/dist/{ui-provider-D2_TeLqw.js → ui-provider-C_U0Xma4.js} +13 -5
  525. package/dist/ui-provider-C_U0Xma4.js.map +1 -0
  526. package/dist/ui-provider.js +3 -3
  527. package/dist/{upload-B0WHW7ak.js → upload-CXyxmQBP.js} +210 -209
  528. package/dist/upload-CXyxmQBP.js.map +1 -0
  529. package/dist/{upload-queue-BHZ_wBfd.js → upload-queue-Boscubn9.js} +111 -111
  530. package/dist/upload-queue-Boscubn9.js.map +1 -0
  531. package/dist/upload.recipes-BbxTqrCT.js +61 -0
  532. package/dist/upload.recipes-BbxTqrCT.js.map +1 -0
  533. package/dist/{usage-card-U0YBLTNT.js → usage-card-BhO5eqkX.js} +45 -29
  534. package/dist/usage-card-BhO5eqkX.js.map +1 -0
  535. package/dist/{utils-Cospvlj1.js → utils-BRhFDwuU.js} +114 -67
  536. package/dist/utils-BRhFDwuU.js.map +1 -0
  537. package/dist/value-inputs-DXPDjvBU.js +963 -0
  538. package/dist/value-inputs-DXPDjvBU.js.map +1 -0
  539. package/dist/{value-typography-Deb3yQZg.js → value-typography-BP8OG6h5.js} +2 -2
  540. package/dist/{value-typography-Deb3yQZg.js.map → value-typography-BP8OG6h5.js.map} +1 -1
  541. package/dist/workspace-Cdrg7k9f.js +408 -0
  542. package/dist/workspace-Cdrg7k9f.js.map +1 -0
  543. package/docs/consumer-skill/SKILL.md +21 -22
  544. package/docs/consumer-skill/examples/app-layout.tsx +1 -1
  545. package/docs/consumer-skill/examples/composition.tsx +3 -3
  546. package/docs/consumer-skill/examples/detail.tsx +59 -12
  547. package/docs/consumer-skill/examples/edit.tsx +1 -1
  548. package/docs/consumer-skill/examples/receipt.tsx +2 -2
  549. package/docs/consumer-skill/examples/scoped-directory.tsx +1 -1
  550. package/docs/consumer-skill/examples/website.tsx +1 -1
  551. package/docs/consumer-skill/references/agents-md.md +33 -0
  552. package/docs/consumer-skill/references/analytics.md +1 -1
  553. package/docs/consumer-skill/references/composition.md +58 -13
  554. package/docs/consumer-skill/references/design-contract.md +12 -3
  555. package/docs/consumer-skill/references/installation.md +11 -1
  556. package/docs/consumer-skill/references/integration.md +4 -3
  557. package/docs/consumer-skill/references/public-api.json +956 -453
  558. package/docs/consumer-skill/references/review.md +32 -5
  559. package/docs/consumer-skill/references/theming.md +78 -9
  560. package/docs/consumer-skill/references/tokens.json +1 -1
  561. package/docs/consumer-skill/references/workflows.md +54 -10
  562. package/docs/consumer-skill/scripts/composition-policy.mjs +42 -11
  563. package/docs/consumer-skill/scripts/surface-policy.mjs +150 -5
  564. package/package.json +17 -5
  565. package/dist/accordion-CQXVcd7Q.js +0 -205
  566. package/dist/accordion-CQXVcd7Q.js.map +0 -1
  567. package/dist/action-menu-BTpyPWJ2.js +0 -264
  568. package/dist/action-menu-BTpyPWJ2.js.map +0 -1
  569. package/dist/affordance-geometry.generated-CCIXb2A1.js +0 -68
  570. package/dist/affordance-geometry.generated-CCIXb2A1.js.map +0 -1
  571. package/dist/ai-artifact-2PQ2fItc.js +0 -1112
  572. package/dist/ai-artifact-2PQ2fItc.js.map +0 -1
  573. package/dist/attachment-q69dlt5Y.js +0 -244
  574. package/dist/attachment-q69dlt5Y.js.map +0 -1
  575. package/dist/auth-M3vGMgDR.js.map +0 -1
  576. package/dist/avatar-djdaaQ_s.js.map +0 -1
  577. package/dist/badge-0tATj-tW.js +0 -92
  578. package/dist/badge-0tATj-tW.js.map +0 -1
  579. package/dist/breadcrumbs-BG_FfMK4.js +0 -128
  580. package/dist/breadcrumbs-BG_FfMK4.js.map +0 -1
  581. package/dist/button-BS3KDg00.js.map +0 -1
  582. package/dist/button-R9CCoH7A.js.map +0 -1
  583. package/dist/buttons-DS0ZIwJ_.js +0 -99
  584. package/dist/buttons-DS0ZIwJ_.js.map +0 -1
  585. package/dist/cards-QoJ4syG9.js +0 -66
  586. package/dist/cards-QoJ4syG9.js.map +0 -1
  587. package/dist/chart-DwYRKKc-.js.map +0 -1
  588. package/dist/checkbox-B7ygNTYp.js +0 -35
  589. package/dist/checkbox-B7ygNTYp.js.map +0 -1
  590. package/dist/choice-inputs-DrJ17tpL.js +0 -752
  591. package/dist/choice-inputs-DrJ17tpL.js.map +0 -1
  592. package/dist/code-block-CD0B7M93.js +0 -183
  593. package/dist/code-block-CD0B7M93.js.map +0 -1
  594. package/dist/combobox-6dvVny2q.js +0 -272
  595. package/dist/combobox-6dvVny2q.js.map +0 -1
  596. package/dist/combobox-CB7039j7.js +0 -865
  597. package/dist/combobox-CB7039j7.js.map +0 -1
  598. package/dist/comments-You0Bzbr.js.map +0 -1
  599. package/dist/components/layout/page/partials/page-header-commands.d.ts +0 -13
  600. package/dist/containers-D_L4mTVb.js.map +0 -1
  601. package/dist/data-display-3xWQUnMA.js +0 -1335
  602. package/dist/data-display-3xWQUnMA.js.map +0 -1
  603. package/dist/date-picker-DrDFj8Lo.js +0 -1527
  604. package/dist/date-picker-DrDFj8Lo.js.map +0 -1
  605. package/dist/date-pickers-CnFCb0n2.js +0 -174
  606. package/dist/date-pickers-CnFCb0n2.js.map +0 -1
  607. package/dist/display-DrdvPwF0.js +0 -343
  608. package/dist/display-DrdvPwF0.js.map +0 -1
  609. package/dist/dropdown-menu-CURh59jb.js +0 -193
  610. package/dist/dropdown-menu-CURh59jb.js.map +0 -1
  611. package/dist/editable-text-recipe-Bkm6wKHp.js +0 -10
  612. package/dist/editable-text-recipe-Bkm6wKHp.js.map +0 -1
  613. package/dist/feedback-C7nR0UtT.js +0 -232
  614. package/dist/feedback-C7nR0UtT.js.map +0 -1
  615. package/dist/field-affordance-recipes-CkOCdE2y.js +0 -46
  616. package/dist/field-affordance-recipes-CkOCdE2y.js.map +0 -1
  617. package/dist/field-state-recipes-C-MFBX_8.js +0 -11
  618. package/dist/field-state-recipes-C-MFBX_8.js.map +0 -1
  619. package/dist/filters-Da-gNPsE.js.map +0 -1
  620. package/dist/form-field-VZRULhUK.js.map +0 -1
  621. package/dist/form-sizing-uWP4lzVh.js.map +0 -1
  622. package/dist/forms-numeric-D3CO60IF.js +0 -905
  623. package/dist/forms-numeric-D3CO60IF.js.map +0 -1
  624. package/dist/header-2ycNqGOR.js.map +0 -1
  625. package/dist/icon-badge-DKlaKXoo.js +0 -53
  626. package/dist/icon-badge-DKlaKXoo.js.map +0 -1
  627. package/dist/input-BoLm9Hks.js +0 -20
  628. package/dist/input-BoLm9Hks.js.map +0 -1
  629. package/dist/input-DhQdBnV3.js +0 -255
  630. package/dist/input-DhQdBnV3.js.map +0 -1
  631. package/dist/item-xzh8Df65.js +0 -264
  632. package/dist/item-xzh8Df65.js.map +0 -1
  633. package/dist/media-gallery-DQUQ0m3O.js +0 -201
  634. package/dist/media-gallery-DQUQ0m3O.js.map +0 -1
  635. package/dist/mentions-DwnO1hh4.js +0 -564
  636. package/dist/mentions-DwnO1hh4.js.map +0 -1
  637. package/dist/message-YfFmbXNP.js.map +0 -1
  638. package/dist/navigation-Cbp5V8gG.js +0 -264
  639. package/dist/navigation-Cbp5V8gG.js.map +0 -1
  640. package/dist/navigation-Cs1npsPm.js +0 -300
  641. package/dist/navigation-Cs1npsPm.js.map +0 -1
  642. package/dist/overlay.recipes-CNO2S9V6.js +0 -34
  643. package/dist/overlay.recipes-CNO2S9V6.js.map +0 -1
  644. package/dist/overlays-DhZO7N-I.js +0 -994
  645. package/dist/overlays-DhZO7N-I.js.map +0 -1
  646. package/dist/page-C6R_8jFt.js +0 -325
  647. package/dist/page-C6R_8jFt.js.map +0 -1
  648. package/dist/page-header-hUTzcRZX.js +0 -112
  649. package/dist/page-header-hUTzcRZX.js.map +0 -1
  650. package/dist/pagination-Cm0jqa3I.js +0 -149
  651. package/dist/pagination-Cm0jqa3I.js.map +0 -1
  652. package/dist/popover-Dcv_9jxr.js.map +0 -1
  653. package/dist/popover-menu-DnRFKnHP.js +0 -99
  654. package/dist/popover-menu-DnRFKnHP.js.map +0 -1
  655. package/dist/popover.recipes-wmbvL8Ah.js.map +0 -1
  656. package/dist/primitives-BHrwQXFC.js.map +0 -1
  657. package/dist/rich-text-editor-CF8QYt5p.js +0 -574
  658. package/dist/rich-text-editor-CF8QYt5p.js.map +0 -1
  659. package/dist/rich-text-editor.recipes-CnrbmTS1.js +0 -81
  660. package/dist/rich-text-editor.recipes-CnrbmTS1.js.map +0 -1
  661. package/dist/rich-text-editor.strings-BpnIQgMl.js +0 -25
  662. package/dist/rich-text-editor.strings-BpnIQgMl.js.map +0 -1
  663. package/dist/rich-text-j-FGAeZW.js +0 -32
  664. package/dist/rich-text-j-FGAeZW.js.map +0 -1
  665. package/dist/sanitize-html-BG9FGe-j.js +0 -64
  666. package/dist/sanitize-html-BG9FGe-j.js.map +0 -1
  667. package/dist/scroll-area-DRdr16Pt.js +0 -47
  668. package/dist/scroll-area-DRdr16Pt.js.map +0 -1
  669. package/dist/settings-DHk0L2MF.js +0 -161
  670. package/dist/settings-DHk0L2MF.js.map +0 -1
  671. package/dist/sheet-DRFNY1_D.js +0 -207
  672. package/dist/sheet-DRFNY1_D.js.map +0 -1
  673. package/dist/sidebar-Cb8WzOvE.js.map +0 -1
  674. package/dist/sidebar-Crc9M9JV.js.map +0 -1
  675. package/dist/smart-card-Bek-TwUp.js +0 -599
  676. package/dist/smart-card-Bek-TwUp.js.map +0 -1
  677. package/dist/spinner-CmTAbEp0.js +0 -80
  678. package/dist/spinner-CmTAbEp0.js.map +0 -1
  679. package/dist/surface-recipes-DOdoBXGm.js +0 -28
  680. package/dist/surface-recipes-DOdoBXGm.js.map +0 -1
  681. package/dist/table-D6zKeYQX.js +0 -162
  682. package/dist/table-D6zKeYQX.js.map +0 -1
  683. package/dist/table-Dn4XSrSB.js +0 -1444
  684. package/dist/table-Dn4XSrSB.js.map +0 -1
  685. package/dist/tabs-Dk8E_knt.js +0 -189
  686. package/dist/tabs-Dk8E_knt.js.map +0 -1
  687. package/dist/text-inputs-BFpku0Qd.js +0 -331
  688. package/dist/text-inputs-BFpku0Qd.js.map +0 -1
  689. package/dist/theme-scope-kStaAer0.js +0 -39
  690. package/dist/theme-scope-kStaAer0.js.map +0 -1
  691. package/dist/timelines-CxuAFIc2.js +0 -439
  692. package/dist/timelines-CxuAFIc2.js.map +0 -1
  693. package/dist/tree-BotPlyiD.js.map +0 -1
  694. package/dist/typography-CAr3dQhX.js +0 -116
  695. package/dist/typography-CAr3dQhX.js.map +0 -1
  696. package/dist/ui-provider-D2_TeLqw.js.map +0 -1
  697. package/dist/upload-B0WHW7ak.js.map +0 -1
  698. package/dist/upload-queue-BHZ_wBfd.js.map +0 -1
  699. package/dist/usage-card-U0YBLTNT.js.map +0 -1
  700. package/dist/use-file-drop-target-BX7GnhoQ.js +0 -39
  701. package/dist/use-file-drop-target-BX7GnhoQ.js.map +0 -1
  702. package/dist/utils-Cospvlj1.js.map +0 -1
  703. package/dist/value-inputs-CjfzGMsN.js +0 -854
  704. package/dist/value-inputs-CjfzGMsN.js.map +0 -1
  705. package/dist/workspace-YoFjXi6i.js +0 -394
  706. package/dist/workspace-YoFjXi6i.js.map +0 -1
  707. /package/dist/components/{blocks/data-display/metadata → base/metadata-list}/metadata-list.strings.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments-BYYlTA8E.js","names":["ImageIcon","_Fragment","NumberValue","_Fragment","useCommentsUIDefaults","useCommentsConfig","useDatesConfig","cn","Button","TextButton","Text","DisplayLabel","TextLink","TooltipTrigger","TooltipContent","TooltipProvider","Tooltip","Stack","toneRecipes","rowBlockPaddingClasses","useOverlayVisibility","ConfirmDialog","interactionRecipes","sanitizeHtml","contentTypographyClassName","RichText","SecondaryValue","FileSize","Percent","Number$1","RelativeTime","AvatarFallback","Avatar","AvatarImage","Badge","fieldAffordanceRecipes","PopoverTrigger","Popover","EmptyState","RichTextEditor","useMentions","MentionInlineSuggestions","MentionContent","MentionPicker","parseMentionsFromHtml","Fragment$1","defaultCommentsStrings","useResolvedStrings","useStrings","propStrings","useResolvedAccessors","dates","useMemo","propAccessors","useComments","options","composerMode","setComposerMode","useState","isSubmitting","setIsSubmitting","isSubmittingRef","useRef","formErrors","setFormErrors","resetKey","setResetKey","setSubmitting","useCallback","submitting","resetComposer","k","helpers","reportError","error","onError","comment","onUpdate","payload","values","onAfterMutate","onSubmit","onDelete","id","pickIcon","att","Image","FileText","File","Paperclip","CommentAttachmentChip","stringsProp","strings","url","accessors","attachment","name","Icon","isUploading","isFailed","meta","surface","compact","className","iconNode","Loader2","labelRow","onRetry","editable","onRemove","X","defaultAttachmentUploadStrings","useAttachmentUpload","attachments","setAttachmentsState","initialAttachments","inFlightRef","fileCacheRef","attachmentsRef","commitAttachments","list","next","onValueChangeRef","onValueChange","updateAttachment","a","patch","setAttachments","beginUpload","onUpload","controller","uploaded","message","err","addFiles","disabled","files","filesInput","pending","file","maxFiles","maxSize","removeAttachment","entry","retryAttachment","reset","useEffect","inFlight","cache","hasMeaningfulContent","html","CommentComposer","forwardRef","resourcesProp","onResourceSearchProp","attachmentsProp","maxAttachmentsProp","allowAttachmentsProp","resources","onResourceSearch","allowAttachments","maxAttachments","attachmentsConfig","editorRef","body","setBody","initialValues","editingComment","contentError","setContentError","attachmentError","setAttachmentError","mentions","attachmentUpload","handleCancel","onCancel","useImperativeHandle","ref","context","errors","handleSubmit","event","replyingTo","fileInputRef","handleAttachmentClick","handleFiles","hasAttachments","isEditing","isReplying","submitLabel","eyebrow","ComposerEyebrow","makeReplyEyebrow","extraToolbarItems","items","AtSign","canComment","submitButton","cancelButton","attachmentChips","footerSlot","trailingSubmit","inlineSubmit","showFooterRow","kind","parsed","previous","m","byId","merged","p","placeholder","autoFocus","label","onClose","closeLabel","interpolateString","template","CommentEmpty","icon","MessageCircle","CommentContent","props","contentType","richContent","renderRichContent","renderReference","plainContent","decodeQuotedString","rawContent","Fragment","renderRichBlock","block","index","decoded","data","raw","text","stripHtml","level","createElement","sanitizedItems","item","caption","value","trimmed","FALLBACK_INITIAL","defaultGetMediaUrl","defaultGetMediaName","defaultGetStatusLabel","s","CommentItem","memo","allowReactionsProp","allowRepliesProp","allowReactions","allowReplies","resolvedGetMediaUrl","resolvedGetMediaName","resolvedGetStatusLabel","resolvedFormatRelativeTime","authorName","avatarUrl","fallbackInitial","tagList","tag","reactions","isPinned","isEdited","showStatus","statusLabel","canDeleteComment","canModerate","canEditComment","canReply","onReply","canReact","onReact","canPin","onPinToggle","canEdit","onEdit","canDelete","hasActions","attachmentConfirm","pendingAttachmentId","setPendingAttachmentId","requestAttachmentRemoval","attachmentId","Pin","renderAttachment","canRemoveAttachment","onAttachmentRemove","reaction","CornerDownRight","Smile","Pencil","Trash2","CommentTimeline","comments","defaultItem","renderItem","emptySlot","Comments","ui","composerPosition","title","confirmDelete","deleteConfirm","pendingDeleteId","setPendingDeleteId","commentsState","requestDelete","startReply","handleReply","commentId","composer","timeline","composerBlock","inner","ariaLabel"],"sources":["../src/components/features/comments/comments.strings.ts","../src/components/features/comments/comments-provider.tsx","../src/components/features/comments/hooks/use-comments.ts","../src/components/features/comments/partials/comment-attachment-chip.tsx","../src/components/features/comments/hooks/use-attachment-upload.ts","../src/components/features/comments/partials/comment-composer.tsx","../src/components/features/comments/partials/comment-empty.tsx","../src/components/features/comments/partials/comment-content.tsx","../src/components/features/comments/partials/comment-item.tsx","../src/components/features/comments/partials/comment-timeline.tsx","../src/components/features/comments/comments.tsx"],"sourcesContent":["/**\n * Strings for the Comments feature. Consumers override via the `strings`\n * prop on `<Comments>` / sub-components — values are\n * deep-merged over these defaults.\n */\nexport interface CommentsStrings {\n\t/** Card title — usually \"Comments\". Set to \"\" to hide. */\n\ttitle: string;\n\t/** Subtitle under the card title — optional. */\n\tsubtitle: string;\n\t/** Empty-state copy for the timeline. */\n\tempty: string;\n\t/** Empty-state secondary copy. */\n\temptyHint: string;\n\n\t// Composer ---------------------------------------------------------\n\t/** Composer rich-text placeholder. */\n\tcomposerPlaceholder: string;\n\t/** Submit label for new comments. */\n\tcomposerSubmit: string;\n\t/** Submit label while pending. */\n\tcomposerSubmitting: string;\n\t/** Submit label when editing. */\n\tcomposerSave: string;\n\t/** Required-content error. */\n\tinvalidContent: string;\n\t/** Cancel/dismiss draft. */\n\tcomposerCancel: string;\n\t/** \"Edit comment\" eyebrow shown above the composer in edit mode. */\n\tcomposerEditingEyebrow: string;\n\t/** \"Reply to {{name}}\" eyebrow shown above the composer in reply mode. */\n\tcomposerReplyingEyebrow: string;\n\n\t// Toolbar buttons --------------------------------------------------\n\tcomposerAttachmentLabel: string;\n\t/** Control that inserts a mention or link. */\n\tcomposerReferenceLabel: string;\n\t/** Heading of the insert-reference menu. */\n\tcomposerReferenceMenuTitle: string;\n\t/** Placeholder in the reference search field. */\n\tcomposerReferenceSearchPlaceholder: string;\n\t/** Shown when a reference search matches nothing. */\n\tcomposerReferenceEmpty: string;\n\t/** Shown while reference results are loading. */\n\tcomposerReferenceLoading: string;\n\n\t// Item -------------------------------------------------------------\n\tfallbackAuthor: string;\n\t/** Chip marking a pinned comment. */\n\tpinned: string;\n\t/** Suffix marking an edited comment. */\n\tedited: string;\n\t/** Trash button aria-label / tooltip. */\n\tdeleteLabel: string;\n\t/** Edit button label. */\n\teditLabel: string;\n\t/** Reply button label. */\n\treplyLabel: string;\n\t/** Pin/unpin button label. */\n\tpinLabel: string;\n\t/** Action that unpins a comment. */\n\tunpinLabel: string;\n\t/** \"More actions\" trigger aria-label. */\n\tmoreActionsLabel: string;\n\t/** Confirm-delete button label inside the action menu. */\n\tconfirmDeleteLabel: string;\n\t/** Title of the confirmation shown before a comment is deleted. */\n\tconfirmDeleteTitle: string;\n\t/** Title of the confirmation shown before an attachment is removed. */\n\tconfirmRemoveAttachmentTitle: string;\n\t/** Consequence of removing an attachment from a posted comment. */\n\tconfirmRemoveAttachmentDescription: string;\n\t/** Sentence explaining the consequence before the delete is committed. */\n\tconfirmDeleteDescription: string;\n\n\t// Attachments ------------------------------------------------------\n\tattachmentFallback: string;\n\t/** Removes an attachment — staged in the composer, or posted on a comment. */\n\tattachmentRemoveLabel: string;\n\t/** Shown while an attachment uploads. */\n\tattachmentUploadingLabel: string;\n\t/** Shown when an attachment upload fails. */\n\tattachmentFailedLabel: string;\n\t/** Shown when a file exceeds the size limit. */\n\tattachmentTooLargeError: string;\n\t/** Shown when too many files are attached. */\n\tattachmentTooManyError: string;\n\t/** Action that retries a failed upload. */\n\tattachmentRetryLabel: string;\n\t/** Action that downloads an attachment. */\n\tattachmentDownloadLabel: string;\n\n\t// Reactions --------------------------------------------------------\n\taddReactionLabel: string;\n\t/** Reaction button name; interpolates {{emoji}} and {{count}}. Optional for existing complete string objects. */\n\treactionLabel?: string;\n\n\t// Misc -------------------------------------------------------------\n\tshowRepliesLabel: string;\n\t/** Control that collapses a reply thread. */\n\thideRepliesLabel: string;\n}\n\nexport const defaultCommentsStrings: CommentsStrings = {\n\ttitle: 'Comments',\n\tsubtitle: '',\n\tempty: 'No comments yet.',\n\temptyHint: 'Start the conversation — your team will see it instantly.',\n\n\tcomposerPlaceholder: 'Write a comment…',\n\tcomposerSubmit: 'Post comment',\n\tcomposerSubmitting: 'Posting…',\n\tcomposerSave: 'Save changes',\n\tinvalidContent: 'Comment cannot be empty.',\n\tcomposerCancel: 'Cancel',\n\tcomposerEditingEyebrow: 'Editing comment',\n\tcomposerReplyingEyebrow: 'Replying to {{name}}',\n\n\tcomposerAttachmentLabel: 'Attach file',\n\tcomposerReferenceLabel: 'Mention or link',\n\tcomposerReferenceMenuTitle: 'Insert reference',\n\tcomposerReferenceSearchPlaceholder: 'Search…',\n\tcomposerReferenceEmpty: 'No matches.',\n\tcomposerReferenceLoading: 'Searching…',\n\n\tfallbackAuthor: 'Anonymous',\n\tpinned: 'Pinned',\n\tedited: 'edited',\n\tdeleteLabel: 'Delete',\n\teditLabel: 'Edit',\n\treplyLabel: 'Reply',\n\tpinLabel: 'Pin',\n\tunpinLabel: 'Unpin',\n\tmoreActionsLabel: 'More actions',\n\tconfirmDeleteLabel: 'Delete comment',\n\tconfirmDeleteTitle: 'Delete this comment?',\n\tconfirmRemoveAttachmentTitle: 'Remove this attachment?',\n\tconfirmRemoveAttachmentDescription: 'The file is detached from the comment for everyone. This cannot be undone.',\n\tconfirmDeleteDescription: 'The comment and its replies are removed for everyone. This cannot be undone.',\n\n\tattachmentFallback: 'Attachment',\n\tattachmentRemoveLabel: 'Remove attachment',\n\tattachmentUploadingLabel: 'Uploading…',\n\tattachmentFailedLabel: 'Upload failed',\n\tattachmentTooLargeError: 'File is too large.',\n\tattachmentTooManyError: 'Too many attachments.',\n\tattachmentRetryLabel: 'Retry',\n\tattachmentDownloadLabel: 'Download',\n\n\taddReactionLabel: 'Add reaction',\n\treactionLabel: 'Reaction {{emoji}}: {{count}}',\n\n\tshowRepliesLabel: 'Show replies',\n\thideRepliesLabel: 'Hide replies',\n};\n","/**\n * Comments — internal helper hooks for resolving strings and accessors.\n *\n * Rationale: the previous `<CommentsProvider>` is gone. Library-wide\n * Per-mount overrides flow as direct props on `<Comments>` and its partials.\n * Date formatting may still inherit the app-wide dates configuration.\n *\n * Resolution order everywhere:\n *\n * props.strings ← deep-merged over `defaultCommentsStrings`\n * props.accessor.X ← falls back to UIProvider's dates formatter, then\n * to a built-in default at the call site.\n */\nimport { useMemo } from 'react';\n\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { useDatesConfig } from '../../../lib/ui-provider';\n\nimport {\n\tdefaultCommentsStrings,\n\ttype CommentsStrings,\n} from './comments.strings';\nimport type { CommentsAccessors } from './comments.types';\n\n/**\n * Resolve final strings by merging defaults → component prop. Stable\n * identity when the prop reference is unchanged.\n */\nexport function useResolvedStrings(\n\tpropStrings?: StringsProp<CommentsStrings>,\n): CommentsStrings {\n\treturn useStrings(defaultCommentsStrings, propStrings);\n}\n\n/**\n * Resolve accessors. Order:\n * 1. explicit prop accessor\n * 2. the UIProvider date formatter for relative time\n * 3. caller's own fallback when neither is present (handled at call site)\n */\nexport function useResolvedAccessors(\n\tpropAccessors?: CommentsAccessors,\n): CommentsAccessors {\n\tconst dates = useDatesConfig();\n\treturn useMemo<CommentsAccessors>(\n\t\t() => ({\n\t\t\tgetMediaUrl: propAccessors?.getMediaUrl,\n\t\t\tgetMediaName: propAccessors?.getMediaName,\n\t\t\tgetStatusLabel: propAccessors?.getStatusLabel,\n\t\t\tformatRelativeTime:\n\t\t\t\tpropAccessors?.formatRelativeTime ?? dates.formatRelativeTime,\n\t\t}),\n\t\t[propAccessors, dates.formatRelativeTime],\n\t);\n}\n","/**\n * useComments — headless state machine for the Comments feature.\n *\n * Tracks composer mode (idle | replying | editing), submit/delete\n * helpers, error state, and resetKey bumping. The default `<Comments>`\n * component composes this hook; consumers building a fully custom UI\n * can use it directly.\n */\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\nimport type {\n\tCommentData,\n\tCommentFormValues,\n\tCommentSubmitHelpers,\n\tCommentUser,\n\tCommentsConfig,\n} from '../comments.types';\n\nexport type ComposerMode<\n\tTResource extends string = string,\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n> =\n\t| { kind: 'idle' }\n\t| { kind: 'editing'; comment: CommentData<TUser, TMeta, TResource> }\n\t| { kind: 'replying'; commentId: string; authorName?: string };\n\nexport interface UseCommentsOptions<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n> {\n\tonSubmit?: CommentsConfig<TUser, TMeta, TResource>['onSubmit'];\n\tonUpdate?: CommentsConfig<TUser, TMeta, TResource>['onUpdate'];\n\tonDelete?: CommentsConfig<TUser, TMeta, TResource>['onDelete'];\n\tonAfterMutate?: CommentsConfig<TUser, TMeta, TResource>['onAfterMutate'];\n\tonError?: CommentsConfig<TUser, TMeta, TResource>['onError'];\n}\n\nexport interface UseCommentsReturn<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n> {\n\tcomposerMode: ComposerMode<TResource, TUser, TMeta>;\n\tisSubmitting: boolean;\n\tformErrors: Record<string, string>;\n\tresetKey: number;\n\n\tstartReply: (comment: CommentData<TUser, TMeta, TResource>) => void;\n\tstartEdit: (comment: CommentData<TUser, TMeta, TResource>) => void;\n\tcancelComposerMode: () => void;\n\n\tsubmit: (values: CommentFormValues<TResource>) => Promise<void>;\n\tdeleteComment: (id: string) => Promise<void>;\n\n\t/** Imperative reset — bumps `resetKey` so the composer clears itself. */\n\tresetComposer: () => void;\n\t/** Helpers exposed to onSubmit/onUpdate. */\n\thelpers: CommentSubmitHelpers;\n}\n\nexport function useComments<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>(\n\toptions: UseCommentsOptions<TUser, TMeta, TResource> = {},\n): UseCommentsReturn<TUser, TMeta, TResource> {\n\tconst { onSubmit, onUpdate, onDelete, onAfterMutate, onError } = options;\n\n\tconst [composerMode, setComposerMode] = useState<\n\t\tComposerMode<TResource, TUser, TMeta>\n\t>({\n\t\tkind: 'idle',\n\t});\n\tconst [isSubmitting, setIsSubmitting] = useState(false);\n\tconst isSubmittingRef = useRef(false);\n\tconst [formErrors, setFormErrors] = useState<Record<string, string>>({});\n\tconst [resetKey, setResetKey] = useState(0);\n\n\tconst setSubmitting = useCallback((submitting: boolean) => {\n\t\tisSubmittingRef.current = submitting;\n\t\tsetIsSubmitting(submitting);\n\t}, []);\n\n\tconst resetComposer = useCallback(() => {\n\t\tsetResetKey((k) => k + 1);\n\t\tsetComposerMode({ kind: 'idle' });\n\t\tsetFormErrors({});\n\t\tsetSubmitting(false);\n\t}, [setSubmitting]);\n\n\tconst helpers = useMemo<CommentSubmitHelpers>(\n\t\t() => ({\n\t\t\tsetErrors: setFormErrors,\n\t\t\treset: resetComposer,\n\t\t\tsetSubmitting,\n\t\t}),\n\t\t[resetComposer, setSubmitting],\n\t);\n\n\tconst reportError = useCallback(\n\t\t(error: unknown) => {\n\t\t\ttry {\n\t\t\t\tonError?.(error);\n\t\t\t} catch (callbackError) {\n\t\t\t\tif (import.meta.env?.DEV) {\n\t\t\t\t\tconsole.warn('[Comments] onError callback failed.', callbackError);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[onError],\n\t);\n\n\tconst startReply = useCallback(\n\t\t(comment: CommentData<TUser, TMeta, TResource>) => {\n\t\t\tif (!comment.id) return;\n\t\t\tsetFormErrors({});\n\t\t\tsetComposerMode({\n\t\t\t\tkind: 'replying',\n\t\t\t\tcommentId: comment.id,\n\t\t\t\tauthorName: comment.user?.name,\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\tconst startEdit = useCallback(\n\t\t(comment: CommentData<TUser, TMeta, TResource>) => {\n\t\t\tif (!comment.id) return;\n\t\t\tsetFormErrors({});\n\t\t\tsetComposerMode({ kind: 'editing', comment });\n\t\t},\n\t\t[],\n\t);\n\n\tconst cancelComposerMode = useCallback(() => {\n\t\tresetComposer();\n\t}, [resetComposer]);\n\n\tconst submit = useCallback(\n\t\tasync (values: CommentFormValues<TResource>) => {\n\t\t\tif (composerMode.kind === 'editing' && composerMode.comment.id) {\n\t\t\t\tif (!onUpdate) return;\n\t\t\t\tif (isSubmittingRef.current) return;\n\n\t\t\t\tconst payload = {\n\t\t\t\t\t...values,\n\t\t\t\t\teditingId: composerMode.comment.id,\n\t\t\t\t};\n\t\t\t\tsetSubmitting(true);\n\t\t\t\tsetFormErrors({});\n\t\t\t\ttry {\n\t\t\t\t\tawait onUpdate(composerMode.comment.id, payload, helpers);\n\t\t\t\t\tonAfterMutate?.('update', payload);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treportError(error);\n\t\t\t\t} finally {\n\t\t\t\t\tsetSubmitting(false);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!onSubmit) return;\n\t\t\tif (isSubmittingRef.current) return;\n\n\t\t\tconst payload: CommentFormValues<TResource> =\n\t\t\t\tcomposerMode.kind === 'replying'\n\t\t\t\t\t? { ...values, replyToId: composerMode.commentId }\n\t\t\t\t\t: values;\n\n\t\t\tsetSubmitting(true);\n\t\t\tsetFormErrors({});\n\t\t\ttry {\n\t\t\t\tawait onSubmit(payload, helpers);\n\t\t\t\tonAfterMutate?.('create', payload);\n\t\t\t} catch (error) {\n\t\t\t\treportError(error);\n\t\t\t} finally {\n\t\t\t\tsetSubmitting(false);\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tcomposerMode,\n\t\t\thelpers,\n\t\t\tonAfterMutate,\n\t\t\tonSubmit,\n\t\t\tonUpdate,\n\t\t\treportError,\n\t\t\tsetSubmitting,\n\t\t],\n\t);\n\n\tconst deleteComment = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!onDelete || !id) return;\n\t\t\ttry {\n\t\t\t\tawait onDelete(id);\n\t\t\t\tonAfterMutate?.('delete', { commentId: id });\n\t\t\t} catch (error) {\n\t\t\t\treportError(error);\n\t\t\t}\n\t\t},\n\t\t[onAfterMutate, onDelete, reportError],\n\t);\n\n\treturn {\n\t\tcomposerMode,\n\t\tisSubmitting,\n\t\tformErrors,\n\t\tresetKey,\n\t\tstartReply,\n\t\tstartEdit,\n\t\tcancelComposerMode,\n\t\tsubmit,\n\t\tdeleteComment,\n\t\tresetComposer,\n\t\thelpers,\n\t};\n}\n","/**\n * CommentAttachmentChip — small attachment pill used in the composer draft\n * and the timeline. Single inline row: icon + name · size, with progress /\n * error states overlaid on the same line. Editable mode reveals a remove\n * button; failed uploads expose a retry pill.\n */\nimport { File, FileText, Image as ImageIcon, Loader2, Paperclip, X } from 'lucide-react';\nimport type { FC, ReactNode } from 'react';\n\nimport { TextButton } from '../../../base/buttons';\nimport { FileSize, Percent, SecondaryValue } from '../../../primitives';\nimport { Text, TextLink } from '../../../typography';\nimport { useStrings, type StringsProp } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\nimport { rowBlockPaddingClasses } from '../../../../lib/row-recipes';\nimport { fieldAffordanceRecipes } from '../../../../lib/field-affordance-recipes';\n\nimport type {\n\t\tCommentAttachment,\n\t\tCommentsAccessors,\n} from '../comments.types';\nimport {\n\t\tdefaultCommentsStrings,\n\t\ttype CommentsStrings,\n} from '../comments.strings';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { toneRecipes } from '../../../../lib/tone-recipes';\n\nexport interface CommentAttachmentChipProps {\n\t\t/** The attachment this chip represents. */\n\t\tattachment: CommentAttachment;\n\t\t/** Editable mode shows a remove button. */\n\t\teditable?: boolean;\n\t\t/** Fired when an entry is removed. */\n\t\tonRemove?: (id: string) => void;\n\t\t/** Fired when the user retries after an entry failure. */\n\t\tonRetry?: (id: string) => void;\n\t\t/** Reads the fields this surface needs off your own shape. */\n\t\taccessors?: CommentsAccessors;\n\t\t/** Overrides this surface's own copy. */\n\t\tstrings?: StringsProp<CommentsStrings>;\n\t\t/** Compact chips have smaller text and tighter padding. */\n\t\tcompact?: boolean;\n\t\t/** Merged onto the outermost node. */\n\t\tclassName?: string;\n}\n\nfunction pickIcon(att: CommentAttachment) {\n\t\tif (att.mimeType?.startsWith('image/')) return ImageIcon;\n\t\tif (att.mimeType === 'application/pdf') return FileText;\n\t\tif (att.mimeType?.startsWith('text/')) return FileText;\n\t\tif (att.mimeType) return File;\n\t\treturn Paperclip;\n}\n\nexport const CommentAttachmentChip: FC<CommentAttachmentChipProps> = ({\n\t\tattachment,\n\t\teditable = false,\n\t\tonRemove,\n\t\tonRetry,\n\t\taccessors,\n\t\tstrings: stringsProp,\n\t\tcompact = false,\n\t\tclassName,\n}) => {\n\t\tconst strings = useStrings(defaultCommentsStrings, stringsProp);\n\n\t\tconst url = accessors?.getMediaUrl?.(attachment) ?? attachment.url;\n\t\tconst name =\n\t\t\t\taccessors?.getMediaName?.(attachment) ??\n\t\t\t\tattachment.name ??\n\t\t\t\tstrings.attachmentFallback;\n\t\tconst Icon = pickIcon(attachment);\n\n\t\tconst isUploading = attachment.status === 'uploading';\n\t\tconst isFailed = attachment.status === 'failed';\n\t\tconst meta: ReactNode = isUploading\n\t\t\t\t? (\n\t\t\t\t\t\t<SecondaryValue size=\"xs\" className=\"shrink-0\">\n\t\t\t\t\t\t\t\t{strings.attachmentUploadingLabel}\n\t\t\t\t\t\t\t\t{typeof attachment.progress === 'number' ? (\n\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t<Percent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={Math.round(attachment.progress)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tscaled\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\talign=\"left\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</SecondaryValue>\n\t\t\t\t)\n\t\t\t\t: isFailed\n\t\t\t\t\t? (\n\t\t\t\t\t\t\t<SecondaryValue size=\"xs\" className=\"shrink-0\">\n\t\t\t\t\t\t\t\t\t{attachment.error ?? strings.attachmentFailedLabel}\n\t\t\t\t\t\t\t</SecondaryValue>\n\t\t\t\t\t)\n\t\t\t\t\t: typeof attachment.size === 'number'\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<FileSize value={attachment.size} size=\"xs\" className=\"shrink-0\" />\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: null;\n\n\t\tconst surface = cn(\n\t\t'comment-attachment-chip--component',\n\t\t\t\t'relative inline-flex min-w-0 max-w-[20rem] items-center gap-space-sm rounded-radius',\n\t\t\t\t'ring-1 ring-inset transition-colors',\n\t\t\t\tcompact ? 'px-control-xs' : 'px-control-sm',\n\t\t\t\trowBlockPaddingClasses.compact,\n\t\t\t\tisFailed\n\t\t\t\t\t\t? `${toneRecipes.destructive.tint} ${toneRecipes.destructive.halo}`\n\t\t\t\t\t\t: `bg-muted ring-border/60 ${interactionRecipes.rowHover}`,\n\t\t\t\tclassName,\n\t\t);\n\n\t\tconst iconNode = isUploading ? (\n\t\t\t\t<Loader2\n\t\t\t\t\t\tclassName={cn('shrink-0 animate-spin text-muted-foreground', 'size-icon-md')}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t/>\n\t\t) : (\n\t\t\t\t<Icon\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'shrink-0',\n\t\t\t\t\t\t\t\t'size-icon-md',\n\t\t\t\t\t\t\t\tisFailed ? 'text-destructive' : 'text-muted-foreground',\n\t\t\t\t\t\t)}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t/>\n\t\t);\n\n\t\tconst labelRow = (\n\t\t\t\t<span className=\"inline-flex min-w-0 items-baseline gap-space-sm\">\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\tweight=\"medium\"\n\t\t\t\t\t\t\t\tclassName={cn('truncate', isFailed && 'text-destructive')}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{name}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{meta}\n\t\t\t\t</span>\n\t\t);\n\n\t\tconst isInteractive = !!url && !isUploading && !isFailed;\n\n\t\treturn (\n\t\t\t\t<div className={surface}>\n\t\t\t\t\t\t{iconNode}\n\t\t\t\t\t\t{isInteractive ? (\n\t\t\t\t<TextLink\n\t\t\t\t\thref={url}\n\t\t\t\t\tsize=\"inherit\"\n\t\t\t\t\tunderline={false}\n\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\tclassName=\"inline-flex min-w-0 flex-1 items-baseline gap-space-sm hover:underline\"\n\t\t\t\t\t\t\t\t\t\taria-label={strings.attachmentDownloadLabel}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{labelRow}\n\t\t\t\t</TextLink>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tlabelRow\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{isUploading && typeof attachment.progress === 'number' && (\n\t\t\t\t\t\t\t\t<div className={cn(toneRecipes.primary.line, 'absolute bottom-0 left-2 right-2 h-px overflow-hidden rounded-full')}>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"bg-primary h-full transition-[width]\"\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\twidth: `${Math.min(100, Math.max(0, attachment.progress))}%`,\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{isFailed && onRetry && (\n\t\t\t\t\t\t\t\t<TextButton\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRetry(attachment.id)}\n\t\t\t\t\t\t\t\t\t\tclassName=\"shrink-0 text-destructive decoration-destructive/30 hover:decoration-destructive/60\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" weight=\"medium\" className=\"text-inherit\">{strings.attachmentRetryLabel}</Text>\n\t\t\t\t\t\t\t\t</TextButton>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{editable && onRemove && (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRemove(attachment.id)}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(fieldAffordanceRecipes.target, fieldAffordanceRecipes.focus, fieldAffordanceRecipes.toggle)}\n\t\t\t\t\t\t\t\t\t\taria-label={strings.attachmentRemoveLabel}\n\t\t\t\t\t\t\t\t\t\ttitle={strings.attachmentRemoveLabel}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X className={fieldAffordanceRecipes.icon} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t);\n};\n","/**\n * useAttachmentUpload — manages a list of in-flight + uploaded\n * `CommentAttachment`s for a comment composer.\n *\n * Pass the consumer-supplied `onUpload` callback directly via the\n * `attachments` prop on `<Comments>` (or `<CommentComposer>`). Aborts\n * in-flight uploads when an attachment is removed.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useStrings, type StringsProp } from '../../../../lib/strings';\nimport { defaultCommentsStrings, type CommentsStrings } from '../comments.strings';\n\nimport type {\n\tCommentAttachment,\n\tCommentsAttachmentsConfig,\n} from '../comments.types';\n\ninterface InFlightEntry {\n\tcontroller: AbortController;\n}\n\nconst defaultAttachmentUploadStrings = {\n\tattachmentTooLargeError: defaultCommentsStrings.attachmentTooLargeError,\n\tattachmentTooManyError: defaultCommentsStrings.attachmentTooManyError,\n\tattachmentFailedLabel: defaultCommentsStrings.attachmentFailedLabel,\n};\n\nexport interface UseAttachmentUploadOptions extends CommentsAttachmentsConfig {\n\t/** Initial attachments — useful when editing an existing comment. */\n\tinitialAttachments?: ReadonlyArray<CommentAttachment>;\n\t/** Fires when the list of uploaded attachments changes. */\n\tonValueChange?: (attachments: ReadonlyArray<CommentAttachment>) => void;\n\t/** Fires when a validation or upload error happens. */\n\tonError?: (error: string) => void;\n\t/** Validation and non-Error upload fallback copy; omitted keys use Comments defaults.\n\t * Error objects retain their caller-supplied message. */\n\tstrings?: StringsProp<Pick<CommentsStrings, 'attachmentTooLargeError' | 'attachmentTooManyError' | 'attachmentFailedLabel'>>;\n}\n\nexport interface UseAttachmentUploadReturn {\n\t/** All attachments — uploading + uploaded + failed. */\n\tattachments: ReadonlyArray<CommentAttachment>;\n\t/** Subset of attachments that finished uploading. Use this in the form payload. */\n\tuploadedAttachments: ReadonlyArray<CommentAttachment>;\n\t/** True while at least one upload is in flight. */\n\tisUploading: boolean;\n\t/** Add files. Validates against `maxSize` / `maxFiles` first. */\n\taddFiles: (files: ReadonlyArray<File> | FileList) => void;\n\t/** Remove an attachment by id (aborts in-flight uploads). */\n\tremoveAttachment: (id: string) => void;\n\t/** Retry a failed upload. */\n\tretryAttachment: (id: string) => void;\n\t/** Replace the list (used when editing or after submit). */\n\tsetAttachments: (attachments: ReadonlyArray<CommentAttachment>) => void;\n\t/** Clear the list and abort everything in flight. */\n\treset: () => void;\n}\n\nexport function useAttachmentUpload(\n\toptions: UseAttachmentUploadOptions = {},\n): UseAttachmentUploadReturn {\n\tconst {\n\t\tonUpload,\n\t\tmaxSize,\n\t\tmaxFiles,\n\t\t// `accept` is consumed by the surrounding `<input type=\"file\"\n\t\t// accept>` element, not here — destructuring is intentional\n\t\t// even though we don't reference it inside the hook.\n\t\tdisabled,\n\t\tinitialAttachments,\n\t\tonValueChange,\n\t\tonError,\n\t\tstrings: stringsProp,\n\t} = options;\n\tconst strings = useStrings(defaultAttachmentUploadStrings, stringsProp);\n\n\tconst [attachments, setAttachmentsState] = useState<CommentAttachment[]>(() =>\n\t\tinitialAttachments ? [...initialAttachments] : [],\n\t);\n\tconst inFlightRef = useRef<Map<string, InFlightEntry>>(new Map());\n\tconst fileCacheRef = useRef<Map<string, File>>(new Map());\n\tconst attachmentsRef = useRef(attachments);\n\t// Keep sequential picks and async updates current without calling consumers\n\t// from a React state updater (which StrictMode may evaluate more than once).\n\tconst commitAttachments = useCallback((next: ReadonlyArray<CommentAttachment>) => {\n\t\tconst list = [...next];\n\t\tattachmentsRef.current = list;\n\t\tsetAttachmentsState(list);\n\t}, []);\n\tconst onValueChangeRef = useRef(onValueChange);\n\tonValueChangeRef.current = onValueChange;\n\n\tconst updateAttachment = useCallback(\n\t\t(id: string, patch: Partial<CommentAttachment>) => {\n\t\t\tcommitAttachments(attachmentsRef.current.map((a) => (a.id === id ? { ...a, ...patch } : a)));\n\t\t},\n\t\t[commitAttachments],\n\t);\n\n\tconst setAttachments = useCallback(\n\t\t(next: ReadonlyArray<CommentAttachment>) => {\n\t\t\tcommitAttachments(next);\n\t\t},\n\t\t[commitAttachments],\n\t);\n\n\tconst beginUpload = useCallback(\n\t\t(id: string, file: File) => {\n\t\t\tif (!onUpload || !fileCacheRef.current.has(id)) return;\n\t\t\tconst controller = new AbortController();\n\t\t\tinFlightRef.current.set(id, { controller });\n\n\t\t\tupdateAttachment(id, {\n\t\t\t\tstatus: 'uploading',\n\t\t\t\tprogress: 0,\n\t\t\t\terror: undefined,\n\t\t\t});\n\n\t\t\tconst onProgress = (progress: number) => {\n\t\t\t\tif (controller.signal.aborted) return;\n\t\t\t\tupdateAttachment(id, { progress });\n\t\t\t};\n\n\t\t\tonUpload({ file, onProgress, signal: controller.signal })\n\t\t\t\t.then((uploaded) => {\n\t\t\t\t\tif (controller.signal.aborted) return;\n\t\t\t\t\tinFlightRef.current.delete(id);\n\t\t\t\t\tupdateAttachment(id, {\n\t\t\t\t\t\t...uploaded,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tstatus: 'uploaded',\n\t\t\t\t\t\tprogress: 100,\n\t\t\t\t\t\terror: undefined,\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tinFlightRef.current.delete(id);\n\t\t\t\t\tif (controller.signal.aborted) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst message =\n\t\t\t\t\t\terr instanceof Error ? err.message : strings.attachmentFailedLabel;\n\t\t\t\t\tupdateAttachment(id, {\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t\terror: message,\n\t\t\t\t\t});\n\t\t\t\t\tonError?.(message);\n\t\t\t\t});\n\t\t},\n\t\t[onError, onUpload, strings.attachmentFailedLabel, updateAttachment],\n\t);\n\n\tconst addFiles = useCallback(\n\t\t(filesInput: ReadonlyArray<File> | FileList) => {\n\t\t\tif (disabled || !onUpload) return;\n\t\t\tconst files = Array.from(filesInput);\n\t\t\tif (files.length === 0) return;\n\n\t\t\tconst next = [...attachmentsRef.current];\n\t\t\tconst pending: Array<{id: string; file: File}> = [];\n\t\t\tfor (const file of files) {\n\t\t\t\tif (\n\t\t\t\t\ttypeof maxFiles === 'number' &&\n\t\t\t\t\tnext.length >= maxFiles\n\t\t\t\t) {\n\t\t\t\t\tonError?.(strings.attachmentTooManyError);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\ttypeof maxSize === 'number' &&\n\t\t\t\t\tfile.size > maxSize\n\t\t\t\t) {\n\t\t\t\t\tonError?.(strings.attachmentTooLargeError);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst id =\n\t\t\t\t\ttypeof crypto !== 'undefined' && 'randomUUID' in crypto\n\t\t\t\t\t\t? crypto.randomUUID()\n\t\t\t\t\t\t: `att-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n\t\t\t\tfileCacheRef.current.set(id, file);\n\n\t\t\t\tnext.push({\n\t\t\t\t\tid,\n\t\t\t\t\tname: file.name,\n\t\t\t\t\tsize: file.size,\n\t\t\t\t\tmimeType: file.type,\n\t\t\t\t\tstatus: 'uploading',\n\t\t\t\t\tprogress: 0,\n\t\t\t\t});\n\n\t\t\t\tpending.push({id, file});\n\t\t\t}\n\t\t\tcommitAttachments(next);\n\t\t\tfor (const {id, file} of pending) queueMicrotask(() => beginUpload(id, file));\n\t\t},\n\t\t[beginUpload, commitAttachments, disabled, maxFiles, maxSize, onError, onUpload, strings.attachmentTooLargeError, strings.attachmentTooManyError],\n\t);\n\n\tconst removeAttachment = useCallback((id: string) => {\n\t\tconst entry = inFlightRef.current.get(id);\n\t\tif (entry) {\n\t\t\tentry.controller.abort();\n\t\t\tinFlightRef.current.delete(id);\n\t\t}\n\t\tfileCacheRef.current.delete(id);\n\t\tcommitAttachments(attachmentsRef.current.filter((a) => a.id !== id));\n\t}, [commitAttachments]);\n\n\tconst retryAttachment = useCallback(\n\t\t(id: string) => {\n\t\t\tconst file = fileCacheRef.current.get(id);\n\t\t\tif (!file) return;\n\t\t\tbeginUpload(id, file);\n\t\t},\n\t\t[beginUpload],\n\t);\n\n\tconst reset = useCallback(() => {\n\t\tfor (const entry of inFlightRef.current.values()) {\n\t\t\tentry.controller.abort();\n\t\t}\n\t\tinFlightRef.current.clear();\n\t\tfileCacheRef.current.clear();\n\t\tcommitAttachments([]);\n\t}, [commitAttachments]);\n\n\tuseEffect(() => {\n\t\tonValueChangeRef.current?.(attachments);\n\t}, [attachments]);\n\n\tuseEffect(() => {\n\t\tconst inFlight = inFlightRef.current;\n\t\tconst cache = fileCacheRef.current;\n\t\treturn () => {\n\t\t\tfor (const entry of inFlight.values()) {\n\t\t\t\tentry.controller.abort();\n\t\t\t}\n\t\t\tcache.clear();\n\t\t};\n\t}, []);\n\n\tconst uploadedAttachments = useMemo(\n\t\t() => attachments.filter((a) => a.status === 'uploaded' || !a.status),\n\t\t[attachments],\n\t);\n\n\tconst isUploading = useMemo(\n\t\t() => attachments.some((a) => a.status === 'uploading'),\n\t\t[attachments],\n\t);\n\n\treturn {\n\t\tattachments,\n\t\tuploadedAttachments,\n\t\tisUploading,\n\t\taddFiles,\n\t\tremoveAttachment,\n\t\tretryAttachment,\n\t\tsetAttachments,\n\t\treset,\n\t};\n}\n","/**\n * CommentComposer — TipTap-backed rich text editor with inline reference\n * picker and attachment uploader. Default composer for `<Comments>`.\n *\n * Mention/reference handling is delegated to the shared\n * `features/mentions` module: `useMentions` drives picker state +\n * caret-trigger detection, `<MentionPicker>` renders the popover, and\n * `<MentionChip>` renders draft-list chips. The same primitives power\n * inline references in `features/activities`.\n */\nimport { AtSign, Loader2, Paperclip, X } from 'lucide-react';\nimport {\n\t\tforwardRef,\n\t\tuseEffect,\n\t\tuseImperativeHandle,\n\t\tuseMemo,\n\t\tuseRef,\n\t\tuseState,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport type { ReactElement, RefAttributes } from 'react';\n\nimport { Button } from '../../../base/buttons';\nimport { Popover, PopoverTrigger } from '../../../base/popover';\nimport { Stack } from '../../../base/structure';\nimport { DisplayLabel, Text } from '../../../typography';\nimport {\n\t\tRichTextEditor,\n\t\ttype RichTextEditorHandle,\n\t\ttype RichTextEditorToolbarItem,\n} from '../../rich-text-editor/rich-text-editor';\nimport {\n\t\tMentionInlineSuggestions,\n\t\tMentionPicker,\n\t\tparseMentionsFromHtml,\n\t\tuseMentions,\n} from '../../mentions';\nimport { useResolvedStrings } from '../comments-provider';\nimport { interpolateString } from '../../../../lib/strings';\nimport { rowBlockPaddingClasses } from '../../../../lib/row-recipes';\nimport { cn } from '../../../../lib/utils';\nimport { fieldAffordanceRecipes } from '../../../../lib/field-affordance-recipes';\nimport type {\n\t\tCommentComposerProps,\n\t\tCommentFormValues,\n} from '../comments.types';\nimport { CommentAttachmentChip } from './comment-attachment-chip';\nimport { useAttachmentUpload } from '../hooks/use-attachment-upload';\n\nexport interface CommentComposerHandle {\n\t\tfocus(): void;\n\t\tclear(): void;\n\t\t/** Imperatively set the draft body. */\n\t\tsetBody(html: string): void;\n}\n\nfunction hasMeaningfulContent(html: string): boolean {\n\t\tif (!html || typeof html !== 'string') return false;\n\t\tconst text = html.replace(/<[^>]*>/g, '').trim();\n\t\treturn text.length > 0;\n}\n\nconst CommentComposerBase = forwardRef<\n\t\tCommentComposerHandle,\n\t\tCommentComposerProps\n>(function CommentComposer(\n\t\t{\n\t\t\t\tcontext,\n\t\t\t\tcanComment = true,\n\t\t\t\tsubmitting = false,\n\t\t\t\terrors,\n\t\t\t\tresetKey = 0,\n\t\t\t\tonSubmit,\n\t\t\t\tonCancel,\n\t\t\t\teditingComment,\n\t\t\t\treplyingTo,\n\t\t\t\tstrings: stringsProp,\n\t\t\t\tresources: resourcesProp,\n\t\t\t\tonResourceSearch: onResourceSearchProp,\n\t\t\t\tattachments: attachmentsProp,\n\t\t\t\tmaxAttachments: maxAttachmentsProp,\n\t\t\t\tallowAttachments: allowAttachmentsProp,\n\t\t\t\tinitialValues,\n\t\t\t\tautoFocus = false,\n\t\t\t\tinlineSubmit = true,\n\t\t\t\tplaceholder,\n\t\t},\n\t\tref,\n) {\n\t\tconst strings = useResolvedStrings(stringsProp);\n\t\tconst resources = resourcesProp;\n\t\tconst onResourceSearch = onResourceSearchProp;\n\t\tconst allowAttachments = allowAttachmentsProp ?? true;\n\t\tconst maxAttachments =\n\t\t\t\tattachmentsProp?.maxFiles ??\n\t\t\t\tmaxAttachmentsProp ??\n\t\t\t\t5;\n\t\tconst attachmentsConfig = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\t\t...attachmentsProp,\n\t\t\t\t\t\tmaxFiles: maxAttachments,\n\t\t\t\t\t\tdisabled: attachmentsProp?.disabled === true || !allowAttachments,\n\t\t\t\t}),\n\t\t\t\t[allowAttachments, attachmentsProp, maxAttachments],\n\t\t);\n\n\t\tconst editorRef = useRef<RichTextEditorHandle>(null);\n\t\tconst [body, setBody] = useState<string>(\n\t\t\t\t() => initialValues?.content ?? editingComment?.content ?? '',\n\t\t);\n\t\tconst [contentError, setContentError] = useState<string | null>(null);\n\t\tconst [attachmentError, setAttachmentError] = useState<string | null>(null);\n\n\t\t/**\n\t\t * Mentions state — picker + caret-trigger detection. The hook reads\n\t\t * the editor handle via the ref we pass; on suggestion select it\n\t\t * inserts the chip and replaces the trigger range automatically.\n\t\t */\n\t\tconst mentions = useMentions({\n\t\t\t\tresources,\n\t\t\t\tonResourceSearch,\n\t\t\t\teditorRef,\n\t\t\t\tinitialMentions:\n\t\t\t\t\t\tinitialValues?.references ?? editingComment?.references,\n\t\t});\n\n\t\tconst attachmentUpload = useAttachmentUpload({\n\t\t\t\t...attachmentsConfig,\n\t\t\t\tinitialAttachments: initialValues?.attachments ?? undefined,\n\t\t\t\tstrings,\n\t\t\t\tonError: setAttachmentError,\n\t\t});\n\t\tconst handleCancel = () => {\n\t\t\t\tattachmentUpload.reset();\n\t\t\t\tsetAttachmentError(null);\n\t\t\t\tonCancel?.();\n\t\t};\n\n\t\tuseImperativeHandle(\n\t\t\t\tref,\n\t\t\t\t() => ({\n\t\t\t\t\t\tfocus: () => editorRef.current?.focus(),\n\t\t\t\t\t\tclear: () => {\n\t\t\t\t\t\t\t\teditorRef.current?.clear();\n\t\t\t\t\t\t\t\tmentions.reset();\n\t\t\t\t\t\t\t\tattachmentUpload.reset();\n\t\t\t\t\t\t\t\tsetContentError(null);\n\t\t\t\t\t\t\t\tsetAttachmentError(null);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tsetBody: (html) => {\n\t\t\t\t\t\t\t\teditorRef.current?.setHTML(html);\n\t\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\t[attachmentUpload, mentions],\n\t\t);\n\n\t\t// Reset on context change / resetKey bump\n\t\tuseEffect(() => {\n\t\t\t\teditorRef.current?.setHTML(initialValues?.content ?? '');\n\t\t\t\tmentions.setMentions(initialValues?.references ?? []);\n\t\t\t\tattachmentUpload.reset();\n\t\t\t\tattachmentUpload.setAttachments(initialValues?.attachments ?? []);\n\t\t\t\tsetContentError(null);\n\t\t\t\tsetAttachmentError(null);\n\t\t\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t}, [context.id, context.type, resetKey]);\n\n\t\t// Sync editing comment payload\n\t\tuseEffect(() => {\n\t\t\t\tif (!editingComment) return;\n\t\t\t\teditorRef.current?.setHTML(editingComment.content ?? '');\n\t\t\t\tmentions.setMentions(editingComment.references ?? []);\n\t\t\t\tconst list = (editingComment.attachments ?? []).filter(\n\t\t\t\t\t\t(a): a is NonNullable<typeof a> => !!a,\n\t\t\t\t);\n\t\t\t\tattachmentUpload.reset();\n\t\t\t\tattachmentUpload.setAttachments(list);\n\t\t\t\tsetAttachmentError(null);\n\t\t\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t}, [editingComment?.id]);\n\n\t\t// Surface server-side errors\n\t\tuseEffect(() => {\n\t\t\t\tif (errors?.content) {\n\t\t\t\t\t\tsetContentError(errors.content);\n\t\t\t\t}\n\t\t}, [errors]);\n\n\t\tconst handleSubmit = (event?: React.FormEvent) => {\n\t\t\t\tevent?.preventDefault();\n\t\t\t\tif (submitting || attachmentUpload.isUploading) return;\n\t\t\t\tconst html = editorRef.current?.getHTML() ?? body;\n\t\t\t\tif (!hasMeaningfulContent(html)) {\n\t\t\t\t\t\tsetContentError(strings.invalidContent);\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetContentError(null);\n\n\t\t\t\tconst values: CommentFormValues = {\n\t\t\t\t\t\tcontent: html,\n\t\t\t\t\t\tcommentableId: context.id,\n\t\t\t\t\t\tcommentableType: context.type,\n\t\t\t\t\t\tmoduleKey: context.moduleKey,\n\t\t\t\t\t\tcontentType: 'html',\n\t\t\t\t\t\treferences: mentions.mentions,\n\t\t\t\t\t\tattachments: attachmentUpload.uploadedAttachments,\n\t\t\t\t\t\treplyToId: replyingTo?.commentId ?? initialValues?.replyToId,\n\t\t\t\t\t\teditingId: editingComment?.id,\n\t\t\t\t};\n\n\t\t\t\tonSubmit(values);\n\t\t};\n\n\t\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\t\tconst handleAttachmentClick = () => fileInputRef.current?.click();\n\t\tconst handleFiles = (files: FileList | null) => {\n\t\t\t\tif (!files?.length) return;\n\t\t\t\tsetAttachmentError(null);\n\t\t\t\tattachmentUpload.addFiles(files);\n\t\t};\n\n\t\tconst hasAttachments = attachmentUpload.attachments.length > 0;\n\t\tconst isEditing = !!editingComment;\n\t\tconst isReplying = !isEditing && !!replyingTo;\n\n\t\tconst submitLabel = submitting\n\t\t\t\t? strings.composerSubmitting\n\t\t\t\t: isEditing\n\t\t\t\t\t? strings.composerSave\n\t\t\t\t\t: strings.composerSubmit;\n\n\t\tconst eyebrow: ReactNode = isEditing ? (\n\t\t\t\t<ComposerEyebrow\n\t\t\t\t\t\tlabel={strings.composerEditingEyebrow}\n\t\t\t\t\t\tcloseLabel={strings.composerCancel}\n\t\t\t\t\t\tonClose={onCancel ? handleCancel : undefined}\n\t\t\t\t/>\n\t\t) : isReplying ? (\n\t\t\t\t<ComposerEyebrow\n\t\t\t\t\t\tlabel={makeReplyEyebrow(\n\t\t\t\t\t\t\t\tstrings.composerReplyingEyebrow,\n\t\t\t\t\t\t\t\treplyingTo.authorName,\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tcloseLabel={strings.composerCancel}\n\t\t\t\t\t\tonClose={onCancel ? handleCancel : undefined}\n\t\t\t\t/>\n\t\t) : null;\n\n\t\tconst extraToolbarItems = useMemo<ReadonlyArray<RichTextEditorToolbarItem>>(() => {\n\t\t\t\tconst items: RichTextEditorToolbarItem[] = [];\n\t\t\t\tif (resources && Object.keys(resources).length > 0) {\n\t\t\t\t\t\titems.push({\n\t\t\t\t\t\t\t\tid: 'reference',\n\t\t\t\t\t\t\t\ticon: AtSign,\n\t\t\t\t\t\t\t\tlabel: strings.composerReferenceLabel,\n\t\t\t\t\t\t\t\tonClick: () => mentions.setPickerOpen(true),\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (attachmentsConfig?.onUpload && !attachmentsConfig.disabled) {\n\t\t\t\t\t\titems.push({\n\t\t\t\t\t\t\t\tid: 'attachment',\n\t\t\t\t\t\t\t\ticon: Paperclip,\n\t\t\t\t\t\t\t\tlabel: strings.composerAttachmentLabel,\n\t\t\t\t\t\t\t\tonClick: handleAttachmentClick,\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn items;\n\t\t\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t}, [\n\t\t\t\tresources,\n\t\t\t\tattachmentsConfig?.onUpload,\n\t\t\t\tattachmentsConfig?.disabled,\n\t\t\t\tstrings.composerReferenceLabel,\n\t\t\t\tstrings.composerAttachmentLabel,\n\t\t]);\n\n\t\tif (!canComment) return null;\n\n\t\tconst submitButton = (\n\t\t\t\t<Button tone=\"primary\"\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => handleSubmit()}\n\t\t\t\t\t\tdisabled={submitting || attachmentUpload.isUploading}\n\t\t\t\t\t\ticon={submitting ? Loader2 : undefined}\n\t\t\t\t>\n\t\t\t\t\t\t{submitLabel}\n\t\t\t\t</Button>\n\t\t);\n\n\t\tconst cancelButton = (isEditing || isReplying || onCancel) ? (\n\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tonClick={handleCancel}\n\t\t\t\t\t\tdisabled={submitting}\n\t\t\t\t>\n\t\t\t\t\t\t{strings.composerCancel}\n\t\t\t\t</Button>\n\t\t) : null;\n\n\t\t// Mentions live as inline `<span class=\"rsc-mention\" contenteditable=\"false\">`\n\t\t// chips inside the editor body — they're visible, dismissible (single\n\t\t// backspace deletes the whole span), and the HTML→mentions sync keeps\n\t\t// `mentions.mentions` aligned automatically. Rendering them again as a\n\t\t// chip-list below the editor was redundant and confusing.\n\n\t\tconst attachmentChips = hasAttachments ? (\n\t\t\t\t<Stack direction=\"horizontal\" wrap align=\"center\" gap=\"sm\">\n\t\t\t\t\t\t{attachmentUpload.attachments.map((attachment) => (\n\t\t\t\t\t\t\t\t<CommentAttachmentChip\n\t\t\t\t\t\t\t\t\t\tkey={attachment.id}\n\t\t\t\t\t\t\t\t\t\tattachment={attachment}\n\t\t\t\t\t\t\t\t\t\teditable\n\t\t\t\t\t\t\t\t\t\tonRemove={(id) => { setAttachmentError(null); attachmentUpload.removeAttachment(id); }}\n\t\t\t\t\t\t\t\t\t\tonRetry={(id) => { setAttachmentError(null); attachmentUpload.retryAttachment(id); }}\n\t\t\t\t\t\t\t\t\t\tstrings={stringsProp}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t</Stack>\n\t\t) : null;\n\n\t\tconst footerSlot = hasAttachments ? attachmentChips : null;\n\n\t\tconst trailingSubmit =\n\t\t\t\tinlineSubmit !== false && !isEditing && !isReplying\n\t\t\t\t\t\t? submitButton\n\t\t\t\t\t\t: null;\n\t\tconst showFooterRow = inlineSubmit === false || isEditing || isReplying;\n\n\t\treturn (\n\t\t<Stack render={<form />} gap=\"md\" onSubmit={handleSubmit} className=\"comment-composer--component\">\n\t\t\t\t\t\t{eyebrow}\n\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tref={fileInputRef}\n\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\t\thidden\n\t\t\t\t\t\t\t\taccept={attachmentsConfig?.accept}\n\t\t\t\t\t\t\t\tonChange={(e) => {\n\t\t\t\t\t\t\t\t\t\thandleFiles(e.target.files);\n\t\t\t\t\t\t\t\t\t\te.target.value = '';\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{/* Manual button-click flow: regular popover anchored to the\n\t\t\t\t\t\t\t\thidden trigger. The inline-trigger flow uses the panel\n\t\t\t\t\t\t\t\trendered below — no focus stealing while the user types. */}\n\t\t\t\t\t\t{!mentions.triggerActive && (\n\t\t\t\t\t\t\t\t<Popover open={mentions.pickerOpen} onOpenChange={mentions.setPickerOpen}>\n\t\t\t\t\t\t\t\t\t\t<PopoverTrigger\n\t\t\t\t\t\t\t\t\t\t\t\trender={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"sr-only\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{strings.composerReferenceLabel}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<MentionPicker\n\t\t\t\t\t\t\t\t\t\t\t\topen={mentions.pickerOpen}\n\t\t\t\t\t\t\t\t\t\t\t\tactiveKind={mentions.activeKind}\n\t\t\t\t\t\t\t\t\t\t\t\tsetActiveKind={(kind) => { mentions.setActiveKind(kind); mentions.setManualKindOverride(true); }}\n\t\t\t\t\t\t\t\t\t\t\t\tkinds={mentions.kinds}\n\t\t\t\t\t\t\t\t\t\t\t\tresources={resources}\n\t\t\t\t\t\t\t\t\t\t\t\tquery={mentions.query}\n\t\t\t\t\t\t\t\t\t\t\t\tsetQuery={mentions.setQuery}\n\t\t\t\t\t\t\t\t\t\t\t\tsuggestions={mentions.suggestions}\n\t\t\t\t\t\t\t\t\t\t\t\tloading={mentions.isLoading}\n\t\t\t\t\t\t\t\t\t\t\t\tonSelect={mentions.pickSuggestion}\n\t\t\t\t\t\t\t\t\t\t\t\tstrings={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle: strings.composerReferenceMenuTitle,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsearchPlaceholder: strings.composerReferenceSearchPlaceholder,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tempty: strings.composerReferenceEmpty,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tloading: strings.composerReferenceLoading,\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</Popover>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t<div className=\"comment-composer--editor relative\">\n\t\t\t\t\t\t\t\t<RichTextEditor\n\t\t\t\t\t\t\t\t\t\tref={editorRef}\n\t\t\t\t\t\t\t\t\t\tvalue={body}\n\t\t\t\t\t\t\t\t\t\tonValueChange={(html) => {\n\t\t\t\t\t\t\t\t\t\t\t\tsetBody(html);\n\t\t\t\t\t\t\t\t\t\t\t\t// Sync the draft's mentions list with what's\n\t\t\t\t\t\t\t\t\t\t\t\t// actually present in the HTML — when the user\n\t\t\t\t\t\t\t\t\t\t\t\t// backspaces a chip span out of the body, the\n\t\t\t\t\t\t\t\t\t\t\t\t// chip-list below shrinks too. We merge with\n\t\t\t\t\t\t\t\t\t\t\t\t// the previously-known list so consumer-supplied\n\t\t\t\t\t\t\t\t\t\t\t\t// `href` / `data` payloads survive parsing.\n\t\t\t\t\t\t\t\t\t\t\t\tconst parsed = parseMentionsFromHtml<string>(html);\n\t\t\t\t\t\t\t\t\t\t\t\tconst previous = mentions.mentions;\n\t\t\t\t\t\t\t\t\t\t\t\tconst previousIds = previous.map((m) => m.id).join('|');\n\t\t\t\t\t\t\t\t\t\t\t\tconst currentIds = parsed.map((m) => m.id).join('|');\n\t\t\t\t\t\t\t\t\t\t\t\tif (previousIds !== currentIds) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst byId = new Map(previous.map((m) => [m.id, m]));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst merged = parsed.map(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(p) => byId.get(p.id) ?? p,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmentions.setMentions(merged);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tplaceholder={placeholder ?? strings.composerPlaceholder}\n\t\t\t\t\t\t\t\t\t\tstrings={{\n\t\t\t\t\t\t\t\t\t\t\t\teditorLabel: placeholder ?? strings.composerPlaceholder,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tbodyHeight=\"field\"\n\t\t\t\t\t\t\t\t\t\tautoFocus={autoFocus || isEditing || isReplying}\n\t\t\t\t\t\t\t\t\t\textraToolbarItems={extraToolbarItems}\n\t\t\t\t\t\t\t\t\t\ttoolbarTrailing={trailingSubmit}\n\t\t\t\t\t\t\t\t\t\tfooterSlot={footerSlot}\n\t\t\t\t\t\t\t\t\t\tonCaretChange={mentions.handleCaretChange}\n\t\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t\t<MentionInlineSuggestions\n\t\t\t\t\t\t\t\t\t\topen={mentions.triggerActive && mentions.pickerOpen}\n\t\t\t\t\t\t\t\t\t\tactiveKind={mentions.activeKind}\n\t\t\t\t\t\t\t\t\t\tsetActiveKind={(kind) => { mentions.setActiveKind(kind); mentions.setManualKindOverride(true); }}\n\t\t\t\t\t\t\t\t\t\tkinds={mentions.kinds}\n\t\t\t\t\t\t\t\t\t\tresources={resources}\n\t\t\t\t\t\t\t\t\t\tquery={mentions.query}\n\t\t\t\t\t\t\t\t\t\tsuggestions={mentions.suggestions}\n\t\t\t\t\t\t\t\t\t\tsuggestionsByKind={mentions.suggestionsByKind}\n\t\t\t\t\t\t\t\t\t\tloading={mentions.isLoading}\n\t\t\t\t\t\t\t\t\t\tonSelect={mentions.pickSuggestion}\n\t\t\t\t\t\t\t\t\t\tstrings={{\n\t\t\t\t\t\t\t\t\t\t\t\ttitle: strings.composerReferenceMenuTitle,\n\t\t\t\t\t\t\t\t\t\t\t\tempty: strings.composerReferenceEmpty,\n\t\t\t\t\t\t\t\t\t\t\t\tloading: strings.composerReferenceLoading,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{attachmentError && (\n\t\t\t\t\t\t\t\t<Text role=\"alert\" size=\"xs\" type=\"error\" className=\"comment-composer--attachment-error\">\n\t\t\t\t\t\t\t\t\t\t{attachmentError}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{contentError && (\n\t\t\t\t\t\t\t\t<Text size=\"xs\" type=\"error\">\n\t\t\t\t\t\t\t\t\t\t{contentError}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{showFooterRow && (\n\t\t\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" justify=\"end\" gap=\"md\" className=\"comment-composer--footer-actions\">\n\t\t\t\t\t\t\t\t\t\t{cancelButton}\n\t\t\t\t\t\t\t\t\t\t{submitButton}\n\t\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t)}\n\t\t</Stack>\n\t\t);\n});\n\n/** Preserve the consumer's resource-kind union through the forwarded-ref boundary. */\nexport const CommentComposer = CommentComposerBase as <\n\t\tTResource extends string = string,\n>(\n\t\tprops: CommentComposerProps<TResource> & RefAttributes<CommentComposerHandle>,\n) => ReactElement | null;\n\n/* ------------------------------------------------------------------ */\n/* ComposerEyebrow */\n/* ------------------------------------------------------------------ */\n\nfunction ComposerEyebrow({\n\t\tlabel,\n\t\tcloseLabel,\n\t\tonClose,\n}: {\n\t\tlabel: string;\n\t\tcloseLabel: string;\n\t\tonClose?: () => void;\n}) {\n\t\treturn (\n\t\t\t\t<div className={cn('comment-composer--eyebrow bg-muted/30 ring-border/60 flex min-w-0 items-center justify-between gap-space-sm rounded-radius px-row-x ring-1 ring-inset', rowBlockPaddingClasses.compact)}>\n\t\t\t\t\t\t<DisplayLabel>\n\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t</DisplayLabel>\n\t\t\t\t\t\t{onClose ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\t\t\t\t\tclassName={cn(fieldAffordanceRecipes.target, fieldAffordanceRecipes.focus, fieldAffordanceRecipes.toggle)}\n\t\t\t\t\t\t\t\t\t\taria-label={closeLabel}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X className={fieldAffordanceRecipes.icon} aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t);\n}\n\n/** Helper export for templated reply eyebrow. */\nexport function makeReplyEyebrow(template: string, name?: string): string {\n\t\treturn interpolateString(template, { name }, { missing: 'empty' });\n}\n","/**\n * CommentEmpty — default empty state for the timeline. Replaceable via\n * the `emptySlot` prop on `<Comments>` / `<CommentTimeline>`.\n */\nimport { MessageCircle } from 'lucide-react';\nimport type { FC, ReactNode } from 'react';\n\nimport { EmptyState } from '../../../blocks/data-display';\nimport type { StringsProp } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { useResolvedStrings } from '../comments-provider';\nimport type { CommentsStrings } from '../comments.strings';\n\nexport interface CommentEmptyProps {\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<CommentsStrings>;\n\t/** Leading glyph. */\n\ticon?: ReactNode;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nexport const CommentEmpty: FC<CommentEmptyProps> = ({\n\tstrings: stringsProp,\n\ticon,\n\tclassName,\n}) => {\n\tconst strings = useResolvedStrings(stringsProp);\n\n\treturn (\n\t\t<EmptyState\n\t\t\ttitle={strings.empty}\n\t\t\tdescription={strings.emptyHint || false}\n\t\t\tmedia={icon ?? <MessageCircle className=\"size-icon\" aria-hidden=\"true\" />}\n\t\t\tmediaVariant=\"icon-soft\"\n\t\t\tpadding=\"md\"\n\t\t\tclassName={cn('comment-empty--component', className)}\n\t\t/>\n\t);\n};\n","import type { ReactNode } from 'react';\nimport { Fragment, createElement } from 'react';\n\nimport { Text } from '../../../typography';\nimport { sanitizeHtml } from '../../../../lib/sanitize-html';\nimport { contentTypographyClassName } from '../../../typography/content-typography';\n\nimport { RichText } from '../../../typography/rich-text';\nimport { MentionContent } from '../../mentions';\n\nimport type {\n\tCommentData,\n\tCommentUser,\n\tCommentsConfig,\n\tCommentsSlots,\n} from '../comments.types';\n\nexport interface CommentContentProps<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n> {\n\t/** The comment to render. */\n\tcomment: CommentData<TUser, TMeta, TResource>;\n\t/** Resource registry — passed through to `<MentionContent>`. */\n\tresources?: CommentsConfig<TUser, TMeta, TResource>['resources'];\n\t/** Replaces the default rendering of an inline reference. */\n\trenderReference?: CommentsSlots<\n\t\tTUser,\n\t\tTMeta,\n\t\tTResource\n\t>['renderReference'];\n\t/** Optional sanitizer override. The package safe allowlist is the default. */\n\tsanitizer?: (html: string) => string;\n}\n\nexport function CommentContent<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>(\n\tprops: CommentContentProps<TUser, TMeta, TResource>,\n): ReactNode {\n\tconst { comment, resources, renderReference, sanitizer } = props;\n\tconst contentType =\n\t\tcomment.contentType ??\n\t\t(comment as Record<string, unknown>).content_type ??\n\t\t'text';\n\n\tif (contentType === 'rich') {\n\t\tconst richContent = renderRichContent(comment.content);\n\t\treturn richContent ? (\n\t\t\t<div className=\"comment-content--component\">{richContent}</div>\n\t\t) : null;\n\t}\n\n\tif (contentType === 'html') {\n\t\treturn (\n\t\t\t<div className=\"comment-content--component\">\n\t\t\t\t<MentionContent<TResource>\n\t\t\t\t\tclassName=\"text-inherit\"\n\t\t\t\t\thtml={comment.content ?? ''}\n\t\t\t\t\tmentions={comment.references}\n\t\t\t\t\tresources={resources}\n\t\t\t\t\trenderMention={renderReference}\n\t\t\t\t\tsanitizer={sanitizer}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst plainContent = decodeQuotedString(comment.content ?? '');\n\n\treturn (\n\t\t<Text type=\"inherit\" className=\"comment-content--component whitespace-pre-line\">\n\t\t\t{plainContent}\n\t\t</Text>\n\t);\n}\n\n/* ------------------------------------------------------------------ */\n/* Rich-block renderer for Editor.js-style structured content */\n/* ------------------------------------------------------------------ */\n\nfunction renderRichContent(rawContent: string | null | undefined): ReactNode {\n\tif (!rawContent) return null;\n\n\ttry {\n\t\tconst parsed = JSON.parse(rawContent) as {\n\t\t\tblocks?: Array<{ id?: string; type: string; data?: Record<string, unknown> }>;\n\t\t};\n\n\t\tif (!parsed || !Array.isArray(parsed.blocks) || parsed.blocks.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<Text tag=\"div\" type=\"inherit\" className={contentTypographyClassName}>\n\t\t\t\t{parsed.blocks.map((block, index) => (\n\t\t\t\t\t<Fragment key={block.id ?? `${block.type}-${index}`}>\n\t\t\t\t\t\t{renderRichBlock(block)}\n\t\t\t\t\t</Fragment>\n\t\t\t\t))}\n\t\t\t</Text>\n\t\t);\n\t} catch {\n\t\tconst decoded = decodeQuotedString(rawContent);\n\t\treturn (\n\t\t\t<Text type=\"inherit\" className=\"whitespace-pre-line\">\n\t\t\t\t{decoded}\n\t\t\t</Text>\n\t\t);\n\t}\n}\n\nfunction renderRichBlock(block: { type: string; data?: Record<string, unknown> }): ReactNode {\n\tconst data = block.data ?? {};\n\n\tswitch (block.type) {\n\t\tcase 'paragraph': {\n\t\t\tconst raw = String(data.text ?? '').trim();\n\t\t\tif (!raw) return null;\n\t\t\tconst html = sanitizeHtml(raw);\n\t\t\treturn html ? <p dangerouslySetInnerHTML={{ __html: html }} /> : null;\n\t\t}\n\t\tcase 'header': {\n\t\t\tconst text = stripHtml(String(data.text ?? ''));\n\t\t\tconst level = Number(data.level ?? 3);\n\t\t\tif (!text) return null;\n\t\t\tconst safeLevel = Math.min(Math.max(level, 1), 6);\n\t\t\treturn createElement(\n\t\t\t\t`h${safeLevel}`,\n\t\t\t\tnull,\n\t\t\t\ttext,\n\t\t\t);\n\t\t}\n\t\tcase 'list': {\n\t\t\tconst items = Array.isArray(data.items) ? data.items : [];\n\t\t\tconst sanitizedItems = items\n\t\t\t\t.map((item) => stripHtml(String(item ?? '')))\n\t\t\t\t.filter((item) => item.length > 0);\n\n\t\t\tif (sanitizedItems.length === 0) return null;\n\n\t\t\tif (data.style === 'ordered') {\n\t\t\t\treturn (\n\t\t\t\t\t<ol>\n\t\t\t\t\t\t{sanitizedItems.map((item, index) => (\n\t\t\t\t\t\t\t<li key={`${item}-${index}`}>\n\t\t\t\t\t\t\t\t<Text tag=\"span\" type=\"inherit\">{item}</Text>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ol>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<ul>\n\t\t\t\t\t{sanitizedItems.map((item) => (\n\t\t\t\t\t\t<li key={item}>\n\t\t\t\t\t\t\t<Text tag=\"span\" type=\"inherit\">{item}</Text>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t);\n\t\t}\n\t\tcase 'quote': {\n\t\t\tconst text = String(data.text ?? '').trim();\n\t\t\tif (!text) return null;\n\t\t\tconst caption = stripHtml(String(data.caption ?? ''));\n\t\t\treturn (\n\t\t\t\t<blockquote className=\"italic\">\n\t\t\t\t\t<RichText tag=\"div\" html={text} type=\"secondary\" />\n\t\t\t\t\t{caption.length > 0 && (\n\t\t\t\t\t\t<cite className=\"mt-1 block not-italic\">\n\t\t\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\">\n\t\t\t\t\t\t\t\t— {caption}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t</cite>\n\t\t\t\t\t)}\n\t\t\t\t</blockquote>\n\t\t\t);\n\t\t}\n\t\tcase 'delimiter':\n\t\t\treturn (\n\t\t\t\t<hr\n\t\t\t\t\tclassName=\"border-dashed\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t/>\n\t\t\t);\n\t\tdefault: {\n\t\t\tconst text = stripHtml(String(data.text ?? ''));\n\t\t\tif (!text) return null;\n\t\t\treturn <p className=\"whitespace-pre-line\">{text}</p>;\n\t\t}\n\t}\n}\n\nfunction stripHtml(value: string): string {\n\treturn value.replace(/<[^>]*>/g, '').trim();\n}\n\nfunction decodeQuotedString(value: string | null | undefined): string {\n\tif (typeof value !== 'string') return '';\n\tconst trimmed = value.trim();\n\tif (trimmed === '') return '';\n\tif (trimmed.startsWith('{') || trimmed.startsWith('[')) return trimmed;\n\ttry {\n\t\tconst parsed = JSON.parse(trimmed);\n\t\tif (typeof parsed === 'string') return parsed;\n\t} catch {\n\t\t// ignore\n\t}\n\tif (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n\t\treturn trimmed.slice(1, -1);\n\t}\n\treturn trimmed;\n}\n","import {\n\tCornerDownRight,\n\tPencil,\n\tPin,\n\tSmile,\n\tTrash2,\n} from 'lucide-react';\nimport type { FC } from 'react';\nimport { memo, useCallback, useMemo, useState } from 'react';\n\nimport {\n\tAvatar,\n\tAvatarFallback,\n\tAvatarImage,\n} from '../../../base/avatar';\nimport { Badge } from '../../../base/badge';\nimport { Button } from '../../../base/buttons';\nimport { ConfirmDialog, useOverlayVisibility } from '../../overlays';\nimport {\n\tTooltip,\n\tTooltipContent,\n\tTooltipProvider,\n\tTooltipTrigger,\n} from '../../../base/display/tooltip';\nimport { Number as NumberValue, RelativeTime } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { Stack } from '../../../base/structure';\nimport { cn } from '../../../../lib/utils';\nimport { fieldAffordanceRecipes } from '../../../../lib/field-affordance-recipes';\nimport { interpolateString } from '../../../../lib/strings';\nimport { defaultCommentsStrings } from '../comments.strings';\n\nimport {\n\tuseResolvedAccessors,\n\tuseResolvedStrings,\n} from '../comments-provider';\nimport type {\n\tCommentAttachment,\n\tCommentItemProps,\n\tCommentUser,\n} from '../comments.types';\nimport { CommentAttachmentChip } from './comment-attachment-chip';\nimport { CommentContent } from './comment-content';\n\nconst FALLBACK_INITIAL = '?';\n\nconst defaultGetMediaUrl = (m: CommentAttachment | null | undefined) => m?.url;\nconst defaultGetMediaName = (m: CommentAttachment | null | undefined) => m?.name;\nconst defaultGetStatusLabel = (s: string) =>\n\ts.charAt(0).toUpperCase() + s.slice(1).replace(/_/g, ' ');\n\nexport const CommentItem = memo(function CommentItem<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>({\n\tcomment,\n\tcanModerate,\n\tonDelete,\n\tonAttachmentRemove,\n\tonEdit,\n\tonPinToggle,\n\tonReact,\n\tonReply,\n\tallowReactions: allowReactionsProp,\n\tallowReplies: allowRepliesProp,\n\tsanitizer,\n\tstrings: stringsProp,\n\tgetMediaUrl,\n\tgetMediaName,\n\tgetStatusLabel,\n\tformatRelativeTime,\n\tresources,\n\trenderAttachment,\n\trenderReference,\n}: CommentItemProps<TUser, TMeta, TResource>) {\n\tconst strings = useResolvedStrings(stringsProp);\n\tconst allowReactions = allowReactionsProp ?? true;\n\tconst allowReplies = allowRepliesProp ?? true;\n\tconst accessors = useResolvedAccessors({\n\t\tgetMediaUrl,\n\t\tgetMediaName,\n\t\tgetStatusLabel,\n\t\tformatRelativeTime,\n\t});\n\n\tconst resolvedGetMediaUrl = accessors.getMediaUrl ?? defaultGetMediaUrl;\n\tconst resolvedGetMediaName = accessors.getMediaName ?? defaultGetMediaName;\n\tconst resolvedGetStatusLabel =\n\t\taccessors.getStatusLabel ?? defaultGetStatusLabel;\n\tconst resolvedFormatRelativeTime = accessors.formatRelativeTime;\n\n\tconst authorName = comment.user?.name ?? strings.fallbackAuthor;\n\tconst avatarUrl = comment.user?.avatar ?? undefined;\n\n\tconst fallbackInitial = useMemo(() => {\n\t\tif (!authorName) return FALLBACK_INITIAL;\n\t\tconst trimmed = authorName.trim();\n\t\treturn trimmed === ''\n\t\t\t? FALLBACK_INITIAL\n\t\t\t: trimmed.charAt(0).toUpperCase();\n\t}, [authorName]);\n\n\tconst tagList = useMemo(() => {\n\t\tif (Array.isArray(comment.tagsArray)) {\n\t\t\treturn comment.tagsArray.filter(\n\t\t\t\t(tag): tag is string => typeof tag === 'string',\n\t\t\t);\n\t\t}\n\t\tif (comment.tagsArray && typeof comment.tagsArray === 'object') {\n\t\t\treturn Object.values(comment.tagsArray).filter(\n\t\t\t\t(value): value is string => typeof value === 'string',\n\t\t\t);\n\t\t}\n\t\treturn [];\n\t}, [comment.tagsArray]);\n\n\tconst attachments = useMemo(() => {\n\t\tconst list = comment.attachments ?? [];\n\t\treturn list.filter(\n\t\t\t(a): a is CommentAttachment => !!a && typeof a === 'object',\n\t\t);\n\t}, [comment.attachments]);\n\n\tconst reactions = allowReactions ? (comment.reactions ?? []) : [];\n\n\tconst isPinned = comment.isPinned === true;\n\tconst isEdited = comment.isEdited === true;\n\tconst showStatus = comment.status && comment.status !== 'active';\n\tconst statusLabel =\n\t\tshowStatus && comment.status ? resolvedGetStatusLabel(comment.status) : null;\n\tconst canDeleteComment =\n\t\tcomment.canDelete === true || canModerate === true;\n\tconst canEditComment = comment.canEdit === true || canModerate === true;\n\tconst canReply = !!allowReplies && !!onReply && !!comment.id;\n\tconst canReact = !!allowReactions && !!onReact && !!comment.id;\n\tconst canPin = !!onPinToggle && !!canModerate;\n\tconst canEdit = !!canEditComment && !!onEdit && !!comment.id;\n\tconst canDelete = !!canDeleteComment && !!onDelete && !!comment.id;\n\tconst hasActions = canReply || canReact || canPin || canEdit || canDelete;\n\n\tconst attachmentConfirm = useOverlayVisibility();\n\tconst [pendingAttachmentId, setPendingAttachmentId] = useState<string | null>(null);\n\tconst requestAttachmentRemoval = useCallback(\n\t\t(attachmentId: string) => {\n\t\t\tsetPendingAttachmentId(attachmentId);\n\t\t\tattachmentConfirm.show();\n\t\t},\n\t\t[attachmentConfirm],\n\t);\n\n\tconst hasAttachments = attachments.length > 0;\n\n\treturn (\n\t\t<article\n\t\t\tclassName={cn(\n\t\t\t\t'comment-item--component group relative overflow-hidden rounded-radius border transition-colors',\n\t\t\t\t'border-border/60 bg-card text-card-foreground px-surface pt-surface',\n\t\t\t\t// A trailing row of ghost icon buttons already carries its own inset\n\t\t\t\t// around each glyph, so it supplies the rest of the bottom edge and the\n\t\t\t\t// card stays optically even instead of gaining an empty band.\n\t\t\t\thasActions ? 'pb-surface-xs' : 'pb-surface',\n\t\t\t)}\n\t\t\tdata-comment-id={comment.id}\n\t\t>\n\t\t\t<Stack direction=\"horizontal\" align=\"start\" gap=\"lg\" className=\"min-w-0\">\n\t\t\t\t<Avatar className=\"size-avatar shrink-0\">\n\t\t\t\t\t{!!avatarUrl && (\n\t\t\t\t\t\t<AvatarImage src={avatarUrl} alt={authorName} />\n\t\t\t\t\t)}\n\t\t\t\t\t<AvatarFallback className=\"bg-muted text-muted-foreground text-xs font-medium\">\n\t\t\t\t\t\t{fallbackInitial}\n\t\t\t\t\t</AvatarFallback>\n\t\t\t\t</Avatar>\n\n\t\t\t\t<div className=\"comment-item--body min-w-0 flex-1\">\n\t\t\t\t\t{/* The byline and its message are one copy unit: the Stack owns their gap. */}\n\t\t\t\t\t<Stack gap=\"xs\" className=\"comment-item--message min-w-0\">\n\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"baseline\" gap=\"md\" className=\"min-w-0\">\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\ttype=\"inherit\"\n\t\t\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\t\t\tclassName=\"truncate\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{authorName}\n\t\t\t\t\t\t\t</Text>\n\n\t\t\t\t\t\t\t{!!isPinned && (\n\t\t\t\t\t\t\t\t<TooltipProvider delayDuration={0}>\n\t\t\t\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t\t\t\t<TooltipTrigger render={<span className=\"inline-flex shrink-0 self-center\" />}>\n\t\t\t\t\t\t\t\t\t\t\t<Pin className=\"text-muted-foreground size-icon-sm\" aria-hidden />\n\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\t\t\tside=\"top\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-xs\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{strings.pinned}\n\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t</TooltipProvider>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t<RelativeTime\n\t\t\t\t\t\t\t\tvalue={comment.createdAt}\n\t\t\t\t\t\t\t\tformatRelativeTime={resolvedFormatRelativeTime}\n\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\tclassName=\"shrink-0 tabular-nums\"\n\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t{!!isEdited && (\n\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\t\t\t\ttype=\"secondary\"\n\t\t\t\t\t\t\t\t\tclassName=\"shrink-0\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{strings.edited}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{!!showStatus && !!statusLabel && (\n\t\t\t\t\t\t\t\t<Badge size=\"sm\" tone=\"secondary\" className=\"self-center\">\n\t\t\t\t\t\t\t\t\t{statusLabel}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</Stack>\n\n\t\t\t\t\t\t<div className=\"leading-relaxed\">\n\t\t\t\t\t\t\t<CommentContent\n\t\t\t\t\t\t\t\tcomment={comment}\n\t\t\t\t\t\t\t\tresources={resources}\n\t\t\t\t\t\t\t\trenderReference={renderReference}\n\t\t\t\t\t\t\t\tsanitizer={sanitizer}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Stack>\n\n\t\t\t\t\t{tagList.length > 0 && (\n\t\t\t\t\t\t<div className=\"mt-space-md flex flex-wrap gap-space-sm\">\n\t\t\t\t\t\t\t{tagList.map((tag) => (\n\t\t\t\t\t\t\t\t<Badge key={tag} size=\"sm\" tone=\"secondary\">\n\t\t\t\t\t\t\t\t\t{tag}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{hasAttachments && (\n\t\t\t\t\t\t<div className=\"mt-space-md flex flex-wrap gap-space-sm\">\n\t\t\t\t\t\t\t{attachments.map((attachment) => {\n\t\t\t\t\t\t\t\tif (renderAttachment) {\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<div key={attachment.id ?? attachment.name}>\n\t\t\t\t\t\t\t\t\t\t\t{renderAttachment(attachment)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t\t * Posted attachments were read-only: no control, no\n\t\t\t\t\t\t\t\t * callback, nothing to remove. The control appears only\n\t\t\t\t\t\t\t\t * when the consumer supplies `onAttachmentRemove` and the\n\t\t\t\t\t\t\t\t * viewer may edit the comment, and detaching a published\n\t\t\t\t\t\t\t\t * file is irreversible, so it asks first.\n\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\tconst canRemoveAttachment =\n\t\t\t\t\t\t\t\t\t!!onAttachmentRemove && !!attachment.id && canDeleteComment;\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<CommentAttachmentChip\n\t\t\t\t\t\t\t\t\t\tkey={attachment.id ?? attachment.name}\n\t\t\t\t\t\t\t\t\t\tattachment={attachment}\n\t\t\t\t\t\t\t\t\t\teditable={canRemoveAttachment}\n\t\t\t\t\t\t\t\t\t\tonRemove={\n\t\t\t\t\t\t\t\t\t\t\tcanRemoveAttachment\n\t\t\t\t\t\t\t\t\t\t\t\t? () => requestAttachmentRemoval(attachment.id as string)\n\t\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\taccessors={{\n\t\t\t\t\t\t\t\t\t\t\tgetMediaUrl: resolvedGetMediaUrl,\n\t\t\t\t\t\t\t\t\t\t\tgetMediaName: resolvedGetMediaName,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tstrings={stringsProp}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{reactions.length > 0 && (\n\t\t\t\t\t\t<Stack direction=\"horizontal\" wrap align=\"center\" gap=\"xs\" className=\"mt-space-md\">\n\t\t\t\t\t\t\t{reactions.map((reaction) => (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={reaction.emoji}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\taria-label={interpolateString(strings.reactionLabel ?? defaultCommentsStrings.reactionLabel!, { emoji: reaction.emoji, count: reaction.count })}\n\t\t\t\t\t\t\t\t\taria-pressed={reaction.mine ?? false}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tonReact && comment.id\n\t\t\t\t\t\t\t\t\t\t\t? onReact(comment.id, reaction.emoji)\n\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttitle={reaction.users?.join(', ')}\n\t\t\t\t\t\t\t\t\tclassName={cn(fieldAffordanceRecipes.inline, fieldAffordanceRecipes.focus)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\ttone={reaction.mine ? 'info' : 'secondary'}\n\t\t\t\t\t\t\t\t\t\tclassName=\"cursor-pointer transition-colors\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\ttag=\"span\"\n\t\t\t\t\t\t\t\t\t\t\tsize=\"inherit\"\n\t\t\t\t\t\t\t\t\t\t\tlineHeight=\"none\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-inherit\"\n\t\t\t\t\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{reaction.emoji}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t<NumberValue\n\t\t\t\t\t\t\t\t\t\t\tvalue={reaction.count}\n\t\t\t\t\t\t\t\t\t\t\tsize=\"inherit\"\n\t\t\t\t\t\t\t\t\t\t\talign=\"left\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tabular-nums text-current\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\n\t\t\t\t{/* Actions own a separate row so they never reserve message width. */}\n\t\t\t\t{hasActions && <div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'comment-item--actions relative mt-space-xs ms-auto w-fit max-w-full flex-wrap opacity-100 transition-opacity',\n\t\t\t\t\t\t'group-hover:opacity-100 focus-within:opacity-100',\n\t\t\t\t\t\t'inline-flex items-center gap-space-2xs',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{canReply && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tcomment.id && onReply(comment.id)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttitle={strings.replyLabel}\n\t\t\t\t\t\t\taria-label={strings.replyLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CornerDownRight className=\"size-icon-md\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{canReact && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tcomment.id && onReact(comment.id, '👍')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttitle={strings.addReactionLabel}\n\t\t\t\t\t\t\taria-label={strings.addReactionLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Smile className=\"size-icon-md\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{canPin && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\tonClick={() => onPinToggle(comment)}\n\t\t\t\t\t\t\ttitle={isPinned ? strings.unpinLabel : strings.pinLabel}\n\t\t\t\t\t\t\taria-label={isPinned ? strings.unpinLabel : strings.pinLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Pin\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'size-icon-md',\n\t\t\t\t\t\t\t\t\tisPinned && 'text-foreground',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{canEdit && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\ttitle={strings.editLabel}\n\t\t\t\t\t\t\taria-label={strings.editLabel}\n\t\t\t\t\t\t\tonClick={() => onEdit(comment)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Pencil className=\"size-icon-md\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{canDelete && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\tclassName=\"hover:text-destructive\"\n\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\tonDelete(comment.id as string)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttitle={strings.deleteLabel}\n\t\t\t\t\t\t\t\taria-label={strings.deleteLabel}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Trash2 className=\"size-icon-md\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t</div>}\n\t\t\t\t</div>\n\t\t\t</Stack>\n\t\t\t{!!onAttachmentRemove && (\n\t\t\t\t<ConfirmDialog\n\t\t\t\t\t{...attachmentConfirm.overlayProps}\n\t\t\t\t\tdestructive\n\t\t\t\t\ttitle={strings.confirmRemoveAttachmentTitle}\n\t\t\t\t\tdescription={strings.confirmRemoveAttachmentDescription}\n\t\t\t\t\tstrings={{ confirm: strings.attachmentRemoveLabel }}\n\t\t\t\t\tonConfirm={() => {\n\t\t\t\t\t\tif (pendingAttachmentId && comment.id) {\n\t\t\t\t\t\t\tvoid onAttachmentRemove(comment.id as string, pendingAttachmentId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</article>\n\t);\n}) as <\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>(\n\tprops: CommentItemProps<TUser, TMeta, TResource>,\n) => ReturnType<FC>;\n","import type { FC } from 'react';\n\nimport { Stack } from '../../../base/structure';\nimport type { CommentTimelineProps, CommentUser } from '../comments.types';\nimport { CommentEmpty } from './comment-empty';\nimport { CommentItem } from './comment-item';\n\nexport const CommentTimeline = function CommentTimeline<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>({\n\tcomments,\n\tcanModerate,\n\tonDelete,\n\tonAttachmentRemove,\n\tonEdit,\n\tonPinToggle,\n\tonReact,\n\tonReply,\n\tallowReactions,\n\tallowReplies,\n\tsanitizer,\n\tstrings: stringsProp,\n\tgetMediaUrl,\n\tgetMediaName,\n\tgetStatusLabel,\n\tformatRelativeTime,\n\tresources,\n\trenderItem,\n\trenderAttachment,\n\trenderReference,\n\temptySlot,\n}: CommentTimelineProps<TUser, TMeta, TResource>) {\n\tif (!comments.length) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{emptySlot ?? <CommentEmpty strings={stringsProp} />}\n\t\t\t</>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Stack gap=\"sm\" className=\"comment-timeline--component\">\n\t\t\t{comments.map((comment, index) => {\n\t\t\t\tconst defaultItem = (\n\t\t\t\t\t<CommentItem<TUser, TMeta, TResource>\n\t\t\t\t\t\tcomment={comment}\n\t\t\t\t\t\tcanModerate={canModerate}\n\t\t\t\t\t\tonDelete={onDelete}\n\t\t\t\t\t\tonAttachmentRemove={onAttachmentRemove}\n\t\t\t\t\t\tonEdit={onEdit}\n\t\t\t\t\t\tonPinToggle={onPinToggle}\n\t\t\t\t\t\tonReact={onReact}\n\t\t\t\t\t\tonReply={onReply}\n\t\t\t\t\t\tallowReactions={allowReactions}\n\t\t\t\t\t\tallowReplies={allowReplies}\n\t\t\t\t\t\tsanitizer={sanitizer}\n\t\t\t\t\t\tstrings={stringsProp}\n\t\t\t\t\t\tgetMediaUrl={getMediaUrl}\n\t\t\t\t\t\tgetMediaName={getMediaName}\n\t\t\t\t\t\tgetStatusLabel={getStatusLabel}\n\t\t\t\t\t\tformatRelativeTime={formatRelativeTime}\n\t\t\t\t\t\tresources={resources}\n\t\t\t\t\t\trenderAttachment={renderAttachment}\n\t\t\t\t\t\trenderReference={renderReference}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\t\tif (renderItem) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div key={comment.id ?? `comment-${index}`}>\n\t\t\t\t\t\t\t{renderItem({\n\t\t\t\t\t\t\t\tcomment,\n\t\t\t\t\t\t\t\tcanModerate: canModerate ?? false,\n\t\t\t\t\t\t\t\tonDelete,\n\t\t\t\t\t\t\t\tonAttachmentRemove,\n\t\t\t\t\t\t\t\tonEdit,\n\t\t\t\t\t\t\t\tdefaultItem,\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<div key={comment.id ?? `comment-${index}`}>\n\t\t\t\t\t\t{defaultItem}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Stack>\n\t);\n} as <\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>(\n\tprops: CommentTimelineProps<TUser, TMeta, TResource>,\n) => ReturnType<FC>;\n","/**\n * Comments — top-level entry for the Comments feature.\n *\n * Composes the composer + timeline + empty state behind a single API.\n * Generic in `<TUser, TMeta, TResource>` so consumers can type their\n * domain (user shape, custom meta payload, resource-kind union).\n *\n * Per-mount wiring (callbacks, resources, accessors) flows as direct\n * props. Library-wide display defaults (composer position, etc.) come\n * from `<UIProvider>` — see `@/lib/ui-provider`. Slots, render-props,\n * and the headless `useComments()` hook cover the composability\n * spectrum.\n *\n * Wrap the feature in `Card` at the call site when card chrome is desired.\n */\nimport { useCallback, useState } from 'react';\n\nimport { Stack } from '../../base/structure';\nimport { ConfirmDialog, useOverlayVisibility } from '../overlays';\nimport { Text } from '../../typography';\nimport { useCommentsConfig as useCommentsUIDefaults } from '../../../lib/ui-provider';\n\nimport { useResolvedStrings } from './comments-provider';\nimport type { CommentUser, CommentsProps } from './comments.types';\nimport { useComments } from './hooks/use-comments';\nimport { CommentComposer } from './partials/comment-composer';\nimport { CommentEmpty } from './partials/comment-empty';\nimport { CommentTimeline } from './partials/comment-timeline';\n\nimport { cn } from '../../../lib/utils';\nexport function Comments<\n\tTUser extends CommentUser = CommentUser,\n\tTMeta = unknown,\n\tTResource extends string = string,\n>(props: CommentsProps<TUser, TMeta, TResource>) {\n\tconst ui = useCommentsUIDefaults();\n\n\tconst composerPosition =\n\t\tprops.composerPosition ?? ui.composerPosition ?? 'top';\n\tconst maxAttachments = props.maxAttachments ?? 5;\n\tconst allowAttachments = props.allowAttachments ?? true;\n\tconst allowReactions = props.allowReactions ?? true;\n\tconst allowReplies = props.allowReplies ?? true;\n\n\tconst canComment = props.canComment ?? false;\n\tconst canModerate = props.canModerate ?? false;\n\n\tconst onPinToggle = props.onPinToggle;\n\n\tconst resources = props.resources;\n\tconst attachments = props.attachments;\n\n\tconst strings = useResolvedStrings(props.strings);\n\tconst title = props.title === undefined ? strings.title : props.title;\n\n\t/*\n\t * Deleting a comment is irreversible and the trigger is a bare icon button\n\t * next to Edit, so the confirmation is the component's job rather than every\n\t * consumer's. `confirmDelete={false}` opts out for apps that already confirm\n\t * upstream — otherwise they would ask twice.\n\t */\n\tconst confirmDelete = props.confirmDelete ?? true;\n\tconst deleteConfirm = useOverlayVisibility();\n\tconst [pendingDeleteId, setPendingDeleteId] = useState<string | null>(null);\n\n\tconst commentsState = useComments<TUser, TMeta, TResource>({\n\t\tonSubmit: props.onSubmit,\n\t\tonUpdate: props.onUpdate,\n\t\tonDelete: props.onDelete,\n\t\tonAfterMutate: props.onAfterMutate,\n\t\tonError: props.onError,\n\t});\n\n\tconst requestDelete = useCallback(\n\t\t(id: string) => {\n\t\t\tif (!confirmDelete) {\n\t\t\t\tvoid commentsState.deleteComment(id);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetPendingDeleteId(id);\n\t\t\tdeleteConfirm.show();\n\t\t},\n\t\t[confirmDelete, commentsState, deleteConfirm],\n\t);\n\tconst startReply = commentsState.startReply;\n\tconst comments = props.comments;\n\tconst onReply = props.onReply;\n\n\tconst handleReply = useCallback(\n\t\t(commentId: string) => {\n\t\t\tconst comment = comments.find((item) => item.id === commentId);\n\t\t\tif (comment) startReply(comment);\n\t\t\tonReply?.(commentId);\n\t\t},\n\t\t[comments, onReply, startReply],\n\t);\n\n\tconst editingComment =\n\t\tcommentsState.composerMode.kind === 'editing'\n\t\t\t? commentsState.composerMode.comment\n\t\t\t: undefined;\n\tconst replyingTo =\n\t\tcommentsState.composerMode.kind === 'replying'\n\t\t\t? {\n\t\t\t\t\tcommentId: commentsState.composerMode.commentId,\n\t\t\t\t\tauthorName: commentsState.composerMode.authorName,\n\t\t\t\t}\n\t\t\t: undefined;\n\n\tconst composer = props.composerSlot ?? (\n\t\tcanComment ? (\n\t\t\t<CommentComposer<TResource>\n\t\t\t\tcontext={props.context}\n\t\t\t\tcanComment={canComment}\n\t\t\t\tsubmitting={commentsState.isSubmitting}\n\t\t\t\terrors={commentsState.formErrors}\n\t\t\t\tresetKey={commentsState.resetKey}\n\t\t\t\teditingComment={editingComment}\n\t\t\t\treplyingTo={replyingTo}\n\t\t\t\tonCancel={\n\t\t\t\t\tcommentsState.composerMode.kind === 'idle'\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: commentsState.cancelComposerMode\n\t\t\t\t}\n\t\t\t\tonSubmit={commentsState.submit}\n\t\t\t\tstrings={props.strings}\n\t\t\t\tresources={resources}\n\t\t\t\tonResourceSearch={props.onResourceSearch}\n\t\t\t\tattachments={attachments}\n\t\t\t\tmaxAttachments={maxAttachments}\n\t\t\t\tallowAttachments={allowAttachments}\n\t\t\t/>\n\t\t) : null\n\t);\n\n\tconst timeline = (\n\t\t<CommentTimeline<TUser, TMeta, TResource>\n\t\t\tcomments={props.comments}\n\t\t\tcanModerate={canModerate}\n\t\t\tonDelete={props.onDelete ? requestDelete : undefined}\n\t\t\tonAttachmentRemove={props.onAttachmentRemove}\n\t\t\tonEdit={\n\t\t\t\tcanComment && props.onUpdate\n\t\t\t\t\t? commentsState.startEdit\n\t\t\t\t\t: undefined\n\t\t\t}\n\t\t\tonPinToggle={onPinToggle}\n\t\t\tonReact={props.onReact}\n\t\t\tonReply={canComment && allowReplies ? handleReply : undefined}\n\t\t\tallowReactions={allowReactions}\n\t\t\tallowReplies={allowReplies}\n\t\t\tsanitizer={props.sanitizer}\n\t\t\tstrings={props.strings}\n\t\t\tgetMediaUrl={props.getMediaUrl}\n\t\t\tgetMediaName={props.getMediaName}\n\t\t\tgetStatusLabel={props.getStatusLabel}\n\t\t\tformatRelativeTime={props.formatRelativeTime}\n\t\t\tresources={resources}\n\t\t\trenderItem={props.renderItem}\n\t\t\trenderAttachment={props.renderAttachment}\n\t\t\trenderReference={props.renderReference}\n\t\t\temptySlot={\n\t\t\t\tprops.emptySlot ?? <CommentEmpty strings={props.strings} />\n\t\t\t}\n\t\t/>\n\t);\n\n\tconst composerBlock = composer ? <div>{composer}</div> : null;\n\n\tconst inner = (\n\t\t<Stack gap=\"xl\" className=\"comments--body\">\n\t\t\t{props.headerSlot}\n\t\t\t{composerPosition === 'top' && composerBlock}\n\t\t\t{timeline}\n\t\t\t{composerPosition === 'bottom' && composerBlock}\n\t\t\t{props.footerSlot}\n\t\t</Stack>\n\t);\n\n\tif (props.bare) {\n\t\treturn inner;\n\t}\n\n\tconst ariaLabel = typeof title === 'string' ? title : undefined;\n\n\treturn (\n\t\t<Stack\n\t\t\trender={<section />}\n\t\t\tgap=\"lg\"\n\t\t\tdata-component=\"comments\"\n\t\t\tdata-slot=\"comments\"\n\t\t\tclassName={cn('comments--component', props.className)}\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t{!!(title !== false && (title || strings.subtitle)) && (\n\t\t\t\t<Stack gap=\"normal\" className=\"comments--header\">\n\t\t\t\t\t{!!title && <Text weight=\"semibold\">{title}</Text>}\n\t\t\t\t\t{!!strings.subtitle && <Text type=\"secondary\">{strings.subtitle}</Text>}\n\t\t\t\t</Stack>\n\t\t\t)}\n\t\t\t{inner}\n\t\t\t{!!(confirmDelete && props.onDelete) && (\n\t\t\t\t<ConfirmDialog\n\t\t\t\t\t{...deleteConfirm.overlayProps}\n\t\t\t\t\tdestructive\n\t\t\t\t\ttitle={strings.confirmDeleteTitle}\n\t\t\t\t\tdescription={strings.confirmDeleteDescription}\n\t\t\t\t\tstrings={{ confirm: strings.confirmDeleteLabel }}\n\t\t\t\t\tonAsyncConfirm={async () => {\n\t\t\t\t\t\tif (pendingDeleteId) await commentsState.deleteComment(pendingDeleteId);\n\t\t\t\t\t}}\n\t\t\t\t\tonError={props.onError}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n"],"mappings":"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"}
@@ -7,6 +7,11 @@
7
7
  * separation, links, disabled state, and density. `ActionButtons` renders the
8
8
  * same definitions as inline buttons for page/toolbars that need visible
9
9
  * actions plus an overflow menu.
10
+ *
11
+ * Without a visible `label` the trigger is the shared overflow square from
12
+ * `action-menu.recipes.ts`: a `⋯` glyph named "More actions", ghost `inline`
13
+ * or outline `commands`, at the size of the controls beside it or the
14
+ * provider scale.
10
15
  */
11
16
  import type { LucideIcon } from 'lucide-react';
12
17
  import React, { type ComponentType, type ReactElement, type ReactNode } from 'react';
@@ -15,6 +20,7 @@ import { type CollectionDensity } from '../popover/popover.recipes';
15
20
  import { DropdownMenuTrigger } from '../navigation/dropdown-menu';
16
21
  import type { ActionPresentation } from '../../../lib/action-presentation';
17
22
  import { type StringsProp } from '../../../lib/strings';
23
+ import { type ActionMenuContext } from './action-menu.recipes';
18
24
  import { type ActionMenuStrings } from './action-menu.strings';
19
25
  type ActionMenuButtonProps = Partial<React.ComponentPropsWithoutRef<typeof Button>> & {
20
26
  [key: `data-${string}`]: string | boolean | undefined;
@@ -82,13 +88,24 @@ export interface ActionMenuProps {
82
88
  * `preserveOrder` is set.
83
89
  */
84
90
  actions: readonly ActionMenuAction[];
85
- /** Trigger text. Omit for an icon-only trigger, and set `srText` instead. */
91
+ /** Trigger text. Omit for the shared icon-only overflow trigger, and set `srText` to name it. */
86
92
  label?: string;
87
- /** Trigger glyph. Defaults to the vertical ellipsis (`MoreVertical`). */
93
+ /** Trigger glyph. Defaults to the horizontal ellipsis (`MoreHorizontal`) every overflow menu shares. */
88
94
  icon?: ActionMenuIcon;
89
- /** Accessible name when the trigger shows no visible `label`. */
95
+ /** Accessible name when the trigger shows no visible `label`. Defaults to `strings.openMenuLabel`, "More actions". */
90
96
  srText?: string;
91
- /** Escape hatch forwarded to the trigger button. */
97
+ /**
98
+ * Where the menu sits, which picks the trigger treatment. `inline` (the
99
+ * default) is the quiet ghost square for rows, cards and footers; `commands`
100
+ * is the outline square that ends a row of outline commands. Place the menu
101
+ * after any primary command in the same row.
102
+ */
103
+ context?: ActionMenuContext;
104
+ /**
105
+ * Escape hatch forwarded to the trigger button. An icon-only trigger takes
106
+ * `size` from here to match the controls beside it, otherwise the provider
107
+ * scale.
108
+ */
92
109
  buttonProps?: ActionMenuButtonProps;
93
110
  /** Menu alignment against the trigger. Defaults to `end`. */
94
111
  align?: 'center' | 'start' | 'end';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Where an overflow menu sits. `inline` is the quiet ghost square for rows,
3
+ * cards, list items and footers; `commands` is the outline square that ends a
4
+ * row of outline commands, such as a page header or toolbar.
5
+ */
6
+ export type ActionMenuContext = 'inline' | 'commands';
7
+ export declare const overflowTriggerRecipes: {
8
+ readonly icon: import("lucide-react").LucideIcon;
9
+ readonly context: {
10
+ readonly inline: {
11
+ readonly tone: "secondary";
12
+ readonly buttonStyle: "ghost";
13
+ readonly glyph: "text-muted-foreground";
14
+ };
15
+ readonly commands: {
16
+ readonly tone: "secondary";
17
+ readonly buttonStyle: "outline";
18
+ readonly glyph: undefined;
19
+ };
20
+ };
21
+ };
@@ -8,4 +8,5 @@
8
8
  * beside breadcrumbs and tab bars.
9
9
  */
10
10
  export { ActionButtons, ActionMenu, type ActionButtonsProps, type ActionMenuAction, type ActionMenuIcon, type ActionMenuLinkRenderProps, type ActionMenuProps, } from './action-menu';
11
+ export { type ActionMenuContext } from './action-menu.recipes';
11
12
  export { defaultActionMenuStrings, type ActionMenuStrings, } from './action-menu.strings';
@@ -1,20 +1,20 @@
1
1
  /** Private Tailwind recipes; public props and DOM hooks remain owned by the component. */
2
2
  export declare const badgeRecipes: {
3
3
  readonly root: "inline-flex items-center justify-center shrink-0 h-fit rounded-radius font-sans font-medium border border-transparent w-fit max-w-full whitespace-nowrap overflow-visible box-border align-middle";
4
- readonly sizeSm: "min-h-0 py-space-2xs px-control-xs gap-space-xs text-xs leading-none";
5
- readonly sizeMd: "min-h-0 py-space-2xs px-control-xs gap-space-xs text-xs leading-tight";
4
+ readonly sizeSm: "min-h-0 py-[calc(0.1875rem*var(--space-scale))] px-control-xs gap-space-xs text-xs leading-none";
5
+ readonly sizeMd: "min-h-0 py-[calc(0.1875rem*var(--space-scale))] px-control-xs gap-space-xs text-xs leading-tight";
6
6
  readonly sizeLg: "min-h-0 py-space-xs px-control-sm gap-space-sm text-sm leading-tight";
7
7
  readonly isInline: "inline-flex align-baseline text-xs py-space-2xs px-control-xs leading-none";
8
8
  readonly isPending: "[&_.badge-dot]:bg-transparent [&_.badge-dot]:border-[1.5px] [&_.badge-dot]:border-current";
9
9
  readonly isPulse: "[&_.badge-dot]:animate-badge-pulse motion-reduce:[&_.badge-dot]:animate-none";
10
- readonly dot: "badge-dot size-1.5 rounded-full shrink-0 bg-current";
10
+ readonly dot: "badge-dot size-1.5 shrink-0 rounded-full bg-current";
11
11
  readonly icon: "size-icon-sm shrink-0";
12
12
  readonly label: "inline-flex min-w-0 max-w-full items-center gap-space-xs overflow-hidden text-ellipsis whitespace-nowrap";
13
13
  readonly tonePrimary: "bg-primary text-primary-foreground border-primary";
14
14
  readonly toneNeutral: "bg-foreground/8 text-foreground border-transparent";
15
15
  readonly toneSecondary: "bg-foreground/8 text-foreground border-transparent";
16
16
  readonly toneSuccess: "bg-success/20 text-success border-success/30";
17
- readonly toneInfo: "bg-info/10 text-info border-info/30";
18
- readonly toneWarning: "bg-warning/20 text-warning-accent border-warning/35";
17
+ readonly toneInfo: "bg-info/20 text-info border-info/30";
18
+ readonly toneWarning: "bg-warning/20 text-warning-accent border-warning/40";
19
19
  readonly toneDestructive: "bg-destructive/10 text-destructive border-destructive/30";
20
20
  };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * BatchActionBar — the bar shown once a selection exists: the count, the bulk
3
+ * actions, and a way out.
4
+ *
5
+ * Several features share it (DataTable, MediaLibrary, product variants), so it
6
+ * lives in base. `floating` docks to the bottom centre of the viewport, so the
7
+ * selection stays reachable after scrolling a long list; `inline` stays in flow
8
+ * inside a panel that scrolls its own body, where a dock would cover the rows.
9
+ *
10
+ * Callers can mount it unconditionally: at a count of zero it renders nothing.
11
+ * The count is a polite live region, so changes are announced. Escape inside
12
+ * the bar clears, and when the bar goes away with focus inside it (Clear, or an
13
+ * action that drops the selection), focus returns to `returnFocusRef` or to the
14
+ * control focus came from rather than falling to the document body.
15
+ */
16
+ import { type ReactNode, type RefObject } from 'react';
17
+ import { type StringsProp } from '../../../lib/strings';
18
+ import { type BatchActionBarStrings } from './batch-action-bar.strings';
19
+ export type BatchActionBarPlacement = 'floating' | 'inline';
20
+ export interface BatchActionBarProps {
21
+ /** How many items are selected. At zero or below no bar renders, so a caller can mount it unconditionally. */
22
+ selectedCount: number;
23
+ /** Denominator for the summary. Omit when the total is unknown or unbounded. */
24
+ totalCount?: number;
25
+ /** Drops the selection. Omit to render no Clear control or Escape shortcut; a selection the user cannot drop needs a reason. */
26
+ onClear?: () => void;
27
+ /**
28
+ * `floating` (default) docks to the bottom centre of the viewport, or of the
29
+ * nearest transformed ancestor; `inline` sits in flow at full width.
30
+ */
31
+ placement?: BatchActionBarPlacement;
32
+ /**
33
+ * Where focus goes when the bar disappears while focus is inside it: the list
34
+ * it acts on, or that list's select-all control. When focus entered the bar
35
+ * from a control inside this element that is still there, it returns to that
36
+ * control instead. Without it, or when it cannot take focus, focus returns to
37
+ * the control it entered the bar from, if that is still in the document.
38
+ */
39
+ returnFocusRef?: RefObject<HTMLElement | null>;
40
+ /** Overrides this bar's own copy: `summary(selected, total)`, `clear`, and the region's accessible `label`. */
41
+ strings?: StringsProp<BatchActionBarStrings>;
42
+ /** The bulk actions: buttons, a menu, whatever the surface needs. Clear follows them. */
43
+ children?: ReactNode;
44
+ /** Merged onto the bar. */
45
+ className?: string;
46
+ }
47
+ export declare function BatchActionBar({ selectedCount, totalCount, onClear, placement, returnFocusRef, strings: stringsProp, children, className, }: BatchActionBarProps): import("react").JSX.Element | null;
48
+ export declare namespace BatchActionBar {
49
+ var displayName: string;
50
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Default user-facing strings for `<BatchActionBar>`.
3
+ *
4
+ * Consumers wire their own i18n at the call site:
5
+ *
6
+ * <BatchActionBar strings={{ summary: (n, total) => t('selection.summary', { n, total }) }} … />
7
+ */
8
+ export interface BatchActionBarStrings {
9
+ /**
10
+ * The selection summary ("3 selected", "3 of 250 selected"). A function,
11
+ * because the sentence shape varies by language; `total` is `undefined`
12
+ * when the caller does not know or bound the total.
13
+ */
14
+ summary: (selected: number, total?: number) => string;
15
+ /** The control that drops the selection. */
16
+ clear: string;
17
+ /** The accessible name of the bar's region. */
18
+ label: string;
19
+ }
20
+ export declare const defaultBatchActionBarStrings: BatchActionBarStrings;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * batch-action-bar — the selection bar: a count, bulk actions and Clear.
3
+ *
4
+ * A base structure shared by DataTable, MediaLibrary and product variants;
5
+ * any list with a selection can mount it.
6
+ */
7
+ export { BatchActionBar, type BatchActionBarPlacement, type BatchActionBarProps, } from './batch-action-bar';
8
+ export { defaultBatchActionBarStrings, type BatchActionBarStrings, } from './batch-action-bar.strings';
@@ -1,6 +1,6 @@
1
1
  /** Private Tailwind recipes; public props and DOM hooks remain owned by the component. */
2
2
  export declare const buttonGroupRecipes: {
3
3
  readonly root: "inline-flex items-stretch rounded-inner box-border data-[orientation=vertical]:flex-col [&[data-orientation=horizontal]>:not(:last-child)]:rounded-e-none [&[data-orientation=horizontal]>:not(:first-child)]:rounded-s-none [&[data-orientation=horizontal]>:not(:first-child)]:border-s-0 [&[data-orientation=vertical]>:not(:last-child)]:rounded-b-none [&[data-orientation=vertical]>:not(:first-child)]:rounded-t-none [&[data-orientation=vertical]>:not(:first-child)]:border-t-0";
4
- readonly text: "inline-flex items-center rounded-inner px-control-sm py-0 bg-muted border border-foreground/15 text-sm text-muted-foreground";
4
+ readonly text: "inline-flex items-center rounded-inner px-control-sm py-0 bg-muted border border-input text-sm text-muted-foreground";
5
5
  readonly separator: "bg-border w-px self-stretch";
6
6
  };
@@ -1,8 +1,8 @@
1
1
  /** Shared interaction states and loader anatomy; public variants own geometry. */
2
2
  export declare const buttonRecipes: {
3
3
  readonly solidInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:brightness-95 [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:brightness-90";
4
- readonly neutralInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-accent [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-muted";
5
- readonly secondaryInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-secondary [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-accent";
4
+ readonly neutralInteractive: "hover:text-accent-foreground [&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-accent [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-muted";
5
+ readonly secondaryInteractive: "hover:text-accent-foreground [&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-accent [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-muted";
6
6
  readonly primaryInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-primary/10 [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-primary/20";
7
7
  readonly destructiveInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-destructive/10 [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-destructive/20";
8
8
  readonly successInteractive: "[&:hover:not(:active):not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-success/10 [&:active:not(:disabled):not([data-disabled]):not([aria-disabled=true])]:bg-success/20";
@@ -32,11 +32,12 @@ interface LoaderButtonContentProps {
32
32
  loadingText: string;
33
33
  icon?: BaseButtonProps['icon'];
34
34
  iconPosition?: BaseButtonProps['iconPosition'];
35
+ iconOnly?: boolean;
35
36
  size?: ButtonSize;
36
37
  /** Ends the label with an ellipsis instead of wrapping it. */
37
38
  truncate?: boolean;
38
39
  children: React.ReactNode;
39
40
  }
40
- export declare function LoaderButtonContent({ isLoading, loadingText, icon: Icon, iconPosition, size: _size, truncate, children, }: LoaderButtonContentProps): React.JSX.Element;
41
+ export declare function LoaderButtonContent({ isLoading, loadingText, icon: Icon, iconPosition, iconOnly, size: _size, truncate, children, }: LoaderButtonContentProps): React.JSX.Element;
41
42
  declare const LoaderButton: React.ForwardRefExoticComponent<Omit<LoaderButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
42
43
  export { LoaderButton };
@@ -11,7 +11,7 @@ export declare const cardRecipes: {
11
11
  readonly shell: "@container/card flex flex-col w-full font-sans rounded-radius box-border overflow-hidden py-surface gap-space-xl transition-[background-color,border-color,box-shadow] duration-150";
12
12
  readonly surfaceCard: "bg-card border border-border shadow-sm text-card-foreground";
13
13
  readonly surfaceDefault: "bg-card border border-border shadow-sm text-card-foreground";
14
- readonly surfaceFlat: "bg-transparent border-0 shadow-none text-foreground";
14
+ readonly surfaceFlat: "bg-transparent border-0 shadow-none text-inherit";
15
15
  readonly surfaceFramed: "bg-card border border-border shadow-sm ring-4 ring-border/30 text-card-foreground";
16
16
  readonly surfaceRaised: "bg-card border border-border shadow-md text-card-foreground";
17
17
  readonly surfaceSunken: "bg-muted border border-border text-foreground";
@@ -22,11 +22,10 @@ export declare const cardRecipes: {
22
22
  readonly headerLeadingSingle: "basis-36";
23
23
  readonly headerTrailing: "flex max-w-full flex-wrap shrink-0 items-center gap-space-md";
24
24
  readonly headerDivider: "border-b border-border [&.border-b]:!pb-surface";
25
- readonly title: "min-w-0 leading-tight text-card-foreground";
25
+ readonly title: "min-w-0 leading-tight text-inherit";
26
26
  readonly titleSm: "text-sm";
27
27
  readonly titleMd: "text-base";
28
28
  readonly titleLg: "text-lg";
29
- readonly description: "text-sm text-muted-foreground leading-normal";
30
29
  readonly content: "px-surface box-border min-w-0";
31
30
  readonly footer: "flex items-center px-surface box-border";
32
31
  readonly footerDivider: "border-t border-border [&.border-t]:!pt-surface";
@@ -1,16 +1,6 @@
1
- /**
2
- * SmartCardSkeleton — placeholder shell rendered while a SmartCard's
3
- * data is loading. Picks up the canonical card surface so the loading
4
- * state visually matches the eventual `SmartCard` it'll replace.
5
- */
6
- import type { ReactNode } from 'react';
7
- export interface SmartCardSkeletonProps {
8
- /** Surface title. */
9
- title?: ReactNode;
10
- lines?: number;
11
- className?: string;
12
- }
13
- export declare function SmartCardSkeleton({ title, lines, className }: SmartCardSkeletonProps): import("react").JSX.Element;
1
+ import type { SmartCardSkeletonProps } from '../smart-card.types';
2
+ export type { SmartCardSkeletonProps } from '../smart-card.types';
3
+ export declare function SmartCardSkeleton({ title, lines, surface, className }: SmartCardSkeletonProps): import("react").JSX.Element;
14
4
  export declare namespace SmartCardSkeleton {
15
5
  var displayName: string;
16
6
  }
@@ -104,12 +104,17 @@ export interface SmartCardProps extends Omit<ComponentPropsWithoutRef<'div'>, 'c
104
104
  */
105
105
  footerSlot?: ReactNode;
106
106
  /**
107
- * Render a `border-b` rule between header and content. Defaults to
108
- * `UIProvider.card.defaultHeaderDivider` (`false` unless configured).
109
- * With no body/alert, header and footer share one footer-owned divider.
107
+ * Render a `border-b` rule between header and content. On a framed
108
+ * surface it defaults to `UIProvider.card.defaultHeaderDivider` (`true`
109
+ * unless configured); a flat surface and `headerPlacement="frame"` default
110
+ * to no rule. With no body/alert, header and footer share one footer-owned divider.
110
111
  */
111
112
  headerDivider?: boolean;
112
- /** Footer rule inherits UIProvider.card.defaultFooterDivider; false suppresses it. Adjacent header/footer regions share one rule. */
113
+ /**
114
+ * Footer rule. On a framed surface it inherits UIProvider.card.defaultFooterDivider
115
+ * (`true` unless configured); a flat surface defaults to no rule. `false`
116
+ * suppresses it. Adjacent header/footer regions share one rule.
117
+ */
113
118
  footerDivider?: boolean;
114
119
  /**
115
120
  * Make the card body collapsible. Pass `true` for default behavior
@@ -141,6 +146,8 @@ export interface SmartCardSkeletonProps {
141
146
  title?: ReactNode;
142
147
  /** Placeholder body lines to draw. */
143
148
  lines?: number;
149
+ /** Matches Card's explicit > provider > framed surface resolution while loading. */
150
+ surface?: SmartCardSurface;
144
151
  /** Merged onto the skeleton root. */
145
152
  className?: string;
146
153
  }