@liveblocks/react-ui 3.15.0-components1 → 3.15.0-thread2

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 (145) hide show
  1. package/dist/_private/index.cjs +7 -1
  2. package/dist/_private/index.cjs.map +1 -1
  3. package/dist/_private/index.d.cts +10 -4
  4. package/dist/_private/index.d.ts +10 -4
  5. package/dist/_private/index.js +3 -1
  6. package/dist/_private/index.js.map +1 -1
  7. package/dist/components/AiChat.cjs +10 -2
  8. package/dist/components/AiChat.cjs.map +1 -1
  9. package/dist/components/AiChat.js +10 -2
  10. package/dist/components/AiChat.js.map +1 -1
  11. package/dist/components/Comment.cjs +277 -232
  12. package/dist/components/Comment.cjs.map +1 -1
  13. package/dist/components/Comment.js +263 -237
  14. package/dist/components/Comment.js.map +1 -1
  15. package/dist/components/Composer.cjs +4 -2
  16. package/dist/components/Composer.cjs.map +1 -1
  17. package/dist/components/Composer.js +5 -3
  18. package/dist/components/Composer.js.map +1 -1
  19. package/dist/components/InboxNotification.cjs +6 -4
  20. package/dist/components/InboxNotification.cjs.map +1 -1
  21. package/dist/components/InboxNotification.js +7 -5
  22. package/dist/components/InboxNotification.js.map +1 -1
  23. package/dist/components/Thread.cjs +71 -45
  24. package/dist/components/Thread.cjs.map +1 -1
  25. package/dist/components/Thread.js +56 -49
  26. package/dist/components/Thread.js.map +1 -1
  27. package/dist/components/internal/AiComposer.cjs +2 -1
  28. package/dist/components/internal/AiComposer.cjs.map +1 -1
  29. package/dist/components/internal/AiComposer.js +2 -1
  30. package/dist/components/internal/AiComposer.js.map +1 -1
  31. package/dist/components/internal/CodeBlock.cjs +2 -1
  32. package/dist/components/internal/CodeBlock.cjs.map +1 -1
  33. package/dist/components/internal/CodeBlock.js +2 -1
  34. package/dist/components/internal/CodeBlock.js.map +1 -1
  35. package/dist/components/internal/Dropdown.cjs +28 -7
  36. package/dist/components/internal/Dropdown.cjs.map +1 -1
  37. package/dist/components/internal/Dropdown.js +7 -7
  38. package/dist/components/internal/Dropdown.js.map +1 -1
  39. package/dist/components/internal/EmojiPicker.cjs +27 -6
  40. package/dist/components/internal/EmojiPicker.cjs.map +1 -1
  41. package/dist/components/internal/EmojiPicker.js +6 -6
  42. package/dist/components/internal/EmojiPicker.js.map +1 -1
  43. package/dist/components/internal/List.cjs +2 -2
  44. package/dist/components/internal/List.cjs.map +1 -1
  45. package/dist/components/internal/List.js +2 -2
  46. package/dist/components/internal/List.js.map +1 -1
  47. package/dist/components/internal/Tooltip.cjs +28 -7
  48. package/dist/components/internal/Tooltip.cjs.map +1 -1
  49. package/dist/components/internal/Tooltip.js +7 -7
  50. package/dist/components/internal/Tooltip.js.map +1 -1
  51. package/dist/index.cjs +0 -12
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +197 -213
  54. package/dist/index.d.ts +197 -213
  55. package/dist/index.js +0 -6
  56. package/dist/index.js.map +1 -1
  57. package/dist/primitives/AiComposer/index.cjs +4 -5
  58. package/dist/primitives/AiComposer/index.cjs.map +1 -1
  59. package/dist/primitives/AiComposer/index.js +4 -5
  60. package/dist/primitives/AiComposer/index.js.map +1 -1
  61. package/dist/primitives/AiMessage/index.cjs +2 -2
  62. package/dist/primitives/AiMessage/index.cjs.map +1 -1
  63. package/dist/primitives/AiMessage/index.js +2 -2
  64. package/dist/primitives/AiMessage/index.js.map +1 -1
  65. package/dist/primitives/Collapsible/index.cjs +4 -4
  66. package/dist/primitives/Collapsible/index.cjs.map +1 -1
  67. package/dist/primitives/Collapsible/index.js +4 -4
  68. package/dist/primitives/Collapsible/index.js.map +1 -1
  69. package/dist/primitives/Comment/index.cjs +4 -4
  70. package/dist/primitives/Comment/index.cjs.map +1 -1
  71. package/dist/primitives/Comment/index.js +4 -4
  72. package/dist/primitives/Comment/index.js.map +1 -1
  73. package/dist/primitives/Composer/index.cjs +35 -23
  74. package/dist/primitives/Composer/index.cjs.map +1 -1
  75. package/dist/primitives/Composer/index.js +16 -23
  76. package/dist/primitives/Composer/index.js.map +1 -1
  77. package/dist/primitives/Duration.cjs +2 -2
  78. package/dist/primitives/Duration.cjs.map +1 -1
  79. package/dist/primitives/Duration.js +2 -2
  80. package/dist/primitives/Duration.js.map +1 -1
  81. package/dist/primitives/FileSize.cjs +2 -2
  82. package/dist/primitives/FileSize.cjs.map +1 -1
  83. package/dist/primitives/FileSize.js +2 -2
  84. package/dist/primitives/FileSize.js.map +1 -1
  85. package/dist/primitives/Markdown.cjs +2 -2
  86. package/dist/primitives/Markdown.cjs.map +1 -1
  87. package/dist/primitives/Markdown.js +2 -2
  88. package/dist/primitives/Markdown.js.map +1 -1
  89. package/dist/primitives/Timestamp.cjs +2 -2
  90. package/dist/primitives/Timestamp.cjs.map +1 -1
  91. package/dist/primitives/Timestamp.js +2 -2
  92. package/dist/primitives/Timestamp.js.map +1 -1
  93. package/dist/utils/Portal.cjs +2 -2
  94. package/dist/utils/Portal.cjs.map +1 -1
  95. package/dist/utils/Portal.js +2 -2
  96. package/dist/utils/Portal.js.map +1 -1
  97. package/dist/utils/use-stable-component.cjs +32 -0
  98. package/dist/utils/use-stable-component.cjs.map +1 -0
  99. package/dist/utils/use-stable-component.js +30 -0
  100. package/dist/utils/use-stable-component.js.map +1 -0
  101. package/dist/version.cjs +1 -1
  102. package/dist/version.cjs.map +1 -1
  103. package/dist/version.js +1 -1
  104. package/dist/version.js.map +1 -1
  105. package/package.json +10 -6
  106. package/src/styles/dark/index.css +1 -1
  107. package/src/styles/index.css +4 -252
  108. package/styles/dark/attributes.css +1 -1
  109. package/styles/dark/attributes.css.map +1 -1
  110. package/styles/dark/media-query.css +1 -1
  111. package/styles/dark/media-query.css.map +1 -1
  112. package/styles.css +1 -1
  113. package/styles.css.map +1 -1
  114. package/dist/components/AvatarStack.cjs +0 -115
  115. package/dist/components/AvatarStack.cjs.map +0 -1
  116. package/dist/components/AvatarStack.js +0 -113
  117. package/dist/components/AvatarStack.js.map +0 -1
  118. package/dist/components/CommentPin.cjs +0 -27
  119. package/dist/components/CommentPin.cjs.map +0 -1
  120. package/dist/components/CommentPin.js +0 -25
  121. package/dist/components/CommentPin.js.map +0 -1
  122. package/dist/components/Cursor.cjs +0 -40
  123. package/dist/components/Cursor.cjs.map +0 -1
  124. package/dist/components/Cursor.js +0 -38
  125. package/dist/components/Cursor.js.map +0 -1
  126. package/dist/components/Cursors.cjs +0 -252
  127. package/dist/components/Cursors.cjs.map +0 -1
  128. package/dist/components/Cursors.js +0 -250
  129. package/dist/components/Cursors.js.map +0 -1
  130. package/dist/components/FloatingComposer.cjs +0 -82
  131. package/dist/components/FloatingComposer.cjs.map +0 -1
  132. package/dist/components/FloatingComposer.js +0 -80
  133. package/dist/components/FloatingComposer.js.map +0 -1
  134. package/dist/components/FloatingThread.cjs +0 -82
  135. package/dist/components/FloatingThread.cjs.map +0 -1
  136. package/dist/components/FloatingThread.js +0 -80
  137. package/dist/components/FloatingThread.js.map +0 -1
  138. package/dist/utils/animation-loop.cjs +0 -44
  139. package/dist/utils/animation-loop.cjs.map +0 -1
  140. package/dist/utils/animation-loop.js +0 -42
  141. package/dist/utils/animation-loop.js.map +0 -1
  142. package/dist/utils/use-pre-resolve-user.cjs +0 -18
  143. package/dist/utils/use-pre-resolve-user.cjs.map +0 -1
  144. package/dist/utils/use-pre-resolve-user.js +0 -16
  145. package/dist/utils/use-pre-resolve-user.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InboxNotification.cjs","sources":["../../src/components/InboxNotification.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n InboxNotificationCustomData,\n InboxNotificationData,\n InboxNotificationTextMentionData,\n InboxNotificationThreadData,\n KDAD,\n} from \"@liveblocks/core\";\nimport {\n assertNever,\n generateUrl,\n sanitizeUrl,\n warnOnce,\n} from \"@liveblocks/core\";\nimport {\n useClient,\n useDeleteInboxNotification,\n useInboxNotificationThread,\n useMarkInboxNotificationAsRead,\n useRoomInfo,\n} from \"@liveblocks/react\";\nimport { useRoomThreadSubscription } from \"@liveblocks/react/_private\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentType,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n SyntheticEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { useComponents } from \"../components\";\nimport { BellIcon } from \"../icons/Bell\";\nimport { BellCrossedIcon } from \"../icons/BellCrossed\";\nimport { CheckIcon } from \"../icons/Check\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { WarningIcon } from \"../icons/Warning\";\nimport type {\n CommentOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport type { SlotProp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { CodeBlock } from \"./internal/CodeBlock\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport {\n generateInboxNotificationThreadContents,\n INBOX_NOTIFICATION_THREAD_MAX_COMMENTS,\n InboxNotificationComment,\n} from \"./internal/InboxNotificationThread\";\nimport { List } from \"./internal/List\";\nimport { Room } from \"./internal/Room\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ntype ComponentTypeWithRef<\n T extends keyof JSX.IntrinsicElements,\n P,\n> = ComponentType<P & Pick<ComponentProps<T>, \"ref\">>;\n\ntype InboxNotificationKinds<KS extends KDAD = KDAD> = {\n // For some reason, we cannot directly use KDAD in the mapped type line\n // below, because it will result in '{}' rather than picking up the\n // definition from the user-provided 'ActivitiesData'. Might be an internal\n // TS optimization, so we're making it a param to defer the resolution.\n [K in KS]: ComponentTypeWithRef<\"a\", InboxNotificationCustomKindProps<K>>;\n} & {\n thread: ComponentTypeWithRef<\"a\", InboxNotificationThreadKindProps>;\n textMention: ComponentTypeWithRef<\"a\", InboxNotificationTextMentionKindProps>;\n};\n\ninterface InboxNotificationSharedProps {\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n}\n\nexport interface InboxNotificationProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n\n /**\n * Override specific kinds of inbox notifications.\n */\n kinds?: Partial<InboxNotificationKinds>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n InboxNotificationOverrides &\n ThreadOverrides &\n CommentOverrides\n >;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents>;\n}\n\nexport interface InboxNotificationThreadProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationThreadData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n}\n\nexport interface InboxNotificationTextMentionProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationTextMentionData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n}\n\nexport interface InboxNotificationInspectorProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n}\n\nexport interface InboxNotificationCustomProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps,\n SlotProp {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationCustomData;\n\n /**\n * The inbox notification's content.\n */\n children: ReactNode;\n\n /**\n * The inbox notification's title.\n */\n title: ReactNode;\n\n /**\n * The inbox notification's aside content.\n * Can be combined with `InboxNotification.Icon` or `InboxNotification.Avatar` to easily follow default styles.\n */\n aside?: ReactNode;\n\n /**\n * Whether to mark the inbox notification as read when clicked.\n */\n markAsReadOnClick?: boolean;\n}\n\nexport type InboxNotificationThreadKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationThreadData;\n};\n\nexport type InboxNotificationTextMentionKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationTextMentionData;\n};\n\nexport type InboxNotificationCustomKindProps<K extends KDAD = KDAD> = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationCustomData<K>;\n};\n\ninterface InboxNotificationLayoutProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps,\n SlotProp {\n inboxNotification: InboxNotificationData;\n aside?: ReactNode;\n title: ReactNode;\n date: Date | string | number;\n unread?: boolean;\n overrides?: Partial<GlobalOverrides & InboxNotificationOverrides>;\n components?: Partial<GlobalComponents>;\n markAsReadOnClick?: boolean;\n\n /**\n * @internal\n */\n additionalDropdownItemsBefore?: ReactNode;\n\n /**\n * @internal\n */\n additionalDropdownItemsAfter?: ReactNode;\n}\n\nexport type InboxNotificationIconProps = ComponentProps<\"div\">;\n\nexport interface InboxNotificationAvatarProps extends ComponentProps<\"div\"> {\n /**\n * The user ID to display the avatar for.\n */\n userId: string;\n}\n\nconst InboxNotificationLayout = forwardRef<\n HTMLAnchorElement,\n InboxNotificationLayoutProps\n>(\n (\n {\n inboxNotification,\n children,\n aside,\n title,\n date,\n unread,\n markAsReadOnClick,\n onClick,\n href,\n showActions,\n overrides,\n components,\n className,\n asChild,\n additionalDropdownItemsBefore,\n additionalDropdownItemsAfter,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const { Anchor } = useComponents(components);\n const Component = asChild ? SlotPrimitive.Slot : Anchor;\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();\n const deleteInboxNotification = useDeleteInboxNotification();\n\n const handleClick = useCallback(\n (event: ReactMouseEvent<HTMLAnchorElement, MouseEvent>) => {\n onClick?.(event);\n\n const shouldMarkAsReadOnClick = markAsReadOnClick ?? Boolean(href);\n\n if (unread && shouldMarkAsReadOnClick) {\n markInboxNotificationAsRead(inboxNotification.id);\n }\n },\n [\n href,\n inboxNotification.id,\n markAsReadOnClick,\n markInboxNotificationAsRead,\n onClick,\n unread,\n ]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const preventDefaultAndStopPropagation = useCallback(\n (event: SyntheticEvent) => {\n event.preventDefault();\n event.stopPropagation();\n },\n []\n );\n\n const handleMoreClick = useCallback((event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setMoreActionOpen((open) => !open);\n }, []);\n\n const handleMarkAsRead = useCallback(() => {\n markInboxNotificationAsRead(inboxNotification.id);\n }, [inboxNotification.id, markInboxNotificationAsRead]);\n\n const handleDelete = useCallback(() => {\n deleteInboxNotification(inboxNotification.id);\n }, [inboxNotification.id, deleteInboxNotification]);\n\n return (\n <TooltipProvider>\n <Component\n className={cn(\n \"lb-root lb-inbox-notification\",\n showActions === \"hover\" &&\n \"lb-inbox-notification:show-actions-hover\",\n isMoreActionOpen && \"lb-inbox-notification:action-open\",\n className\n )}\n dir={$.dir}\n data-unread={unread ? \"\" : undefined}\n data-kind={inboxNotification.kind}\n onClick={handleClick}\n href={href}\n {...props}\n ref={forwardedRef}\n >\n {aside && <div className=\"lb-inbox-notification-aside\">{aside}</div>}\n <div className=\"lb-inbox-notification-content\">\n <div className=\"lb-inbox-notification-header\">\n <span className=\"lb-inbox-notification-title\">{title}</span>\n <div className=\"lb-inbox-notification-details\">\n <span className=\"lb-inbox-notification-details-labels\">\n <Timestamp\n locale={$.locale}\n date={date}\n className=\"lb-date lb-inbox-notification-date\"\n />\n {unread && (\n <span\n className=\"lb-inbox-notification-unread-indicator\"\n role=\"presentation\"\n />\n )}\n </span>\n </div>\n {showActions && (\n <div className=\"lb-inbox-notification-actions\">\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n {additionalDropdownItemsBefore}\n {unread ? (\n <DropdownItem\n onSelect={handleMarkAsRead}\n onClick={stopPropagation}\n icon={<CheckIcon />}\n >\n {$.INBOX_NOTIFICATION_MARK_AS_READ}\n </DropdownItem>\n ) : null}\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.INBOX_NOTIFICATION_DELETE}\n </DropdownItem>\n {additionalDropdownItemsAfter}\n </>\n }\n >\n <Tooltip content={$.INBOX_NOTIFICATION_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-inbox-notification-action\"\n onClick={handleMoreClick}\n onPointerDown={preventDefaultAndStopPropagation}\n onPointerUp={preventDefaultAndStopPropagation}\n aria-label={$.INBOX_NOTIFICATION_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n </div>\n )}\n </div>\n <div className=\"lb-inbox-notification-body\">{children}</div>\n </div>\n </Component>\n </TooltipProvider>\n );\n }\n);\n\nfunction InboxNotificationIcon({\n className,\n ...props\n}: InboxNotificationIconProps) {\n return (\n <div className={cn(\"lb-inbox-notification-icon\", className)} {...props} />\n );\n}\n\nfunction InboxNotificationAvatar({\n className,\n ...props\n}: InboxNotificationAvatarProps) {\n return (\n <Avatar\n className={cn(\"lb-inbox-notification-avatar\", className)}\n {...props}\n />\n );\n}\n\nconst InboxNotificationThread = forwardRef<\n HTMLAnchorElement,\n InboxNotificationThreadProps\n>(\n (\n {\n inboxNotification,\n href,\n showRoomName = true,\n showReactions = true,\n showAttachments = true,\n showActions = \"hover\",\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const client = useClient();\n const thread = useInboxNotificationThread(inboxNotification.id);\n const {\n status: subscriptionStatus,\n subscribe,\n unsubscribe,\n } = useRoomThreadSubscription(thread.roomId, thread.id);\n const currentUserId = useCurrentUserId();\n const { info } = useRoomInfo(inboxNotification.roomId);\n const contents = useMemo(() => {\n const contents = generateInboxNotificationThreadContents(\n client,\n inboxNotification,\n thread,\n currentUserId ?? \"\"\n );\n\n if (contents.comments.length === 0 || contents.userIds.length === 0) {\n return null;\n }\n\n switch (contents.type) {\n case \"comments\": {\n const reversedUserIds = [...contents.userIds].reverse();\n const firstUserId = reversedUserIds[0]!;\n\n const aside = <InboxNotificationAvatar userId={firstUserId} />;\n const title = $.INBOX_NOTIFICATION_THREAD_COMMENTS_LIST(\n <List\n values={reversedUserIds.map((userId) => (\n <User key={userId} userId={userId} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={INBOX_NOTIFICATION_THREAD_MAX_COMMENTS - 1}\n locale={$.locale}\n />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined,\n reversedUserIds.length\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n {contents.comments.map((comment) => (\n <InboxNotificationComment\n key={comment.id}\n comment={comment}\n showHeader={contents.comments.length > 1}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n ))}\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: contents.comments[contents.comments.length - 1]!.id,\n };\n }\n\n case \"mention\": {\n const mentionCreatedBy = contents.userIds[0]!;\n const mentionComment = contents.comments[0]!;\n\n const aside = <InboxNotificationAvatar userId={mentionCreatedBy} />;\n const title = $.INBOX_NOTIFICATION_THREAD_MENTION(\n <User key={mentionCreatedBy} userId={mentionCreatedBy} />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n <InboxNotificationComment\n key={mentionComment.id}\n comment={mentionComment}\n showHeader={false}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: mentionComment.id,\n };\n }\n\n default:\n return assertNever(\n contents,\n \"Unexpected thread inbox notification type\"\n );\n }\n }, [\n $,\n client,\n currentUserId,\n inboxNotification,\n overrides,\n showRoomName,\n showAttachments,\n showReactions,\n thread,\n ]);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? // Set the comment ID as the URL hash.\n generateUrl(resolvedHref, undefined, contents?.commentId)\n : undefined;\n }, [contents?.commentId, href, info?.url]);\n\n const handleSubscribeChange = useCallback(() => {\n if (subscriptionStatus === \"subscribed\") {\n unsubscribe();\n } else {\n subscribe();\n }\n }, [subscriptionStatus, subscribe, unsubscribe]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n if (!contents) {\n return null;\n }\n\n const { aside, title, content, date, unread } = contents;\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={date}\n unread={unread}\n overrides={overrides}\n href={resolvedHref}\n showActions={showActions}\n markAsReadOnClick={false}\n additionalDropdownItemsBefore={\n <DropdownItem\n onSelect={handleSubscribeChange}\n onClick={stopPropagation}\n icon={\n subscriptionStatus === \"subscribed\" ? (\n <BellCrossedIcon />\n ) : (\n <BellIcon />\n )\n }\n >\n {subscriptionStatus === \"subscribed\"\n ? $.THREAD_UNSUBSCRIBE\n : $.THREAD_SUBSCRIBE}\n </DropdownItem>\n }\n {...props}\n ref={forwardedRef}\n >\n {content}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationTextMention = forwardRef<\n HTMLAnchorElement,\n InboxNotificationTextMentionProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n showRoomName = true,\n href,\n overrides,\n ...props\n },\n ref\n ) => {\n const $ = useOverrides(overrides);\n const { info } = useRoomInfo(inboxNotification.roomId);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? (sanitizeUrl(resolvedHref) ?? undefined)\n : undefined;\n }, [href, info?.url]);\n\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={<InboxNotificationAvatar userId={inboxNotification.createdBy} />}\n title={$.INBOX_NOTIFICATION_TEXT_MENTION(\n <User\n key={inboxNotification.createdBy}\n userId={inboxNotification.createdBy}\n />,\n showRoomName ? <Room roomId={inboxNotification.roomId} /> : undefined\n )}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n href={resolvedHref}\n {...props}\n ref={ref}\n />\n );\n }\n);\n\nconst InboxNotificationCustom = forwardRef<\n HTMLAnchorElement,\n InboxNotificationCustomProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n title,\n aside,\n children,\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n >\n {children}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationInspector = forwardRef<\n HTMLAnchorElement,\n InboxNotificationInspectorProps\n>(\n (\n { inboxNotification, showActions = \"hover\", overrides, ...props },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n title={<code>{inboxNotification.id}</code>}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n data-inspector=\"\"\n >\n <CodeBlock\n title=\"Data\"\n code={JSON.stringify(inboxNotification, null, 2)}\n />\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationCustomMissing = forwardRef<\n HTMLAnchorElement,\n Omit<InboxNotificationCustomProps, \"children\" | \"title\" | \"aside\">\n>(({ inboxNotification, ...props }, forwardedRef) => {\n return (\n <InboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n title={\n <>\n Custom notification kind <code>{inboxNotification.kind}</code> is not\n handled\n </>\n }\n aside={\n <InboxNotificationIcon>\n <WarningIcon />\n </InboxNotificationIcon>\n }\n ref={forwardedRef}\n data-missing=\"\"\n >\n Notifications of this kind won’t be displayed in production. Use the{\" \"}\n <code>kinds</code> prop to define how they should be rendered, learn more\n in the console.\n </InboxNotificationCustom>\n );\n});\n\n/**\n * Displays a single inbox notification.\n *\n * @example\n * <>\n * {inboxNotifications.map((inboxNotification) => (\n * <InboxNotification\n * key={inboxNotification.id}\n * inboxNotification={inboxNotification}\n * href={`/rooms/${inboxNotification.roomId}`\n * />\n * ))}\n * </>\n */\nexport const InboxNotification = Object.assign(\n forwardRef<HTMLAnchorElement, InboxNotificationProps>(\n ({ inboxNotification, kinds, ...props }, forwardedRef) => {\n switch (inboxNotification.kind) {\n case \"thread\": {\n const ResolvedInboxNotificationThread =\n kinds?.thread ?? InboxNotificationThread;\n\n return (\n <ResolvedInboxNotificationThread\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n case \"textMention\": {\n const ResolvedInboxNotificationTextMention =\n kinds?.textMention ?? InboxNotificationTextMention;\n\n return (\n <ResolvedInboxNotificationTextMention\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n default: {\n const ResolvedInboxNotificationCustom =\n kinds?.[inboxNotification.kind];\n\n if (!ResolvedInboxNotificationCustom) {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n `Custom notification kind \"${inboxNotification.kind}\" is not handled so notifications of this kind will not be displayed in production. Use the kinds prop to define how they should be rendered. Learn more: https://liveblocks.io/docs/api-reference/liveblocks-react-ui#Rendering-notification-kinds-differently.`\n );\n\n return (\n <InboxNotificationCustomMissing\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n } else {\n // Don't render anything in production if this inbox notification kind is not defined.\n return null;\n }\n }\n\n return (\n <ResolvedInboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n }\n }\n ),\n {\n /**\n * Displays a thread inbox notification kind.\n */\n Thread: InboxNotificationThread,\n\n /**\n * Displays a text mention inbox notification kind.\n */\n TextMention: InboxNotificationTextMention,\n\n /**\n * Displays a custom inbox notification kind.\n */\n Custom: InboxNotificationCustom,\n\n /**\n * Display the inbox notification's data, which can be useful during development.\n *\n * @example\n * <InboxNotification\n * inboxNotification={inboxNotification}\n * kinds={{\n * $custom: InboxNotification.Inspector,\n * }}\n * />\n */\n Inspector: InboxNotificationInspector,\n Icon: InboxNotificationIcon,\n Avatar: InboxNotificationAvatar,\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2PA;AAAgC;AAK5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AAEA;AAAoB;AAEhB;AAEA;AAEA;AACE;AAAgD;AAClD;AACF;AACA;AACE;AACkB;AAClB;AACA;AACA;AACA;AACF;AAGF;AACE;AAAsB;AAGxB;AAAyC;AAErC;AACA;AAAsB;AACxB;AACC;AAGH;AACE;AACA;AACA;AAAiC;AAGnC;AACE;AAAgD;AAGlD;AACE;AAA4C;AAG9C;AAEI;AAAC;AAAA;AACY;AACT;AAEE;AACkB;AACpB;AACF;AACO;AACoB;AACE;AACpB;AACT;AACI;AACC;AAEJ;AAA6D;AAE5D;AACE;AAAqD;AAGjD;AAAA;AAAC;AAAA;AACW;AACV;AACU;AAAA;AACZ;AAEE;AAAC;AAAA;AACW;AACL;AAAA;AACP;AAGN;AAGI;AAAC;AAAA;AACO;AACQ;AACR;AAGD;AAAA;AAEC;AAAC;AAAA;AACW;AACD;AACQ;AAEd;AAAA;AAEH;AACJ;AAAC;AAAA;AACW;AACD;AACS;AAEf;AAAA;AACL;AACC;AACH;AAKE;AAAC;AAAA;AACW;AACD;AACM;AACF;AACC;AACM;AAAA;AAG1B;AAAA;AAEJ;AAEJ;AACsD;AACxD;AAAA;AAAA;AAEJ;AAGN;AAEA;AAA+B;AAC7B;AAEF;AACE;AAGF;AAEA;AAAiC;AAC/B;AAEF;AACE;AACE;AAAC;AAAA;AACwD;AACnD;AAAA;AAGV;AAEA;AAAgC;AAK5B;AACE;AACA;AACe;AACC;AACE;AACJ;AACd;AACG;AAIL;AACA;AACA;AACA;AAAM;AACI;AACR;AACA;AAEF;AACA;AACA;AACE;AAAiB;AACf;AACA;AACA;AACiB;AAGnB;AACE;AAAO;AAGT;AAAuB;AAEnB;AACA;AAEA;AACA;AAAgB;AACd;AAAC;AAAA;AAGE;AACkB;AACgC;AACzC;AAAA;AACZ;AACiD;AACjC;AAElB;AAGM;AAAC;AAAA;AAEC;AACuC;AACvC;AACA;AACA;AAAA;AALa;AAWrB;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AAC2C;AAC9D;AACF;AAGE;AACA;AAEA;AACA;AAAgB;AACyC;AACN;AAEnD;AAEI;AAAC;AAAA;AAEU;AACG;AACZ;AACA;AACA;AAAA;AALoB;AAU1B;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AACS;AAC5B;AACF;AAGE;AAAO;AACL;AACA;AACF;AACJ;AACC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGF;AACE;AAEA;AAAO;AAAA;AAEqD;AACxD;AAGN;AACE;AACE;AAAY;AAEZ;AAAU;AACZ;AAGF;AACE;AAAsB;AAGxB;AACE;AAAO;AAGT;AAEA;AACE;AAAC;AAAA;AACC;AACA;AACA;AACA;AACA;AACA;AACM;AACN;AACmB;AAEjB;AAAC;AAAA;AACW;AACD;AAKK;AAMR;AAAA;AACR;AAEE;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAqC;AAKjC;AACE;AACc;AACC;AACf;AACA;AACG;AAIL;AACA;AAEA;AACE;AAEA;AAEI;AAGN;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACqE;AAC5D;AACP;AAAC;AAAA;AAE2B;AAAA;AADH;AAEzB;AAC4D;AAC9D;AACwB;AACxB;AACA;AACA;AACM;AACF;AACJ;AAAA;AACF;AAGN;AAEA;AAAgC;AAK5B;AACE;AACc;AACd;AACA;AACA;AACA;AACG;AAIL;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACA;AACA;AACwB;AACxB;AACA;AACA;AACI;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAmC;AAQ/B;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACmC;AACX;AACxB;AACA;AACA;AACI;AACC;AACU;AAEf;AAAC;AAAA;AACO;AACyC;AAAA;AACjD;AAAA;AACF;AAGN;AAEA;AAIE;AACE;AAAC;AAAA;AACC;AACI;AAEA;AAAA;AACuD;AAAO;AAEhE;AAKA;AAEG;AACQ;AACd;AAAA;AACsE;AAC1D;AAAO;AAAA;AAAA;AAIxB;AAgBO;AAAiC;AACtC;AAEI;AAAgC;AAE5B;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AACE;AAAA;AACqD;AAGrD;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAIF;AAAO;AACT;AAGF;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AACF;AACF;AACF;AACA;AAAA;AAAA;AAAA;AAIU;AAAA;AAAA;AAAA;AAKK;AAAA;AAAA;AAAA;AAKL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaG;AACL;AACE;AAEZ;;"}
1
+ {"version":3,"file":"InboxNotification.cjs","sources":["../../src/components/InboxNotification.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n InboxNotificationCustomData,\n InboxNotificationData,\n InboxNotificationTextMentionData,\n InboxNotificationThreadData,\n KDAD,\n} from \"@liveblocks/core\";\nimport {\n assertNever,\n generateUrl,\n sanitizeUrl,\n warnOnce,\n} from \"@liveblocks/core\";\nimport {\n useClient,\n useDeleteInboxNotification,\n useInboxNotificationThread,\n useMarkInboxNotificationAsRead,\n useRoomInfo,\n} from \"@liveblocks/react\";\nimport { useRoomThreadSubscription } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { TooltipProvider } from \"@radix-ui/react-tooltip\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentType,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n SyntheticEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { useComponents } from \"../components\";\nimport { BellIcon } from \"../icons/Bell\";\nimport { BellCrossedIcon } from \"../icons/BellCrossed\";\nimport { CheckIcon } from \"../icons/Check\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { WarningIcon } from \"../icons/Warning\";\nimport type {\n CommentOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport type { SlotProp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { CodeBlock } from \"./internal/CodeBlock\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport {\n generateInboxNotificationThreadContents,\n INBOX_NOTIFICATION_THREAD_MAX_COMMENTS,\n InboxNotificationComment,\n} from \"./internal/InboxNotificationThread\";\nimport { List } from \"./internal/List\";\nimport { Room } from \"./internal/Room\";\nimport { Tooltip } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ntype ComponentTypeWithRef<\n T extends keyof JSX.IntrinsicElements,\n P,\n> = ComponentType<P & Pick<ComponentProps<T>, \"ref\">>;\n\ntype InboxNotificationKinds<KS extends KDAD = KDAD> = {\n // For some reason, we cannot directly use KDAD in the mapped type line\n // below, because it will result in '{}' rather than picking up the\n // definition from the user-provided 'ActivitiesData'. Might be an internal\n // TS optimization, so we're making it a param to defer the resolution.\n [K in KS]: ComponentTypeWithRef<\"a\", InboxNotificationCustomKindProps<K>>;\n} & {\n thread: ComponentTypeWithRef<\"a\", InboxNotificationThreadKindProps>;\n textMention: ComponentTypeWithRef<\"a\", InboxNotificationTextMentionKindProps>;\n};\n\ninterface InboxNotificationSharedProps {\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n}\n\nexport interface InboxNotificationProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n\n /**\n * Override specific kinds of inbox notifications.\n */\n kinds?: Partial<InboxNotificationKinds>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n InboxNotificationOverrides &\n ThreadOverrides &\n CommentOverrides\n >;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents>;\n}\n\nexport interface InboxNotificationThreadProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationThreadData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n}\n\nexport interface InboxNotificationTextMentionProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationTextMentionData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n}\n\nexport interface InboxNotificationInspectorProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n}\n\nexport interface InboxNotificationCustomProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps,\n SlotProp {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationCustomData;\n\n /**\n * The inbox notification's content.\n */\n children: ReactNode;\n\n /**\n * The inbox notification's title.\n */\n title: ReactNode;\n\n /**\n * The inbox notification's aside content.\n * Can be combined with `InboxNotification.Icon` or `InboxNotification.Avatar` to easily follow default styles.\n */\n aside?: ReactNode;\n\n /**\n * Whether to mark the inbox notification as read when clicked.\n */\n markAsReadOnClick?: boolean;\n}\n\nexport type InboxNotificationThreadKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationThreadData;\n};\n\nexport type InboxNotificationTextMentionKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationTextMentionData;\n};\n\nexport type InboxNotificationCustomKindProps<K extends KDAD = KDAD> = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationCustomData<K>;\n};\n\ninterface InboxNotificationLayoutProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps,\n SlotProp {\n inboxNotification: InboxNotificationData;\n aside?: ReactNode;\n title: ReactNode;\n date: Date | string | number;\n unread?: boolean;\n overrides?: Partial<GlobalOverrides & InboxNotificationOverrides>;\n components?: Partial<GlobalComponents>;\n markAsReadOnClick?: boolean;\n\n /**\n * @internal\n */\n additionalDropdownItemsBefore?: ReactNode;\n\n /**\n * @internal\n */\n additionalDropdownItemsAfter?: ReactNode;\n}\n\nexport type InboxNotificationIconProps = ComponentProps<\"div\">;\n\nexport interface InboxNotificationAvatarProps extends ComponentProps<\"div\"> {\n /**\n * The user ID to display the avatar for.\n */\n userId: string;\n}\n\nconst InboxNotificationLayout = forwardRef<\n HTMLAnchorElement,\n InboxNotificationLayoutProps\n>(\n (\n {\n inboxNotification,\n children,\n aside,\n title,\n date,\n unread,\n markAsReadOnClick,\n onClick,\n href,\n showActions,\n overrides,\n components,\n className,\n asChild,\n additionalDropdownItemsBefore,\n additionalDropdownItemsAfter,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const { Anchor } = useComponents(components);\n const Component = asChild ? Slot : Anchor;\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();\n const deleteInboxNotification = useDeleteInboxNotification();\n\n const handleClick = useCallback(\n (event: ReactMouseEvent<HTMLAnchorElement, MouseEvent>) => {\n onClick?.(event);\n\n const shouldMarkAsReadOnClick = markAsReadOnClick ?? Boolean(href);\n\n if (unread && shouldMarkAsReadOnClick) {\n markInboxNotificationAsRead(inboxNotification.id);\n }\n },\n [\n href,\n inboxNotification.id,\n markAsReadOnClick,\n markInboxNotificationAsRead,\n onClick,\n unread,\n ]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const preventDefaultAndStopPropagation = useCallback(\n (event: SyntheticEvent) => {\n event.preventDefault();\n event.stopPropagation();\n },\n []\n );\n\n const handleMoreClick = useCallback((event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setMoreActionOpen((open) => !open);\n }, []);\n\n const handleMarkAsRead = useCallback(() => {\n markInboxNotificationAsRead(inboxNotification.id);\n }, [inboxNotification.id, markInboxNotificationAsRead]);\n\n const handleDelete = useCallback(() => {\n deleteInboxNotification(inboxNotification.id);\n }, [inboxNotification.id, deleteInboxNotification]);\n\n return (\n <TooltipProvider>\n <Component\n className={cn(\n \"lb-root lb-inbox-notification\",\n showActions === \"hover\" &&\n \"lb-inbox-notification:show-actions-hover\",\n isMoreActionOpen && \"lb-inbox-notification:action-open\",\n className\n )}\n dir={$.dir}\n data-unread={unread ? \"\" : undefined}\n data-kind={inboxNotification.kind}\n onClick={handleClick}\n href={href}\n {...props}\n ref={forwardedRef}\n >\n {aside && <div className=\"lb-inbox-notification-aside\">{aside}</div>}\n <div className=\"lb-inbox-notification-content\">\n <div className=\"lb-inbox-notification-header\">\n <span className=\"lb-inbox-notification-title\">{title}</span>\n <div className=\"lb-inbox-notification-details\">\n <span className=\"lb-inbox-notification-details-labels\">\n <Timestamp\n locale={$.locale}\n date={date}\n className=\"lb-date lb-inbox-notification-date\"\n />\n {unread && (\n <span\n className=\"lb-inbox-notification-unread-indicator\"\n role=\"presentation\"\n />\n )}\n </span>\n </div>\n {showActions && (\n <div className=\"lb-inbox-notification-actions\">\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n {additionalDropdownItemsBefore}\n {unread ? (\n <DropdownItem\n onSelect={handleMarkAsRead}\n onClick={stopPropagation}\n icon={<CheckIcon />}\n >\n {$.INBOX_NOTIFICATION_MARK_AS_READ}\n </DropdownItem>\n ) : null}\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.INBOX_NOTIFICATION_DELETE}\n </DropdownItem>\n {additionalDropdownItemsAfter}\n </>\n }\n >\n <Tooltip content={$.INBOX_NOTIFICATION_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-inbox-notification-action\"\n onClick={handleMoreClick}\n onPointerDown={preventDefaultAndStopPropagation}\n onPointerUp={preventDefaultAndStopPropagation}\n aria-label={$.INBOX_NOTIFICATION_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n </div>\n )}\n </div>\n <div className=\"lb-inbox-notification-body\">{children}</div>\n </div>\n </Component>\n </TooltipProvider>\n );\n }\n);\n\nfunction InboxNotificationIcon({\n className,\n ...props\n}: InboxNotificationIconProps) {\n return (\n <div className={cn(\"lb-inbox-notification-icon\", className)} {...props} />\n );\n}\n\nfunction InboxNotificationAvatar({\n className,\n ...props\n}: InboxNotificationAvatarProps) {\n return (\n <Avatar\n className={cn(\"lb-inbox-notification-avatar\", className)}\n {...props}\n />\n );\n}\n\nconst InboxNotificationThread = forwardRef<\n HTMLAnchorElement,\n InboxNotificationThreadProps\n>(\n (\n {\n inboxNotification,\n href,\n showRoomName = true,\n showReactions = true,\n showAttachments = true,\n showActions = \"hover\",\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const client = useClient();\n const thread = useInboxNotificationThread(inboxNotification.id);\n const {\n status: subscriptionStatus,\n subscribe,\n unsubscribe,\n } = useRoomThreadSubscription(thread.roomId, thread.id);\n const currentUserId = useCurrentUserId();\n const { info } = useRoomInfo(inboxNotification.roomId);\n const contents = useMemo(() => {\n const contents = generateInboxNotificationThreadContents(\n client,\n inboxNotification,\n thread,\n currentUserId ?? \"\"\n );\n\n if (contents.comments.length === 0 || contents.userIds.length === 0) {\n return null;\n }\n\n switch (contents.type) {\n case \"comments\": {\n const reversedUserIds = [...contents.userIds].reverse();\n const firstUserId = reversedUserIds[0]!;\n\n const aside = <InboxNotificationAvatar userId={firstUserId} />;\n const title = $.INBOX_NOTIFICATION_THREAD_COMMENTS_LIST(\n <List\n values={reversedUserIds.map((userId) => (\n <User key={userId} userId={userId} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={INBOX_NOTIFICATION_THREAD_MAX_COMMENTS - 1}\n locale={$.locale}\n />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined,\n reversedUserIds.length\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n {contents.comments.map((comment) => (\n <InboxNotificationComment\n key={comment.id}\n comment={comment}\n showHeader={contents.comments.length > 1}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n ))}\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: contents.comments[contents.comments.length - 1]!.id,\n };\n }\n\n case \"mention\": {\n const mentionCreatedBy = contents.userIds[0]!;\n const mentionComment = contents.comments[0]!;\n\n const aside = <InboxNotificationAvatar userId={mentionCreatedBy} />;\n const title = $.INBOX_NOTIFICATION_THREAD_MENTION(\n <User key={mentionCreatedBy} userId={mentionCreatedBy} />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n <InboxNotificationComment\n key={mentionComment.id}\n comment={mentionComment}\n showHeader={false}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: mentionComment.id,\n };\n }\n\n default:\n return assertNever(\n contents,\n \"Unexpected thread inbox notification type\"\n );\n }\n }, [\n $,\n client,\n currentUserId,\n inboxNotification,\n overrides,\n showRoomName,\n showAttachments,\n showReactions,\n thread,\n ]);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? // Set the comment ID as the URL hash.\n generateUrl(resolvedHref, undefined, contents?.commentId)\n : undefined;\n }, [contents?.commentId, href, info?.url]);\n\n const handleSubscribeChange = useCallback(() => {\n if (subscriptionStatus === \"subscribed\") {\n unsubscribe();\n } else {\n subscribe();\n }\n }, [subscriptionStatus, subscribe, unsubscribe]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n if (!contents) {\n return null;\n }\n\n const { aside, title, content, date, unread } = contents;\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={date}\n unread={unread}\n overrides={overrides}\n href={resolvedHref}\n showActions={showActions}\n markAsReadOnClick={false}\n additionalDropdownItemsBefore={\n <DropdownItem\n onSelect={handleSubscribeChange}\n onClick={stopPropagation}\n icon={\n subscriptionStatus === \"subscribed\" ? (\n <BellCrossedIcon />\n ) : (\n <BellIcon />\n )\n }\n >\n {subscriptionStatus === \"subscribed\"\n ? $.THREAD_UNSUBSCRIBE\n : $.THREAD_SUBSCRIBE}\n </DropdownItem>\n }\n {...props}\n ref={forwardedRef}\n >\n {content}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationTextMention = forwardRef<\n HTMLAnchorElement,\n InboxNotificationTextMentionProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n showRoomName = true,\n href,\n overrides,\n ...props\n },\n ref\n ) => {\n const $ = useOverrides(overrides);\n const { info } = useRoomInfo(inboxNotification.roomId);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? (sanitizeUrl(resolvedHref) ?? undefined)\n : undefined;\n }, [href, info?.url]);\n\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={<InboxNotificationAvatar userId={inboxNotification.createdBy} />}\n title={$.INBOX_NOTIFICATION_TEXT_MENTION(\n <User\n key={inboxNotification.createdBy}\n userId={inboxNotification.createdBy}\n />,\n showRoomName ? <Room roomId={inboxNotification.roomId} /> : undefined\n )}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n href={resolvedHref}\n {...props}\n ref={ref}\n />\n );\n }\n);\n\nconst InboxNotificationCustom = forwardRef<\n HTMLAnchorElement,\n InboxNotificationCustomProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n title,\n aside,\n children,\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n >\n {children}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationInspector = forwardRef<\n HTMLAnchorElement,\n InboxNotificationInspectorProps\n>(\n (\n { inboxNotification, showActions = \"hover\", overrides, ...props },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n title={<code>{inboxNotification.id}</code>}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n data-inspector=\"\"\n >\n <CodeBlock\n title=\"Data\"\n code={JSON.stringify(inboxNotification, null, 2)}\n />\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationCustomMissing = forwardRef<\n HTMLAnchorElement,\n Omit<InboxNotificationCustomProps, \"children\" | \"title\" | \"aside\">\n>(({ inboxNotification, ...props }, forwardedRef) => {\n return (\n <InboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n title={\n <>\n Custom notification kind <code>{inboxNotification.kind}</code> is not\n handled\n </>\n }\n aside={\n <InboxNotificationIcon>\n <WarningIcon />\n </InboxNotificationIcon>\n }\n ref={forwardedRef}\n data-missing=\"\"\n >\n Notifications of this kind won’t be displayed in production. Use the{\" \"}\n <code>kinds</code> prop to define how they should be rendered, learn more\n in the console.\n </InboxNotificationCustom>\n );\n});\n\n/**\n * Displays a single inbox notification.\n *\n * @example\n * <>\n * {inboxNotifications.map((inboxNotification) => (\n * <InboxNotification\n * key={inboxNotification.id}\n * inboxNotification={inboxNotification}\n * href={`/rooms/${inboxNotification.roomId}`\n * />\n * ))}\n * </>\n */\nexport const InboxNotification = Object.assign(\n forwardRef<HTMLAnchorElement, InboxNotificationProps>(\n ({ inboxNotification, kinds, ...props }, forwardedRef) => {\n switch (inboxNotification.kind) {\n case \"thread\": {\n const ResolvedInboxNotificationThread =\n kinds?.thread ?? InboxNotificationThread;\n\n return (\n <ResolvedInboxNotificationThread\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n case \"textMention\": {\n const ResolvedInboxNotificationTextMention =\n kinds?.textMention ?? InboxNotificationTextMention;\n\n return (\n <ResolvedInboxNotificationTextMention\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n default: {\n const ResolvedInboxNotificationCustom =\n kinds?.[inboxNotification.kind];\n\n if (!ResolvedInboxNotificationCustom) {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n `Custom notification kind \"${inboxNotification.kind}\" is not handled so notifications of this kind will not be displayed in production. Use the kinds prop to define how they should be rendered. Learn more: https://liveblocks.io/docs/api-reference/liveblocks-react-ui#Rendering-notification-kinds-differently.`\n );\n\n return (\n <InboxNotificationCustomMissing\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n } else {\n // Don't render anything in production if this inbox notification kind is not defined.\n return null;\n }\n }\n\n return (\n <ResolvedInboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n }\n }\n ),\n {\n /**\n * Displays a thread inbox notification kind.\n */\n Thread: InboxNotificationThread,\n\n /**\n * Displays a text mention inbox notification kind.\n */\n TextMention: InboxNotificationTextMention,\n\n /**\n * Displays a custom inbox notification kind.\n */\n Custom: InboxNotificationCustom,\n\n /**\n * Display the inbox notification's data, which can be useful during development.\n *\n * @example\n * <InboxNotification\n * inboxNotification={inboxNotification}\n * kinds={{\n * $custom: InboxNotification.Inspector,\n * }}\n * />\n */\n Inspector: InboxNotificationInspector,\n Icon: InboxNotificationIcon,\n Avatar: InboxNotificationAvatar,\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4PA;AAAgC;AAK5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AAEA;AAAoB;AAEhB;AAEA;AAEA;AACE;AAAgD;AAClD;AACF;AACA;AACE;AACkB;AAClB;AACA;AACA;AACA;AACF;AAGF;AACE;AAAsB;AAGxB;AAAyC;AAErC;AACA;AAAsB;AACxB;AACC;AAGH;AACE;AACA;AACA;AAAiC;AAGnC;AACE;AAAgD;AAGlD;AACE;AAA4C;AAG9C;AAEI;AAAC;AAAA;AACY;AACT;AAEE;AACkB;AACpB;AACF;AACO;AACoB;AACE;AACpB;AACT;AACI;AACC;AAEJ;AAA6D;AAE5D;AACE;AAAqD;AAGjD;AAAA;AAAC;AAAA;AACW;AACV;AACU;AAAA;AACZ;AAEE;AAAC;AAAA;AACW;AACL;AAAA;AACP;AAGN;AAGI;AAAC;AAAA;AACO;AACQ;AACR;AAGD;AAAA;AAEC;AAAC;AAAA;AACW;AACD;AACQ;AAEd;AAAA;AAEH;AACJ;AAAC;AAAA;AACW;AACD;AACS;AAEf;AAAA;AACL;AACC;AACH;AAKE;AAAC;AAAA;AACW;AACD;AACM;AACF;AACC;AACM;AAAA;AAG1B;AAAA;AAEJ;AAEJ;AACsD;AACxD;AAAA;AAAA;AAEJ;AAGN;AAEA;AAA+B;AAC7B;AAEF;AACE;AAGF;AAEA;AAAiC;AAC/B;AAEF;AACE;AACE;AAAC;AAAA;AACwD;AACnD;AAAA;AAGV;AAEA;AAAgC;AAK5B;AACE;AACA;AACe;AACC;AACE;AACJ;AACd;AACG;AAIL;AACA;AACA;AACA;AAAM;AACI;AACR;AACA;AAEF;AACA;AACA;AACE;AAAiB;AACf;AACA;AACA;AACiB;AAGnB;AACE;AAAO;AAGT;AAAuB;AAEnB;AACA;AAEA;AACA;AAAgB;AACd;AAAC;AAAA;AAGE;AACkB;AACgC;AACzC;AAAA;AACZ;AACiD;AACjC;AAElB;AAGM;AAAC;AAAA;AAEC;AACuC;AACvC;AACA;AACA;AAAA;AALa;AAWrB;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AAC2C;AAC9D;AACF;AAGE;AACA;AAEA;AACA;AAAgB;AACyC;AACN;AAEnD;AAEI;AAAC;AAAA;AAEU;AACG;AACZ;AACA;AACA;AAAA;AALoB;AAU1B;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AACS;AAC5B;AACF;AAGE;AAAO;AACL;AACA;AACF;AACJ;AACC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGF;AACE;AAEA;AAAO;AAAA;AAEqD;AACxD;AAGN;AACE;AACE;AAAY;AAEZ;AAAU;AACZ;AAGF;AACE;AAAsB;AAGxB;AACE;AAAO;AAGT;AAEA;AACE;AAAC;AAAA;AACC;AACA;AACA;AACA;AACA;AACA;AACM;AACN;AACmB;AAEjB;AAAC;AAAA;AACW;AACD;AAKK;AAMR;AAAA;AACR;AAEE;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAqC;AAKjC;AACE;AACc;AACC;AACf;AACA;AACG;AAIL;AACA;AAEA;AACE;AAEA;AAEI;AAGN;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACqE;AAC5D;AACP;AAAC;AAAA;AAE2B;AAAA;AADH;AAEzB;AAC4D;AAC9D;AACwB;AACxB;AACA;AACA;AACM;AACF;AACJ;AAAA;AACF;AAGN;AAEA;AAAgC;AAK5B;AACE;AACc;AACd;AACA;AACA;AACA;AACG;AAIL;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACA;AACA;AACwB;AACxB;AACA;AACA;AACI;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAmC;AAQ/B;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACmC;AACX;AACxB;AACA;AACA;AACI;AACC;AACU;AAEf;AAAC;AAAA;AACO;AACyC;AAAA;AACjD;AAAA;AACF;AAGN;AAEA;AAIE;AACE;AAAC;AAAA;AACC;AACI;AAEA;AAAA;AACuD;AAAO;AAEhE;AAKA;AAEG;AACQ;AACd;AAAA;AACsE;AAC1D;AAAO;AAAA;AAAA;AAIxB;AAgBO;AAAiC;AACtC;AAEI;AAAgC;AAE5B;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AACE;AAAA;AACqD;AAGrD;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAIF;AAAO;AACT;AAGF;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AACF;AACF;AACF;AACA;AAAA;AAAA;AAAA;AAIU;AAAA;AAAA;AAAA;AAKK;AAAA;AAAA;AAAA;AAKL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaG;AACL;AACE;AAEZ;;"}
@@ -3,7 +3,8 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { assertNever, generateUrl, sanitizeUrl, warnOnce } from '@liveblocks/core';
4
4
  import { useMarkInboxNotificationAsRead, useDeleteInboxNotification, useClient, useInboxNotificationThread, useRoomInfo } from '@liveblocks/react';
5
5
  import { useRoomThreadSubscription } from '@liveblocks/react/_private';
6
- import { Slot } from 'radix-ui';
6
+ import { Slot } from '@radix-ui/react-slot';
7
+ import { TooltipProvider } from '@radix-ui/react-tooltip';
7
8
  import { forwardRef, useState, useCallback, useMemo } from 'react';
8
9
  import { useComponents } from '../components.js';
9
10
  import { BellIcon } from '../icons/Bell.js';
@@ -19,12 +20,13 @@ import { cn } from '../utils/cn.js';
19
20
  import { Avatar } from './internal/Avatar.js';
20
21
  import { Button } from './internal/Button.js';
21
22
  import { CodeBlock } from './internal/CodeBlock.js';
22
- import { Dropdown, DropdownItem, DropdownTrigger } from './internal/Dropdown.js';
23
+ import { Dropdown, DropdownItem } from './internal/Dropdown.js';
23
24
  import { generateInboxNotificationThreadContents, InboxNotificationComment, INBOX_NOTIFICATION_THREAD_MAX_COMMENTS } from './internal/InboxNotificationThread.js';
24
25
  import { List } from './internal/List.js';
25
26
  import { Room } from './internal/Room.js';
26
- import { TooltipProvider, Tooltip } from './internal/Tooltip.js';
27
+ import { Tooltip } from './internal/Tooltip.js';
27
28
  import { User } from './internal/User.js';
29
+ import { DropdownMenuTrigger } from '@radix-ui/react-dropdown-menu';
28
30
 
29
31
 
30
32
  const InboxNotificationLayout = forwardRef(
@@ -49,7 +51,7 @@ const InboxNotificationLayout = forwardRef(
49
51
  }, forwardedRef) => {
50
52
  const $ = useOverrides(overrides);
51
53
  const { Anchor } = useComponents(components);
52
- const Component = asChild ? Slot.Slot : Anchor;
54
+ const Component = asChild ? Slot : Anchor;
53
55
  const [isMoreActionOpen, setMoreActionOpen] = useState(false);
54
56
  const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();
55
57
  const deleteInboxNotification = useDeleteInboxNotification();
@@ -157,7 +159,7 @@ const InboxNotificationLayout = forwardRef(
157
159
  ),
158
160
  additionalDropdownItemsAfter
159
161
  ] }),
160
- children: /* @__PURE__ */ jsx(Tooltip, { content: $.INBOX_NOTIFICATION_MORE, children: /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
162
+ children: /* @__PURE__ */ jsx(Tooltip, { content: $.INBOX_NOTIFICATION_MORE, children: /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
161
163
  Button,
162
164
  {
163
165
  className: "lb-inbox-notification-action",
@@ -1 +1 @@
1
- {"version":3,"file":"InboxNotification.js","sources":["../../src/components/InboxNotification.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n InboxNotificationCustomData,\n InboxNotificationData,\n InboxNotificationTextMentionData,\n InboxNotificationThreadData,\n KDAD,\n} from \"@liveblocks/core\";\nimport {\n assertNever,\n generateUrl,\n sanitizeUrl,\n warnOnce,\n} from \"@liveblocks/core\";\nimport {\n useClient,\n useDeleteInboxNotification,\n useInboxNotificationThread,\n useMarkInboxNotificationAsRead,\n useRoomInfo,\n} from \"@liveblocks/react\";\nimport { useRoomThreadSubscription } from \"@liveblocks/react/_private\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentType,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n SyntheticEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { useComponents } from \"../components\";\nimport { BellIcon } from \"../icons/Bell\";\nimport { BellCrossedIcon } from \"../icons/BellCrossed\";\nimport { CheckIcon } from \"../icons/Check\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { WarningIcon } from \"../icons/Warning\";\nimport type {\n CommentOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport type { SlotProp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { CodeBlock } from \"./internal/CodeBlock\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport {\n generateInboxNotificationThreadContents,\n INBOX_NOTIFICATION_THREAD_MAX_COMMENTS,\n InboxNotificationComment,\n} from \"./internal/InboxNotificationThread\";\nimport { List } from \"./internal/List\";\nimport { Room } from \"./internal/Room\";\nimport { Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ntype ComponentTypeWithRef<\n T extends keyof JSX.IntrinsicElements,\n P,\n> = ComponentType<P & Pick<ComponentProps<T>, \"ref\">>;\n\ntype InboxNotificationKinds<KS extends KDAD = KDAD> = {\n // For some reason, we cannot directly use KDAD in the mapped type line\n // below, because it will result in '{}' rather than picking up the\n // definition from the user-provided 'ActivitiesData'. Might be an internal\n // TS optimization, so we're making it a param to defer the resolution.\n [K in KS]: ComponentTypeWithRef<\"a\", InboxNotificationCustomKindProps<K>>;\n} & {\n thread: ComponentTypeWithRef<\"a\", InboxNotificationThreadKindProps>;\n textMention: ComponentTypeWithRef<\"a\", InboxNotificationTextMentionKindProps>;\n};\n\ninterface InboxNotificationSharedProps {\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n}\n\nexport interface InboxNotificationProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n\n /**\n * Override specific kinds of inbox notifications.\n */\n kinds?: Partial<InboxNotificationKinds>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n InboxNotificationOverrides &\n ThreadOverrides &\n CommentOverrides\n >;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents>;\n}\n\nexport interface InboxNotificationThreadProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationThreadData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n}\n\nexport interface InboxNotificationTextMentionProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationTextMentionData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n}\n\nexport interface InboxNotificationInspectorProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n}\n\nexport interface InboxNotificationCustomProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps,\n SlotProp {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationCustomData;\n\n /**\n * The inbox notification's content.\n */\n children: ReactNode;\n\n /**\n * The inbox notification's title.\n */\n title: ReactNode;\n\n /**\n * The inbox notification's aside content.\n * Can be combined with `InboxNotification.Icon` or `InboxNotification.Avatar` to easily follow default styles.\n */\n aside?: ReactNode;\n\n /**\n * Whether to mark the inbox notification as read when clicked.\n */\n markAsReadOnClick?: boolean;\n}\n\nexport type InboxNotificationThreadKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationThreadData;\n};\n\nexport type InboxNotificationTextMentionKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationTextMentionData;\n};\n\nexport type InboxNotificationCustomKindProps<K extends KDAD = KDAD> = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationCustomData<K>;\n};\n\ninterface InboxNotificationLayoutProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps,\n SlotProp {\n inboxNotification: InboxNotificationData;\n aside?: ReactNode;\n title: ReactNode;\n date: Date | string | number;\n unread?: boolean;\n overrides?: Partial<GlobalOverrides & InboxNotificationOverrides>;\n components?: Partial<GlobalComponents>;\n markAsReadOnClick?: boolean;\n\n /**\n * @internal\n */\n additionalDropdownItemsBefore?: ReactNode;\n\n /**\n * @internal\n */\n additionalDropdownItemsAfter?: ReactNode;\n}\n\nexport type InboxNotificationIconProps = ComponentProps<\"div\">;\n\nexport interface InboxNotificationAvatarProps extends ComponentProps<\"div\"> {\n /**\n * The user ID to display the avatar for.\n */\n userId: string;\n}\n\nconst InboxNotificationLayout = forwardRef<\n HTMLAnchorElement,\n InboxNotificationLayoutProps\n>(\n (\n {\n inboxNotification,\n children,\n aside,\n title,\n date,\n unread,\n markAsReadOnClick,\n onClick,\n href,\n showActions,\n overrides,\n components,\n className,\n asChild,\n additionalDropdownItemsBefore,\n additionalDropdownItemsAfter,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const { Anchor } = useComponents(components);\n const Component = asChild ? SlotPrimitive.Slot : Anchor;\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();\n const deleteInboxNotification = useDeleteInboxNotification();\n\n const handleClick = useCallback(\n (event: ReactMouseEvent<HTMLAnchorElement, MouseEvent>) => {\n onClick?.(event);\n\n const shouldMarkAsReadOnClick = markAsReadOnClick ?? Boolean(href);\n\n if (unread && shouldMarkAsReadOnClick) {\n markInboxNotificationAsRead(inboxNotification.id);\n }\n },\n [\n href,\n inboxNotification.id,\n markAsReadOnClick,\n markInboxNotificationAsRead,\n onClick,\n unread,\n ]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const preventDefaultAndStopPropagation = useCallback(\n (event: SyntheticEvent) => {\n event.preventDefault();\n event.stopPropagation();\n },\n []\n );\n\n const handleMoreClick = useCallback((event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setMoreActionOpen((open) => !open);\n }, []);\n\n const handleMarkAsRead = useCallback(() => {\n markInboxNotificationAsRead(inboxNotification.id);\n }, [inboxNotification.id, markInboxNotificationAsRead]);\n\n const handleDelete = useCallback(() => {\n deleteInboxNotification(inboxNotification.id);\n }, [inboxNotification.id, deleteInboxNotification]);\n\n return (\n <TooltipProvider>\n <Component\n className={cn(\n \"lb-root lb-inbox-notification\",\n showActions === \"hover\" &&\n \"lb-inbox-notification:show-actions-hover\",\n isMoreActionOpen && \"lb-inbox-notification:action-open\",\n className\n )}\n dir={$.dir}\n data-unread={unread ? \"\" : undefined}\n data-kind={inboxNotification.kind}\n onClick={handleClick}\n href={href}\n {...props}\n ref={forwardedRef}\n >\n {aside && <div className=\"lb-inbox-notification-aside\">{aside}</div>}\n <div className=\"lb-inbox-notification-content\">\n <div className=\"lb-inbox-notification-header\">\n <span className=\"lb-inbox-notification-title\">{title}</span>\n <div className=\"lb-inbox-notification-details\">\n <span className=\"lb-inbox-notification-details-labels\">\n <Timestamp\n locale={$.locale}\n date={date}\n className=\"lb-date lb-inbox-notification-date\"\n />\n {unread && (\n <span\n className=\"lb-inbox-notification-unread-indicator\"\n role=\"presentation\"\n />\n )}\n </span>\n </div>\n {showActions && (\n <div className=\"lb-inbox-notification-actions\">\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n {additionalDropdownItemsBefore}\n {unread ? (\n <DropdownItem\n onSelect={handleMarkAsRead}\n onClick={stopPropagation}\n icon={<CheckIcon />}\n >\n {$.INBOX_NOTIFICATION_MARK_AS_READ}\n </DropdownItem>\n ) : null}\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.INBOX_NOTIFICATION_DELETE}\n </DropdownItem>\n {additionalDropdownItemsAfter}\n </>\n }\n >\n <Tooltip content={$.INBOX_NOTIFICATION_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-inbox-notification-action\"\n onClick={handleMoreClick}\n onPointerDown={preventDefaultAndStopPropagation}\n onPointerUp={preventDefaultAndStopPropagation}\n aria-label={$.INBOX_NOTIFICATION_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n </div>\n )}\n </div>\n <div className=\"lb-inbox-notification-body\">{children}</div>\n </div>\n </Component>\n </TooltipProvider>\n );\n }\n);\n\nfunction InboxNotificationIcon({\n className,\n ...props\n}: InboxNotificationIconProps) {\n return (\n <div className={cn(\"lb-inbox-notification-icon\", className)} {...props} />\n );\n}\n\nfunction InboxNotificationAvatar({\n className,\n ...props\n}: InboxNotificationAvatarProps) {\n return (\n <Avatar\n className={cn(\"lb-inbox-notification-avatar\", className)}\n {...props}\n />\n );\n}\n\nconst InboxNotificationThread = forwardRef<\n HTMLAnchorElement,\n InboxNotificationThreadProps\n>(\n (\n {\n inboxNotification,\n href,\n showRoomName = true,\n showReactions = true,\n showAttachments = true,\n showActions = \"hover\",\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const client = useClient();\n const thread = useInboxNotificationThread(inboxNotification.id);\n const {\n status: subscriptionStatus,\n subscribe,\n unsubscribe,\n } = useRoomThreadSubscription(thread.roomId, thread.id);\n const currentUserId = useCurrentUserId();\n const { info } = useRoomInfo(inboxNotification.roomId);\n const contents = useMemo(() => {\n const contents = generateInboxNotificationThreadContents(\n client,\n inboxNotification,\n thread,\n currentUserId ?? \"\"\n );\n\n if (contents.comments.length === 0 || contents.userIds.length === 0) {\n return null;\n }\n\n switch (contents.type) {\n case \"comments\": {\n const reversedUserIds = [...contents.userIds].reverse();\n const firstUserId = reversedUserIds[0]!;\n\n const aside = <InboxNotificationAvatar userId={firstUserId} />;\n const title = $.INBOX_NOTIFICATION_THREAD_COMMENTS_LIST(\n <List\n values={reversedUserIds.map((userId) => (\n <User key={userId} userId={userId} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={INBOX_NOTIFICATION_THREAD_MAX_COMMENTS - 1}\n locale={$.locale}\n />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined,\n reversedUserIds.length\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n {contents.comments.map((comment) => (\n <InboxNotificationComment\n key={comment.id}\n comment={comment}\n showHeader={contents.comments.length > 1}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n ))}\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: contents.comments[contents.comments.length - 1]!.id,\n };\n }\n\n case \"mention\": {\n const mentionCreatedBy = contents.userIds[0]!;\n const mentionComment = contents.comments[0]!;\n\n const aside = <InboxNotificationAvatar userId={mentionCreatedBy} />;\n const title = $.INBOX_NOTIFICATION_THREAD_MENTION(\n <User key={mentionCreatedBy} userId={mentionCreatedBy} />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n <InboxNotificationComment\n key={mentionComment.id}\n comment={mentionComment}\n showHeader={false}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: mentionComment.id,\n };\n }\n\n default:\n return assertNever(\n contents,\n \"Unexpected thread inbox notification type\"\n );\n }\n }, [\n $,\n client,\n currentUserId,\n inboxNotification,\n overrides,\n showRoomName,\n showAttachments,\n showReactions,\n thread,\n ]);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? // Set the comment ID as the URL hash.\n generateUrl(resolvedHref, undefined, contents?.commentId)\n : undefined;\n }, [contents?.commentId, href, info?.url]);\n\n const handleSubscribeChange = useCallback(() => {\n if (subscriptionStatus === \"subscribed\") {\n unsubscribe();\n } else {\n subscribe();\n }\n }, [subscriptionStatus, subscribe, unsubscribe]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n if (!contents) {\n return null;\n }\n\n const { aside, title, content, date, unread } = contents;\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={date}\n unread={unread}\n overrides={overrides}\n href={resolvedHref}\n showActions={showActions}\n markAsReadOnClick={false}\n additionalDropdownItemsBefore={\n <DropdownItem\n onSelect={handleSubscribeChange}\n onClick={stopPropagation}\n icon={\n subscriptionStatus === \"subscribed\" ? (\n <BellCrossedIcon />\n ) : (\n <BellIcon />\n )\n }\n >\n {subscriptionStatus === \"subscribed\"\n ? $.THREAD_UNSUBSCRIBE\n : $.THREAD_SUBSCRIBE}\n </DropdownItem>\n }\n {...props}\n ref={forwardedRef}\n >\n {content}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationTextMention = forwardRef<\n HTMLAnchorElement,\n InboxNotificationTextMentionProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n showRoomName = true,\n href,\n overrides,\n ...props\n },\n ref\n ) => {\n const $ = useOverrides(overrides);\n const { info } = useRoomInfo(inboxNotification.roomId);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? (sanitizeUrl(resolvedHref) ?? undefined)\n : undefined;\n }, [href, info?.url]);\n\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={<InboxNotificationAvatar userId={inboxNotification.createdBy} />}\n title={$.INBOX_NOTIFICATION_TEXT_MENTION(\n <User\n key={inboxNotification.createdBy}\n userId={inboxNotification.createdBy}\n />,\n showRoomName ? <Room roomId={inboxNotification.roomId} /> : undefined\n )}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n href={resolvedHref}\n {...props}\n ref={ref}\n />\n );\n }\n);\n\nconst InboxNotificationCustom = forwardRef<\n HTMLAnchorElement,\n InboxNotificationCustomProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n title,\n aside,\n children,\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n >\n {children}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationInspector = forwardRef<\n HTMLAnchorElement,\n InboxNotificationInspectorProps\n>(\n (\n { inboxNotification, showActions = \"hover\", overrides, ...props },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n title={<code>{inboxNotification.id}</code>}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n data-inspector=\"\"\n >\n <CodeBlock\n title=\"Data\"\n code={JSON.stringify(inboxNotification, null, 2)}\n />\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationCustomMissing = forwardRef<\n HTMLAnchorElement,\n Omit<InboxNotificationCustomProps, \"children\" | \"title\" | \"aside\">\n>(({ inboxNotification, ...props }, forwardedRef) => {\n return (\n <InboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n title={\n <>\n Custom notification kind <code>{inboxNotification.kind}</code> is not\n handled\n </>\n }\n aside={\n <InboxNotificationIcon>\n <WarningIcon />\n </InboxNotificationIcon>\n }\n ref={forwardedRef}\n data-missing=\"\"\n >\n Notifications of this kind won’t be displayed in production. Use the{\" \"}\n <code>kinds</code> prop to define how they should be rendered, learn more\n in the console.\n </InboxNotificationCustom>\n );\n});\n\n/**\n * Displays a single inbox notification.\n *\n * @example\n * <>\n * {inboxNotifications.map((inboxNotification) => (\n * <InboxNotification\n * key={inboxNotification.id}\n * inboxNotification={inboxNotification}\n * href={`/rooms/${inboxNotification.roomId}`\n * />\n * ))}\n * </>\n */\nexport const InboxNotification = Object.assign(\n forwardRef<HTMLAnchorElement, InboxNotificationProps>(\n ({ inboxNotification, kinds, ...props }, forwardedRef) => {\n switch (inboxNotification.kind) {\n case \"thread\": {\n const ResolvedInboxNotificationThread =\n kinds?.thread ?? InboxNotificationThread;\n\n return (\n <ResolvedInboxNotificationThread\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n case \"textMention\": {\n const ResolvedInboxNotificationTextMention =\n kinds?.textMention ?? InboxNotificationTextMention;\n\n return (\n <ResolvedInboxNotificationTextMention\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n default: {\n const ResolvedInboxNotificationCustom =\n kinds?.[inboxNotification.kind];\n\n if (!ResolvedInboxNotificationCustom) {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n `Custom notification kind \"${inboxNotification.kind}\" is not handled so notifications of this kind will not be displayed in production. Use the kinds prop to define how they should be rendered. Learn more: https://liveblocks.io/docs/api-reference/liveblocks-react-ui#Rendering-notification-kinds-differently.`\n );\n\n return (\n <InboxNotificationCustomMissing\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n } else {\n // Don't render anything in production if this inbox notification kind is not defined.\n return null;\n }\n }\n\n return (\n <ResolvedInboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n }\n }\n ),\n {\n /**\n * Displays a thread inbox notification kind.\n */\n Thread: InboxNotificationThread,\n\n /**\n * Displays a text mention inbox notification kind.\n */\n TextMention: InboxNotificationTextMention,\n\n /**\n * Displays a custom inbox notification kind.\n */\n Custom: InboxNotificationCustom,\n\n /**\n * Display the inbox notification's data, which can be useful during development.\n *\n * @example\n * <InboxNotification\n * inboxNotification={inboxNotification}\n * kinds={{\n * $custom: InboxNotification.Inspector,\n * }}\n * />\n */\n Inspector: InboxNotificationInspector,\n Icon: InboxNotificationIcon,\n Avatar: InboxNotificationAvatar,\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2PA;AAAgC;AAK5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AAEA;AAAoB;AAEhB;AAEA;AAEA;AACE;AAAgD;AAClD;AACF;AACA;AACE;AACkB;AAClB;AACA;AACA;AACA;AACF;AAGF;AACE;AAAsB;AAGxB;AAAyC;AAErC;AACA;AAAsB;AACxB;AACC;AAGH;AACE;AACA;AACA;AAAiC;AAGnC;AACE;AAAgD;AAGlD;AACE;AAA4C;AAG9C;AAEI;AAAC;AAAA;AACY;AACT;AAEE;AACkB;AACpB;AACF;AACO;AACoB;AACE;AACpB;AACT;AACI;AACC;AAEJ;AAA6D;AAE5D;AACE;AAAqD;AAGjD;AAAA;AAAC;AAAA;AACW;AACV;AACU;AAAA;AACZ;AAEE;AAAC;AAAA;AACW;AACL;AAAA;AACP;AAGN;AAGI;AAAC;AAAA;AACO;AACQ;AACR;AAGD;AAAA;AAEC;AAAC;AAAA;AACW;AACD;AACQ;AAEd;AAAA;AAEH;AACJ;AAAC;AAAA;AACW;AACD;AACS;AAEf;AAAA;AACL;AACC;AACH;AAKE;AAAC;AAAA;AACW;AACD;AACM;AACF;AACC;AACM;AAAA;AAG1B;AAAA;AAEJ;AAEJ;AACsD;AACxD;AAAA;AAAA;AAEJ;AAGN;AAEA;AAA+B;AAC7B;AAEF;AACE;AAGF;AAEA;AAAiC;AAC/B;AAEF;AACE;AACE;AAAC;AAAA;AACwD;AACnD;AAAA;AAGV;AAEA;AAAgC;AAK5B;AACE;AACA;AACe;AACC;AACE;AACJ;AACd;AACG;AAIL;AACA;AACA;AACA;AAAM;AACI;AACR;AACA;AAEF;AACA;AACA;AACE;AAAiB;AACf;AACA;AACA;AACiB;AAGnB;AACE;AAAO;AAGT;AAAuB;AAEnB;AACA;AAEA;AACA;AAAgB;AACd;AAAC;AAAA;AAGE;AACkB;AACgC;AACzC;AAAA;AACZ;AACiD;AACjC;AAElB;AAGM;AAAC;AAAA;AAEC;AACuC;AACvC;AACA;AACA;AAAA;AALa;AAWrB;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AAC2C;AAC9D;AACF;AAGE;AACA;AAEA;AACA;AAAgB;AACyC;AACN;AAEnD;AAEI;AAAC;AAAA;AAEU;AACG;AACZ;AACA;AACA;AAAA;AALoB;AAU1B;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AACS;AAC5B;AACF;AAGE;AAAO;AACL;AACA;AACF;AACJ;AACC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGF;AACE;AAEA;AAAO;AAAA;AAEqD;AACxD;AAGN;AACE;AACE;AAAY;AAEZ;AAAU;AACZ;AAGF;AACE;AAAsB;AAGxB;AACE;AAAO;AAGT;AAEA;AACE;AAAC;AAAA;AACC;AACA;AACA;AACA;AACA;AACA;AACM;AACN;AACmB;AAEjB;AAAC;AAAA;AACW;AACD;AAKK;AAMR;AAAA;AACR;AAEE;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAqC;AAKjC;AACE;AACc;AACC;AACf;AACA;AACG;AAIL;AACA;AAEA;AACE;AAEA;AAEI;AAGN;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACqE;AAC5D;AACP;AAAC;AAAA;AAE2B;AAAA;AADH;AAEzB;AAC4D;AAC9D;AACwB;AACxB;AACA;AACA;AACM;AACF;AACJ;AAAA;AACF;AAGN;AAEA;AAAgC;AAK5B;AACE;AACc;AACd;AACA;AACA;AACA;AACG;AAIL;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACA;AACA;AACwB;AACxB;AACA;AACA;AACI;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAmC;AAQ/B;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACmC;AACX;AACxB;AACA;AACA;AACI;AACC;AACU;AAEf;AAAC;AAAA;AACO;AACyC;AAAA;AACjD;AAAA;AACF;AAGN;AAEA;AAIE;AACE;AAAC;AAAA;AACC;AACI;AAEA;AAAA;AACuD;AAAO;AAEhE;AAKA;AAEG;AACQ;AACd;AAAA;AACsE;AAC1D;AAAO;AAAA;AAAA;AAIxB;AAgBO;AAAiC;AACtC;AAEI;AAAgC;AAE5B;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AACE;AAAA;AACqD;AAGrD;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAIF;AAAO;AACT;AAGF;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AACF;AACF;AACF;AACA;AAAA;AAAA;AAAA;AAIU;AAAA;AAAA;AAAA;AAKK;AAAA;AAAA;AAAA;AAKL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaG;AACL;AACE;AAEZ;;"}
1
+ {"version":3,"file":"InboxNotification.js","sources":["../../src/components/InboxNotification.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n InboxNotificationCustomData,\n InboxNotificationData,\n InboxNotificationTextMentionData,\n InboxNotificationThreadData,\n KDAD,\n} from \"@liveblocks/core\";\nimport {\n assertNever,\n generateUrl,\n sanitizeUrl,\n warnOnce,\n} from \"@liveblocks/core\";\nimport {\n useClient,\n useDeleteInboxNotification,\n useInboxNotificationThread,\n useMarkInboxNotificationAsRead,\n useRoomInfo,\n} from \"@liveblocks/react\";\nimport { useRoomThreadSubscription } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { TooltipProvider } from \"@radix-ui/react-tooltip\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n ComponentType,\n MouseEvent as ReactMouseEvent,\n ReactNode,\n SyntheticEvent,\n} from \"react\";\nimport { forwardRef, useCallback, useMemo, useState } from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { useComponents } from \"../components\";\nimport { BellIcon } from \"../icons/Bell\";\nimport { BellCrossedIcon } from \"../icons/BellCrossed\";\nimport { CheckIcon } from \"../icons/Check\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { WarningIcon } from \"../icons/Warning\";\nimport type {\n CommentOverrides,\n GlobalOverrides,\n InboxNotificationOverrides,\n ThreadOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport type { SlotProp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button } from \"./internal/Button\";\nimport { CodeBlock } from \"./internal/CodeBlock\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport {\n generateInboxNotificationThreadContents,\n INBOX_NOTIFICATION_THREAD_MAX_COMMENTS,\n InboxNotificationComment,\n} from \"./internal/InboxNotificationThread\";\nimport { List } from \"./internal/List\";\nimport { Room } from \"./internal/Room\";\nimport { Tooltip } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\ntype ComponentTypeWithRef<\n T extends keyof JSX.IntrinsicElements,\n P,\n> = ComponentType<P & Pick<ComponentProps<T>, \"ref\">>;\n\ntype InboxNotificationKinds<KS extends KDAD = KDAD> = {\n // For some reason, we cannot directly use KDAD in the mapped type line\n // below, because it will result in '{}' rather than picking up the\n // definition from the user-provided 'ActivitiesData'. Might be an internal\n // TS optimization, so we're making it a param to defer the resolution.\n [K in KS]: ComponentTypeWithRef<\"a\", InboxNotificationCustomKindProps<K>>;\n} & {\n thread: ComponentTypeWithRef<\"a\", InboxNotificationThreadKindProps>;\n textMention: ComponentTypeWithRef<\"a\", InboxNotificationTextMentionKindProps>;\n};\n\ninterface InboxNotificationSharedProps {\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n}\n\nexport interface InboxNotificationProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n\n /**\n * Override specific kinds of inbox notifications.\n */\n kinds?: Partial<InboxNotificationKinds>;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<\n GlobalOverrides &\n InboxNotificationOverrides &\n ThreadOverrides &\n CommentOverrides\n >;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents>;\n}\n\nexport interface InboxNotificationThreadProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationThreadData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n\n /**\n * Whether to show reactions.\n */\n showReactions?: boolean;\n\n /**\n * Whether to show attachments.\n */\n showAttachments?: boolean;\n}\n\nexport interface InboxNotificationTextMentionProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationTextMentionData;\n\n /**\n * Whether to show the room name in the title.\n */\n showRoomName?: boolean;\n}\n\nexport interface InboxNotificationInspectorProps\n extends Omit<InboxNotificationProps, \"kinds\" | \"children\">,\n InboxNotificationSharedProps {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationData;\n}\n\nexport interface InboxNotificationCustomProps\n extends Omit<InboxNotificationProps, \"kinds\">,\n InboxNotificationSharedProps,\n SlotProp {\n /**\n * The inbox notification to display.\n */\n inboxNotification: InboxNotificationCustomData;\n\n /**\n * The inbox notification's content.\n */\n children: ReactNode;\n\n /**\n * The inbox notification's title.\n */\n title: ReactNode;\n\n /**\n * The inbox notification's aside content.\n * Can be combined with `InboxNotification.Icon` or `InboxNotification.Avatar` to easily follow default styles.\n */\n aside?: ReactNode;\n\n /**\n * Whether to mark the inbox notification as read when clicked.\n */\n markAsReadOnClick?: boolean;\n}\n\nexport type InboxNotificationThreadKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationThreadData;\n};\n\nexport type InboxNotificationTextMentionKindProps = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationTextMentionData;\n};\n\nexport type InboxNotificationCustomKindProps<K extends KDAD = KDAD> = Omit<\n InboxNotificationProps,\n \"kinds\"\n> & {\n inboxNotification: InboxNotificationCustomData<K>;\n};\n\ninterface InboxNotificationLayoutProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"title\">,\n InboxNotificationSharedProps,\n SlotProp {\n inboxNotification: InboxNotificationData;\n aside?: ReactNode;\n title: ReactNode;\n date: Date | string | number;\n unread?: boolean;\n overrides?: Partial<GlobalOverrides & InboxNotificationOverrides>;\n components?: Partial<GlobalComponents>;\n markAsReadOnClick?: boolean;\n\n /**\n * @internal\n */\n additionalDropdownItemsBefore?: ReactNode;\n\n /**\n * @internal\n */\n additionalDropdownItemsAfter?: ReactNode;\n}\n\nexport type InboxNotificationIconProps = ComponentProps<\"div\">;\n\nexport interface InboxNotificationAvatarProps extends ComponentProps<\"div\"> {\n /**\n * The user ID to display the avatar for.\n */\n userId: string;\n}\n\nconst InboxNotificationLayout = forwardRef<\n HTMLAnchorElement,\n InboxNotificationLayoutProps\n>(\n (\n {\n inboxNotification,\n children,\n aside,\n title,\n date,\n unread,\n markAsReadOnClick,\n onClick,\n href,\n showActions,\n overrides,\n components,\n className,\n asChild,\n additionalDropdownItemsBefore,\n additionalDropdownItemsAfter,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const { Anchor } = useComponents(components);\n const Component = asChild ? Slot : Anchor;\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();\n const deleteInboxNotification = useDeleteInboxNotification();\n\n const handleClick = useCallback(\n (event: ReactMouseEvent<HTMLAnchorElement, MouseEvent>) => {\n onClick?.(event);\n\n const shouldMarkAsReadOnClick = markAsReadOnClick ?? Boolean(href);\n\n if (unread && shouldMarkAsReadOnClick) {\n markInboxNotificationAsRead(inboxNotification.id);\n }\n },\n [\n href,\n inboxNotification.id,\n markAsReadOnClick,\n markInboxNotificationAsRead,\n onClick,\n unread,\n ]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const preventDefaultAndStopPropagation = useCallback(\n (event: SyntheticEvent) => {\n event.preventDefault();\n event.stopPropagation();\n },\n []\n );\n\n const handleMoreClick = useCallback((event: ReactMouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n setMoreActionOpen((open) => !open);\n }, []);\n\n const handleMarkAsRead = useCallback(() => {\n markInboxNotificationAsRead(inboxNotification.id);\n }, [inboxNotification.id, markInboxNotificationAsRead]);\n\n const handleDelete = useCallback(() => {\n deleteInboxNotification(inboxNotification.id);\n }, [inboxNotification.id, deleteInboxNotification]);\n\n return (\n <TooltipProvider>\n <Component\n className={cn(\n \"lb-root lb-inbox-notification\",\n showActions === \"hover\" &&\n \"lb-inbox-notification:show-actions-hover\",\n isMoreActionOpen && \"lb-inbox-notification:action-open\",\n className\n )}\n dir={$.dir}\n data-unread={unread ? \"\" : undefined}\n data-kind={inboxNotification.kind}\n onClick={handleClick}\n href={href}\n {...props}\n ref={forwardedRef}\n >\n {aside && <div className=\"lb-inbox-notification-aside\">{aside}</div>}\n <div className=\"lb-inbox-notification-content\">\n <div className=\"lb-inbox-notification-header\">\n <span className=\"lb-inbox-notification-title\">{title}</span>\n <div className=\"lb-inbox-notification-details\">\n <span className=\"lb-inbox-notification-details-labels\">\n <Timestamp\n locale={$.locale}\n date={date}\n className=\"lb-date lb-inbox-notification-date\"\n />\n {unread && (\n <span\n className=\"lb-inbox-notification-unread-indicator\"\n role=\"presentation\"\n />\n )}\n </span>\n </div>\n {showActions && (\n <div className=\"lb-inbox-notification-actions\">\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n {additionalDropdownItemsBefore}\n {unread ? (\n <DropdownItem\n onSelect={handleMarkAsRead}\n onClick={stopPropagation}\n icon={<CheckIcon />}\n >\n {$.INBOX_NOTIFICATION_MARK_AS_READ}\n </DropdownItem>\n ) : null}\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.INBOX_NOTIFICATION_DELETE}\n </DropdownItem>\n {additionalDropdownItemsAfter}\n </>\n }\n >\n <Tooltip content={$.INBOX_NOTIFICATION_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-inbox-notification-action\"\n onClick={handleMoreClick}\n onPointerDown={preventDefaultAndStopPropagation}\n onPointerUp={preventDefaultAndStopPropagation}\n aria-label={$.INBOX_NOTIFICATION_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n </div>\n )}\n </div>\n <div className=\"lb-inbox-notification-body\">{children}</div>\n </div>\n </Component>\n </TooltipProvider>\n );\n }\n);\n\nfunction InboxNotificationIcon({\n className,\n ...props\n}: InboxNotificationIconProps) {\n return (\n <div className={cn(\"lb-inbox-notification-icon\", className)} {...props} />\n );\n}\n\nfunction InboxNotificationAvatar({\n className,\n ...props\n}: InboxNotificationAvatarProps) {\n return (\n <Avatar\n className={cn(\"lb-inbox-notification-avatar\", className)}\n {...props}\n />\n );\n}\n\nconst InboxNotificationThread = forwardRef<\n HTMLAnchorElement,\n InboxNotificationThreadProps\n>(\n (\n {\n inboxNotification,\n href,\n showRoomName = true,\n showReactions = true,\n showAttachments = true,\n showActions = \"hover\",\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n const client = useClient();\n const thread = useInboxNotificationThread(inboxNotification.id);\n const {\n status: subscriptionStatus,\n subscribe,\n unsubscribe,\n } = useRoomThreadSubscription(thread.roomId, thread.id);\n const currentUserId = useCurrentUserId();\n const { info } = useRoomInfo(inboxNotification.roomId);\n const contents = useMemo(() => {\n const contents = generateInboxNotificationThreadContents(\n client,\n inboxNotification,\n thread,\n currentUserId ?? \"\"\n );\n\n if (contents.comments.length === 0 || contents.userIds.length === 0) {\n return null;\n }\n\n switch (contents.type) {\n case \"comments\": {\n const reversedUserIds = [...contents.userIds].reverse();\n const firstUserId = reversedUserIds[0]!;\n\n const aside = <InboxNotificationAvatar userId={firstUserId} />;\n const title = $.INBOX_NOTIFICATION_THREAD_COMMENTS_LIST(\n <List\n values={reversedUserIds.map((userId) => (\n <User key={userId} userId={userId} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={INBOX_NOTIFICATION_THREAD_MAX_COMMENTS - 1}\n locale={$.locale}\n />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined,\n reversedUserIds.length\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n {contents.comments.map((comment) => (\n <InboxNotificationComment\n key={comment.id}\n comment={comment}\n showHeader={contents.comments.length > 1}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n ))}\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: contents.comments[contents.comments.length - 1]!.id,\n };\n }\n\n case \"mention\": {\n const mentionCreatedBy = contents.userIds[0]!;\n const mentionComment = contents.comments[0]!;\n\n const aside = <InboxNotificationAvatar userId={mentionCreatedBy} />;\n const title = $.INBOX_NOTIFICATION_THREAD_MENTION(\n <User key={mentionCreatedBy} userId={mentionCreatedBy} />,\n showRoomName ? <Room roomId={thread.roomId} /> : undefined\n );\n const content = (\n <div className=\"lb-inbox-notification-comments\">\n <InboxNotificationComment\n key={mentionComment.id}\n comment={mentionComment}\n showHeader={false}\n showAttachments={showAttachments}\n showReactions={showReactions}\n overrides={overrides}\n />\n </div>\n );\n\n return {\n unread: contents.unread,\n date: contents.date,\n aside,\n title,\n content,\n threadId: thread.id,\n commentId: mentionComment.id,\n };\n }\n\n default:\n return assertNever(\n contents,\n \"Unexpected thread inbox notification type\"\n );\n }\n }, [\n $,\n client,\n currentUserId,\n inboxNotification,\n overrides,\n showRoomName,\n showAttachments,\n showReactions,\n thread,\n ]);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? // Set the comment ID as the URL hash.\n generateUrl(resolvedHref, undefined, contents?.commentId)\n : undefined;\n }, [contents?.commentId, href, info?.url]);\n\n const handleSubscribeChange = useCallback(() => {\n if (subscriptionStatus === \"subscribed\") {\n unsubscribe();\n } else {\n subscribe();\n }\n }, [subscriptionStatus, subscribe, unsubscribe]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n if (!contents) {\n return null;\n }\n\n const { aside, title, content, date, unread } = contents;\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={date}\n unread={unread}\n overrides={overrides}\n href={resolvedHref}\n showActions={showActions}\n markAsReadOnClick={false}\n additionalDropdownItemsBefore={\n <DropdownItem\n onSelect={handleSubscribeChange}\n onClick={stopPropagation}\n icon={\n subscriptionStatus === \"subscribed\" ? (\n <BellCrossedIcon />\n ) : (\n <BellIcon />\n )\n }\n >\n {subscriptionStatus === \"subscribed\"\n ? $.THREAD_UNSUBSCRIBE\n : $.THREAD_SUBSCRIBE}\n </DropdownItem>\n }\n {...props}\n ref={forwardedRef}\n >\n {content}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationTextMention = forwardRef<\n HTMLAnchorElement,\n InboxNotificationTextMentionProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n showRoomName = true,\n href,\n overrides,\n ...props\n },\n ref\n ) => {\n const $ = useOverrides(overrides);\n const { info } = useRoomInfo(inboxNotification.roomId);\n // Use URL from `resolveRoomsInfo` if `href` isn't set.\n const resolvedHref = useMemo(() => {\n const resolvedHref = href ?? info?.url;\n\n return resolvedHref\n ? (sanitizeUrl(resolvedHref) ?? undefined)\n : undefined;\n }, [href, info?.url]);\n\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={<InboxNotificationAvatar userId={inboxNotification.createdBy} />}\n title={$.INBOX_NOTIFICATION_TEXT_MENTION(\n <User\n key={inboxNotification.createdBy}\n userId={inboxNotification.createdBy}\n />,\n showRoomName ? <Room roomId={inboxNotification.roomId} /> : undefined\n )}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n href={resolvedHref}\n {...props}\n ref={ref}\n />\n );\n }\n);\n\nconst InboxNotificationCustom = forwardRef<\n HTMLAnchorElement,\n InboxNotificationCustomProps\n>(\n (\n {\n inboxNotification,\n showActions = \"hover\",\n title,\n aside,\n children,\n overrides,\n ...props\n },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n aside={aside}\n title={title}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n >\n {children}\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationInspector = forwardRef<\n HTMLAnchorElement,\n InboxNotificationInspectorProps\n>(\n (\n { inboxNotification, showActions = \"hover\", overrides, ...props },\n forwardedRef\n ) => {\n const unread = useMemo(() => {\n return (\n !inboxNotification.readAt ||\n inboxNotification.notifiedAt > inboxNotification.readAt\n );\n }, [inboxNotification.notifiedAt, inboxNotification.readAt]);\n\n return (\n <InboxNotificationLayout\n inboxNotification={inboxNotification}\n title={<code>{inboxNotification.id}</code>}\n date={inboxNotification.notifiedAt}\n unread={unread}\n overrides={overrides}\n showActions={showActions}\n {...props}\n ref={forwardedRef}\n data-inspector=\"\"\n >\n <CodeBlock\n title=\"Data\"\n code={JSON.stringify(inboxNotification, null, 2)}\n />\n </InboxNotificationLayout>\n );\n }\n);\n\nconst InboxNotificationCustomMissing = forwardRef<\n HTMLAnchorElement,\n Omit<InboxNotificationCustomProps, \"children\" | \"title\" | \"aside\">\n>(({ inboxNotification, ...props }, forwardedRef) => {\n return (\n <InboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n title={\n <>\n Custom notification kind <code>{inboxNotification.kind}</code> is not\n handled\n </>\n }\n aside={\n <InboxNotificationIcon>\n <WarningIcon />\n </InboxNotificationIcon>\n }\n ref={forwardedRef}\n data-missing=\"\"\n >\n Notifications of this kind won’t be displayed in production. Use the{\" \"}\n <code>kinds</code> prop to define how they should be rendered, learn more\n in the console.\n </InboxNotificationCustom>\n );\n});\n\n/**\n * Displays a single inbox notification.\n *\n * @example\n * <>\n * {inboxNotifications.map((inboxNotification) => (\n * <InboxNotification\n * key={inboxNotification.id}\n * inboxNotification={inboxNotification}\n * href={`/rooms/${inboxNotification.roomId}`\n * />\n * ))}\n * </>\n */\nexport const InboxNotification = Object.assign(\n forwardRef<HTMLAnchorElement, InboxNotificationProps>(\n ({ inboxNotification, kinds, ...props }, forwardedRef) => {\n switch (inboxNotification.kind) {\n case \"thread\": {\n const ResolvedInboxNotificationThread =\n kinds?.thread ?? InboxNotificationThread;\n\n return (\n <ResolvedInboxNotificationThread\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n case \"textMention\": {\n const ResolvedInboxNotificationTextMention =\n kinds?.textMention ?? InboxNotificationTextMention;\n\n return (\n <ResolvedInboxNotificationTextMention\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n\n default: {\n const ResolvedInboxNotificationCustom =\n kinds?.[inboxNotification.kind];\n\n if (!ResolvedInboxNotificationCustom) {\n if (process.env.NODE_ENV !== \"production\") {\n warnOnce(\n `Custom notification kind \"${inboxNotification.kind}\" is not handled so notifications of this kind will not be displayed in production. Use the kinds prop to define how they should be rendered. Learn more: https://liveblocks.io/docs/api-reference/liveblocks-react-ui#Rendering-notification-kinds-differently.`\n );\n\n return (\n <InboxNotificationCustomMissing\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n } else {\n // Don't render anything in production if this inbox notification kind is not defined.\n return null;\n }\n }\n\n return (\n <ResolvedInboxNotificationCustom\n inboxNotification={inboxNotification}\n {...props}\n ref={forwardedRef}\n />\n );\n }\n }\n }\n ),\n {\n /**\n * Displays a thread inbox notification kind.\n */\n Thread: InboxNotificationThread,\n\n /**\n * Displays a text mention inbox notification kind.\n */\n TextMention: InboxNotificationTextMention,\n\n /**\n * Displays a custom inbox notification kind.\n */\n Custom: InboxNotificationCustom,\n\n /**\n * Display the inbox notification's data, which can be useful during development.\n *\n * @example\n * <InboxNotification\n * inboxNotification={inboxNotification}\n * kinds={{\n * $custom: InboxNotification.Inspector,\n * }}\n * />\n */\n Inspector: InboxNotificationInspector,\n Icon: InboxNotificationIcon,\n Avatar: InboxNotificationAvatar,\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4PA;AAAgC;AAK5B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AAEA;AAAoB;AAEhB;AAEA;AAEA;AACE;AAAgD;AAClD;AACF;AACA;AACE;AACkB;AAClB;AACA;AACA;AACA;AACF;AAGF;AACE;AAAsB;AAGxB;AAAyC;AAErC;AACA;AAAsB;AACxB;AACC;AAGH;AACE;AACA;AACA;AAAiC;AAGnC;AACE;AAAgD;AAGlD;AACE;AAA4C;AAG9C;AAEI;AAAC;AAAA;AACY;AACT;AAEE;AACkB;AACpB;AACF;AACO;AACoB;AACE;AACpB;AACT;AACI;AACC;AAEJ;AAA6D;AAE5D;AACE;AAAqD;AAGjD;AAAA;AAAC;AAAA;AACW;AACV;AACU;AAAA;AACZ;AAEE;AAAC;AAAA;AACW;AACL;AAAA;AACP;AAGN;AAGI;AAAC;AAAA;AACO;AACQ;AACR;AAGD;AAAA;AAEC;AAAC;AAAA;AACW;AACD;AACQ;AAEd;AAAA;AAEH;AACJ;AAAC;AAAA;AACW;AACD;AACS;AAEf;AAAA;AACL;AACC;AACH;AAKE;AAAC;AAAA;AACW;AACD;AACM;AACF;AACC;AACM;AAAA;AAG1B;AAAA;AAEJ;AAEJ;AACsD;AACxD;AAAA;AAAA;AAEJ;AAGN;AAEA;AAA+B;AAC7B;AAEF;AACE;AAGF;AAEA;AAAiC;AAC/B;AAEF;AACE;AACE;AAAC;AAAA;AACwD;AACnD;AAAA;AAGV;AAEA;AAAgC;AAK5B;AACE;AACA;AACe;AACC;AACE;AACJ;AACd;AACG;AAIL;AACA;AACA;AACA;AAAM;AACI;AACR;AACA;AAEF;AACA;AACA;AACE;AAAiB;AACf;AACA;AACA;AACiB;AAGnB;AACE;AAAO;AAGT;AAAuB;AAEnB;AACA;AAEA;AACA;AAAgB;AACd;AAAC;AAAA;AAGE;AACkB;AACgC;AACzC;AAAA;AACZ;AACiD;AACjC;AAElB;AAGM;AAAC;AAAA;AAEC;AACuC;AACvC;AACA;AACA;AAAA;AALa;AAWrB;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AAC2C;AAC9D;AACF;AAGE;AACA;AAEA;AACA;AAAgB;AACyC;AACN;AAEnD;AAEI;AAAC;AAAA;AAEU;AACG;AACZ;AACA;AACA;AAAA;AALoB;AAU1B;AAAO;AACY;AACF;AACf;AACA;AACA;AACiB;AACS;AAC5B;AACF;AAGE;AAAO;AACL;AACA;AACF;AACJ;AACC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGF;AACE;AAEA;AAAO;AAAA;AAEqD;AACxD;AAGN;AACE;AACE;AAAY;AAEZ;AAAU;AACZ;AAGF;AACE;AAAsB;AAGxB;AACE;AAAO;AAGT;AAEA;AACE;AAAC;AAAA;AACC;AACA;AACA;AACA;AACA;AACA;AACM;AACN;AACmB;AAEjB;AAAC;AAAA;AACW;AACD;AAKK;AAMR;AAAA;AACR;AAEE;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAqC;AAKjC;AACE;AACc;AACC;AACf;AACA;AACG;AAIL;AACA;AAEA;AACE;AAEA;AAEI;AAGN;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACqE;AAC5D;AACP;AAAC;AAAA;AAE2B;AAAA;AADH;AAEzB;AAC4D;AAC9D;AACwB;AACxB;AACA;AACA;AACM;AACF;AACJ;AAAA;AACF;AAGN;AAEA;AAAgC;AAK5B;AACE;AACc;AACd;AACA;AACA;AACA;AACG;AAIL;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACA;AACA;AACwB;AACxB;AACA;AACA;AACI;AACC;AAEJ;AAAA;AACH;AAGN;AAEA;AAAmC;AAQ/B;AACE;AAEmD;AAIrD;AACE;AAAC;AAAA;AACC;AACmC;AACX;AACxB;AACA;AACA;AACI;AACC;AACU;AAEf;AAAC;AAAA;AACO;AACyC;AAAA;AACjD;AAAA;AACF;AAGN;AAEA;AAIE;AACE;AAAC;AAAA;AACC;AACI;AAEA;AAAA;AACuD;AAAO;AAEhE;AAKA;AAEG;AACQ;AACd;AAAA;AACsE;AAC1D;AAAO;AAAA;AAAA;AAIxB;AAgBO;AAAiC;AACtC;AAEI;AAAgC;AAE5B;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AAGE;AAGA;AACE;AACE;AAAA;AACqD;AAGrD;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAIF;AAAO;AACT;AAGF;AACE;AAAC;AAAA;AACC;AACI;AACC;AAAA;AACP;AAEJ;AACF;AACF;AACF;AACA;AAAA;AAAA;AAAA;AAIU;AAAA;AAAA;AAAA;AAKK;AAAA;AAAA;AAAA;AAKL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaG;AACL;AACE;AAEZ;;"}
@@ -4,7 +4,7 @@
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var core = require('@liveblocks/core');
6
6
  var _private = require('@liveblocks/react/_private');
7
- var radixUi = require('radix-ui');
7
+ var TogglePrimitive = require('@radix-ui/react-toggle');
8
8
  var react = require('react');
9
9
  var ArrowDown = require('../icons/ArrowDown.cjs');
10
10
  var Bell = require('../icons/Bell.cjs');
@@ -13,12 +13,62 @@ var CheckCircle = require('../icons/CheckCircle.cjs');
13
13
  var CheckCircleFill = require('../icons/CheckCircleFill.cjs');
14
14
  var overrides = require('../overrides.cjs');
15
15
  var cn = require('../utils/cn.cjs');
16
+ var useStableComponent = require('../utils/use-stable-component.cjs');
17
+ var useVisible = require('../utils/use-visible.cjs');
18
+ var useWindowFocus = require('../utils/use-window-focus.cjs');
16
19
  var Comment = require('./Comment.cjs');
17
20
  var Composer = require('./Composer.cjs');
18
21
  var Button = require('./internal/Button.cjs');
19
22
  var Tooltip = require('./internal/Tooltip.cjs');
23
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
20
24
 
25
+ function _interopNamespaceDefault(e) {
26
+ var n = Object.create(null);
27
+ if (e) {
28
+ Object.keys(e).forEach(function (k) {
29
+ if (k !== 'default') {
30
+ var d = Object.getOwnPropertyDescriptor(e, k);
31
+ Object.defineProperty(n, k, d.get ? d : {
32
+ enumerable: true,
33
+ get: function () { return e[k]; }
34
+ });
35
+ }
36
+ });
37
+ }
38
+ n.default = e;
39
+ return Object.freeze(n);
40
+ }
41
+
42
+ var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TogglePrimitive);
21
43
 
44
+
45
+ function MarkThreadAsReadMarker({ thread }) {
46
+ const { id: threadId, roomId } = thread;
47
+ const ref = react.useRef(null);
48
+ const markThreadAsRead = _private.useMarkRoomThreadAsRead(roomId);
49
+ const isWindowFocused = useWindowFocus.useWindowFocus();
50
+ useVisible.useIntersectionCallback(
51
+ ref,
52
+ (isIntersecting) => {
53
+ if (isIntersecting) {
54
+ markThreadAsRead(threadId);
55
+ }
56
+ },
57
+ {
58
+ // The underlying IntersectionObserver is only enabled when the window is focused
59
+ enabled: isWindowFocused
60
+ }
61
+ );
62
+ return /* @__PURE__ */ jsxRuntime.jsx(
63
+ "div",
64
+ {
65
+ ref,
66
+ style: { height: 0 },
67
+ "aria-hidden": true,
68
+ "data-mark-as-read-marker": ""
69
+ }
70
+ );
71
+ }
22
72
  const Thread = react.forwardRef(
23
73
  ({
24
74
  thread,
@@ -32,6 +82,7 @@ const Thread = react.forwardRef(
32
82
  showComposerFormattingControls = true,
33
83
  maxVisibleComments,
34
84
  commentDropdownItems,
85
+ additionalContent,
35
86
  onResolvedChange,
36
87
  onCommentEdit,
37
88
  onCommentDelete,
@@ -41,12 +92,12 @@ const Thread = react.forwardRef(
41
92
  onAttachmentClick,
42
93
  onComposerSubmit,
43
94
  blurComposerOnSubmit,
44
- autoFocus,
45
95
  overrides: overrides$1,
46
96
  components,
47
97
  className,
48
98
  ...props
49
99
  }, forwardedRef) => {
100
+ const Comment$1 = useStableComponent.useStableComponent(components?.Comment, Comment.Comment);
50
101
  const markThreadAsResolved = _private.useMarkRoomThreadAsResolved(thread.roomId);
51
102
  const markThreadAsUnresolved = _private.useMarkRoomThreadAsUnresolved(thread.roomId);
52
103
  const $ = overrides.useOverrides(overrides$1);
@@ -57,9 +108,6 @@ const Thread = react.forwardRef(
57
108
  const lastCommentIndex = react.useMemo(() => {
58
109
  return showDeletedComments ? thread.comments.length - 1 : core.findLastIndex(thread.comments, (comment) => Boolean(comment.body));
59
110
  }, [showDeletedComments, thread.comments]);
60
- const commentsCount = react.useMemo(() => {
61
- return showDeletedComments ? thread.comments.length : thread.comments.filter((comment) => comment.body).length;
62
- }, [showDeletedComments, thread.comments]);
63
111
  const hiddenComments = react.useMemo(() => {
64
112
  const maxVisibleCommentsCount = typeof maxVisibleComments === "number" ? maxVisibleComments : maxVisibleComments?.max;
65
113
  const visibleCommentsShow = (typeof maxVisibleComments === "object" ? maxVisibleComments?.show : void 0) ?? "newest";
@@ -173,8 +221,7 @@ const Thread = react.forwardRef(
173
221
  subscribe();
174
222
  }
175
223
  }, [subscriptionStatus, subscribe, unsubscribe]);
176
- let currentCommentIndex = 0;
177
- return /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
224
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
178
225
  "div",
179
226
  {
180
227
  className: cn.cn(
@@ -188,11 +235,11 @@ const Thread = react.forwardRef(
188
235
  ...props,
189
236
  ref: forwardedRef,
190
237
  children: [
191
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lb-thread-comments", role: "feed", children: thread.comments.map((comment, index) => {
192
- const isNonDeletedComment = showDeletedComments || comment.body;
238
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lb-thread-comments", children: thread.comments.map((comment, index) => {
193
239
  const isFirstComment = index === firstCommentIndex;
194
240
  const isUnread = unreadIndex !== void 0 && index >= unreadIndex;
195
241
  const isHidden = hiddenComments && index >= hiddenComments.firstIndex && index <= hiddenComments.lastIndex;
242
+ const isHiddenBecauseDeleted = !showDeletedComments && !comment.body;
196
243
  const isFirstHiddenComment = isHidden && index === hiddenComments.firstIndex;
197
244
  if (isFirstHiddenComment) {
198
245
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -209,21 +256,15 @@ const Thread = react.forwardRef(
209
256
  }
210
257
  )
211
258
  },
212
- `${comment.id}:show-more`
259
+ `${comment.id}-show-more`
213
260
  );
214
261
  }
215
- if (isNonDeletedComment) {
216
- currentCommentIndex++;
217
- }
218
- if (isHidden) {
262
+ if (isHidden || isHiddenBecauseDeleted) {
219
263
  return null;
220
264
  }
221
265
  const children = /* @__PURE__ */ jsxRuntime.jsx(
222
- Comment.Comment,
266
+ Comment$1,
223
267
  {
224
- tabIndex: 0,
225
- "aria-posinset": currentCommentIndex,
226
- "aria-setsize": commentsCount,
227
268
  overrides: overrides$1,
228
269
  className: "lb-thread-comment",
229
270
  "data-unread": isUnread ? "" : void 0,
@@ -240,14 +281,13 @@ const Thread = react.forwardRef(
240
281
  onMentionClick,
241
282
  onAttachmentClick,
242
283
  components,
243
- autoMarkReadThreadId: index === lastCommentIndex && isUnread ? thread.id : void 0,
244
284
  actionsClassName: isFirstComment ? "lb-thread-actions" : void 0,
245
285
  actions: isFirstComment && showResolveAction ? /* @__PURE__ */ jsxRuntime.jsx(
246
286
  Tooltip.Tooltip,
247
287
  {
248
288
  content: thread.resolved ? $.THREAD_UNRESOLVE : $.THREAD_RESOLVE,
249
289
  children: /* @__PURE__ */ jsxRuntime.jsx(
250
- radixUi.Toggle.Root,
290
+ TogglePrimitive__namespace.Root,
251
291
  {
252
292
  pressed: thread.resolved,
253
293
  onPressedChange: handleResolvedChange,
@@ -266,30 +306,15 @@ const Thread = react.forwardRef(
266
306
  )
267
307
  }
268
308
  ) : null,
269
- dropdownItems: ({ children: children2 }) => {
270
- const threadDropdownItems = isFirstComment ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
271
- Comment.Comment.DropdownItem,
272
- {
273
- onSelect: handleSubscribeChange,
274
- icon: subscriptionStatus === "subscribed" ? /* @__PURE__ */ jsxRuntime.jsx(BellCrossed.BellCrossedIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(Bell.BellIcon, {}),
275
- children: subscriptionStatus === "subscribed" ? $.THREAD_UNSUBSCRIBE : $.THREAD_SUBSCRIBE
276
- }
277
- ) }) : null;
278
- if (typeof commentDropdownItems === "function") {
279
- return commentDropdownItems({
280
- children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
281
- threadDropdownItems,
282
- children2
283
- ] }),
284
- comment
285
- });
309
+ internalDropdownItems: isFirstComment ? /* @__PURE__ */ jsxRuntime.jsx(
310
+ Comment.Comment.DropdownItem,
311
+ {
312
+ onSelect: handleSubscribeChange,
313
+ icon: subscriptionStatus === "subscribed" ? /* @__PURE__ */ jsxRuntime.jsx(BellCrossed.BellCrossedIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(Bell.BellIcon, {}),
314
+ children: subscriptionStatus === "subscribed" ? $.THREAD_UNSUBSCRIBE : $.THREAD_SUBSCRIBE
286
315
  }
287
- return threadDropdownItems || commentDropdownItems || children2 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
288
- threadDropdownItems,
289
- children2,
290
- commentDropdownItems
291
- ] }) : null;
292
- }
316
+ ) : void 0,
317
+ dropdownItems: commentDropdownItems
293
318
  },
294
319
  comment.id
295
320
  );
@@ -308,6 +333,8 @@ const Thread = react.forwardRef(
308
333
  children
309
334
  ] }, comment.id) : children;
310
335
  }) }),
336
+ unreadIndex !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(MarkThreadAsReadMarker, { thread }),
337
+ additionalContent,
311
338
  showComposer && /* @__PURE__ */ jsxRuntime.jsx(
312
339
  Composer.Composer,
313
340
  {
@@ -323,8 +350,7 @@ const Thread = react.forwardRef(
323
350
  COMPOSER_SEND: $.THREAD_COMPOSER_SEND,
324
351
  ...overrides$1
325
352
  },
326
- roomId: thread.roomId,
327
- autoFocus
353
+ roomId: thread.roomId
328
354
  }
329
355
  )
330
356
  ]