@liveblocks/react-ui 2.14.0 → 2.15.0-debug1

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 (258) hide show
  1. package/dist/_private/index.d.mts +24 -22
  2. package/dist/_private/index.d.ts +24 -22
  3. package/dist/components/Comment.js +355 -254
  4. package/dist/components/Comment.js.map +1 -1
  5. package/dist/components/Comment.mjs +330 -229
  6. package/dist/components/Comment.mjs.map +1 -1
  7. package/dist/components/Composer.js +305 -224
  8. package/dist/components/Composer.js.map +1 -1
  9. package/dist/components/Composer.mjs +281 -200
  10. package/dist/components/Composer.mjs.map +1 -1
  11. package/dist/components/HistoryVersionSummary.js +25 -22
  12. package/dist/components/HistoryVersionSummary.js.map +1 -1
  13. package/dist/components/HistoryVersionSummary.mjs +24 -21
  14. package/dist/components/HistoryVersionSummary.mjs.map +1 -1
  15. package/dist/components/HistoryVersionSummaryList.js +10 -9
  16. package/dist/components/HistoryVersionSummaryList.js.map +1 -1
  17. package/dist/components/HistoryVersionSummaryList.mjs +9 -8
  18. package/dist/components/HistoryVersionSummaryList.mjs.map +1 -1
  19. package/dist/components/InboxNotification.js +201 -143
  20. package/dist/components/InboxNotification.js.map +1 -1
  21. package/dist/components/InboxNotification.mjs +179 -121
  22. package/dist/components/InboxNotification.mjs.map +1 -1
  23. package/dist/components/InboxNotificationList.js +18 -14
  24. package/dist/components/InboxNotificationList.js.map +1 -1
  25. package/dist/components/InboxNotificationList.mjs +16 -12
  26. package/dist/components/InboxNotificationList.mjs.map +1 -1
  27. package/dist/components/Thread.js +103 -86
  28. package/dist/components/Thread.js.map +1 -1
  29. package/dist/components/Thread.mjs +92 -75
  30. package/dist/components/Thread.mjs.map +1 -1
  31. package/dist/components/internal/Attachment.js +158 -107
  32. package/dist/components/internal/Attachment.js.map +1 -1
  33. package/dist/components/internal/Attachment.mjs +147 -96
  34. package/dist/components/internal/Attachment.mjs.map +1 -1
  35. package/dist/components/internal/Attribution.js +15 -13
  36. package/dist/components/internal/Attribution.js.map +1 -1
  37. package/dist/components/internal/Attribution.mjs +15 -13
  38. package/dist/components/internal/Attribution.mjs.map +1 -1
  39. package/dist/components/internal/Avatar.js +26 -20
  40. package/dist/components/internal/Avatar.js.map +1 -1
  41. package/dist/components/internal/Avatar.mjs +22 -16
  42. package/dist/components/internal/Avatar.mjs.map +1 -1
  43. package/dist/components/internal/Button.js +4 -4
  44. package/dist/components/internal/Button.js.map +1 -1
  45. package/dist/components/internal/Button.mjs +3 -3
  46. package/dist/components/internal/Button.mjs.map +1 -1
  47. package/dist/components/internal/Dropdown.js +26 -19
  48. package/dist/components/internal/Dropdown.js.map +1 -1
  49. package/dist/components/internal/Dropdown.mjs +25 -18
  50. package/dist/components/internal/Dropdown.mjs.map +1 -1
  51. package/dist/components/internal/Emoji.js +4 -3
  52. package/dist/components/internal/Emoji.js.map +1 -1
  53. package/dist/components/internal/Emoji.mjs +3 -2
  54. package/dist/components/internal/Emoji.mjs.map +1 -1
  55. package/dist/components/internal/EmojiPicker.js +96 -72
  56. package/dist/components/internal/EmojiPicker.js.map +1 -1
  57. package/dist/components/internal/EmojiPicker.mjs +90 -66
  58. package/dist/components/internal/EmojiPicker.mjs.map +1 -1
  59. package/dist/components/internal/Icon.js +5 -4
  60. package/dist/components/internal/Icon.js.map +1 -1
  61. package/dist/components/internal/Icon.mjs +5 -4
  62. package/dist/components/internal/Icon.mjs.map +1 -1
  63. package/dist/components/internal/InboxNotificationThread.js +53 -38
  64. package/dist/components/internal/InboxNotificationThread.js.map +1 -1
  65. package/dist/components/internal/InboxNotificationThread.mjs +53 -38
  66. package/dist/components/internal/InboxNotificationThread.mjs.map +1 -1
  67. package/dist/components/internal/List.js +8 -6
  68. package/dist/components/internal/List.js.map +1 -1
  69. package/dist/components/internal/List.mjs +6 -4
  70. package/dist/components/internal/List.mjs.map +1 -1
  71. package/dist/components/internal/Room.js +7 -6
  72. package/dist/components/internal/Room.js.map +1 -1
  73. package/dist/components/internal/Room.mjs +6 -5
  74. package/dist/components/internal/Room.mjs.map +1 -1
  75. package/dist/components/internal/Tooltip.js +48 -33
  76. package/dist/components/internal/Tooltip.js.map +1 -1
  77. package/dist/components/internal/Tooltip.mjs +45 -30
  78. package/dist/components/internal/Tooltip.mjs.map +1 -1
  79. package/dist/components/internal/User.js +7 -6
  80. package/dist/components/internal/User.js.map +1 -1
  81. package/dist/components/internal/User.mjs +6 -5
  82. package/dist/components/internal/User.mjs.map +1 -1
  83. package/dist/components.js +11 -29
  84. package/dist/components.js.map +1 -1
  85. package/dist/components.mjs +5 -5
  86. package/dist/components.mjs.map +1 -1
  87. package/dist/config.js +15 -12
  88. package/dist/config.js.map +1 -1
  89. package/dist/config.mjs +12 -9
  90. package/dist/config.mjs.map +1 -1
  91. package/dist/icons/ArrowDown.js +7 -6
  92. package/dist/icons/ArrowDown.js.map +1 -1
  93. package/dist/icons/ArrowDown.mjs +7 -6
  94. package/dist/icons/ArrowDown.mjs.map +1 -1
  95. package/dist/icons/ArrowUp.js +7 -6
  96. package/dist/icons/ArrowUp.js.map +1 -1
  97. package/dist/icons/ArrowUp.mjs +7 -6
  98. package/dist/icons/ArrowUp.mjs.map +1 -1
  99. package/dist/icons/Attachment.js +7 -6
  100. package/dist/icons/Attachment.js.map +1 -1
  101. package/dist/icons/Attachment.mjs +7 -6
  102. package/dist/icons/Attachment.mjs.map +1 -1
  103. package/dist/icons/Bold.js +7 -6
  104. package/dist/icons/Bold.js.map +1 -1
  105. package/dist/icons/Bold.mjs +7 -6
  106. package/dist/icons/Bold.mjs.map +1 -1
  107. package/dist/icons/Check.js +7 -6
  108. package/dist/icons/Check.js.map +1 -1
  109. package/dist/icons/Check.mjs +7 -6
  110. package/dist/icons/Check.mjs.map +1 -1
  111. package/dist/icons/Code.js +7 -6
  112. package/dist/icons/Code.js.map +1 -1
  113. package/dist/icons/Code.mjs +7 -6
  114. package/dist/icons/Code.mjs.map +1 -1
  115. package/dist/icons/Cross.js +12 -8
  116. package/dist/icons/Cross.js.map +1 -1
  117. package/dist/icons/Cross.mjs +12 -8
  118. package/dist/icons/Cross.mjs.map +1 -1
  119. package/dist/icons/Delete.js +7 -6
  120. package/dist/icons/Delete.js.map +1 -1
  121. package/dist/icons/Delete.mjs +7 -6
  122. package/dist/icons/Delete.mjs.map +1 -1
  123. package/dist/icons/Edit.js +7 -6
  124. package/dist/icons/Edit.js.map +1 -1
  125. package/dist/icons/Edit.mjs +7 -6
  126. package/dist/icons/Edit.mjs.map +1 -1
  127. package/dist/icons/Ellipsis.js +21 -16
  128. package/dist/icons/Ellipsis.js.map +1 -1
  129. package/dist/icons/Ellipsis.mjs +21 -16
  130. package/dist/icons/Ellipsis.mjs.map +1 -1
  131. package/dist/icons/Emoji.js +25 -18
  132. package/dist/icons/Emoji.js.map +1 -1
  133. package/dist/icons/Emoji.mjs +25 -18
  134. package/dist/icons/Emoji.mjs.map +1 -1
  135. package/dist/icons/EmojiAdd.js +28 -20
  136. package/dist/icons/EmojiAdd.js.map +1 -1
  137. package/dist/icons/EmojiAdd.mjs +28 -20
  138. package/dist/icons/EmojiAdd.mjs.map +1 -1
  139. package/dist/icons/Italic.js +7 -6
  140. package/dist/icons/Italic.js.map +1 -1
  141. package/dist/icons/Italic.mjs +7 -6
  142. package/dist/icons/Italic.mjs.map +1 -1
  143. package/dist/icons/Mention.js +12 -8
  144. package/dist/icons/Mention.js.map +1 -1
  145. package/dist/icons/Mention.mjs +12 -8
  146. package/dist/icons/Mention.mjs.map +1 -1
  147. package/dist/icons/Resolve.js +14 -10
  148. package/dist/icons/Resolve.js.map +1 -1
  149. package/dist/icons/Resolve.mjs +14 -10
  150. package/dist/icons/Resolve.mjs.map +1 -1
  151. package/dist/icons/Resolved.js +16 -12
  152. package/dist/icons/Resolved.js.map +1 -1
  153. package/dist/icons/Resolved.mjs +16 -12
  154. package/dist/icons/Resolved.mjs.map +1 -1
  155. package/dist/icons/Restore.js +12 -8
  156. package/dist/icons/Restore.js.map +1 -1
  157. package/dist/icons/Restore.mjs +12 -8
  158. package/dist/icons/Restore.mjs.map +1 -1
  159. package/dist/icons/Search.js +7 -6
  160. package/dist/icons/Search.js.map +1 -1
  161. package/dist/icons/Search.mjs +7 -6
  162. package/dist/icons/Search.mjs.map +1 -1
  163. package/dist/icons/Send.js +7 -6
  164. package/dist/icons/Send.js.map +1 -1
  165. package/dist/icons/Send.mjs +7 -6
  166. package/dist/icons/Send.mjs.map +1 -1
  167. package/dist/icons/Spinner.js +8 -7
  168. package/dist/icons/Spinner.js.map +1 -1
  169. package/dist/icons/Spinner.mjs +8 -7
  170. package/dist/icons/Spinner.mjs.map +1 -1
  171. package/dist/icons/Strikethrough.js +7 -6
  172. package/dist/icons/Strikethrough.js.map +1 -1
  173. package/dist/icons/Strikethrough.mjs +7 -6
  174. package/dist/icons/Strikethrough.mjs.map +1 -1
  175. package/dist/icons/Warning.js +14 -10
  176. package/dist/icons/Warning.js.map +1 -1
  177. package/dist/icons/Warning.mjs +14 -10
  178. package/dist/icons/Warning.mjs.map +1 -1
  179. package/dist/index.d.mts +14 -12
  180. package/dist/index.d.ts +14 -12
  181. package/dist/overrides.js +64 -36
  182. package/dist/overrides.js.map +1 -1
  183. package/dist/overrides.mjs +58 -12
  184. package/dist/overrides.mjs.map +1 -1
  185. package/dist/primitives/Comment/index.js +75 -66
  186. package/dist/primitives/Comment/index.js.map +1 -1
  187. package/dist/primitives/Comment/index.mjs +71 -62
  188. package/dist/primitives/Comment/index.mjs.map +1 -1
  189. package/dist/primitives/Composer/contexts.js +11 -11
  190. package/dist/primitives/Composer/index.js +329 -271
  191. package/dist/primitives/Composer/index.js.map +1 -1
  192. package/dist/primitives/Composer/index.mjs +254 -196
  193. package/dist/primitives/Composer/index.mjs.map +1 -1
  194. package/dist/primitives/Composer/utils.js +18 -20
  195. package/dist/primitives/Composer/utils.js.map +1 -1
  196. package/dist/primitives/Composer/utils.mjs +1 -3
  197. package/dist/primitives/Composer/utils.mjs.map +1 -1
  198. package/dist/primitives/EmojiPicker/contexts.js +3 -3
  199. package/dist/primitives/EmojiPicker/index.js +159 -142
  200. package/dist/primitives/EmojiPicker/index.js.map +1 -1
  201. package/dist/primitives/EmojiPicker/index.mjs +120 -103
  202. package/dist/primitives/EmojiPicker/index.mjs.map +1 -1
  203. package/dist/primitives/FileSize.js +8 -7
  204. package/dist/primitives/FileSize.js.map +1 -1
  205. package/dist/primitives/FileSize.mjs +6 -5
  206. package/dist/primitives/FileSize.mjs.map +1 -1
  207. package/dist/primitives/Timestamp.js +11 -10
  208. package/dist/primitives/Timestamp.js.map +1 -1
  209. package/dist/primitives/Timestamp.mjs +6 -5
  210. package/dist/primitives/Timestamp.mjs.map +1 -1
  211. package/dist/primitives/index.d.mts +24 -23
  212. package/dist/primitives/index.d.ts +24 -23
  213. package/dist/primitives/internal/Emoji.js +7 -5
  214. package/dist/primitives/internal/Emoji.js.map +1 -1
  215. package/dist/primitives/internal/Emoji.mjs +6 -4
  216. package/dist/primitives/internal/Emoji.mjs.map +1 -1
  217. package/dist/shared.js +2 -7
  218. package/dist/shared.js.map +1 -1
  219. package/dist/shared.mjs +2 -7
  220. package/dist/shared.mjs.map +1 -1
  221. package/dist/utils/Persist.js +18 -18
  222. package/dist/utils/Persist.js.map +1 -1
  223. package/dist/utils/Persist.mjs +6 -6
  224. package/dist/utils/Persist.mjs.map +1 -1
  225. package/dist/utils/Portal.js +4 -4
  226. package/dist/utils/Portal.js.map +1 -1
  227. package/dist/utils/Portal.mjs +3 -3
  228. package/dist/utils/Portal.mjs.map +1 -1
  229. package/dist/utils/use-controllable-state.js +5 -5
  230. package/dist/utils/use-index.js +7 -7
  231. package/dist/utils/use-initial.js +2 -2
  232. package/dist/utils/use-interval.js +4 -4
  233. package/dist/utils/use-latest.js +3 -3
  234. package/dist/utils/use-observable.js +2 -2
  235. package/dist/utils/use-refs.js +2 -2
  236. package/dist/utils/use-rerender.js +2 -2
  237. package/dist/utils/use-visible.js +2 -2
  238. package/dist/utils/use-window-focus.js +2 -2
  239. package/dist/utils/use-window-focus.js.map +1 -1
  240. package/dist/utils/use-window-focus.mjs +1 -1
  241. package/dist/utils/use-window-focus.mjs.map +1 -1
  242. package/dist/version.js +1 -1
  243. package/dist/version.js.map +1 -1
  244. package/dist/version.mjs +1 -1
  245. package/dist/version.mjs.map +1 -1
  246. package/package.json +6 -8
  247. package/dist/utils/use-id.js +0 -29
  248. package/dist/utils/use-id.js.map +0 -1
  249. package/dist/utils/use-id.mjs +0 -27
  250. package/dist/utils/use-id.mjs.map +0 -1
  251. package/dist/utils/use-layout-effect.js +0 -8
  252. package/dist/utils/use-layout-effect.js.map +0 -1
  253. package/dist/utils/use-layout-effect.mjs +0 -6
  254. package/dist/utils/use-layout-effect.mjs.map +0 -1
  255. package/dist/utils/use-transition.js +0 -16
  256. package/dist/utils/use-transition.js.map +0 -1
  257. package/dist/utils/use-transition.mjs +0 -14
  258. 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';
@@ -108,79 +108,96 @@ const Thread = forwardRef(
108
108
  },
109
109
  [onCommentDelete, onThreadDelete, thread]
110
110
  );
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
- })));
111
+ return /* @__PURE__ */ jsx(TooltipProvider, {
112
+ children: /* @__PURE__ */ jsxs("div", {
113
+ className: classNames(
114
+ "lb-root lb-thread",
115
+ showActions === "hover" && "lb-thread:show-actions-hover",
116
+ className
117
+ ),
118
+ "data-resolved": thread.resolved ? "" : void 0,
119
+ "data-unread": unreadIndex !== void 0 ? "" : void 0,
120
+ dir: $.dir,
121
+ ...props,
122
+ ref: forwardedRef,
123
+ children: [
124
+ /* @__PURE__ */ jsx("div", {
125
+ className: "lb-thread-comments",
126
+ children: thread.comments.map((comment, index) => {
127
+ const isFirstComment = index === firstCommentIndex;
128
+ const isUnread = unreadIndex !== void 0 && index >= unreadIndex;
129
+ const children = /* @__PURE__ */ jsx(Comment, {
130
+ className: "lb-thread-comment",
131
+ "data-unread": isUnread ? "" : void 0,
132
+ comment,
133
+ indentContent: indentCommentContent,
134
+ showDeleted: showDeletedComments,
135
+ showActions,
136
+ showReactions,
137
+ showAttachments,
138
+ showComposerFormattingControls,
139
+ onCommentEdit,
140
+ onCommentDelete: handleCommentDelete,
141
+ onAuthorClick,
142
+ onMentionClick,
143
+ onAttachmentClick,
144
+ autoMarkReadThreadId: index === lastCommentIndex && isUnread ? thread.id : void 0,
145
+ additionalActionsClassName: isFirstComment ? "lb-thread-actions" : void 0,
146
+ additionalActions: isFirstComment && showResolveAction ? /* @__PURE__ */ jsx(Tooltip, {
147
+ content: thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
148
+ children: /* @__PURE__ */ jsx(TogglePrimitive.Root, {
149
+ pressed: thread.resolved,
150
+ onPressedChange: handleResolvedChange,
151
+ asChild: true,
152
+ children: /* @__PURE__ */ jsx(Button, {
153
+ className: "lb-comment-action",
154
+ onClick: stopPropagation,
155
+ "aria-label": thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
156
+ children: thread.resolved ? /* @__PURE__ */ jsx(ResolvedIcon, {
157
+ className: "lb-button-icon"
158
+ }) : /* @__PURE__ */ jsx(ResolveIcon, {
159
+ className: "lb-button-icon"
160
+ })
161
+ })
162
+ })
163
+ }) : null
164
+ }, comment.id);
165
+ return index === newIndicatorIndex && newIndicatorIndex !== firstCommentIndex && newIndicatorIndex <= lastCommentIndex ? /* @__PURE__ */ jsxs(Fragment, {
166
+ children: [
167
+ /* @__PURE__ */ jsx("div", {
168
+ className: "lb-thread-new-indicator",
169
+ "aria-label": $.THREAD_NEW_INDICATOR_DESCRIPTION,
170
+ children: /* @__PURE__ */ jsxs("span", {
171
+ className: "lb-thread-new-indicator-label",
172
+ children: [
173
+ /* @__PURE__ */ jsx(ArrowDownIcon, {
174
+ className: "lb-thread-new-indicator-label-icon"
175
+ }),
176
+ $.THREAD_NEW_INDICATOR
177
+ ]
178
+ })
179
+ }),
180
+ children
181
+ ]
182
+ }, comment.id) : children;
183
+ })
184
+ }),
185
+ showComposer && /* @__PURE__ */ jsx(Composer, {
186
+ className: "lb-thread-composer",
187
+ threadId: thread.id,
188
+ defaultCollapsed: showComposer === "collapsed" ? true : void 0,
189
+ showAttachments,
190
+ showFormattingControls: showComposerFormattingControls,
191
+ onComposerSubmit,
192
+ overrides: {
193
+ COMPOSER_PLACEHOLDER: $.THREAD_COMPOSER_PLACEHOLDER,
194
+ COMPOSER_SEND: $.THREAD_COMPOSER_SEND
195
+ },
196
+ roomId: thread.roomId
197
+ })
198
+ ]
199
+ })
200
+ });
184
201
  }
185
202
  );
186
203
 
@@ -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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"}