@liveblocks/react-ui 2.14.0 → 2.15.0

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 (272) hide show
  1. package/dist/_private/index.d.mts +24 -22
  2. package/dist/_private/index.d.ts +24 -22
  3. package/dist/_private/index.js +1 -0
  4. package/dist/_private/index.js.map +1 -1
  5. package/dist/_private/index.mjs +1 -0
  6. package/dist/_private/index.mjs.map +1 -1
  7. package/dist/components/Comment.js +358 -256
  8. package/dist/components/Comment.js.map +1 -1
  9. package/dist/components/Comment.mjs +334 -232
  10. package/dist/components/Comment.mjs.map +1 -1
  11. package/dist/components/Composer.js +308 -225
  12. package/dist/components/Composer.js.map +1 -1
  13. package/dist/components/Composer.mjs +288 -206
  14. package/dist/components/Composer.mjs.map +1 -1
  15. package/dist/components/HistoryVersionSummary.js +28 -32
  16. package/dist/components/HistoryVersionSummary.js.map +1 -1
  17. package/dist/components/HistoryVersionSummary.mjs +27 -31
  18. package/dist/components/HistoryVersionSummary.mjs.map +1 -1
  19. package/dist/components/HistoryVersionSummaryList.js +11 -9
  20. package/dist/components/HistoryVersionSummaryList.js.map +1 -1
  21. package/dist/components/HistoryVersionSummaryList.mjs +10 -8
  22. package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
  23. package/dist/components/InboxNotification.js +202 -143
  24. package/dist/components/InboxNotification.js.map +1 -1
  25. package/dist/components/InboxNotification.mjs +180 -121
  26. package/dist/components/InboxNotification.mjs.map +1 -1
  27. package/dist/components/InboxNotificationList.js +19 -14
  28. package/dist/components/InboxNotificationList.js.map +1 -1
  29. package/dist/components/InboxNotificationList.mjs +17 -12
  30. package/dist/components/InboxNotificationList.mjs.map +1 -1
  31. package/dist/components/Thread.js +104 -86
  32. package/dist/components/Thread.js.map +1 -1
  33. package/dist/components/Thread.mjs +93 -75
  34. package/dist/components/Thread.mjs.map +1 -1
  35. package/dist/components/internal/Attachment.js +161 -113
  36. package/dist/components/internal/Attachment.js.map +1 -1
  37. package/dist/components/internal/Attachment.mjs +150 -102
  38. package/dist/components/internal/Attachment.mjs.map +1 -1
  39. package/dist/components/internal/Attribution.js +15 -13
  40. package/dist/components/internal/Attribution.js.map +1 -1
  41. package/dist/components/internal/Attribution.mjs +15 -13
  42. package/dist/components/internal/Attribution.mjs.map +1 -1
  43. package/dist/components/internal/Avatar.js +27 -20
  44. package/dist/components/internal/Avatar.js.map +1 -1
  45. package/dist/components/internal/Avatar.mjs +23 -16
  46. package/dist/components/internal/Avatar.mjs.map +1 -1
  47. package/dist/components/internal/Button.js +5 -4
  48. package/dist/components/internal/Button.js.map +1 -1
  49. package/dist/components/internal/Button.mjs +4 -3
  50. package/dist/components/internal/Button.mjs.map +1 -1
  51. package/dist/components/internal/Dropdown.js +27 -19
  52. package/dist/components/internal/Dropdown.js.map +1 -1
  53. package/dist/components/internal/Dropdown.mjs +26 -18
  54. package/dist/components/internal/Dropdown.mjs.map +1 -1
  55. package/dist/components/internal/Emoji.js +4 -3
  56. package/dist/components/internal/Emoji.js.map +1 -1
  57. package/dist/components/internal/Emoji.mjs +3 -2
  58. package/dist/components/internal/Emoji.mjs.map +1 -1
  59. package/dist/components/internal/EmojiPicker.js +96 -72
  60. package/dist/components/internal/EmojiPicker.js.map +1 -1
  61. package/dist/components/internal/EmojiPicker.mjs +90 -66
  62. package/dist/components/internal/EmojiPicker.mjs.map +1 -1
  63. package/dist/components/internal/Icon.js +5 -4
  64. package/dist/components/internal/Icon.js.map +1 -1
  65. package/dist/components/internal/Icon.mjs +5 -4
  66. package/dist/components/internal/Icon.mjs.map +1 -1
  67. package/dist/components/internal/InboxNotificationThread.js +53 -38
  68. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  69. package/dist/components/internal/InboxNotificationThread.mjs +53 -38
  70. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  71. package/dist/components/internal/List.js +8 -6
  72. package/dist/components/internal/List.js.map +1 -1
  73. package/dist/components/internal/List.mjs +6 -4
  74. package/dist/components/internal/List.mjs.map +1 -1
  75. package/dist/components/internal/Room.js +8 -6
  76. package/dist/components/internal/Room.js.map +1 -1
  77. package/dist/components/internal/Room.mjs +7 -5
  78. package/dist/components/internal/Room.mjs.map +1 -1
  79. package/dist/components/internal/Tooltip.js +49 -33
  80. package/dist/components/internal/Tooltip.js.map +1 -1
  81. package/dist/components/internal/Tooltip.mjs +46 -30
  82. package/dist/components/internal/Tooltip.mjs.map +1 -1
  83. package/dist/components/internal/User.js +8 -6
  84. package/dist/components/internal/User.js.map +1 -1
  85. package/dist/components/internal/User.mjs +7 -5
  86. package/dist/components/internal/User.mjs.map +1 -1
  87. package/dist/components.js +12 -29
  88. package/dist/components.js.map +1 -1
  89. package/dist/components.mjs +6 -5
  90. package/dist/components.mjs.map +1 -1
  91. package/dist/config.js +16 -12
  92. package/dist/config.js.map +1 -1
  93. package/dist/config.mjs +13 -9
  94. package/dist/config.mjs.map +1 -1
  95. package/dist/icons/ArrowDown.js +7 -6
  96. package/dist/icons/ArrowDown.js.map +1 -1
  97. package/dist/icons/ArrowDown.mjs +7 -6
  98. package/dist/icons/ArrowDown.mjs.map +1 -1
  99. package/dist/icons/ArrowUp.js +7 -6
  100. package/dist/icons/ArrowUp.js.map +1 -1
  101. package/dist/icons/ArrowUp.mjs +7 -6
  102. package/dist/icons/ArrowUp.mjs.map +1 -1
  103. package/dist/icons/Attachment.js +7 -6
  104. package/dist/icons/Attachment.js.map +1 -1
  105. package/dist/icons/Attachment.mjs +7 -6
  106. package/dist/icons/Attachment.mjs.map +1 -1
  107. package/dist/icons/Bold.js +7 -6
  108. package/dist/icons/Bold.js.map +1 -1
  109. package/dist/icons/Bold.mjs +7 -6
  110. package/dist/icons/Bold.mjs.map +1 -1
  111. package/dist/icons/Check.js +7 -6
  112. package/dist/icons/Check.js.map +1 -1
  113. package/dist/icons/Check.mjs +7 -6
  114. package/dist/icons/Check.mjs.map +1 -1
  115. package/dist/icons/Code.js +7 -6
  116. package/dist/icons/Code.js.map +1 -1
  117. package/dist/icons/Code.mjs +7 -6
  118. package/dist/icons/Code.mjs.map +1 -1
  119. package/dist/icons/Cross.js +12 -8
  120. package/dist/icons/Cross.js.map +1 -1
  121. package/dist/icons/Cross.mjs +12 -8
  122. package/dist/icons/Cross.mjs.map +1 -1
  123. package/dist/icons/Delete.js +7 -6
  124. package/dist/icons/Delete.js.map +1 -1
  125. package/dist/icons/Delete.mjs +7 -6
  126. package/dist/icons/Delete.mjs.map +1 -1
  127. package/dist/icons/Edit.js +7 -6
  128. package/dist/icons/Edit.js.map +1 -1
  129. package/dist/icons/Edit.mjs +7 -6
  130. package/dist/icons/Edit.mjs.map +1 -1
  131. package/dist/icons/Ellipsis.js +21 -16
  132. package/dist/icons/Ellipsis.js.map +1 -1
  133. package/dist/icons/Ellipsis.mjs +21 -16
  134. package/dist/icons/Ellipsis.mjs.map +1 -1
  135. package/dist/icons/Emoji.js +25 -18
  136. package/dist/icons/Emoji.js.map +1 -1
  137. package/dist/icons/Emoji.mjs +25 -18
  138. package/dist/icons/Emoji.mjs.map +1 -1
  139. package/dist/icons/EmojiAdd.js +28 -20
  140. package/dist/icons/EmojiAdd.js.map +1 -1
  141. package/dist/icons/EmojiAdd.mjs +28 -20
  142. package/dist/icons/EmojiAdd.mjs.map +1 -1
  143. package/dist/icons/Italic.js +7 -6
  144. package/dist/icons/Italic.js.map +1 -1
  145. package/dist/icons/Italic.mjs +7 -6
  146. package/dist/icons/Italic.mjs.map +1 -1
  147. package/dist/icons/Mention.js +12 -8
  148. package/dist/icons/Mention.js.map +1 -1
  149. package/dist/icons/Mention.mjs +12 -8
  150. package/dist/icons/Mention.mjs.map +1 -1
  151. package/dist/icons/Resolve.js +14 -10
  152. package/dist/icons/Resolve.js.map +1 -1
  153. package/dist/icons/Resolve.mjs +14 -10
  154. package/dist/icons/Resolve.mjs.map +1 -1
  155. package/dist/icons/Resolved.js +16 -12
  156. package/dist/icons/Resolved.js.map +1 -1
  157. package/dist/icons/Resolved.mjs +16 -12
  158. package/dist/icons/Resolved.mjs.map +1 -1
  159. package/dist/icons/Restore.js +12 -8
  160. package/dist/icons/Restore.js.map +1 -1
  161. package/dist/icons/Restore.mjs +12 -8
  162. package/dist/icons/Restore.mjs.map +1 -1
  163. package/dist/icons/Search.js +7 -6
  164. package/dist/icons/Search.js.map +1 -1
  165. package/dist/icons/Search.mjs +7 -6
  166. package/dist/icons/Search.mjs.map +1 -1
  167. package/dist/icons/Send.js +7 -6
  168. package/dist/icons/Send.js.map +1 -1
  169. package/dist/icons/Send.mjs +7 -6
  170. package/dist/icons/Send.mjs.map +1 -1
  171. package/dist/icons/Spinner.js +8 -7
  172. package/dist/icons/Spinner.js.map +1 -1
  173. package/dist/icons/Spinner.mjs +8 -7
  174. package/dist/icons/Spinner.mjs.map +1 -1
  175. package/dist/icons/Strikethrough.js +7 -6
  176. package/dist/icons/Strikethrough.js.map +1 -1
  177. package/dist/icons/Strikethrough.mjs +7 -6
  178. package/dist/icons/Strikethrough.mjs.map +1 -1
  179. package/dist/icons/Warning.js +14 -10
  180. package/dist/icons/Warning.js.map +1 -1
  181. package/dist/icons/Warning.mjs +14 -10
  182. package/dist/icons/Warning.mjs.map +1 -1
  183. package/dist/icons/index.js +42 -0
  184. package/dist/icons/index.js.map +1 -0
  185. package/dist/icons/index.mjs +19 -0
  186. package/dist/icons/index.mjs.map +1 -0
  187. package/dist/index.d.mts +14 -12
  188. package/dist/index.d.ts +14 -12
  189. package/dist/overrides.js +65 -36
  190. package/dist/overrides.js.map +1 -1
  191. package/dist/overrides.mjs +59 -12
  192. package/dist/overrides.mjs.map +1 -1
  193. package/dist/primitives/Comment/index.js +75 -66
  194. package/dist/primitives/Comment/index.js.map +1 -1
  195. package/dist/primitives/Comment/index.mjs +71 -62
  196. package/dist/primitives/Comment/index.mjs.map +1 -1
  197. package/dist/primitives/Composer/contexts.js +11 -11
  198. package/dist/primitives/Composer/index.js +343 -284
  199. package/dist/primitives/Composer/index.js.map +1 -1
  200. package/dist/primitives/Composer/index.mjs +262 -203
  201. package/dist/primitives/Composer/index.mjs.map +1 -1
  202. package/dist/primitives/Composer/utils.js +20 -21
  203. package/dist/primitives/Composer/utils.js.map +1 -1
  204. package/dist/primitives/Composer/utils.mjs +4 -5
  205. package/dist/primitives/Composer/utils.mjs.map +1 -1
  206. package/dist/primitives/EmojiPicker/contexts.js +3 -3
  207. package/dist/primitives/EmojiPicker/index.js +160 -142
  208. package/dist/primitives/EmojiPicker/index.js.map +1 -1
  209. package/dist/primitives/EmojiPicker/index.mjs +122 -104
  210. package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
  211. package/dist/primitives/FileSize.js +9 -7
  212. package/dist/primitives/FileSize.js.map +1 -1
  213. package/dist/primitives/FileSize.mjs +7 -5
  214. package/dist/primitives/FileSize.mjs.map +1 -1
  215. package/dist/primitives/Timestamp.js +12 -10
  216. package/dist/primitives/Timestamp.js.map +1 -1
  217. package/dist/primitives/Timestamp.mjs +7 -5
  218. package/dist/primitives/Timestamp.mjs.map +1 -1
  219. package/dist/primitives/index.d.mts +24 -23
  220. package/dist/primitives/index.d.ts +24 -23
  221. package/dist/primitives/internal/Emoji.js +7 -5
  222. package/dist/primitives/internal/Emoji.js.map +1 -1
  223. package/dist/primitives/internal/Emoji.mjs +6 -4
  224. package/dist/primitives/internal/Emoji.mjs.map +1 -1
  225. package/dist/shared.js +2 -7
  226. package/dist/shared.js.map +1 -1
  227. package/dist/shared.mjs +2 -7
  228. package/dist/shared.mjs.map +1 -1
  229. package/dist/slate/plugins/auto-links.mjs +1 -1
  230. package/dist/slate/plugins/custom-links.mjs +1 -1
  231. package/dist/slate/plugins/mentions.mjs +1 -1
  232. package/dist/utils/Persist.js +19 -18
  233. package/dist/utils/Persist.js.map +1 -1
  234. package/dist/utils/Persist.mjs +7 -6
  235. package/dist/utils/Persist.mjs.map +1 -1
  236. package/dist/utils/Portal.js +5 -4
  237. package/dist/utils/Portal.js.map +1 -1
  238. package/dist/utils/Portal.mjs +4 -3
  239. package/dist/utils/Portal.mjs.map +1 -1
  240. package/dist/utils/use-controllable-state.js +5 -5
  241. package/dist/utils/use-index.js +7 -7
  242. package/dist/utils/use-initial.js +2 -2
  243. package/dist/utils/use-interval.js +4 -4
  244. package/dist/utils/use-latest.js +3 -3
  245. package/dist/utils/use-observable.js +2 -2
  246. package/dist/utils/use-refs.js +2 -2
  247. package/dist/utils/use-rerender.js +2 -2
  248. package/dist/utils/use-visible.js +24 -2
  249. package/dist/utils/use-visible.js.map +1 -1
  250. package/dist/utils/use-visible.mjs +23 -2
  251. package/dist/utils/use-visible.mjs.map +1 -1
  252. package/dist/utils/use-window-focus.js +2 -2
  253. package/dist/utils/use-window-focus.js.map +1 -1
  254. package/dist/utils/use-window-focus.mjs +1 -1
  255. package/dist/utils/use-window-focus.mjs.map +1 -1
  256. package/dist/version.js +2 -2
  257. package/dist/version.js.map +1 -1
  258. package/dist/version.mjs +2 -2
  259. package/dist/version.mjs.map +1 -1
  260. package/package.json +10 -25
  261. package/dist/utils/use-id.js +0 -29
  262. package/dist/utils/use-id.js.map +0 -1
  263. package/dist/utils/use-id.mjs +0 -27
  264. package/dist/utils/use-id.mjs.map +0 -1
  265. package/dist/utils/use-layout-effect.js +0 -8
  266. package/dist/utils/use-layout-effect.js.map +0 -1
  267. package/dist/utils/use-layout-effect.mjs +0 -6
  268. package/dist/utils/use-layout-effect.mjs.map +0 -1
  269. package/dist/utils/use-transition.js +0 -16
  270. package/dist/utils/use-transition.js.map +0 -1
  271. package/dist/utils/use-transition.mjs +0 -14
  272. package/dist/utils/use-transition.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Thread.js","sources":["../../src/components/Thread.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentData,\n DM,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { useThreadSubscription } from \"@liveblocks/react\";\nimport {\n useMarkRoomThreadAsResolved,\n useMarkRoomThreadAsUnresolved,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentPropsWithoutRef,\n ForwardedRef,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport React, {\n forwardRef,\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\n\nimport { ArrowDownIcon } from \"../icons/ArrowDown\";\nimport { ResolveIcon } from \"../icons/Resolve\";\nimport { ResolvedIcon } from \"../icons/Resolved\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { classNames } from \"../utils/class-names\";\nimport { findLastIndex } from \"../utils/find-last-index\";\nimport type { CommentProps } from \"./Comment\";\nimport { Comment } from \"./Comment\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport { Button } from \"./internal/Button\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\n\nexport interface ThreadProps<M extends BaseMetadata = DM>\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The thread to display.\n */\n thread: ThreadData<M>;\n\n /**\n * How to show or hide the composer to reply to the thread.\n */\n showComposer?: boolean | \"collapsed\";\n\n /**\n * Whether to show the action to resolve the thread.\n */\n showResolveAction?: boolean;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: CommentProps[\"showActions\"];\n\n /**\n * Whether to show reactions.\n */\n showReactions?: CommentProps[\"showReactions\"];\n\n /**\n * Whether to show the composer's formatting controls.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comments' content.\n */\n indentCommentContent?: CommentProps[\"indentContent\"];\n\n /**\n * Whether to show deleted comments.\n */\n showDeletedComments?: CommentProps[\"showDeleted\"];\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * The event handler called when changing the resolved status.\n */\n onResolvedChange?: (resolved: boolean) => void;\n\n /**\n * The event handler called when a comment is edited.\n */\n onCommentEdit?: CommentProps[\"onCommentEdit\"];\n\n /**\n * The event handler called when a comment is deleted.\n */\n onCommentDelete?: CommentProps[\"onCommentDelete\"];\n\n /**\n * The event handler called when the thread is deleted.\n * A thread is deleted when all its comments are deleted.\n */\n onThreadDelete?: (thread: ThreadData<M>) => void;\n\n /**\n * The event handler called when clicking on a comment's author.\n */\n onAuthorClick?: CommentProps[\"onAuthorClick\"];\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: CommentProps[\"onMentionClick\"];\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: ComposerProps[\"onComposerSubmit\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides\n >;\n}\n\n/**\n * Displays a thread of comments, with a composer to reply\n * to it.\n *\n * @example\n * <>\n * {threads.map((thread) => (\n * <Thread key={thread.id} thread={thread} />\n * ))}\n * </>\n */\nexport const Thread = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n thread,\n indentCommentContent = true,\n showActions = \"hover\",\n showDeletedComments,\n showResolveAction = true,\n showReactions = true,\n showComposer = \"collapsed\",\n showAttachments = true,\n showComposerFormattingControls = true,\n onResolvedChange,\n onCommentEdit,\n onCommentDelete,\n onThreadDelete,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onComposerSubmit,\n overrides,\n className,\n ...props\n }: ThreadProps<M>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const markThreadAsResolved = useMarkRoomThreadAsResolved(thread.roomId);\n const markThreadAsUnresolved = useMarkRoomThreadAsUnresolved(thread.roomId);\n const $ = useOverrides(overrides);\n const firstCommentIndex = useMemo(() => {\n return showDeletedComments\n ? 0\n : thread.comments.findIndex((comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const lastCommentIndex = useMemo(() => {\n return showDeletedComments\n ? thread.comments.length - 1\n : findLastIndex(thread.comments, (comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const { status: subscriptionStatus, unreadSince } = useThreadSubscription(\n thread.id\n );\n const unreadIndex = useMemo(() => {\n // The user is not subscribed to this thread.\n if (subscriptionStatus !== \"subscribed\") {\n return;\n }\n\n // The user hasn't read the thread yet, so all comments are unread.\n if (unreadSince === null) {\n return firstCommentIndex;\n }\n\n // The user has read the thread, so we find the first unread comment.\n const unreadIndex = thread.comments.findIndex(\n (comment) =>\n (showDeletedComments ? true : comment.body) &&\n comment.createdAt > unreadSince\n );\n\n return unreadIndex >= 0 && unreadIndex < thread.comments.length\n ? unreadIndex\n : undefined;\n }, [\n firstCommentIndex,\n showDeletedComments,\n subscriptionStatus,\n thread.comments,\n unreadSince,\n ]);\n const [newIndex, setNewIndex] = useState<number>();\n const newIndicatorIndex = newIndex === undefined ? unreadIndex : newIndex;\n\n useEffect(() => {\n if (unreadIndex) {\n // Keep the \"new\" indicator at the lowest unread index.\n setNewIndex((persistedUnreadIndex) =>\n Math.min(persistedUnreadIndex ?? Infinity, unreadIndex)\n );\n }\n }, [unreadIndex]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleResolvedChange = useCallback(\n (resolved: boolean) => {\n onResolvedChange?.(resolved);\n\n if (resolved) {\n markThreadAsResolved(thread.id);\n } else {\n markThreadAsUnresolved(thread.id);\n }\n },\n [\n markThreadAsResolved,\n markThreadAsUnresolved,\n onResolvedChange,\n thread.id,\n ]\n );\n\n const handleCommentDelete = useCallback(\n (comment: CommentData) => {\n onCommentDelete?.(comment);\n\n const filteredComments = thread.comments.filter(\n (comment) => comment.body\n );\n\n if (filteredComments.length <= 1) {\n onThreadDelete?.(thread);\n }\n },\n [onCommentDelete, onThreadDelete, thread]\n );\n\n return (\n <TooltipProvider>\n <div\n className={classNames(\n \"lb-root lb-thread\",\n showActions === \"hover\" && \"lb-thread:show-actions-hover\",\n className\n )}\n data-resolved={thread.resolved ? \"\" : undefined}\n data-unread={unreadIndex !== undefined ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n >\n <div className=\"lb-thread-comments\">\n {thread.comments.map((comment, index) => {\n const isFirstComment = index === firstCommentIndex;\n const isUnread =\n unreadIndex !== undefined && index >= unreadIndex;\n\n const children = (\n <Comment\n key={comment.id}\n className=\"lb-thread-comment\"\n data-unread={isUnread ? \"\" : undefined}\n comment={comment}\n indentContent={indentCommentContent}\n showDeleted={showDeletedComments}\n showActions={showActions}\n showReactions={showReactions}\n showAttachments={showAttachments}\n showComposerFormattingControls={\n showComposerFormattingControls\n }\n onCommentEdit={onCommentEdit}\n onCommentDelete={handleCommentDelete}\n onAuthorClick={onAuthorClick}\n onMentionClick={onMentionClick}\n onAttachmentClick={onAttachmentClick}\n autoMarkReadThreadId={\n index === lastCommentIndex && isUnread\n ? thread.id\n : undefined\n }\n additionalActionsClassName={\n isFirstComment ? \"lb-thread-actions\" : undefined\n }\n additionalActions={\n isFirstComment && showResolveAction ? (\n <Tooltip\n content={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n <TogglePrimitive.Root\n pressed={thread.resolved}\n onPressedChange={handleResolvedChange}\n asChild\n >\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n {thread.resolved ? (\n <ResolvedIcon className=\"lb-button-icon\" />\n ) : (\n <ResolveIcon className=\"lb-button-icon\" />\n )}\n </Button>\n </TogglePrimitive.Root>\n </Tooltip>\n ) : null\n }\n />\n );\n\n return index === newIndicatorIndex &&\n newIndicatorIndex !== firstCommentIndex &&\n newIndicatorIndex <= lastCommentIndex ? (\n <Fragment key={comment.id}>\n <div\n className=\"lb-thread-new-indicator\"\n aria-label={$.THREAD_NEW_INDICATOR_DESCRIPTION}\n >\n <span className=\"lb-thread-new-indicator-label\">\n <ArrowDownIcon className=\"lb-thread-new-indicator-label-icon\" />\n {$.THREAD_NEW_INDICATOR}\n </span>\n </div>\n {children}\n </Fragment>\n ) : (\n children\n );\n })}\n </div>\n {showComposer && (\n <Composer\n className=\"lb-thread-composer\"\n threadId={thread.id}\n defaultCollapsed={showComposer === \"collapsed\" ? true : undefined}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n onComposerSubmit={onComposerSubmit}\n overrides={{\n COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,\n COMPOSER_SEND: $.THREAD_COMPOSER_SEND,\n }}\n roomId={thread.roomId}\n />\n )}\n </div>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ThreadProps<M> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JO;AAAe;AAElB;AACE;AACuB;AACT;AACd;AACoB;AACJ;AACD;AACG;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACE;AAEuD;AAEzD;AACE;AAE4D;AAE9D;AAAoD;AAC3C;AAET;AAEE;AACE;AAAA;AAIF;AACE;AAAO;AAIT;AAAoC;AAGZ;AAGxB;AAEI;AACH;AACD;AACA;AACA;AACO;AACP;AAEF;AACA;AAEA;AACE;AAEE;AAAA;AACwD;AACxD;AACF;AAGF;AACE;AAAsB;AAGxB;AAA6B;AAEzB;AAEA;AACE;AAA8B;AAE9B;AAAgC;AAClC;AACF;AACA;AACE;AACA;AACA;AACO;AACT;AAGF;AAA4B;AAExB;AAEA;AAAyC;AAClB;AAGvB;AACE;AAAuB;AACzB;AACF;AACwC;AAG1C;AAEK;AACY;AACT;AAC2B;AAC3B;AACF;AACsC;AACQ;AACvC;AACH;AACC;AAEJ;AAAc;AAEX;AACA;AAGA;AACG;AACc;AACH;AACmB;AAC7B;AACe;AACF;AACb;AACA;AACA;AACA;AAGA;AACiB;AACjB;AACA;AACA;AAIM;AAGmC;AAIpC;AAIS;AAGP;AACiB;AACC;AACV;AAEN;AACW;AACD;AAID;AAIL;AAAuB;AAEvB;AAAsB;AAK7B;AAKV;AAGG;AAAsB;AACpB;AACW;AACI;AAEb;AAAe;AACb;AAAwB;AAO/B;AAKH;AACW;AACO;AACuC;AACxD;AACwB;AACxB;AACW;AACe;AACP;AACnB;AACe;AAIvB;AAGN;;"}
1
+ {"version":3,"file":"Thread.js","sources":["../../src/components/Thread.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentData,\n DM,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { useThreadSubscription } from \"@liveblocks/react\";\nimport {\n useMarkRoomThreadAsResolved,\n useMarkRoomThreadAsUnresolved,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentPropsWithoutRef,\n ForwardedRef,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\n\nimport { ArrowDownIcon } from \"../icons/ArrowDown\";\nimport { ResolveIcon } from \"../icons/Resolve\";\nimport { ResolvedIcon } from \"../icons/Resolved\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { classNames } from \"../utils/class-names\";\nimport { findLastIndex } from \"../utils/find-last-index\";\nimport type { CommentProps } from \"./Comment\";\nimport { Comment } from \"./Comment\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport { Button } from \"./internal/Button\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\n\nexport interface ThreadProps<M extends BaseMetadata = DM>\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The thread to display.\n */\n thread: ThreadData<M>;\n\n /**\n * How to show or hide the composer to reply to the thread.\n */\n showComposer?: boolean | \"collapsed\";\n\n /**\n * Whether to show the action to resolve the thread.\n */\n showResolveAction?: boolean;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: CommentProps[\"showActions\"];\n\n /**\n * Whether to show reactions.\n */\n showReactions?: CommentProps[\"showReactions\"];\n\n /**\n * Whether to show the composer's formatting controls.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comments' content.\n */\n indentCommentContent?: CommentProps[\"indentContent\"];\n\n /**\n * Whether to show deleted comments.\n */\n showDeletedComments?: CommentProps[\"showDeleted\"];\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * The event handler called when changing the resolved status.\n */\n onResolvedChange?: (resolved: boolean) => void;\n\n /**\n * The event handler called when a comment is edited.\n */\n onCommentEdit?: CommentProps[\"onCommentEdit\"];\n\n /**\n * The event handler called when a comment is deleted.\n */\n onCommentDelete?: CommentProps[\"onCommentDelete\"];\n\n /**\n * The event handler called when the thread is deleted.\n * A thread is deleted when all its comments are deleted.\n */\n onThreadDelete?: (thread: ThreadData<M>) => void;\n\n /**\n * The event handler called when clicking on a comment's author.\n */\n onAuthorClick?: CommentProps[\"onAuthorClick\"];\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: CommentProps[\"onMentionClick\"];\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: ComposerProps[\"onComposerSubmit\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides\n >;\n}\n\n/**\n * Displays a thread of comments, with a composer to reply\n * to it.\n *\n * @example\n * <>\n * {threads.map((thread) => (\n * <Thread key={thread.id} thread={thread} />\n * ))}\n * </>\n */\nexport const Thread = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n thread,\n indentCommentContent = true,\n showActions = \"hover\",\n showDeletedComments,\n showResolveAction = true,\n showReactions = true,\n showComposer = \"collapsed\",\n showAttachments = true,\n showComposerFormattingControls = true,\n onResolvedChange,\n onCommentEdit,\n onCommentDelete,\n onThreadDelete,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onComposerSubmit,\n overrides,\n className,\n ...props\n }: ThreadProps<M>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const markThreadAsResolved = useMarkRoomThreadAsResolved(thread.roomId);\n const markThreadAsUnresolved = useMarkRoomThreadAsUnresolved(thread.roomId);\n const $ = useOverrides(overrides);\n const firstCommentIndex = useMemo(() => {\n return showDeletedComments\n ? 0\n : thread.comments.findIndex((comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const lastCommentIndex = useMemo(() => {\n return showDeletedComments\n ? thread.comments.length - 1\n : findLastIndex(thread.comments, (comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const { status: subscriptionStatus, unreadSince } = useThreadSubscription(\n thread.id\n );\n const unreadIndex = useMemo(() => {\n // The user is not subscribed to this thread.\n if (subscriptionStatus !== \"subscribed\") {\n return;\n }\n\n // The user hasn't read the thread yet, so all comments are unread.\n if (unreadSince === null) {\n return firstCommentIndex;\n }\n\n // The user has read the thread, so we find the first unread comment.\n const unreadIndex = thread.comments.findIndex(\n (comment) =>\n (showDeletedComments ? true : comment.body) &&\n comment.createdAt > unreadSince\n );\n\n return unreadIndex >= 0 && unreadIndex < thread.comments.length\n ? unreadIndex\n : undefined;\n }, [\n firstCommentIndex,\n showDeletedComments,\n subscriptionStatus,\n thread.comments,\n unreadSince,\n ]);\n const [newIndex, setNewIndex] = useState<number>();\n const newIndicatorIndex = newIndex === undefined ? unreadIndex : newIndex;\n\n useEffect(() => {\n if (unreadIndex) {\n // Keep the \"new\" indicator at the lowest unread index.\n setNewIndex((persistedUnreadIndex) =>\n Math.min(persistedUnreadIndex ?? Infinity, unreadIndex)\n );\n }\n }, [unreadIndex]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleResolvedChange = useCallback(\n (resolved: boolean) => {\n onResolvedChange?.(resolved);\n\n if (resolved) {\n markThreadAsResolved(thread.id);\n } else {\n markThreadAsUnresolved(thread.id);\n }\n },\n [\n markThreadAsResolved,\n markThreadAsUnresolved,\n onResolvedChange,\n thread.id,\n ]\n );\n\n const handleCommentDelete = useCallback(\n (comment: CommentData) => {\n onCommentDelete?.(comment);\n\n const filteredComments = thread.comments.filter(\n (comment) => comment.body\n );\n\n if (filteredComments.length <= 1) {\n onThreadDelete?.(thread);\n }\n },\n [onCommentDelete, onThreadDelete, thread]\n );\n\n return (\n <TooltipProvider>\n <div\n className={classNames(\n \"lb-root lb-thread\",\n showActions === \"hover\" && \"lb-thread:show-actions-hover\",\n className\n )}\n data-resolved={thread.resolved ? \"\" : undefined}\n data-unread={unreadIndex !== undefined ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n >\n <div className=\"lb-thread-comments\">\n {thread.comments.map((comment, index) => {\n const isFirstComment = index === firstCommentIndex;\n const isUnread =\n unreadIndex !== undefined && index >= unreadIndex;\n\n const children = (\n <Comment\n key={comment.id}\n className=\"lb-thread-comment\"\n data-unread={isUnread ? \"\" : undefined}\n comment={comment}\n indentContent={indentCommentContent}\n showDeleted={showDeletedComments}\n showActions={showActions}\n showReactions={showReactions}\n showAttachments={showAttachments}\n showComposerFormattingControls={\n showComposerFormattingControls\n }\n onCommentEdit={onCommentEdit}\n onCommentDelete={handleCommentDelete}\n onAuthorClick={onAuthorClick}\n onMentionClick={onMentionClick}\n onAttachmentClick={onAttachmentClick}\n autoMarkReadThreadId={\n index === lastCommentIndex && isUnread\n ? thread.id\n : undefined\n }\n additionalActionsClassName={\n isFirstComment ? \"lb-thread-actions\" : undefined\n }\n additionalActions={\n isFirstComment && showResolveAction ? (\n <Tooltip\n content={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n <TogglePrimitive.Root\n pressed={thread.resolved}\n onPressedChange={handleResolvedChange}\n asChild\n >\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n {thread.resolved ? (\n <ResolvedIcon className=\"lb-button-icon\" />\n ) : (\n <ResolveIcon className=\"lb-button-icon\" />\n )}\n </Button>\n </TogglePrimitive.Root>\n </Tooltip>\n ) : null\n }\n />\n );\n\n return index === newIndicatorIndex &&\n newIndicatorIndex !== firstCommentIndex &&\n newIndicatorIndex <= lastCommentIndex ? (\n <Fragment key={comment.id}>\n <div\n className=\"lb-thread-new-indicator\"\n aria-label={$.THREAD_NEW_INDICATOR_DESCRIPTION}\n >\n <span className=\"lb-thread-new-indicator-label\">\n <ArrowDownIcon className=\"lb-thread-new-indicator-label-icon\" />\n {$.THREAD_NEW_INDICATOR}\n </span>\n </div>\n {children}\n </Fragment>\n ) : (\n children\n );\n })}\n </div>\n {showComposer && (\n <Composer\n className=\"lb-thread-composer\"\n threadId={thread.id}\n defaultCollapsed={showComposer === \"collapsed\" ? true : undefined}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n onComposerSubmit={onComposerSubmit}\n overrides={{\n COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,\n COMPOSER_SEND: $.THREAD_COMPOSER_SEND,\n }}\n roomId={thread.roomId}\n />\n )}\n </div>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ThreadProps<M> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":["forwardRef","overrides","useMarkRoomThreadAsResolved","useMarkRoomThreadAsUnresolved","useOverrides","useMemo","findLastIndex","useThreadSubscription","unreadIndex","useState","useEffect","useCallback","comment","jsx","TooltipProvider","jsxs","classNames","Comment","Tooltip","TogglePrimitive","Button","ResolvedIcon","ResolveIcon","Fragment","ArrowDownIcon","Composer"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- 'use client';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useThreadSubscription } from '@liveblocks/react';
3
3
  import { useMarkRoomThreadAsResolved, useMarkRoomThreadAsUnresolved } from '@liveblocks/react/_private';
4
4
  import * as TogglePrimitive from '@radix-ui/react-toggle';
5
- import React__default, { forwardRef, useMemo, useState, useEffect, useCallback, Fragment } from 'react';
5
+ import { forwardRef, useMemo, useState, useEffect, useCallback, Fragment } from 'react';
6
6
  import { ArrowDownIcon } from '../icons/ArrowDown.mjs';
7
7
  import { ResolveIcon } from '../icons/Resolve.mjs';
8
8
  import { ResolvedIcon } from '../icons/Resolved.mjs';
@@ -15,6 +15,7 @@ import { Button } from './internal/Button.mjs';
15
15
  import { Tooltip } from './internal/Tooltip.mjs';
16
16
  import { TooltipProvider } from '@radix-ui/react-tooltip';
17
17
 
18
+ "use client";
18
19
  const Thread = forwardRef(
19
20
  ({
20
21
  thread,
@@ -108,79 +109,96 @@ const Thread = forwardRef(
108
109
  },
109
110
  [onCommentDelete, onThreadDelete, thread]
110
111
  );
111
- return /* @__PURE__ */ React__default.createElement(TooltipProvider, null, /* @__PURE__ */ React__default.createElement("div", {
112
- className: classNames(
113
- "lb-root lb-thread",
114
- showActions === "hover" && "lb-thread:show-actions-hover",
115
- className
116
- ),
117
- "data-resolved": thread.resolved ? "" : void 0,
118
- "data-unread": unreadIndex !== void 0 ? "" : void 0,
119
- dir: $.dir,
120
- ...props,
121
- ref: forwardedRef
122
- }, /* @__PURE__ */ React__default.createElement("div", {
123
- className: "lb-thread-comments"
124
- }, thread.comments.map((comment, index) => {
125
- const isFirstComment = index === firstCommentIndex;
126
- const isUnread = unreadIndex !== void 0 && index >= unreadIndex;
127
- const children = /* @__PURE__ */ React__default.createElement(Comment, {
128
- key: comment.id,
129
- className: "lb-thread-comment",
130
- "data-unread": isUnread ? "" : void 0,
131
- comment,
132
- indentContent: indentCommentContent,
133
- showDeleted: showDeletedComments,
134
- showActions,
135
- showReactions,
136
- showAttachments,
137
- showComposerFormattingControls,
138
- onCommentEdit,
139
- onCommentDelete: handleCommentDelete,
140
- onAuthorClick,
141
- onMentionClick,
142
- onAttachmentClick,
143
- autoMarkReadThreadId: index === lastCommentIndex && isUnread ? thread.id : void 0,
144
- additionalActionsClassName: isFirstComment ? "lb-thread-actions" : void 0,
145
- additionalActions: isFirstComment && showResolveAction ? /* @__PURE__ */ React__default.createElement(Tooltip, {
146
- content: thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE
147
- }, /* @__PURE__ */ React__default.createElement(TogglePrimitive.Root, {
148
- pressed: thread.resolved,
149
- onPressedChange: handleResolvedChange,
150
- asChild: true
151
- }, /* @__PURE__ */ React__default.createElement(Button, {
152
- className: "lb-comment-action",
153
- onClick: stopPropagation,
154
- "aria-label": thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE
155
- }, thread.resolved ? /* @__PURE__ */ React__default.createElement(ResolvedIcon, {
156
- className: "lb-button-icon"
157
- }) : /* @__PURE__ */ React__default.createElement(ResolveIcon, {
158
- className: "lb-button-icon"
159
- })))) : null
160
- });
161
- return index === newIndicatorIndex && newIndicatorIndex !== firstCommentIndex && newIndicatorIndex <= lastCommentIndex ? /* @__PURE__ */ React__default.createElement(Fragment, {
162
- key: comment.id
163
- }, /* @__PURE__ */ React__default.createElement("div", {
164
- className: "lb-thread-new-indicator",
165
- "aria-label": $.THREAD_NEW_INDICATOR_DESCRIPTION
166
- }, /* @__PURE__ */ React__default.createElement("span", {
167
- className: "lb-thread-new-indicator-label"
168
- }, /* @__PURE__ */ React__default.createElement(ArrowDownIcon, {
169
- className: "lb-thread-new-indicator-label-icon"
170
- }), $.THREAD_NEW_INDICATOR)), children) : children;
171
- })), showComposer && /* @__PURE__ */ React__default.createElement(Composer, {
172
- className: "lb-thread-composer",
173
- threadId: thread.id,
174
- defaultCollapsed: showComposer === "collapsed" ? true : void 0,
175
- showAttachments,
176
- showFormattingControls: showComposerFormattingControls,
177
- onComposerSubmit,
178
- overrides: {
179
- COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,
180
- COMPOSER_SEND: $.THREAD_COMPOSER_SEND
181
- },
182
- roomId: thread.roomId
183
- })));
112
+ return /* @__PURE__ */ jsx(TooltipProvider, {
113
+ children: /* @__PURE__ */ jsxs("div", {
114
+ className: classNames(
115
+ "lb-root lb-thread",
116
+ showActions === "hover" && "lb-thread:show-actions-hover",
117
+ className
118
+ ),
119
+ "data-resolved": thread.resolved ? "" : void 0,
120
+ "data-unread": unreadIndex !== void 0 ? "" : void 0,
121
+ dir: $.dir,
122
+ ...props,
123
+ ref: forwardedRef,
124
+ children: [
125
+ /* @__PURE__ */ jsx("div", {
126
+ className: "lb-thread-comments",
127
+ children: thread.comments.map((comment, index) => {
128
+ const isFirstComment = index === firstCommentIndex;
129
+ const isUnread = unreadIndex !== void 0 && index >= unreadIndex;
130
+ const children = /* @__PURE__ */ jsx(Comment, {
131
+ className: "lb-thread-comment",
132
+ "data-unread": isUnread ? "" : void 0,
133
+ comment,
134
+ indentContent: indentCommentContent,
135
+ showDeleted: showDeletedComments,
136
+ showActions,
137
+ showReactions,
138
+ showAttachments,
139
+ showComposerFormattingControls,
140
+ onCommentEdit,
141
+ onCommentDelete: handleCommentDelete,
142
+ onAuthorClick,
143
+ onMentionClick,
144
+ onAttachmentClick,
145
+ autoMarkReadThreadId: index === lastCommentIndex && isUnread ? thread.id : void 0,
146
+ additionalActionsClassName: isFirstComment ? "lb-thread-actions" : void 0,
147
+ additionalActions: isFirstComment && showResolveAction ? /* @__PURE__ */ jsx(Tooltip, {
148
+ content: thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
149
+ children: /* @__PURE__ */ jsx(TogglePrimitive.Root, {
150
+ pressed: thread.resolved,
151
+ onPressedChange: handleResolvedChange,
152
+ asChild: true,
153
+ children: /* @__PURE__ */ jsx(Button, {
154
+ className: "lb-comment-action",
155
+ onClick: stopPropagation,
156
+ "aria-label": thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
157
+ children: thread.resolved ? /* @__PURE__ */ jsx(ResolvedIcon, {
158
+ className: "lb-button-icon"
159
+ }) : /* @__PURE__ */ jsx(ResolveIcon, {
160
+ className: "lb-button-icon"
161
+ })
162
+ })
163
+ })
164
+ }) : null
165
+ }, comment.id);
166
+ return index === newIndicatorIndex && newIndicatorIndex !== firstCommentIndex && newIndicatorIndex <= lastCommentIndex ? /* @__PURE__ */ jsxs(Fragment, {
167
+ children: [
168
+ /* @__PURE__ */ jsx("div", {
169
+ className: "lb-thread-new-indicator",
170
+ "aria-label": $.THREAD_NEW_INDICATOR_DESCRIPTION,
171
+ children: /* @__PURE__ */ jsxs("span", {
172
+ className: "lb-thread-new-indicator-label",
173
+ children: [
174
+ /* @__PURE__ */ jsx(ArrowDownIcon, {
175
+ className: "lb-thread-new-indicator-label-icon"
176
+ }),
177
+ $.THREAD_NEW_INDICATOR
178
+ ]
179
+ })
180
+ }),
181
+ children
182
+ ]
183
+ }, comment.id) : children;
184
+ })
185
+ }),
186
+ showComposer && /* @__PURE__ */ jsx(Composer, {
187
+ className: "lb-thread-composer",
188
+ threadId: thread.id,
189
+ defaultCollapsed: showComposer === "collapsed" ? true : void 0,
190
+ showAttachments,
191
+ showFormattingControls: showComposerFormattingControls,
192
+ onComposerSubmit,
193
+ overrides: {
194
+ COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,
195
+ COMPOSER_SEND: $.THREAD_COMPOSER_SEND
196
+ },
197
+ roomId: thread.roomId
198
+ })
199
+ ]
200
+ })
201
+ });
184
202
  }
185
203
  );
186
204
 
@@ -1 +1 @@
1
- {"version":3,"file":"Thread.mjs","sources":["../../src/components/Thread.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentData,\n DM,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { useThreadSubscription } from \"@liveblocks/react\";\nimport {\n useMarkRoomThreadAsResolved,\n useMarkRoomThreadAsUnresolved,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentPropsWithoutRef,\n ForwardedRef,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport React, {\n forwardRef,\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\n\nimport { ArrowDownIcon } from \"../icons/ArrowDown\";\nimport { ResolveIcon } from \"../icons/Resolve\";\nimport { ResolvedIcon } from \"../icons/Resolved\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { classNames } from \"../utils/class-names\";\nimport { findLastIndex } from \"../utils/find-last-index\";\nimport type { CommentProps } from \"./Comment\";\nimport { Comment } from \"./Comment\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport { Button } from \"./internal/Button\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\n\nexport interface ThreadProps<M extends BaseMetadata = DM>\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The thread to display.\n */\n thread: ThreadData<M>;\n\n /**\n * How to show or hide the composer to reply to the thread.\n */\n showComposer?: boolean | \"collapsed\";\n\n /**\n * Whether to show the action to resolve the thread.\n */\n showResolveAction?: boolean;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: CommentProps[\"showActions\"];\n\n /**\n * Whether to show reactions.\n */\n showReactions?: CommentProps[\"showReactions\"];\n\n /**\n * Whether to show the composer's formatting controls.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comments' content.\n */\n indentCommentContent?: CommentProps[\"indentContent\"];\n\n /**\n * Whether to show deleted comments.\n */\n showDeletedComments?: CommentProps[\"showDeleted\"];\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * The event handler called when changing the resolved status.\n */\n onResolvedChange?: (resolved: boolean) => void;\n\n /**\n * The event handler called when a comment is edited.\n */\n onCommentEdit?: CommentProps[\"onCommentEdit\"];\n\n /**\n * The event handler called when a comment is deleted.\n */\n onCommentDelete?: CommentProps[\"onCommentDelete\"];\n\n /**\n * The event handler called when the thread is deleted.\n * A thread is deleted when all its comments are deleted.\n */\n onThreadDelete?: (thread: ThreadData<M>) => void;\n\n /**\n * The event handler called when clicking on a comment's author.\n */\n onAuthorClick?: CommentProps[\"onAuthorClick\"];\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: CommentProps[\"onMentionClick\"];\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: ComposerProps[\"onComposerSubmit\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides\n >;\n}\n\n/**\n * Displays a thread of comments, with a composer to reply\n * to it.\n *\n * @example\n * <>\n * {threads.map((thread) => (\n * <Thread key={thread.id} thread={thread} />\n * ))}\n * </>\n */\nexport const Thread = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n thread,\n indentCommentContent = true,\n showActions = \"hover\",\n showDeletedComments,\n showResolveAction = true,\n showReactions = true,\n showComposer = \"collapsed\",\n showAttachments = true,\n showComposerFormattingControls = true,\n onResolvedChange,\n onCommentEdit,\n onCommentDelete,\n onThreadDelete,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onComposerSubmit,\n overrides,\n className,\n ...props\n }: ThreadProps<M>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const markThreadAsResolved = useMarkRoomThreadAsResolved(thread.roomId);\n const markThreadAsUnresolved = useMarkRoomThreadAsUnresolved(thread.roomId);\n const $ = useOverrides(overrides);\n const firstCommentIndex = useMemo(() => {\n return showDeletedComments\n ? 0\n : thread.comments.findIndex((comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const lastCommentIndex = useMemo(() => {\n return showDeletedComments\n ? thread.comments.length - 1\n : findLastIndex(thread.comments, (comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const { status: subscriptionStatus, unreadSince } = useThreadSubscription(\n thread.id\n );\n const unreadIndex = useMemo(() => {\n // The user is not subscribed to this thread.\n if (subscriptionStatus !== \"subscribed\") {\n return;\n }\n\n // The user hasn't read the thread yet, so all comments are unread.\n if (unreadSince === null) {\n return firstCommentIndex;\n }\n\n // The user has read the thread, so we find the first unread comment.\n const unreadIndex = thread.comments.findIndex(\n (comment) =>\n (showDeletedComments ? true : comment.body) &&\n comment.createdAt > unreadSince\n );\n\n return unreadIndex >= 0 && unreadIndex < thread.comments.length\n ? unreadIndex\n : undefined;\n }, [\n firstCommentIndex,\n showDeletedComments,\n subscriptionStatus,\n thread.comments,\n unreadSince,\n ]);\n const [newIndex, setNewIndex] = useState<number>();\n const newIndicatorIndex = newIndex === undefined ? unreadIndex : newIndex;\n\n useEffect(() => {\n if (unreadIndex) {\n // Keep the \"new\" indicator at the lowest unread index.\n setNewIndex((persistedUnreadIndex) =>\n Math.min(persistedUnreadIndex ?? Infinity, unreadIndex)\n );\n }\n }, [unreadIndex]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleResolvedChange = useCallback(\n (resolved: boolean) => {\n onResolvedChange?.(resolved);\n\n if (resolved) {\n markThreadAsResolved(thread.id);\n } else {\n markThreadAsUnresolved(thread.id);\n }\n },\n [\n markThreadAsResolved,\n markThreadAsUnresolved,\n onResolvedChange,\n thread.id,\n ]\n );\n\n const handleCommentDelete = useCallback(\n (comment: CommentData) => {\n onCommentDelete?.(comment);\n\n const filteredComments = thread.comments.filter(\n (comment) => comment.body\n );\n\n if (filteredComments.length <= 1) {\n onThreadDelete?.(thread);\n }\n },\n [onCommentDelete, onThreadDelete, thread]\n );\n\n return (\n <TooltipProvider>\n <div\n className={classNames(\n \"lb-root lb-thread\",\n showActions === \"hover\" && \"lb-thread:show-actions-hover\",\n className\n )}\n data-resolved={thread.resolved ? \"\" : undefined}\n data-unread={unreadIndex !== undefined ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n >\n <div className=\"lb-thread-comments\">\n {thread.comments.map((comment, index) => {\n const isFirstComment = index === firstCommentIndex;\n const isUnread =\n unreadIndex !== undefined && index >= unreadIndex;\n\n const children = (\n <Comment\n key={comment.id}\n className=\"lb-thread-comment\"\n data-unread={isUnread ? \"\" : undefined}\n comment={comment}\n indentContent={indentCommentContent}\n showDeleted={showDeletedComments}\n showActions={showActions}\n showReactions={showReactions}\n showAttachments={showAttachments}\n showComposerFormattingControls={\n showComposerFormattingControls\n }\n onCommentEdit={onCommentEdit}\n onCommentDelete={handleCommentDelete}\n onAuthorClick={onAuthorClick}\n onMentionClick={onMentionClick}\n onAttachmentClick={onAttachmentClick}\n autoMarkReadThreadId={\n index === lastCommentIndex && isUnread\n ? thread.id\n : undefined\n }\n additionalActionsClassName={\n isFirstComment ? \"lb-thread-actions\" : undefined\n }\n additionalActions={\n isFirstComment && showResolveAction ? (\n <Tooltip\n content={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n <TogglePrimitive.Root\n pressed={thread.resolved}\n onPressedChange={handleResolvedChange}\n asChild\n >\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n {thread.resolved ? (\n <ResolvedIcon className=\"lb-button-icon\" />\n ) : (\n <ResolveIcon className=\"lb-button-icon\" />\n )}\n </Button>\n </TogglePrimitive.Root>\n </Tooltip>\n ) : null\n }\n />\n );\n\n return index === newIndicatorIndex &&\n newIndicatorIndex !== firstCommentIndex &&\n newIndicatorIndex <= lastCommentIndex ? (\n <Fragment key={comment.id}>\n <div\n className=\"lb-thread-new-indicator\"\n aria-label={$.THREAD_NEW_INDICATOR_DESCRIPTION}\n >\n <span className=\"lb-thread-new-indicator-label\">\n <ArrowDownIcon className=\"lb-thread-new-indicator-label-icon\" />\n {$.THREAD_NEW_INDICATOR}\n </span>\n </div>\n {children}\n </Fragment>\n ) : (\n children\n );\n })}\n </div>\n {showComposer && (\n <Composer\n className=\"lb-thread-composer\"\n threadId={thread.id}\n defaultCollapsed={showComposer === \"collapsed\" ? true : undefined}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n onComposerSubmit={onComposerSubmit}\n overrides={{\n COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,\n COMPOSER_SEND: $.THREAD_COMPOSER_SEND,\n }}\n roomId={thread.roomId}\n />\n )}\n </div>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ThreadProps<M> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA2JO;AAAe;AAElB;AACE;AACuB;AACT;AACd;AACoB;AACJ;AACD;AACG;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACE;AAEuD;AAEzD;AACE;AAE4D;AAE9D;AAAoD;AAC3C;AAET;AAEE;AACE;AAAA;AAIF;AACE;AAAO;AAIT;AAAoC;AAGZ;AAGxB;AAEI;AACH;AACD;AACA;AACA;AACO;AACP;AAEF;AACA;AAEA;AACE;AAEE;AAAA;AACwD;AACxD;AACF;AAGF;AACE;AAAsB;AAGxB;AAA6B;AAEzB;AAEA;AACE;AAA8B;AAE9B;AAAgC;AAClC;AACF;AACA;AACE;AACA;AACA;AACO;AACT;AAGF;AAA4B;AAExB;AAEA;AAAyC;AAClB;AAGvB;AACE;AAAuB;AACzB;AACF;AACwC;AAG1C;AAEK;AACY;AACT;AAC2B;AAC3B;AACF;AACsC;AACQ;AACvC;AACH;AACC;AAEJ;AAAc;AAEX;AACA;AAGA;AACG;AACc;AACH;AACmB;AAC7B;AACe;AACF;AACb;AACA;AACA;AACA;AAGA;AACiB;AACjB;AACA;AACA;AAIM;AAGmC;AAIpC;AAIS;AAGP;AACiB;AACC;AACV;AAEN;AACW;AACD;AAID;AAIL;AAAuB;AAEvB;AAAsB;AAK7B;AAKV;AAGG;AAAsB;AACpB;AACW;AACI;AAEb;AAAe;AACb;AAAwB;AAO/B;AAKH;AACW;AACO;AACuC;AACxD;AACwB;AACxB;AACW;AACe;AACP;AACnB;AACe;AAIvB;AAGN;;"}
1
+ {"version":3,"file":"Thread.mjs","sources":["../../src/components/Thread.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BaseMetadata,\n CommentData,\n DM,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { useThreadSubscription } from \"@liveblocks/react\";\nimport {\n useMarkRoomThreadAsResolved,\n useMarkRoomThreadAsUnresolved,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentPropsWithoutRef,\n ForwardedRef,\n RefAttributes,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n Fragment,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\n\nimport { ArrowDownIcon } from \"../icons/ArrowDown\";\nimport { ResolveIcon } from \"../icons/Resolve\";\nimport { ResolvedIcon } from \"../icons/Resolved\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { classNames } from \"../utils/class-names\";\nimport { findLastIndex } from \"../utils/find-last-index\";\nimport type { CommentProps } from \"./Comment\";\nimport { Comment } from \"./Comment\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport { Button } from \"./internal/Button\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\n\nexport interface ThreadProps<M extends BaseMetadata = DM>\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The thread to display.\n */\n thread: ThreadData<M>;\n\n /**\n * How to show or hide the composer to reply to the thread.\n */\n showComposer?: boolean | \"collapsed\";\n\n /**\n * Whether to show the action to resolve the thread.\n */\n showResolveAction?: boolean;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: CommentProps[\"showActions\"];\n\n /**\n * Whether to show reactions.\n */\n showReactions?: CommentProps[\"showReactions\"];\n\n /**\n * Whether to show the composer's formatting controls.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comments' content.\n */\n indentCommentContent?: CommentProps[\"indentContent\"];\n\n /**\n * Whether to show deleted comments.\n */\n showDeletedComments?: CommentProps[\"showDeleted\"];\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n\n /**\n * The event handler called when changing the resolved status.\n */\n onResolvedChange?: (resolved: boolean) => void;\n\n /**\n * The event handler called when a comment is edited.\n */\n onCommentEdit?: CommentProps[\"onCommentEdit\"];\n\n /**\n * The event handler called when a comment is deleted.\n */\n onCommentDelete?: CommentProps[\"onCommentDelete\"];\n\n /**\n * The event handler called when the thread is deleted.\n * A thread is deleted when all its comments are deleted.\n */\n onThreadDelete?: (thread: ThreadData<M>) => void;\n\n /**\n * The event handler called when clicking on a comment's author.\n */\n onAuthorClick?: CommentProps[\"onAuthorClick\"];\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: CommentProps[\"onMentionClick\"];\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n\n /**\n * The event handler called when the composer is submitted.\n */\n onComposerSubmit?: ComposerProps[\"onComposerSubmit\"];\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides\n >;\n}\n\n/**\n * Displays a thread of comments, with a composer to reply\n * to it.\n *\n * @example\n * <>\n * {threads.map((thread) => (\n * <Thread key={thread.id} thread={thread} />\n * ))}\n * </>\n */\nexport const Thread = forwardRef(\n <M extends BaseMetadata = DM>(\n {\n thread,\n indentCommentContent = true,\n showActions = \"hover\",\n showDeletedComments,\n showResolveAction = true,\n showReactions = true,\n showComposer = \"collapsed\",\n showAttachments = true,\n showComposerFormattingControls = true,\n onResolvedChange,\n onCommentEdit,\n onCommentDelete,\n onThreadDelete,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onComposerSubmit,\n overrides,\n className,\n ...props\n }: ThreadProps<M>,\n forwardedRef: ForwardedRef<HTMLDivElement>\n ) => {\n const markThreadAsResolved = useMarkRoomThreadAsResolved(thread.roomId);\n const markThreadAsUnresolved = useMarkRoomThreadAsUnresolved(thread.roomId);\n const $ = useOverrides(overrides);\n const firstCommentIndex = useMemo(() => {\n return showDeletedComments\n ? 0\n : thread.comments.findIndex((comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const lastCommentIndex = useMemo(() => {\n return showDeletedComments\n ? thread.comments.length - 1\n : findLastIndex(thread.comments, (comment) => comment.body);\n }, [showDeletedComments, thread.comments]);\n const { status: subscriptionStatus, unreadSince } = useThreadSubscription(\n thread.id\n );\n const unreadIndex = useMemo(() => {\n // The user is not subscribed to this thread.\n if (subscriptionStatus !== \"subscribed\") {\n return;\n }\n\n // The user hasn't read the thread yet, so all comments are unread.\n if (unreadSince === null) {\n return firstCommentIndex;\n }\n\n // The user has read the thread, so we find the first unread comment.\n const unreadIndex = thread.comments.findIndex(\n (comment) =>\n (showDeletedComments ? true : comment.body) &&\n comment.createdAt > unreadSince\n );\n\n return unreadIndex >= 0 && unreadIndex < thread.comments.length\n ? unreadIndex\n : undefined;\n }, [\n firstCommentIndex,\n showDeletedComments,\n subscriptionStatus,\n thread.comments,\n unreadSince,\n ]);\n const [newIndex, setNewIndex] = useState<number>();\n const newIndicatorIndex = newIndex === undefined ? unreadIndex : newIndex;\n\n useEffect(() => {\n if (unreadIndex) {\n // Keep the \"new\" indicator at the lowest unread index.\n setNewIndex((persistedUnreadIndex) =>\n Math.min(persistedUnreadIndex ?? Infinity, unreadIndex)\n );\n }\n }, [unreadIndex]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleResolvedChange = useCallback(\n (resolved: boolean) => {\n onResolvedChange?.(resolved);\n\n if (resolved) {\n markThreadAsResolved(thread.id);\n } else {\n markThreadAsUnresolved(thread.id);\n }\n },\n [\n markThreadAsResolved,\n markThreadAsUnresolved,\n onResolvedChange,\n thread.id,\n ]\n );\n\n const handleCommentDelete = useCallback(\n (comment: CommentData) => {\n onCommentDelete?.(comment);\n\n const filteredComments = thread.comments.filter(\n (comment) => comment.body\n );\n\n if (filteredComments.length <= 1) {\n onThreadDelete?.(thread);\n }\n },\n [onCommentDelete, onThreadDelete, thread]\n );\n\n return (\n <TooltipProvider>\n <div\n className={classNames(\n \"lb-root lb-thread\",\n showActions === \"hover\" && \"lb-thread:show-actions-hover\",\n className\n )}\n data-resolved={thread.resolved ? \"\" : undefined}\n data-unread={unreadIndex !== undefined ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={forwardedRef}\n >\n <div className=\"lb-thread-comments\">\n {thread.comments.map((comment, index) => {\n const isFirstComment = index === firstCommentIndex;\n const isUnread =\n unreadIndex !== undefined && index >= unreadIndex;\n\n const children = (\n <Comment\n key={comment.id}\n className=\"lb-thread-comment\"\n data-unread={isUnread ? \"\" : undefined}\n comment={comment}\n indentContent={indentCommentContent}\n showDeleted={showDeletedComments}\n showActions={showActions}\n showReactions={showReactions}\n showAttachments={showAttachments}\n showComposerFormattingControls={\n showComposerFormattingControls\n }\n onCommentEdit={onCommentEdit}\n onCommentDelete={handleCommentDelete}\n onAuthorClick={onAuthorClick}\n onMentionClick={onMentionClick}\n onAttachmentClick={onAttachmentClick}\n autoMarkReadThreadId={\n index === lastCommentIndex && isUnread\n ? thread.id\n : undefined\n }\n additionalActionsClassName={\n isFirstComment ? \"lb-thread-actions\" : undefined\n }\n additionalActions={\n isFirstComment && showResolveAction ? (\n <Tooltip\n content={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n <TogglePrimitive.Root\n pressed={thread.resolved}\n onPressedChange={handleResolvedChange}\n asChild\n >\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={\n thread.resolved\n ? $.THREAD_UNRESOLVE\n : $.THREAD_RESOLVE\n }\n >\n {thread.resolved ? (\n <ResolvedIcon className=\"lb-button-icon\" />\n ) : (\n <ResolveIcon className=\"lb-button-icon\" />\n )}\n </Button>\n </TogglePrimitive.Root>\n </Tooltip>\n ) : null\n }\n />\n );\n\n return index === newIndicatorIndex &&\n newIndicatorIndex !== firstCommentIndex &&\n newIndicatorIndex <= lastCommentIndex ? (\n <Fragment key={comment.id}>\n <div\n className=\"lb-thread-new-indicator\"\n aria-label={$.THREAD_NEW_INDICATOR_DESCRIPTION}\n >\n <span className=\"lb-thread-new-indicator-label\">\n <ArrowDownIcon className=\"lb-thread-new-indicator-label-icon\" />\n {$.THREAD_NEW_INDICATOR}\n </span>\n </div>\n {children}\n </Fragment>\n ) : (\n children\n );\n })}\n </div>\n {showComposer && (\n <Composer\n className=\"lb-thread-composer\"\n threadId={thread.id}\n defaultCollapsed={showComposer === \"collapsed\" ? true : undefined}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n onComposerSubmit={onComposerSubmit}\n overrides={{\n COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,\n COMPOSER_SEND: $.THREAD_COMPOSER_SEND,\n }}\n roomId={thread.roomId}\n />\n )}\n </div>\n </TooltipProvider>\n );\n }\n) as <M extends BaseMetadata = DM>(\n props: ThreadProps<M> & RefAttributes<HTMLDivElement>\n) => JSX.Element;\n"],"names":["unreadIndex","comment"],"mappings":"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"}