@liveblocks/react-ui 1.12.0-initial1

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 (391) hide show
  1. package/README.md +65 -0
  2. package/dist/components/Comment.js +473 -0
  3. package/dist/components/Comment.js.map +1 -0
  4. package/dist/components/Comment.mjs +447 -0
  5. package/dist/components/Comment.mjs.map +1 -0
  6. package/dist/components/Composer.js +299 -0
  7. package/dist/components/Composer.js.map +1 -0
  8. package/dist/components/Composer.mjs +297 -0
  9. package/dist/components/Composer.mjs.map +1 -0
  10. package/dist/components/InboxNotification.js +374 -0
  11. package/dist/components/InboxNotification.js.map +1 -0
  12. package/dist/components/InboxNotification.mjs +372 -0
  13. package/dist/components/InboxNotification.mjs.map +1 -0
  14. package/dist/components/InboxNotificationList.js +19 -0
  15. package/dist/components/InboxNotificationList.js.map +1 -0
  16. package/dist/components/InboxNotificationList.mjs +17 -0
  17. package/dist/components/InboxNotificationList.mjs.map +1 -0
  18. package/dist/components/Thread.js +188 -0
  19. package/dist/components/Thread.js.map +1 -0
  20. package/dist/components/Thread.mjs +167 -0
  21. package/dist/components/Thread.mjs.map +1 -0
  22. package/dist/components/internal/Attribution.js +26 -0
  23. package/dist/components/internal/Attribution.js.map +1 -0
  24. package/dist/components/internal/Attribution.mjs +24 -0
  25. package/dist/components/internal/Attribution.mjs.map +1 -0
  26. package/dist/components/internal/Avatar.js +40 -0
  27. package/dist/components/internal/Avatar.js.map +1 -0
  28. package/dist/components/internal/Avatar.mjs +38 -0
  29. package/dist/components/internal/Avatar.mjs.map +1 -0
  30. package/dist/components/internal/Button.js +24 -0
  31. package/dist/components/internal/Button.js.map +1 -0
  32. package/dist/components/internal/Button.mjs +22 -0
  33. package/dist/components/internal/Button.mjs.map +1 -0
  34. package/dist/components/internal/Dropdown.js +72 -0
  35. package/dist/components/internal/Dropdown.js.map +1 -0
  36. package/dist/components/internal/Dropdown.mjs +47 -0
  37. package/dist/components/internal/Dropdown.mjs.map +1 -0
  38. package/dist/components/internal/Emoji.js +18 -0
  39. package/dist/components/internal/Emoji.js.map +1 -0
  40. package/dist/components/internal/Emoji.mjs +16 -0
  41. package/dist/components/internal/Emoji.mjs.map +1 -0
  42. package/dist/components/internal/EmojiPicker.js +186 -0
  43. package/dist/components/internal/EmojiPicker.js.map +1 -0
  44. package/dist/components/internal/EmojiPicker.mjs +162 -0
  45. package/dist/components/internal/EmojiPicker.mjs.map +1 -0
  46. package/dist/components/internal/Icon.js +28 -0
  47. package/dist/components/internal/Icon.js.map +1 -0
  48. package/dist/components/internal/Icon.mjs +24 -0
  49. package/dist/components/internal/Icon.mjs.map +1 -0
  50. package/dist/components/internal/InboxNotificationThread.js +116 -0
  51. package/dist/components/internal/InboxNotificationThread.js.map +1 -0
  52. package/dist/components/internal/InboxNotificationThread.mjs +112 -0
  53. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -0
  54. package/dist/components/internal/List.js +34 -0
  55. package/dist/components/internal/List.js.map +1 -0
  56. package/dist/components/internal/List.mjs +32 -0
  57. package/dist/components/internal/List.mjs.map +1 -0
  58. package/dist/components/internal/Room.js +22 -0
  59. package/dist/components/internal/Room.js.map +1 -0
  60. package/dist/components/internal/Room.mjs +20 -0
  61. package/dist/components/internal/Room.mjs.map +1 -0
  62. package/dist/components/internal/Tooltip.js +91 -0
  63. package/dist/components/internal/Tooltip.js.map +1 -0
  64. package/dist/components/internal/Tooltip.mjs +65 -0
  65. package/dist/components/internal/Tooltip.mjs.map +1 -0
  66. package/dist/components/internal/User.js +41 -0
  67. package/dist/components/internal/User.js.map +1 -0
  68. package/dist/components/internal/User.mjs +39 -0
  69. package/dist/components/internal/User.mjs.map +1 -0
  70. package/dist/components.js +64 -0
  71. package/dist/components.js.map +1 -0
  72. package/dist/components.mjs +41 -0
  73. package/dist/components.mjs.map +1 -0
  74. package/dist/config.js +33 -0
  75. package/dist/config.js.map +1 -0
  76. package/dist/config.mjs +30 -0
  77. package/dist/config.mjs.map +1 -0
  78. package/dist/constants.js +10 -0
  79. package/dist/constants.js.map +1 -0
  80. package/dist/constants.mjs +6 -0
  81. package/dist/constants.mjs.map +1 -0
  82. package/dist/icons/ArrowDown.js +15 -0
  83. package/dist/icons/ArrowDown.js.map +1 -0
  84. package/dist/icons/ArrowDown.mjs +13 -0
  85. package/dist/icons/ArrowDown.mjs.map +1 -0
  86. package/dist/icons/Check.js +15 -0
  87. package/dist/icons/Check.js.map +1 -0
  88. package/dist/icons/Check.mjs +13 -0
  89. package/dist/icons/Check.mjs.map +1 -0
  90. package/dist/icons/Cross.js +17 -0
  91. package/dist/icons/Cross.js.map +1 -0
  92. package/dist/icons/Cross.mjs +15 -0
  93. package/dist/icons/Cross.mjs.map +1 -0
  94. package/dist/icons/Delete.js +15 -0
  95. package/dist/icons/Delete.js.map +1 -0
  96. package/dist/icons/Delete.mjs +13 -0
  97. package/dist/icons/Delete.mjs.map +1 -0
  98. package/dist/icons/Edit.js +15 -0
  99. package/dist/icons/Edit.js.map +1 -0
  100. package/dist/icons/Edit.mjs +13 -0
  101. package/dist/icons/Edit.mjs.map +1 -0
  102. package/dist/icons/Ellipsis.js +26 -0
  103. package/dist/icons/Ellipsis.js.map +1 -0
  104. package/dist/icons/Ellipsis.mjs +24 -0
  105. package/dist/icons/Ellipsis.mjs.map +1 -0
  106. package/dist/icons/Emoji.js +27 -0
  107. package/dist/icons/Emoji.js.map +1 -0
  108. package/dist/icons/Emoji.mjs +25 -0
  109. package/dist/icons/Emoji.mjs.map +1 -0
  110. package/dist/icons/EmojiAdd.js +29 -0
  111. package/dist/icons/EmojiAdd.js.map +1 -0
  112. package/dist/icons/EmojiAdd.mjs +27 -0
  113. package/dist/icons/EmojiAdd.mjs.map +1 -0
  114. package/dist/icons/Mention.js +17 -0
  115. package/dist/icons/Mention.js.map +1 -0
  116. package/dist/icons/Mention.mjs +15 -0
  117. package/dist/icons/Mention.mjs.map +1 -0
  118. package/dist/icons/Missing.js +19 -0
  119. package/dist/icons/Missing.js.map +1 -0
  120. package/dist/icons/Missing.mjs +17 -0
  121. package/dist/icons/Missing.mjs.map +1 -0
  122. package/dist/icons/Resolve.js +19 -0
  123. package/dist/icons/Resolve.js.map +1 -0
  124. package/dist/icons/Resolve.mjs +17 -0
  125. package/dist/icons/Resolve.mjs.map +1 -0
  126. package/dist/icons/Resolved.js +21 -0
  127. package/dist/icons/Resolved.js.map +1 -0
  128. package/dist/icons/Resolved.mjs +19 -0
  129. package/dist/icons/Resolved.mjs.map +1 -0
  130. package/dist/icons/Search.js +15 -0
  131. package/dist/icons/Search.js.map +1 -0
  132. package/dist/icons/Search.mjs +13 -0
  133. package/dist/icons/Search.mjs.map +1 -0
  134. package/dist/icons/Send.js +15 -0
  135. package/dist/icons/Send.js.map +1 -0
  136. package/dist/icons/Send.mjs +13 -0
  137. package/dist/icons/Send.mjs.map +1 -0
  138. package/dist/icons/Spinner.js +22 -0
  139. package/dist/icons/Spinner.js.map +1 -0
  140. package/dist/icons/Spinner.mjs +20 -0
  141. package/dist/icons/Spinner.mjs.map +1 -0
  142. package/dist/index.d.mts +476 -0
  143. package/dist/index.d.ts +476 -0
  144. package/dist/index.js +20 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/index.mjs +11 -0
  147. package/dist/index.mjs.map +1 -0
  148. package/dist/overrides.js +100 -0
  149. package/dist/overrides.js.map +1 -0
  150. package/dist/overrides.mjs +77 -0
  151. package/dist/overrides.mjs.map +1 -0
  152. package/dist/primitives/Comment/index.js +113 -0
  153. package/dist/primitives/Comment/index.js.map +1 -0
  154. package/dist/primitives/Comment/index.mjs +109 -0
  155. package/dist/primitives/Comment/index.mjs.map +1 -0
  156. package/dist/primitives/Comment/utils.js +25 -0
  157. package/dist/primitives/Comment/utils.js.map +1 -0
  158. package/dist/primitives/Comment/utils.mjs +20 -0
  159. package/dist/primitives/Comment/utils.mjs.map +1 -0
  160. package/dist/primitives/Composer/contexts.js +34 -0
  161. package/dist/primitives/Composer/contexts.js.map +1 -0
  162. package/dist/primitives/Composer/contexts.mjs +27 -0
  163. package/dist/primitives/Composer/contexts.mjs.map +1 -0
  164. package/dist/primitives/Composer/index.js +771 -0
  165. package/dist/primitives/Composer/index.js.map +1 -0
  166. package/dist/primitives/Composer/index.mjs +762 -0
  167. package/dist/primitives/Composer/index.mjs.map +1 -0
  168. package/dist/primitives/Composer/utils.js +102 -0
  169. package/dist/primitives/Composer/utils.js.map +1 -0
  170. package/dist/primitives/Composer/utils.mjs +93 -0
  171. package/dist/primitives/Composer/utils.mjs.map +1 -0
  172. package/dist/primitives/EmojiPicker/contexts.js +19 -0
  173. package/dist/primitives/EmojiPicker/contexts.js.map +1 -0
  174. package/dist/primitives/EmojiPicker/contexts.mjs +16 -0
  175. package/dist/primitives/EmojiPicker/contexts.mjs.map +1 -0
  176. package/dist/primitives/EmojiPicker/index.js +434 -0
  177. package/dist/primitives/EmojiPicker/index.js.map +1 -0
  178. package/dist/primitives/EmojiPicker/index.mjs +430 -0
  179. package/dist/primitives/EmojiPicker/index.mjs.map +1 -0
  180. package/dist/primitives/EmojiPicker/utils.js +329 -0
  181. package/dist/primitives/EmojiPicker/utils.js.map +1 -0
  182. package/dist/primitives/EmojiPicker/utils.mjs +325 -0
  183. package/dist/primitives/EmojiPicker/utils.mjs.map +1 -0
  184. package/dist/primitives/Timestamp.js +121 -0
  185. package/dist/primitives/Timestamp.js.map +1 -0
  186. package/dist/primitives/Timestamp.mjs +119 -0
  187. package/dist/primitives/Timestamp.mjs.map +1 -0
  188. package/dist/primitives/index.d.mts +502 -0
  189. package/dist/primitives/index.d.ts +502 -0
  190. package/dist/primitives/index.js +16 -0
  191. package/dist/primitives/index.js.map +1 -0
  192. package/dist/primitives/index.mjs +9 -0
  193. package/dist/primitives/index.mjs.map +1 -0
  194. package/dist/primitives/internal/Emoji.js +30 -0
  195. package/dist/primitives/internal/Emoji.js.map +1 -0
  196. package/dist/primitives/internal/Emoji.mjs +28 -0
  197. package/dist/primitives/internal/Emoji.mjs.map +1 -0
  198. package/dist/shared.js +21 -0
  199. package/dist/shared.js.map +1 -0
  200. package/dist/shared.mjs +19 -0
  201. package/dist/shared.mjs.map +1 -0
  202. package/dist/slate/plugins/auto-formatting.js +83 -0
  203. package/dist/slate/plugins/auto-formatting.js.map +1 -0
  204. package/dist/slate/plugins/auto-formatting.mjs +81 -0
  205. package/dist/slate/plugins/auto-formatting.mjs.map +1 -0
  206. package/dist/slate/plugins/auto-links.js +175 -0
  207. package/dist/slate/plugins/auto-links.js.map +1 -0
  208. package/dist/slate/plugins/auto-links.mjs +172 -0
  209. package/dist/slate/plugins/auto-links.mjs.map +1 -0
  210. package/dist/slate/plugins/empty-clear-formatting.js +18 -0
  211. package/dist/slate/plugins/empty-clear-formatting.js.map +1 -0
  212. package/dist/slate/plugins/empty-clear-formatting.mjs +16 -0
  213. package/dist/slate/plugins/empty-clear-formatting.mjs.map +1 -0
  214. package/dist/slate/plugins/mentions.js +112 -0
  215. package/dist/slate/plugins/mentions.js.map +1 -0
  216. package/dist/slate/plugins/mentions.mjs +105 -0
  217. package/dist/slate/plugins/mentions.mjs.map +1 -0
  218. package/dist/slate/utils/get-character.js +50 -0
  219. package/dist/slate/utils/get-character.js.map +1 -0
  220. package/dist/slate/utils/get-character.mjs +47 -0
  221. package/dist/slate/utils/get-character.mjs.map +1 -0
  222. package/dist/slate/utils/get-dom-range.js +17 -0
  223. package/dist/slate/utils/get-dom-range.js.map +1 -0
  224. package/dist/slate/utils/get-dom-range.mjs +15 -0
  225. package/dist/slate/utils/get-dom-range.mjs.map +1 -0
  226. package/dist/slate/utils/get-match-range.js +53 -0
  227. package/dist/slate/utils/get-match-range.js.map +1 -0
  228. package/dist/slate/utils/get-match-range.mjs +51 -0
  229. package/dist/slate/utils/get-match-range.mjs.map +1 -0
  230. package/dist/slate/utils/is-empty-string.js +8 -0
  231. package/dist/slate/utils/is-empty-string.js.map +1 -0
  232. package/dist/slate/utils/is-empty-string.mjs +6 -0
  233. package/dist/slate/utils/is-empty-string.mjs.map +1 -0
  234. package/dist/slate/utils/is-empty.js +10 -0
  235. package/dist/slate/utils/is-empty.js.map +1 -0
  236. package/dist/slate/utils/is-empty.mjs +8 -0
  237. package/dist/slate/utils/is-empty.mjs.map +1 -0
  238. package/dist/slate/utils/is-selection-collapsed.js +10 -0
  239. package/dist/slate/utils/is-selection-collapsed.js.map +1 -0
  240. package/dist/slate/utils/is-selection-collapsed.mjs +8 -0
  241. package/dist/slate/utils/is-selection-collapsed.mjs.map +1 -0
  242. package/dist/slate/utils/marks.js +43 -0
  243. package/dist/slate/utils/marks.js.map +1 -0
  244. package/dist/slate/utils/marks.mjs +38 -0
  245. package/dist/slate/utils/marks.mjs.map +1 -0
  246. package/dist/utils/Persist.js +85 -0
  247. package/dist/utils/Persist.js.map +1 -0
  248. package/dist/utils/Persist.mjs +81 -0
  249. package/dist/utils/Persist.mjs.map +1 -0
  250. package/dist/utils/Portal.js +27 -0
  251. package/dist/utils/Portal.js.map +1 -0
  252. package/dist/utils/Portal.mjs +25 -0
  253. package/dist/utils/Portal.mjs.map +1 -0
  254. package/dist/utils/capitalize.js +8 -0
  255. package/dist/utils/capitalize.js.map +1 -0
  256. package/dist/utils/capitalize.mjs +6 -0
  257. package/dist/utils/capitalize.mjs.map +1 -0
  258. package/dist/utils/chunk.js +12 -0
  259. package/dist/utils/chunk.js.map +1 -0
  260. package/dist/utils/chunk.mjs +10 -0
  261. package/dist/utils/chunk.mjs.map +1 -0
  262. package/dist/utils/clamp.js +8 -0
  263. package/dist/utils/clamp.js.map +1 -0
  264. package/dist/utils/clamp.mjs +6 -0
  265. package/dist/utils/clamp.mjs.map +1 -0
  266. package/dist/utils/class-names.js +8 -0
  267. package/dist/utils/class-names.js.map +1 -0
  268. package/dist/utils/class-names.mjs +6 -0
  269. package/dist/utils/class-names.mjs.map +1 -0
  270. package/dist/utils/exists.js +8 -0
  271. package/dist/utils/exists.js.map +1 -0
  272. package/dist/utils/exists.mjs +6 -0
  273. package/dist/utils/exists.mjs.map +1 -0
  274. package/dist/utils/find-last-index.js +15 -0
  275. package/dist/utils/find-last-index.js.map +1 -0
  276. package/dist/utils/find-last-index.mjs +13 -0
  277. package/dist/utils/find-last-index.mjs.map +1 -0
  278. package/dist/utils/flush-sync.js +12 -0
  279. package/dist/utils/flush-sync.js.map +1 -0
  280. package/dist/utils/flush-sync.mjs +10 -0
  281. package/dist/utils/flush-sync.mjs.map +1 -0
  282. package/dist/utils/get-initials.js +13 -0
  283. package/dist/utils/get-initials.js.map +1 -0
  284. package/dist/utils/get-initials.mjs +11 -0
  285. package/dist/utils/get-initials.mjs.map +1 -0
  286. package/dist/utils/intl.js +24 -0
  287. package/dist/utils/intl.js.map +1 -0
  288. package/dist/utils/intl.mjs +20 -0
  289. package/dist/utils/intl.mjs.map +1 -0
  290. package/dist/utils/is-apple.js +9 -0
  291. package/dist/utils/is-apple.js.map +1 -0
  292. package/dist/utils/is-apple.mjs +7 -0
  293. package/dist/utils/is-apple.mjs.map +1 -0
  294. package/dist/utils/is-key.js +26 -0
  295. package/dist/utils/is-key.js.map +1 -0
  296. package/dist/utils/is-key.mjs +24 -0
  297. package/dist/utils/is-key.mjs.map +1 -0
  298. package/dist/utils/memoize.js +19 -0
  299. package/dist/utils/memoize.js.map +1 -0
  300. package/dist/utils/memoize.mjs +17 -0
  301. package/dist/utils/memoize.mjs.map +1 -0
  302. package/dist/utils/pluralize.js +8 -0
  303. package/dist/utils/pluralize.js.map +1 -0
  304. package/dist/utils/pluralize.mjs +6 -0
  305. package/dist/utils/pluralize.mjs.map +1 -0
  306. package/dist/utils/request-idle-callback.js +15 -0
  307. package/dist/utils/request-idle-callback.js.map +1 -0
  308. package/dist/utils/request-idle-callback.mjs +12 -0
  309. package/dist/utils/request-idle-callback.mjs.map +1 -0
  310. package/dist/utils/request-submit.js +20 -0
  311. package/dist/utils/request-submit.js.map +1 -0
  312. package/dist/utils/request-submit.mjs +18 -0
  313. package/dist/utils/request-submit.mjs.map +1 -0
  314. package/dist/utils/url.js +22 -0
  315. package/dist/utils/url.js.map +1 -0
  316. package/dist/utils/url.mjs +20 -0
  317. package/dist/utils/url.mjs.map +1 -0
  318. package/dist/utils/use-controllable-state.js +34 -0
  319. package/dist/utils/use-controllable-state.js.map +1 -0
  320. package/dist/utils/use-controllable-state.mjs +32 -0
  321. package/dist/utils/use-controllable-state.mjs.map +1 -0
  322. package/dist/utils/use-id.js +29 -0
  323. package/dist/utils/use-id.js.map +1 -0
  324. package/dist/utils/use-id.mjs +27 -0
  325. package/dist/utils/use-id.mjs.map +1 -0
  326. package/dist/utils/use-index.js +32 -0
  327. package/dist/utils/use-index.js.map +1 -0
  328. package/dist/utils/use-index.mjs +30 -0
  329. package/dist/utils/use-index.mjs.map +1 -0
  330. package/dist/utils/use-initial.js +10 -0
  331. package/dist/utils/use-initial.js.map +1 -0
  332. package/dist/utils/use-initial.mjs +8 -0
  333. package/dist/utils/use-initial.mjs.map +1 -0
  334. package/dist/utils/use-interval.js +24 -0
  335. package/dist/utils/use-interval.js.map +1 -0
  336. package/dist/utils/use-interval.mjs +22 -0
  337. package/dist/utils/use-interval.mjs.map +1 -0
  338. package/dist/utils/use-latest.js +14 -0
  339. package/dist/utils/use-latest.js.map +1 -0
  340. package/dist/utils/use-latest.mjs +12 -0
  341. package/dist/utils/use-latest.mjs.map +1 -0
  342. package/dist/utils/use-layout-effect.js +8 -0
  343. package/dist/utils/use-layout-effect.js.map +1 -0
  344. package/dist/utils/use-layout-effect.mjs +6 -0
  345. package/dist/utils/use-layout-effect.mjs.map +1 -0
  346. package/dist/utils/use-refs.js +24 -0
  347. package/dist/utils/use-refs.js.map +1 -0
  348. package/dist/utils/use-refs.mjs +22 -0
  349. package/dist/utils/use-refs.mjs.map +1 -0
  350. package/dist/utils/use-rerender.js +14 -0
  351. package/dist/utils/use-rerender.js.map +1 -0
  352. package/dist/utils/use-rerender.mjs +12 -0
  353. package/dist/utils/use-rerender.mjs.map +1 -0
  354. package/dist/utils/use-transition.js +12 -0
  355. package/dist/utils/use-transition.js.map +1 -0
  356. package/dist/utils/use-transition.mjs +10 -0
  357. package/dist/utils/use-transition.mjs.map +1 -0
  358. package/dist/utils/use-visible.js +48 -0
  359. package/dist/utils/use-visible.js.map +1 -0
  360. package/dist/utils/use-visible.mjs +46 -0
  361. package/dist/utils/use-visible.mjs.map +1 -0
  362. package/dist/utils/visually-hidden.js +17 -0
  363. package/dist/utils/visually-hidden.js.map +1 -0
  364. package/dist/utils/visually-hidden.mjs +15 -0
  365. package/dist/utils/visually-hidden.mjs.map +1 -0
  366. package/dist/utils/wrap.js +9 -0
  367. package/dist/utils/wrap.js.map +1 -0
  368. package/dist/utils/wrap.mjs +7 -0
  369. package/dist/utils/wrap.mjs.map +1 -0
  370. package/dist/version.js +10 -0
  371. package/dist/version.js.map +1 -0
  372. package/dist/version.mjs +6 -0
  373. package/dist/version.mjs.map +1 -0
  374. package/package.json +142 -0
  375. package/primitives/README.md +5 -0
  376. package/primitives/package.json +4 -0
  377. package/src/styles/constants.css +17 -0
  378. package/src/styles/dark/attributes.css +8 -0
  379. package/src/styles/dark/index.css +29 -0
  380. package/src/styles/dark/media-query.css +7 -0
  381. package/src/styles/index.css +1437 -0
  382. package/src/styles/utils.css +36 -0
  383. package/styles/dark/attributes.css +1 -0
  384. package/styles/dark/attributes.css.d.ts +1 -0
  385. package/styles/dark/attributes.css.map +1 -0
  386. package/styles/dark/media-query.css +1 -0
  387. package/styles/dark/media-query.css.d.ts +1 -0
  388. package/styles/dark/media-query.css.map +1 -0
  389. package/styles.css +1 -0
  390. package/styles.css.d.ts +1 -0
  391. package/styles.css.map +1 -0
@@ -0,0 +1,299 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var core = require('@liveblocks/core');
5
+ var react = require('@liveblocks/react');
6
+ var React = require('react');
7
+ var Emoji = require('../icons/Emoji.js');
8
+ var Mention = require('../icons/Mention.js');
9
+ var Send = require('../icons/Send.js');
10
+ var overrides = require('../overrides.js');
11
+ var index = require('../primitives/Composer/index.js');
12
+ var contexts = require('../primitives/Composer/contexts.js');
13
+ var mentions = require('../slate/plugins/mentions.js');
14
+ var classNames = require('../utils/class-names.js');
15
+ var useControllableState = require('../utils/use-controllable-state.js');
16
+ var Attribution = require('./internal/Attribution.js');
17
+ var Avatar = require('./internal/Avatar.js');
18
+ var Button = require('./internal/Button.js');
19
+ var EmojiPicker = require('./internal/EmojiPicker.js');
20
+ var Tooltip = require('./internal/Tooltip.js');
21
+ var User = require('./internal/User.js');
22
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
23
+ var PopoverPrimitive = require('@radix-ui/react-popover');
24
+
25
+ function ComposerInsertMentionEditorAction({
26
+ label,
27
+ className,
28
+ onClick,
29
+ ...props
30
+ }) {
31
+ const { createMention } = contexts.useComposer();
32
+ const preventDefault = React.useCallback((event) => {
33
+ event.preventDefault();
34
+ }, []);
35
+ const handleClick = React.useCallback(
36
+ (event) => {
37
+ onClick?.(event);
38
+ if (!event.isDefaultPrevented()) {
39
+ event.stopPropagation();
40
+ createMention();
41
+ }
42
+ },
43
+ [createMention, onClick]
44
+ );
45
+ return /* @__PURE__ */ React.createElement(Tooltip.Tooltip, {
46
+ content: label
47
+ }, /* @__PURE__ */ React.createElement(Button.Button, {
48
+ className: classNames.classNames("lb-composer-editor-action", className),
49
+ onMouseDown: preventDefault,
50
+ onClick: handleClick,
51
+ "aria-label": label,
52
+ ...props
53
+ }, /* @__PURE__ */ React.createElement(Mention.MentionIcon, {
54
+ className: "lb-button-icon"
55
+ })));
56
+ }
57
+ function ComposerInsertEmojiEditorAction({
58
+ label,
59
+ onPickerOpenChange,
60
+ className,
61
+ ...props
62
+ }) {
63
+ const { insertText } = contexts.useComposer();
64
+ const preventDefault = React.useCallback((event) => {
65
+ event.preventDefault();
66
+ }, []);
67
+ return /* @__PURE__ */ React.createElement(EmojiPicker.EmojiPicker, {
68
+ onEmojiSelect: insertText,
69
+ onOpenChange: onPickerOpenChange
70
+ }, /* @__PURE__ */ React.createElement(Tooltip.Tooltip, {
71
+ content: label
72
+ }, /* @__PURE__ */ React.createElement(PopoverPrimitive.PopoverTrigger, {
73
+ asChild: true
74
+ }, /* @__PURE__ */ React.createElement(Button.Button, {
75
+ className: classNames.classNames("lb-composer-editor-action", className),
76
+ onMouseDown: preventDefault,
77
+ "aria-label": label,
78
+ ...props
79
+ }, /* @__PURE__ */ React.createElement(Emoji.EmojiIcon, {
80
+ className: "lb-button-icon"
81
+ })))));
82
+ }
83
+ function ComposerMention({ userId }) {
84
+ return /* @__PURE__ */ React.createElement(index.Mention, {
85
+ className: "lb-composer-mention"
86
+ }, mentions.MENTION_CHARACTER, /* @__PURE__ */ React.createElement(User.User, {
87
+ userId
88
+ }));
89
+ }
90
+ function ComposerMentionSuggestions({
91
+ userIds
92
+ }) {
93
+ return userIds.length > 0 ? /* @__PURE__ */ React.createElement(index.Suggestions, {
94
+ className: "lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions"
95
+ }, /* @__PURE__ */ React.createElement(index.SuggestionsList, {
96
+ className: "lb-composer-suggestions-list lb-composer-mention-suggestions-list"
97
+ }, userIds.map((userId) => /* @__PURE__ */ React.createElement(index.SuggestionsListItem, {
98
+ key: userId,
99
+ className: "lb-composer-suggestions-list-item lb-composer-mention-suggestion",
100
+ value: userId
101
+ }, /* @__PURE__ */ React.createElement(Avatar.Avatar, {
102
+ userId,
103
+ className: "lb-composer-mention-suggestion-avatar"
104
+ }), /* @__PURE__ */ React.createElement(User.User, {
105
+ userId,
106
+ className: "lb-composer-mention-suggestion-user"
107
+ }))))) : null;
108
+ }
109
+ function ComposerLink({ href, children }) {
110
+ return /* @__PURE__ */ React.createElement(index.Link, {
111
+ href,
112
+ className: "lb-composer-link"
113
+ }, children);
114
+ }
115
+ const editorComponents = {
116
+ Mention: ComposerMention,
117
+ MentionSuggestions: ComposerMentionSuggestions,
118
+ Link: ComposerLink
119
+ };
120
+ const ComposerWithContext = React.forwardRef(
121
+ ({
122
+ defaultValue,
123
+ disabled,
124
+ autoFocus,
125
+ collapsed: controlledCollapsed,
126
+ defaultCollapsed,
127
+ onCollapsedChange: controlledOnCollapsedChange,
128
+ actions,
129
+ overrides: overrides$1,
130
+ showAttribution,
131
+ onFocus,
132
+ onBlur,
133
+ className,
134
+ ...props
135
+ }, forwardedRef) => {
136
+ const client = react.useClient();
137
+ const hasResolveMentionSuggestions = client[core.kInternal].resolveMentionSuggestions !== void 0;
138
+ const { useSelf } = react.useRoomContextBundle();
139
+ const self = useSelf();
140
+ const isDisabled = React.useMemo(
141
+ () => disabled || !self?.canComment,
142
+ [disabled, self?.canComment]
143
+ );
144
+ const { isEmpty } = contexts.useComposer();
145
+ const $ = overrides.useOverrides(overrides$1);
146
+ const [isEmojiPickerOpen, setEmojiPickerOpen] = React.useState(false);
147
+ const [collapsed, onCollapsedChange] = useControllableState.useControllableState(
148
+ controlledCollapsed === void 0 && defaultCollapsed === void 0 ? false : controlledCollapsed,
149
+ controlledOnCollapsedChange,
150
+ defaultCollapsed
151
+ );
152
+ const preventDefault = React.useCallback((event) => {
153
+ event.preventDefault();
154
+ }, []);
155
+ const stopPropagation = React.useCallback((event) => {
156
+ event.stopPropagation();
157
+ }, []);
158
+ const handleEditorClick = React.useCallback(
159
+ (event) => {
160
+ event.stopPropagation();
161
+ if (isEmpty) {
162
+ onCollapsedChange?.(false);
163
+ }
164
+ },
165
+ [isEmpty, onCollapsedChange]
166
+ );
167
+ const handleFocus = React.useCallback(
168
+ (event) => {
169
+ onFocus?.(event);
170
+ if (event.isDefaultPrevented()) {
171
+ return;
172
+ }
173
+ if (isEmpty) {
174
+ onCollapsedChange?.(false);
175
+ }
176
+ },
177
+ [isEmpty, onCollapsedChange, onFocus]
178
+ );
179
+ const handleBlur = React.useCallback(
180
+ (event) => {
181
+ onBlur?.(event);
182
+ if (event.isDefaultPrevented()) {
183
+ return;
184
+ }
185
+ const isOutside = !event.currentTarget.contains(event.relatedTarget);
186
+ if (isOutside && isEmpty && !isEmojiPickerOpen) {
187
+ onCollapsedChange?.(true);
188
+ }
189
+ },
190
+ [isEmojiPickerOpen, isEmpty, onBlur, onCollapsedChange]
191
+ );
192
+ return /* @__PURE__ */ React.createElement("form", {
193
+ className: classNames.classNames(
194
+ "lb-root lb-composer lb-composer-form",
195
+ className
196
+ ),
197
+ dir: $.dir,
198
+ ...props,
199
+ ref: forwardedRef,
200
+ "data-collapsed": collapsed ? "" : void 0,
201
+ onFocus: handleFocus,
202
+ onBlur: handleBlur
203
+ }, /* @__PURE__ */ React.createElement(index.Editor, {
204
+ className: "lb-composer-editor",
205
+ onClick: handleEditorClick,
206
+ placeholder: $.COMPOSER_PLACEHOLDER,
207
+ defaultValue,
208
+ disabled: isDisabled,
209
+ autoFocus,
210
+ components: editorComponents,
211
+ dir: $.dir
212
+ }), !collapsed && /* @__PURE__ */ React.createElement("div", {
213
+ className: "lb-composer-footer"
214
+ }, /* @__PURE__ */ React.createElement("div", {
215
+ className: "lb-composer-editor-actions"
216
+ }, hasResolveMentionSuggestions && /* @__PURE__ */ React.createElement(ComposerInsertMentionEditorAction, {
217
+ label: $.COMPOSER_INSERT_MENTION,
218
+ disabled: isDisabled
219
+ }), /* @__PURE__ */ React.createElement(ComposerInsertEmojiEditorAction, {
220
+ label: $.COMPOSER_INSERT_EMOJI,
221
+ onPickerOpenChange: setEmojiPickerOpen,
222
+ disabled: isDisabled
223
+ })), showAttribution && /* @__PURE__ */ React.createElement(Attribution.Attribution, null), /* @__PURE__ */ React.createElement("div", {
224
+ className: "lb-composer-actions"
225
+ }, actions ?? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Tooltip.ShortcutTooltip, {
226
+ content: $.COMPOSER_SEND,
227
+ shortcut: /* @__PURE__ */ React.createElement(Tooltip.ShortcutTooltipKey, {
228
+ name: "enter"
229
+ })
230
+ }, /* @__PURE__ */ React.createElement(index.Submit, {
231
+ disabled: isDisabled,
232
+ asChild: true
233
+ }, /* @__PURE__ */ React.createElement(Button.Button, {
234
+ onMouseDown: preventDefault,
235
+ onClick: stopPropagation,
236
+ className: "lb-composer-action",
237
+ variant: "primary",
238
+ "aria-label": $.COMPOSER_SEND
239
+ }, /* @__PURE__ */ React.createElement(Send.SendIcon, null))))))));
240
+ }
241
+ );
242
+ const Composer = React.forwardRef(
243
+ ({
244
+ threadId,
245
+ commentId,
246
+ metadata,
247
+ onComposerSubmit,
248
+ ...props
249
+ }, forwardedRef) => {
250
+ const { useCreateThread, useCreateComment, useEditComment } = react.useRoomContextBundle();
251
+ const createThread = useCreateThread();
252
+ const createComment = useCreateComment();
253
+ const editComment = useEditComment();
254
+ const handleCommentSubmit = React.useCallback(
255
+ (comment, event) => {
256
+ onComposerSubmit?.(comment, event);
257
+ if (event.isDefaultPrevented()) {
258
+ return;
259
+ }
260
+ if (commentId && threadId) {
261
+ editComment({
262
+ commentId,
263
+ threadId,
264
+ body: comment.body
265
+ });
266
+ } else if (threadId) {
267
+ createComment({
268
+ threadId,
269
+ body: comment.body
270
+ });
271
+ } else {
272
+ createThread({
273
+ body: comment.body,
274
+ metadata: metadata ?? {}
275
+ });
276
+ }
277
+ },
278
+ [
279
+ commentId,
280
+ createComment,
281
+ createThread,
282
+ editComment,
283
+ metadata,
284
+ onComposerSubmit,
285
+ threadId
286
+ ]
287
+ );
288
+ return /* @__PURE__ */ React.createElement(TooltipPrimitive.TooltipProvider, null, /* @__PURE__ */ React.createElement(index.Form, {
289
+ onComposerSubmit: handleCommentSubmit,
290
+ asChild: true
291
+ }, /* @__PURE__ */ React.createElement(ComposerWithContext, {
292
+ ...props,
293
+ ref: forwardedRef
294
+ })));
295
+ }
296
+ );
297
+
298
+ exports.Composer = Composer;
299
+ //# sourceMappingURL=Composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Composer.js","sources":["../../src/components/Composer.tsx"],"sourcesContent":["\"use client\";\n\nimport { type BaseMetadata, kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoomContextBundle } from \"@liveblocks/react\";\nimport type {\n ComponentPropsWithoutRef,\n FocusEvent,\n FormEvent,\n ForwardedRef,\n MouseEvent,\n ReactNode,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport React, { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport { EmojiIcon } from \"../icons/Emoji\";\nimport { MentionIcon } from \"../icons/Mention\";\nimport { SendIcon } from \"../icons/Send\";\nimport type { ComposerOverrides, GlobalOverrides } from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { useComposer } from \"../primitives/Composer/contexts\";\nimport type {\n ComposerEditorComponents,\n ComposerEditorLinkProps,\n ComposerEditorMentionProps,\n ComposerEditorMentionSuggestionsProps,\n ComposerEditorProps,\n ComposerSubmitComment,\n} from \"../primitives/Composer/types\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { ThreadMetadata } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { Attribution } from \"./internal/Attribution\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport type { EmojiPickerProps } from \"./internal/EmojiPicker\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ninterface EditorActionProps extends ComponentPropsWithoutRef<\"button\"> {\n label: string;\n}\n\ninterface EmojiEditorActionProps extends EditorActionProps {\n onPickerOpenChange?: EmojiPickerProps[\"onOpenChange\"];\n}\n\ntype ComposerCreateThreadProps<M extends BaseMetadata> = {\n threadId?: never;\n commentId?: never;\n\n /**\n * The metadata of the thread to create.\n */\n metadata?: M;\n};\n\ntype ComposerCreateCommentProps = {\n /**\n * The ID of the thread to reply to.\n */\n threadId: string;\n commentId?: never;\n metadata?: never;\n};\n\ntype ComposerEditCommentProps = {\n /**\n * The ID of the thread to edit a comment in.\n */\n threadId: string;\n\n /**\n * The ID of the comment to edit.\n */\n commentId: string;\n metadata?: never;\n};\n\nexport type ComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<\n ComponentPropsWithoutRef<\"form\">,\n \"defaultValue\"\n> &\n (\n | ComposerCreateThreadProps<M>\n | ComposerCreateCommentProps\n | ComposerEditCommentProps\n ) & {\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: (\n comment: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => Promise<void> | void;\n\n /**\n * The composer's initial value.\n */\n defaultValue?: ComposerEditorProps[\"defaultValue\"];\n\n /**\n * Whether the composer is collapsed. Setting a value will make the composer controlled.\n */\n collapsed?: boolean;\n\n /**\n * The event handler called when the collapsed state of the composer changes.\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Whether the composer is initially collapsed. Setting a value will make the composer uncontrolled.\n */\n defaultCollapsed?: boolean;\n\n /**\n * Whether the composer is disabled.\n */\n disabled?: ComposerEditorProps[\"disabled\"];\n\n /**\n * Whether to focus the composer on mount.\n */\n autoFocus?: ComposerEditorProps[\"autoFocus\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n actions?: ReactNode;\n\n /**\n * @internal\n */\n showAttribution?: boolean;\n };\n\nfunction ComposerInsertMentionEditorAction({\n label,\n className,\n onClick,\n ...props\n}: EditorActionProps) {\n const { createMention } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.isDefaultPrevented()) {\n event.stopPropagation();\n createMention();\n }\n },\n [createMention, onClick]\n );\n\n return (\n <Tooltip content={label}>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onMouseDown={preventDefault}\n onClick={handleClick}\n aria-label={label}\n {...props}\n >\n <MentionIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ComposerInsertEmojiEditorAction({\n label,\n onPickerOpenChange,\n className,\n ...props\n}: EmojiEditorActionProps) {\n const { insertText } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n return (\n <EmojiPicker onEmojiSelect={insertText} onOpenChange={onPickerOpenChange}>\n <Tooltip content={label}>\n <EmojiPickerTrigger asChild>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onMouseDown={preventDefault}\n aria-label={label}\n {...props}\n >\n <EmojiIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n );\n}\n\nfunction ComposerMention({ userId }: ComposerEditorMentionProps) {\n return (\n <ComposerPrimitive.Mention className=\"lb-composer-mention\">\n {MENTION_CHARACTER}\n <User userId={userId} />\n </ComposerPrimitive.Mention>\n );\n}\n\nfunction ComposerMentionSuggestions({\n userIds,\n}: ComposerEditorMentionSuggestionsProps) {\n return userIds.length > 0 ? (\n <ComposerPrimitive.Suggestions className=\"lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions\">\n <ComposerPrimitive.SuggestionsList className=\"lb-composer-suggestions-list lb-composer-mention-suggestions-list\">\n {userIds.map((userId) => (\n <ComposerPrimitive.SuggestionsListItem\n key={userId}\n className=\"lb-composer-suggestions-list-item lb-composer-mention-suggestion\"\n value={userId}\n >\n <Avatar\n userId={userId}\n className=\"lb-composer-mention-suggestion-avatar\"\n />\n <User\n userId={userId}\n className=\"lb-composer-mention-suggestion-user\"\n />\n </ComposerPrimitive.SuggestionsListItem>\n ))}\n </ComposerPrimitive.SuggestionsList>\n </ComposerPrimitive.Suggestions>\n ) : null;\n}\n\nfunction ComposerLink({ href, children }: ComposerEditorLinkProps) {\n return (\n <ComposerPrimitive.Link href={href} className=\"lb-composer-link\">\n {children}\n </ComposerPrimitive.Link>\n );\n}\n\nconst editorComponents: ComposerEditorComponents = {\n Mention: ComposerMention,\n MentionSuggestions: ComposerMentionSuggestions,\n Link: ComposerLink,\n};\n\nconst ComposerWithContext = forwardRef<\n HTMLFormElement,\n Omit<ComposerProps, \"threadId\" | \"commentId\" | \"onComposerSubmit\">\n>(\n (\n {\n defaultValue,\n disabled,\n autoFocus,\n collapsed: controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange: controlledOnCollapsedChange,\n actions,\n overrides,\n showAttribution,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const { useSelf } = useRoomContextBundle();\n const self = useSelf();\n const isDisabled = useMemo(\n () => disabled || !self?.canComment,\n [disabled, self?.canComment]\n );\n const { isEmpty } = useComposer();\n const $ = useOverrides(overrides);\n const [isEmojiPickerOpen, setEmojiPickerOpen] = useState(false);\n const [collapsed, onCollapsedChange] = useControllableState(\n // If the composer is neither controlled nor uncontrolled, it defaults to controlled as uncollapsed.\n controlledCollapsed === undefined && defaultCollapsed === undefined\n ? false\n : controlledCollapsed,\n controlledOnCollapsedChange,\n defaultCollapsed\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEditorClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n\n if (isEmpty) {\n onCollapsedChange?.(false);\n }\n },\n [isEmpty, onCollapsedChange]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onFocus?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isEmpty) {\n onCollapsedChange?.(false);\n }\n },\n [isEmpty, onCollapsedChange, onFocus]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onBlur?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const isOutside = !event.currentTarget.contains(event.relatedTarget);\n\n if (isOutside && isEmpty && !isEmojiPickerOpen) {\n onCollapsedChange?.(true);\n }\n },\n [isEmojiPickerOpen, isEmpty, onBlur, onCollapsedChange]\n );\n\n return (\n <form\n className={classNames(\n \"lb-root lb-composer lb-composer-form\",\n className\n )}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n data-collapsed={collapsed ? \"\" : undefined}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n <ComposerPrimitive.Editor\n className=\"lb-composer-editor\"\n onClick={handleEditorClick}\n placeholder={$.COMPOSER_PLACEHOLDER}\n defaultValue={defaultValue}\n disabled={isDisabled}\n autoFocus={autoFocus}\n components={editorComponents}\n dir={$.dir}\n />\n {!collapsed && (\n <div className=\"lb-composer-footer\">\n <div className=\"lb-composer-editor-actions\">\n {hasResolveMentionSuggestions && (\n <ComposerInsertMentionEditorAction\n label={$.COMPOSER_INSERT_MENTION}\n disabled={isDisabled}\n />\n )}\n <ComposerInsertEmojiEditorAction\n label={$.COMPOSER_INSERT_EMOJI}\n onPickerOpenChange={setEmojiPickerOpen}\n disabled={isDisabled}\n />\n </div>\n {showAttribution && <Attribution />}\n <div className=\"lb-composer-actions\">\n {actions ?? (\n <>\n <ShortcutTooltip\n content={$.COMPOSER_SEND}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit disabled={isDisabled} asChild>\n <Button\n onMouseDown={preventDefault}\n onClick={stopPropagation}\n className=\"lb-composer-action\"\n variant=\"primary\"\n aria-label={$.COMPOSER_SEND}\n >\n <SendIcon />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n )}\n </div>\n </div>\n )}\n </form>\n );\n }\n);\n\n/**\n * Displays a composer to create comments.\n *\n * @example\n * <Composer />\n */\nexport const Composer = forwardRef(\n <M extends BaseMetadata = ThreadMetadata>(\n {\n threadId,\n commentId,\n metadata,\n onComposerSubmit,\n ...props\n }: ComposerProps<M>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const { useCreateThread, useCreateComment, useEditComment } =\n useRoomContextBundle();\n const createThread = useCreateThread();\n const createComment = useCreateComment();\n const editComment = useEditComment();\n\n const handleCommentSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (commentId && threadId) {\n editComment({\n commentId,\n threadId,\n body: comment.body,\n });\n } else if (threadId) {\n createComment({\n threadId,\n body: comment.body,\n });\n } else {\n createThread({\n body: comment.body,\n metadata: metadata ?? {},\n });\n }\n },\n [\n commentId,\n createComment,\n createThread,\n editComment,\n metadata,\n onComposerSubmit,\n threadId,\n ]\n );\n\n return (\n <TooltipProvider>\n <ComposerPrimitive.Form onComposerSubmit={handleCommentSubmit} asChild>\n <ComposerWithContext {...props} ref={forwardedRef} />\n </ComposerPrimitive.Form>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = ThreadMetadata>(\n props: ComposerProps<M> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuJA;AAA2C;AACzC;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AAAoB;AAEhB;AAEA;AACE;AACA;AAAc;AAChB;AACF;AACuB;AAGzB;AACG;AAAiB;AACf;AAC6D;AAC/C;AACJ;AACG;AACR;AAEH;AAAsB;AAI/B;AAEA;AAAyC;AACvC;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AACG;AAA2B;AAA0B;AACnD;AAAiB;AACf;AAA0B;AACxB;AAC6D;AAC/C;AACD;AACR;AAEH;AAAoB;AAMjC;AAEA;AACE;AACG;AAAoC;AAElC;AAAK;AAGZ;AAEA;AAAoC;AAEpC;AACE;AACG;AAAwC;AACtC;AAA4C;AAExC;AACM;AACK;AACH;AAEN;AACC;AACU;AAEX;AACC;AACU;AAOxB;AAEA;AACE;AACG;AAAuB;AAAsB;AAIlD;AAEA;AAAmD;AACxC;AACW;AAEtB;AAEA;AAA4B;AAKxB;AACE;AACA;AACA;AACW;AACX;AACmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AAEA;AACA;AACA;AAAmB;AACQ;AACE;AAE7B;AACA;AACA;AACA;AAAuC;AAIjC;AACJ;AACA;AAGF;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AAA0B;AAEtB;AAEA;AACE;AAAyB;AAC3B;AACF;AAC2B;AAG7B;AAAoB;AAEhB;AAEA;AACE;AAAA;AAGF;AACE;AAAyB;AAC3B;AACF;AACoC;AAGtC;AAAmB;AAEf;AAEA;AACE;AAAA;AAGF;AAEA;AACE;AAAwB;AAC1B;AACF;AACsD;AAGxD;AACG;AACY;AACT;AACA;AACF;AACO;AACH;AACC;AAC4B;AACxB;AACD;AAEP;AACW;AACD;AACM;AACf;AACU;AACV;AACY;AACL;AAGN;AAAc;AACZ;AAAc;AAEV;AACU;AACC;AAGb;AACU;AACW;AACV;AAIb;AAAc;AAGR;AACY;AACA;AAAwB;AAAQ;AAE1C;AAAmC;AAAmB;AACpD;AACc;AACJ;AACC;AACF;AACM;AAWhC;AAGN;AAQO;AAAiB;AAEpB;AACE;AACA;AACA;AACA;AACG;AAIL;AAEA;AACA;AACA;AAEA;AAA4B;AAExB;AAEA;AACE;AAAA;AAGF;AACE;AAAY;AACV;AACA;AACc;AACf;AAED;AAAc;AACZ;AACc;AACf;AAED;AAAa;AACG;AACS;AACxB;AACH;AACF;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAGF;AAEK;AAAyC;AAA4B;AACnE;AAAwB;AAAY;AAEzC;AAGN;;"}
@@ -0,0 +1,297 @@
1
+ 'use client';
2
+ import { kInternal } from '@liveblocks/core';
3
+ import { useClient, useRoomContextBundle } from '@liveblocks/react';
4
+ import React__default, { forwardRef, useMemo, useState, useCallback } from 'react';
5
+ import { EmojiIcon } from '../icons/Emoji.mjs';
6
+ import { MentionIcon } from '../icons/Mention.mjs';
7
+ import { SendIcon } from '../icons/Send.mjs';
8
+ import { useOverrides } from '../overrides.mjs';
9
+ import { Editor as ComposerEditor, Submit as ComposerSubmit, Form as ComposerForm, Mention as ComposerMention$1, Suggestions as ComposerSuggestions, SuggestionsList as ComposerSuggestionsList, SuggestionsListItem as ComposerSuggestionsListItem, Link as ComposerLink$1 } from '../primitives/Composer/index.mjs';
10
+ import { useComposer } from '../primitives/Composer/contexts.mjs';
11
+ import { MENTION_CHARACTER } from '../slate/plugins/mentions.mjs';
12
+ import { classNames } from '../utils/class-names.mjs';
13
+ import { useControllableState } from '../utils/use-controllable-state.mjs';
14
+ import { Attribution } from './internal/Attribution.mjs';
15
+ import { Avatar } from './internal/Avatar.mjs';
16
+ import { Button } from './internal/Button.mjs';
17
+ import { EmojiPicker } from './internal/EmojiPicker.mjs';
18
+ import { ShortcutTooltip, ShortcutTooltipKey, Tooltip } from './internal/Tooltip.mjs';
19
+ import { User } from './internal/User.mjs';
20
+ import { TooltipProvider } from '@radix-ui/react-tooltip';
21
+ import { PopoverTrigger } from '@radix-ui/react-popover';
22
+
23
+ function ComposerInsertMentionEditorAction({
24
+ label,
25
+ className,
26
+ onClick,
27
+ ...props
28
+ }) {
29
+ const { createMention } = useComposer();
30
+ const preventDefault = useCallback((event) => {
31
+ event.preventDefault();
32
+ }, []);
33
+ const handleClick = useCallback(
34
+ (event) => {
35
+ onClick?.(event);
36
+ if (!event.isDefaultPrevented()) {
37
+ event.stopPropagation();
38
+ createMention();
39
+ }
40
+ },
41
+ [createMention, onClick]
42
+ );
43
+ return /* @__PURE__ */ React__default.createElement(Tooltip, {
44
+ content: label
45
+ }, /* @__PURE__ */ React__default.createElement(Button, {
46
+ className: classNames("lb-composer-editor-action", className),
47
+ onMouseDown: preventDefault,
48
+ onClick: handleClick,
49
+ "aria-label": label,
50
+ ...props
51
+ }, /* @__PURE__ */ React__default.createElement(MentionIcon, {
52
+ className: "lb-button-icon"
53
+ })));
54
+ }
55
+ function ComposerInsertEmojiEditorAction({
56
+ label,
57
+ onPickerOpenChange,
58
+ className,
59
+ ...props
60
+ }) {
61
+ const { insertText } = useComposer();
62
+ const preventDefault = useCallback((event) => {
63
+ event.preventDefault();
64
+ }, []);
65
+ return /* @__PURE__ */ React__default.createElement(EmojiPicker, {
66
+ onEmojiSelect: insertText,
67
+ onOpenChange: onPickerOpenChange
68
+ }, /* @__PURE__ */ React__default.createElement(Tooltip, {
69
+ content: label
70
+ }, /* @__PURE__ */ React__default.createElement(PopoverTrigger, {
71
+ asChild: true
72
+ }, /* @__PURE__ */ React__default.createElement(Button, {
73
+ className: classNames("lb-composer-editor-action", className),
74
+ onMouseDown: preventDefault,
75
+ "aria-label": label,
76
+ ...props
77
+ }, /* @__PURE__ */ React__default.createElement(EmojiIcon, {
78
+ className: "lb-button-icon"
79
+ })))));
80
+ }
81
+ function ComposerMention({ userId }) {
82
+ return /* @__PURE__ */ React__default.createElement(ComposerMention$1, {
83
+ className: "lb-composer-mention"
84
+ }, MENTION_CHARACTER, /* @__PURE__ */ React__default.createElement(User, {
85
+ userId
86
+ }));
87
+ }
88
+ function ComposerMentionSuggestions({
89
+ userIds
90
+ }) {
91
+ return userIds.length > 0 ? /* @__PURE__ */ React__default.createElement(ComposerSuggestions, {
92
+ className: "lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions"
93
+ }, /* @__PURE__ */ React__default.createElement(ComposerSuggestionsList, {
94
+ className: "lb-composer-suggestions-list lb-composer-mention-suggestions-list"
95
+ }, userIds.map((userId) => /* @__PURE__ */ React__default.createElement(ComposerSuggestionsListItem, {
96
+ key: userId,
97
+ className: "lb-composer-suggestions-list-item lb-composer-mention-suggestion",
98
+ value: userId
99
+ }, /* @__PURE__ */ React__default.createElement(Avatar, {
100
+ userId,
101
+ className: "lb-composer-mention-suggestion-avatar"
102
+ }), /* @__PURE__ */ React__default.createElement(User, {
103
+ userId,
104
+ className: "lb-composer-mention-suggestion-user"
105
+ }))))) : null;
106
+ }
107
+ function ComposerLink({ href, children }) {
108
+ return /* @__PURE__ */ React__default.createElement(ComposerLink$1, {
109
+ href,
110
+ className: "lb-composer-link"
111
+ }, children);
112
+ }
113
+ const editorComponents = {
114
+ Mention: ComposerMention,
115
+ MentionSuggestions: ComposerMentionSuggestions,
116
+ Link: ComposerLink
117
+ };
118
+ const ComposerWithContext = forwardRef(
119
+ ({
120
+ defaultValue,
121
+ disabled,
122
+ autoFocus,
123
+ collapsed: controlledCollapsed,
124
+ defaultCollapsed,
125
+ onCollapsedChange: controlledOnCollapsedChange,
126
+ actions,
127
+ overrides,
128
+ showAttribution,
129
+ onFocus,
130
+ onBlur,
131
+ className,
132
+ ...props
133
+ }, forwardedRef) => {
134
+ const client = useClient();
135
+ const hasResolveMentionSuggestions = client[kInternal].resolveMentionSuggestions !== void 0;
136
+ const { useSelf } = useRoomContextBundle();
137
+ const self = useSelf();
138
+ const isDisabled = useMemo(
139
+ () => disabled || !self?.canComment,
140
+ [disabled, self?.canComment]
141
+ );
142
+ const { isEmpty } = useComposer();
143
+ const $ = useOverrides(overrides);
144
+ const [isEmojiPickerOpen, setEmojiPickerOpen] = useState(false);
145
+ const [collapsed, onCollapsedChange] = useControllableState(
146
+ controlledCollapsed === void 0 && defaultCollapsed === void 0 ? false : controlledCollapsed,
147
+ controlledOnCollapsedChange,
148
+ defaultCollapsed
149
+ );
150
+ const preventDefault = useCallback((event) => {
151
+ event.preventDefault();
152
+ }, []);
153
+ const stopPropagation = useCallback((event) => {
154
+ event.stopPropagation();
155
+ }, []);
156
+ const handleEditorClick = useCallback(
157
+ (event) => {
158
+ event.stopPropagation();
159
+ if (isEmpty) {
160
+ onCollapsedChange?.(false);
161
+ }
162
+ },
163
+ [isEmpty, onCollapsedChange]
164
+ );
165
+ const handleFocus = useCallback(
166
+ (event) => {
167
+ onFocus?.(event);
168
+ if (event.isDefaultPrevented()) {
169
+ return;
170
+ }
171
+ if (isEmpty) {
172
+ onCollapsedChange?.(false);
173
+ }
174
+ },
175
+ [isEmpty, onCollapsedChange, onFocus]
176
+ );
177
+ const handleBlur = useCallback(
178
+ (event) => {
179
+ onBlur?.(event);
180
+ if (event.isDefaultPrevented()) {
181
+ return;
182
+ }
183
+ const isOutside = !event.currentTarget.contains(event.relatedTarget);
184
+ if (isOutside && isEmpty && !isEmojiPickerOpen) {
185
+ onCollapsedChange?.(true);
186
+ }
187
+ },
188
+ [isEmojiPickerOpen, isEmpty, onBlur, onCollapsedChange]
189
+ );
190
+ return /* @__PURE__ */ React__default.createElement("form", {
191
+ className: classNames(
192
+ "lb-root lb-composer lb-composer-form",
193
+ className
194
+ ),
195
+ dir: $.dir,
196
+ ...props,
197
+ ref: forwardedRef,
198
+ "data-collapsed": collapsed ? "" : void 0,
199
+ onFocus: handleFocus,
200
+ onBlur: handleBlur
201
+ }, /* @__PURE__ */ React__default.createElement(ComposerEditor, {
202
+ className: "lb-composer-editor",
203
+ onClick: handleEditorClick,
204
+ placeholder: $.COMPOSER_PLACEHOLDER,
205
+ defaultValue,
206
+ disabled: isDisabled,
207
+ autoFocus,
208
+ components: editorComponents,
209
+ dir: $.dir
210
+ }), !collapsed && /* @__PURE__ */ React__default.createElement("div", {
211
+ className: "lb-composer-footer"
212
+ }, /* @__PURE__ */ React__default.createElement("div", {
213
+ className: "lb-composer-editor-actions"
214
+ }, hasResolveMentionSuggestions && /* @__PURE__ */ React__default.createElement(ComposerInsertMentionEditorAction, {
215
+ label: $.COMPOSER_INSERT_MENTION,
216
+ disabled: isDisabled
217
+ }), /* @__PURE__ */ React__default.createElement(ComposerInsertEmojiEditorAction, {
218
+ label: $.COMPOSER_INSERT_EMOJI,
219
+ onPickerOpenChange: setEmojiPickerOpen,
220
+ disabled: isDisabled
221
+ })), showAttribution && /* @__PURE__ */ React__default.createElement(Attribution, null), /* @__PURE__ */ React__default.createElement("div", {
222
+ className: "lb-composer-actions"
223
+ }, actions ?? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(ShortcutTooltip, {
224
+ content: $.COMPOSER_SEND,
225
+ shortcut: /* @__PURE__ */ React__default.createElement(ShortcutTooltipKey, {
226
+ name: "enter"
227
+ })
228
+ }, /* @__PURE__ */ React__default.createElement(ComposerSubmit, {
229
+ disabled: isDisabled,
230
+ asChild: true
231
+ }, /* @__PURE__ */ React__default.createElement(Button, {
232
+ onMouseDown: preventDefault,
233
+ onClick: stopPropagation,
234
+ className: "lb-composer-action",
235
+ variant: "primary",
236
+ "aria-label": $.COMPOSER_SEND
237
+ }, /* @__PURE__ */ React__default.createElement(SendIcon, null))))))));
238
+ }
239
+ );
240
+ const Composer = forwardRef(
241
+ ({
242
+ threadId,
243
+ commentId,
244
+ metadata,
245
+ onComposerSubmit,
246
+ ...props
247
+ }, forwardedRef) => {
248
+ const { useCreateThread, useCreateComment, useEditComment } = useRoomContextBundle();
249
+ const createThread = useCreateThread();
250
+ const createComment = useCreateComment();
251
+ const editComment = useEditComment();
252
+ const handleCommentSubmit = useCallback(
253
+ (comment, event) => {
254
+ onComposerSubmit?.(comment, event);
255
+ if (event.isDefaultPrevented()) {
256
+ return;
257
+ }
258
+ if (commentId && threadId) {
259
+ editComment({
260
+ commentId,
261
+ threadId,
262
+ body: comment.body
263
+ });
264
+ } else if (threadId) {
265
+ createComment({
266
+ threadId,
267
+ body: comment.body
268
+ });
269
+ } else {
270
+ createThread({
271
+ body: comment.body,
272
+ metadata: metadata ?? {}
273
+ });
274
+ }
275
+ },
276
+ [
277
+ commentId,
278
+ createComment,
279
+ createThread,
280
+ editComment,
281
+ metadata,
282
+ onComposerSubmit,
283
+ threadId
284
+ ]
285
+ );
286
+ return /* @__PURE__ */ React__default.createElement(TooltipProvider, null, /* @__PURE__ */ React__default.createElement(ComposerForm, {
287
+ onComposerSubmit: handleCommentSubmit,
288
+ asChild: true
289
+ }, /* @__PURE__ */ React__default.createElement(ComposerWithContext, {
290
+ ...props,
291
+ ref: forwardedRef
292
+ })));
293
+ }
294
+ );
295
+
296
+ export { Composer };
297
+ //# sourceMappingURL=Composer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Composer.mjs","sources":["../../src/components/Composer.tsx"],"sourcesContent":["\"use client\";\n\nimport { type BaseMetadata, kInternal } from \"@liveblocks/core\";\nimport { useClient, useRoomContextBundle } from \"@liveblocks/react\";\nimport type {\n ComponentPropsWithoutRef,\n FocusEvent,\n FormEvent,\n ForwardedRef,\n MouseEvent,\n ReactNode,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport React, { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport { EmojiIcon } from \"../icons/Emoji\";\nimport { MentionIcon } from \"../icons/Mention\";\nimport { SendIcon } from \"../icons/Send\";\nimport type { ComposerOverrides, GlobalOverrides } from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { useComposer } from \"../primitives/Composer/contexts\";\nimport type {\n ComposerEditorComponents,\n ComposerEditorLinkProps,\n ComposerEditorMentionProps,\n ComposerEditorMentionSuggestionsProps,\n ComposerEditorProps,\n ComposerSubmitComment,\n} from \"../primitives/Composer/types\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { ThreadMetadata } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { useControllableState } from \"../utils/use-controllable-state\";\nimport { Attribution } from \"./internal/Attribution\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport type { EmojiPickerProps } from \"./internal/EmojiPicker\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport {\n ShortcutTooltip,\n ShortcutTooltipKey,\n Tooltip,\n TooltipProvider,\n} from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ninterface EditorActionProps extends ComponentPropsWithoutRef<\"button\"> {\n label: string;\n}\n\ninterface EmojiEditorActionProps extends EditorActionProps {\n onPickerOpenChange?: EmojiPickerProps[\"onOpenChange\"];\n}\n\ntype ComposerCreateThreadProps<M extends BaseMetadata> = {\n threadId?: never;\n commentId?: never;\n\n /**\n * The metadata of the thread to create.\n */\n metadata?: M;\n};\n\ntype ComposerCreateCommentProps = {\n /**\n * The ID of the thread to reply to.\n */\n threadId: string;\n commentId?: never;\n metadata?: never;\n};\n\ntype ComposerEditCommentProps = {\n /**\n * The ID of the thread to edit a comment in.\n */\n threadId: string;\n\n /**\n * The ID of the comment to edit.\n */\n commentId: string;\n metadata?: never;\n};\n\nexport type ComposerProps<M extends BaseMetadata = ThreadMetadata> = Omit<\n ComponentPropsWithoutRef<\"form\">,\n \"defaultValue\"\n> &\n (\n | ComposerCreateThreadProps<M>\n | ComposerCreateCommentProps\n | ComposerEditCommentProps\n ) & {\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: (\n comment: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => Promise<void> | void;\n\n /**\n * The composer's initial value.\n */\n defaultValue?: ComposerEditorProps[\"defaultValue\"];\n\n /**\n * Whether the composer is collapsed. Setting a value will make the composer controlled.\n */\n collapsed?: boolean;\n\n /**\n * The event handler called when the collapsed state of the composer changes.\n */\n onCollapsedChange?: (collapsed: boolean) => void;\n\n /**\n * Whether the composer is initially collapsed. Setting a value will make the composer uncontrolled.\n */\n defaultCollapsed?: boolean;\n\n /**\n * Whether the composer is disabled.\n */\n disabled?: ComposerEditorProps[\"disabled\"];\n\n /**\n * Whether to focus the composer on mount.\n */\n autoFocus?: ComposerEditorProps[\"autoFocus\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n actions?: ReactNode;\n\n /**\n * @internal\n */\n showAttribution?: boolean;\n };\n\nfunction ComposerInsertMentionEditorAction({\n label,\n className,\n onClick,\n ...props\n}: EditorActionProps) {\n const { createMention } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.isDefaultPrevented()) {\n event.stopPropagation();\n createMention();\n }\n },\n [createMention, onClick]\n );\n\n return (\n <Tooltip content={label}>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onMouseDown={preventDefault}\n onClick={handleClick}\n aria-label={label}\n {...props}\n >\n <MentionIcon className=\"lb-button-icon\" />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ComposerInsertEmojiEditorAction({\n label,\n onPickerOpenChange,\n className,\n ...props\n}: EmojiEditorActionProps) {\n const { insertText } = useComposer();\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n return (\n <EmojiPicker onEmojiSelect={insertText} onOpenChange={onPickerOpenChange}>\n <Tooltip content={label}>\n <EmojiPickerTrigger asChild>\n <Button\n className={classNames(\"lb-composer-editor-action\", className)}\n onMouseDown={preventDefault}\n aria-label={label}\n {...props}\n >\n <EmojiIcon className=\"lb-button-icon\" />\n </Button>\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n );\n}\n\nfunction ComposerMention({ userId }: ComposerEditorMentionProps) {\n return (\n <ComposerPrimitive.Mention className=\"lb-composer-mention\">\n {MENTION_CHARACTER}\n <User userId={userId} />\n </ComposerPrimitive.Mention>\n );\n}\n\nfunction ComposerMentionSuggestions({\n userIds,\n}: ComposerEditorMentionSuggestionsProps) {\n return userIds.length > 0 ? (\n <ComposerPrimitive.Suggestions className=\"lb-root lb-portal lb-elevation lb-composer-suggestions lb-composer-mention-suggestions\">\n <ComposerPrimitive.SuggestionsList className=\"lb-composer-suggestions-list lb-composer-mention-suggestions-list\">\n {userIds.map((userId) => (\n <ComposerPrimitive.SuggestionsListItem\n key={userId}\n className=\"lb-composer-suggestions-list-item lb-composer-mention-suggestion\"\n value={userId}\n >\n <Avatar\n userId={userId}\n className=\"lb-composer-mention-suggestion-avatar\"\n />\n <User\n userId={userId}\n className=\"lb-composer-mention-suggestion-user\"\n />\n </ComposerPrimitive.SuggestionsListItem>\n ))}\n </ComposerPrimitive.SuggestionsList>\n </ComposerPrimitive.Suggestions>\n ) : null;\n}\n\nfunction ComposerLink({ href, children }: ComposerEditorLinkProps) {\n return (\n <ComposerPrimitive.Link href={href} className=\"lb-composer-link\">\n {children}\n </ComposerPrimitive.Link>\n );\n}\n\nconst editorComponents: ComposerEditorComponents = {\n Mention: ComposerMention,\n MentionSuggestions: ComposerMentionSuggestions,\n Link: ComposerLink,\n};\n\nconst ComposerWithContext = forwardRef<\n HTMLFormElement,\n Omit<ComposerProps, \"threadId\" | \"commentId\" | \"onComposerSubmit\">\n>(\n (\n {\n defaultValue,\n disabled,\n autoFocus,\n collapsed: controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange: controlledOnCollapsedChange,\n actions,\n overrides,\n showAttribution,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const { useSelf } = useRoomContextBundle();\n const self = useSelf();\n const isDisabled = useMemo(\n () => disabled || !self?.canComment,\n [disabled, self?.canComment]\n );\n const { isEmpty } = useComposer();\n const $ = useOverrides(overrides);\n const [isEmojiPickerOpen, setEmojiPickerOpen] = useState(false);\n const [collapsed, onCollapsedChange] = useControllableState(\n // If the composer is neither controlled nor uncontrolled, it defaults to controlled as uncollapsed.\n controlledCollapsed === undefined && defaultCollapsed === undefined\n ? false\n : controlledCollapsed,\n controlledOnCollapsedChange,\n defaultCollapsed\n );\n\n const preventDefault = useCallback((event: SyntheticEvent) => {\n event.preventDefault();\n }, []);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEditorClick = useCallback(\n (event: MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n\n if (isEmpty) {\n onCollapsedChange?.(false);\n }\n },\n [isEmpty, onCollapsedChange]\n );\n\n const handleFocus = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onFocus?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (isEmpty) {\n onCollapsedChange?.(false);\n }\n },\n [isEmpty, onCollapsedChange, onFocus]\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLFormElement>) => {\n onBlur?.(event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n const isOutside = !event.currentTarget.contains(event.relatedTarget);\n\n if (isOutside && isEmpty && !isEmojiPickerOpen) {\n onCollapsedChange?.(true);\n }\n },\n [isEmojiPickerOpen, isEmpty, onBlur, onCollapsedChange]\n );\n\n return (\n <form\n className={classNames(\n \"lb-root lb-composer lb-composer-form\",\n className\n )}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n data-collapsed={collapsed ? \"\" : undefined}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n <ComposerPrimitive.Editor\n className=\"lb-composer-editor\"\n onClick={handleEditorClick}\n placeholder={$.COMPOSER_PLACEHOLDER}\n defaultValue={defaultValue}\n disabled={isDisabled}\n autoFocus={autoFocus}\n components={editorComponents}\n dir={$.dir}\n />\n {!collapsed && (\n <div className=\"lb-composer-footer\">\n <div className=\"lb-composer-editor-actions\">\n {hasResolveMentionSuggestions && (\n <ComposerInsertMentionEditorAction\n label={$.COMPOSER_INSERT_MENTION}\n disabled={isDisabled}\n />\n )}\n <ComposerInsertEmojiEditorAction\n label={$.COMPOSER_INSERT_EMOJI}\n onPickerOpenChange={setEmojiPickerOpen}\n disabled={isDisabled}\n />\n </div>\n {showAttribution && <Attribution />}\n <div className=\"lb-composer-actions\">\n {actions ?? (\n <>\n <ShortcutTooltip\n content={$.COMPOSER_SEND}\n shortcut={<ShortcutTooltipKey name=\"enter\" />}\n >\n <ComposerPrimitive.Submit disabled={isDisabled} asChild>\n <Button\n onMouseDown={preventDefault}\n onClick={stopPropagation}\n className=\"lb-composer-action\"\n variant=\"primary\"\n aria-label={$.COMPOSER_SEND}\n >\n <SendIcon />\n </Button>\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n )}\n </div>\n </div>\n )}\n </form>\n );\n }\n);\n\n/**\n * Displays a composer to create comments.\n *\n * @example\n * <Composer />\n */\nexport const Composer = forwardRef(\n <M extends BaseMetadata = ThreadMetadata>(\n {\n threadId,\n commentId,\n metadata,\n onComposerSubmit,\n ...props\n }: ComposerProps<M>,\n forwardedRef: ForwardedRef<HTMLFormElement>\n ) => {\n const { useCreateThread, useCreateComment, useEditComment } =\n useRoomContextBundle();\n const createThread = useCreateThread();\n const createComment = useCreateComment();\n const editComment = useEditComment();\n\n const handleCommentSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n if (commentId && threadId) {\n editComment({\n commentId,\n threadId,\n body: comment.body,\n });\n } else if (threadId) {\n createComment({\n threadId,\n body: comment.body,\n });\n } else {\n createThread({\n body: comment.body,\n metadata: metadata ?? {},\n });\n }\n },\n [\n commentId,\n createComment,\n createThread,\n editComment,\n metadata,\n onComposerSubmit,\n threadId,\n ]\n );\n\n return (\n <TooltipProvider>\n <ComposerPrimitive.Form onComposerSubmit={handleCommentSubmit} asChild>\n <ComposerWithContext {...props} ref={forwardedRef} />\n </ComposerPrimitive.Form>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = ThreadMetadata>(\n props: ComposerProps<M> & RefAttributes<HTMLFormElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuJA;AAA2C;AACzC;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AAAoB;AAEhB;AAEA;AACE;AACA;AAAc;AAChB;AACF;AACuB;AAGzB;AACG;AAAiB;AACf;AAC6D;AAC/C;AACJ;AACG;AACR;AAEH;AAAsB;AAI/B;AAEA;AAAyC;AACvC;AACA;AACA;AAEF;AACE;AAEA;AACE;AAAqB;AAGvB;AACG;AAA2B;AAA0B;AACnD;AAAiB;AACf;AAA0B;AACxB;AAC6D;AAC/C;AACD;AACR;AAEH;AAAoB;AAMjC;AAEA;AACE;AACG;AAAoC;AAElC;AAAK;AAGZ;AAEA;AAAoC;AAEpC;AACE;AACG;AAAwC;AACtC;AAA4C;AAExC;AACM;AACK;AACH;AAEN;AACC;AACU;AAEX;AACC;AACU;AAOxB;AAEA;AACE;AACG;AAAuB;AAAsB;AAIlD;AAEA;AAAmD;AACxC;AACW;AAEtB;AAEA;AAA4B;AAKxB;AACE;AACA;AACA;AACW;AACX;AACmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AAEA;AACA;AACA;AAAmB;AACQ;AACE;AAE7B;AACA;AACA;AACA;AAAuC;AAIjC;AACJ;AACA;AAGF;AACE;AAAqB;AAGvB;AACE;AAAsB;AAGxB;AAA0B;AAEtB;AAEA;AACE;AAAyB;AAC3B;AACF;AAC2B;AAG7B;AAAoB;AAEhB;AAEA;AACE;AAAA;AAGF;AACE;AAAyB;AAC3B;AACF;AACoC;AAGtC;AAAmB;AAEf;AAEA;AACE;AAAA;AAGF;AAEA;AACE;AAAwB;AAC1B;AACF;AACsD;AAGxD;AACG;AACY;AACT;AACA;AACF;AACO;AACH;AACC;AAC4B;AACxB;AACD;AAEP;AACW;AACD;AACM;AACf;AACU;AACV;AACY;AACL;AAGN;AAAc;AACZ;AAAc;AAEV;AACU;AACC;AAGb;AACU;AACW;AACV;AAIb;AAAc;AAGR;AACY;AACA;AAAwB;AAAQ;AAE1C;AAAmC;AAAmB;AACpD;AACc;AACJ;AACC;AACF;AACM;AAWhC;AAGN;AAQO;AAAiB;AAEpB;AACE;AACA;AACA;AACA;AACG;AAIL;AAEA;AACA;AACA;AAEA;AAA4B;AAExB;AAEA;AACE;AAAA;AAGF;AACE;AAAY;AACV;AACA;AACc;AACf;AAED;AAAc;AACZ;AACc;AACf;AAED;AAAa;AACG;AACS;AACxB;AACH;AACF;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF;AAGF;AAEK;AAAyC;AAA4B;AACnE;AAAwB;AAAY;AAEzC;AAGN;;"}