@liveblocks/react-ui 2.21.0 → 2.22.1
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.
- package/dist/_private/index.cjs +2 -2
- package/dist/_private/index.d.cts +2 -2
- package/dist/_private/index.d.ts +2 -2
- package/dist/_private/index.js +1 -1
- package/dist/components/Comment.cjs +3 -3
- package/dist/components/Comment.cjs.map +1 -1
- package/dist/components/Comment.js +3 -3
- package/dist/components/Comment.js.map +1 -1
- package/dist/icon.cjs +16 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +8 -0
- package/dist/icon.js.map +1 -1
- package/dist/icons/{EmojiAdd.cjs → EmojiPlus.cjs} +3 -3
- package/dist/icons/EmojiPlus.cjs.map +1 -0
- package/dist/icons/{EmojiAdd.js → EmojiPlus.js} +3 -3
- package/dist/icons/EmojiPlus.js.map +1 -0
- package/dist/icons/index.cjs +2 -2
- package/dist/icons/index.js +1 -1
- package/dist/index.d.cts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/dist/icons/EmojiAdd.cjs.map +0 -1
- package/dist/icons/EmojiAdd.js.map +0 -1
package/dist/_private/index.cjs
CHANGED
|
@@ -28,7 +28,7 @@ var Delete = require('../icons/Delete.cjs');
|
|
|
28
28
|
var Edit = require('../icons/Edit.cjs');
|
|
29
29
|
var Ellipsis = require('../icons/Ellipsis.cjs');
|
|
30
30
|
var Emoji = require('../icons/Emoji.cjs');
|
|
31
|
-
var
|
|
31
|
+
var EmojiPlus = require('../icons/EmojiPlus.cjs');
|
|
32
32
|
var H1 = require('../icons/H1.cjs');
|
|
33
33
|
var H2 = require('../icons/H2.cjs');
|
|
34
34
|
var H3 = require('../icons/H3.cjs');
|
|
@@ -89,7 +89,7 @@ exports.DeleteIcon = Delete.DeleteIcon;
|
|
|
89
89
|
exports.EditIcon = Edit.EditIcon;
|
|
90
90
|
exports.EllipsisIcon = Ellipsis.EllipsisIcon;
|
|
91
91
|
exports.EmojiIcon = Emoji.EmojiIcon;
|
|
92
|
-
exports.
|
|
92
|
+
exports.EmojiPlusIcon = EmojiPlus.EmojiPlusIcon;
|
|
93
93
|
exports.H1Icon = H1.H1Icon;
|
|
94
94
|
exports.H2Icon = H2.H2Icon;
|
|
95
95
|
exports.H3Icon = H3.H3Icon;
|
|
@@ -89,7 +89,7 @@ declare function EllipsisIcon(props: ComponentProps<"svg">): react_jsx_runtime.J
|
|
|
89
89
|
|
|
90
90
|
declare function EmojiIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
91
91
|
|
|
92
|
-
declare function
|
|
92
|
+
declare function EmojiPlusIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
93
93
|
|
|
94
94
|
declare function H1Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
95
95
|
|
|
@@ -153,4 +153,4 @@ declare function useInitial<T>(value: T | (() => T)): T;
|
|
|
153
153
|
|
|
154
154
|
declare function useRefs<T>(...refs: Ref<T>[]): RefCallback<T>;
|
|
155
155
|
|
|
156
|
-
export { ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, BlockquoteIcon, BoldIcon, Button, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, CommentIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon,
|
|
156
|
+
export { ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, BlockquoteIcon, BoldIcon, Button, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, CommentIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, MentionIcon, QuestionMarkIcon, RedoIcon, ResolveIcon, ResolvedIcon, RestoreIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StrikethroughIcon, TextIcon, Tooltip, TranslateIcon, UnderlineIcon, UndoIcon, User, WarningIcon, capitalize, useInitial, useRefs };
|
package/dist/_private/index.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ declare function EllipsisIcon(props: ComponentProps<"svg">): react_jsx_runtime.J
|
|
|
89
89
|
|
|
90
90
|
declare function EmojiIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
91
91
|
|
|
92
|
-
declare function
|
|
92
|
+
declare function EmojiPlusIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
93
93
|
|
|
94
94
|
declare function H1Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
95
95
|
|
|
@@ -153,4 +153,4 @@ declare function useInitial<T>(value: T | (() => T)): T;
|
|
|
153
153
|
|
|
154
154
|
declare function useRefs<T>(...refs: Ref<T>[]): RefCallback<T>;
|
|
155
155
|
|
|
156
|
-
export { ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, BlockquoteIcon, BoldIcon, Button, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, CommentIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon,
|
|
156
|
+
export { ArrowCornerDownRightIcon, ArrowCornerUpRightIcon, ArrowDownIcon, ArrowUpIcon, AttachmentIcon, BlockquoteIcon, BoldIcon, Button, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CodeIcon, CommentIcon, CrossIcon, DeleteIcon, EditIcon, EllipsisIcon, EmojiIcon, EmojiPlusIcon, H1Icon, H2Icon, H3Icon, ItalicIcon, LengthenIcon, List, ListOrderedIcon, ListUnorderedIcon, MentionIcon, QuestionMarkIcon, RedoIcon, ResolveIcon, ResolvedIcon, RestoreIcon, SearchIcon, SelectButton, SendIcon, ShortcutTooltip, ShortenIcon, SparklesIcon, SparklesTextIcon, SpinnerIcon, StrikethroughIcon, TextIcon, Tooltip, TranslateIcon, UnderlineIcon, UndoIcon, User, WarningIcon, capitalize, useInitial, useRefs };
|
package/dist/_private/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { DeleteIcon } from '../icons/Delete.js';
|
|
|
26
26
|
export { EditIcon } from '../icons/Edit.js';
|
|
27
27
|
export { EllipsisIcon } from '../icons/Ellipsis.js';
|
|
28
28
|
export { EmojiIcon } from '../icons/Emoji.js';
|
|
29
|
-
export {
|
|
29
|
+
export { EmojiPlusIcon } from '../icons/EmojiPlus.js';
|
|
30
30
|
export { H1Icon } from '../icons/H1.js';
|
|
31
31
|
export { H2Icon } from '../icons/H2.js';
|
|
32
32
|
export { H3Icon } from '../icons/H3.js';
|
|
@@ -10,7 +10,7 @@ var Cross = require('../icons/Cross.cjs');
|
|
|
10
10
|
var Delete = require('../icons/Delete.cjs');
|
|
11
11
|
var Edit = require('../icons/Edit.cjs');
|
|
12
12
|
var Ellipsis = require('../icons/Ellipsis.cjs');
|
|
13
|
-
var
|
|
13
|
+
var EmojiPlus = require('../icons/EmojiPlus.cjs');
|
|
14
14
|
var overrides = require('../overrides.cjs');
|
|
15
15
|
var index = require('../primitives/Comment/index.cjs');
|
|
16
16
|
var index$1 = require('../primitives/Composer/index.cjs');
|
|
@@ -505,7 +505,7 @@ const Comment = react.forwardRef(
|
|
|
505
505
|
className: "lb-comment-action",
|
|
506
506
|
onClick: stopPropagation,
|
|
507
507
|
"aria-label": $.COMMENT_ADD_REACTION,
|
|
508
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
508
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(EmojiPlus.EmojiPlusIcon, {})
|
|
509
509
|
})
|
|
510
510
|
})
|
|
511
511
|
})
|
|
@@ -645,7 +645,7 @@ const Comment = react.forwardRef(
|
|
|
645
645
|
variant: "outline",
|
|
646
646
|
onClick: stopPropagation,
|
|
647
647
|
"aria-label": $.COMMENT_ADD_REACTION,
|
|
648
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
648
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(EmojiPlus.EmojiPlusIcon, {})
|
|
649
649
|
})
|
|
650
650
|
})
|
|
651
651
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comment.cjs","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button, CustomButton } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: 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 /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <CustomButton\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </CustomButton>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiAddIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n icon={<EditIcon />}\n >\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n icon={<CrossIcon />}\n />\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut=\"Enter\"\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n icon={<CheckIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiAddIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AACM;AACtB;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AACO;AAEb;AACL;AACC;AACW;AACD;AACS;AAEf;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AACQ;AACnB;AACF;AACC;AACY;AACF;AAER;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AACG;AACnB;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"Comment.cjs","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiPlusIcon } from \"../icons/EmojiPlus\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button, CustomButton } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: 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 /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <CustomButton\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </CustomButton>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiPlusIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n icon={<EditIcon />}\n >\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n icon={<CrossIcon />}\n />\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut=\"Enter\"\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n icon={<CheckIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiPlusIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AACO;AACvB;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AACO;AAEb;AACL;AACC;AACW;AACD;AACS;AAEf;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AACQ;AACnB;AACF;AACC;AACY;AACF;AAER;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AACG;AACnB;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AACO;AACvB;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;;;;;;;"}
|
|
@@ -8,7 +8,7 @@ import { CrossIcon } from '../icons/Cross.js';
|
|
|
8
8
|
import { DeleteIcon } from '../icons/Delete.js';
|
|
9
9
|
import { EditIcon } from '../icons/Edit.js';
|
|
10
10
|
import { EllipsisIcon } from '../icons/Ellipsis.js';
|
|
11
|
-
import {
|
|
11
|
+
import { EmojiPlusIcon } from '../icons/EmojiPlus.js';
|
|
12
12
|
import { useOverrides } from '../overrides.js';
|
|
13
13
|
import { Mention as CommentMention$1, Link as CommentLink$1, Body as CommentBody } from '../primitives/Comment/index.js';
|
|
14
14
|
import { Submit as ComposerSubmit } from '../primitives/Composer/index.js';
|
|
@@ -484,7 +484,7 @@ const Comment = forwardRef(
|
|
|
484
484
|
className: "lb-comment-action",
|
|
485
485
|
onClick: stopPropagation,
|
|
486
486
|
"aria-label": $.COMMENT_ADD_REACTION,
|
|
487
|
-
icon: /* @__PURE__ */ jsx(
|
|
487
|
+
icon: /* @__PURE__ */ jsx(EmojiPlusIcon, {})
|
|
488
488
|
})
|
|
489
489
|
})
|
|
490
490
|
})
|
|
@@ -624,7 +624,7 @@ const Comment = forwardRef(
|
|
|
624
624
|
variant: "outline",
|
|
625
625
|
onClick: stopPropagation,
|
|
626
626
|
"aria-label": $.COMMENT_ADD_REACTION,
|
|
627
|
-
icon: /* @__PURE__ */ jsx(
|
|
627
|
+
icon: /* @__PURE__ */ jsx(EmojiPlusIcon, {})
|
|
628
628
|
})
|
|
629
629
|
})
|
|
630
630
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Comment.js","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiAddIcon } from \"../icons/EmojiAdd\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button, CustomButton } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: 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 /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <CustomButton\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </CustomButton>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiAddIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n icon={<EditIcon />}\n >\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n icon={<CrossIcon />}\n />\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut=\"Enter\"\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n icon={<CheckIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiAddIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AACM;AACtB;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AACO;AAEb;AACL;AACC;AACW;AACD;AACS;AAEf;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AACQ;AACnB;AACF;AACC;AACY;AACF;AAER;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AACG;AACnB;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;"}
|
|
1
|
+
{"version":3,"file":"Comment.js","sources":["../../src/components/Comment.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CommentAttachment,\n CommentData,\n CommentReaction as CommentReactionData,\n} from \"@liveblocks/core\";\nimport {\n useAddRoomCommentReaction,\n useDeleteRoomComment,\n useEditRoomComment,\n useMarkRoomThreadAsRead,\n useRemoveRoomCommentReaction,\n useRoomAttachmentUrl,\n} from \"@liveblocks/react/_private\";\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\nimport type {\n ComponentProps,\n ComponentPropsWithoutRef,\n FormEvent,\n MouseEvent,\n ReactNode,\n RefObject,\n SyntheticEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { CheckIcon } from \"../icons/Check\";\nimport { CrossIcon } from \"../icons/Cross\";\nimport { DeleteIcon } from \"../icons/Delete\";\nimport { EditIcon } from \"../icons/Edit\";\nimport { EllipsisIcon } from \"../icons/Ellipsis\";\nimport { EmojiPlusIcon } from \"../icons/EmojiPlus\";\nimport type {\n CommentOverrides,\n ComposerOverrides,\n GlobalOverrides,\n} from \"../overrides\";\nimport { useOverrides } from \"../overrides\";\nimport type { ComposerSubmitComment } from \"../primitives\";\nimport * as CommentPrimitive from \"../primitives/Comment\";\nimport type {\n CommentBodyLinkProps,\n CommentBodyMentionProps,\n CommentLinkProps,\n CommentMentionProps,\n} from \"../primitives/Comment/types\";\nimport * as ComposerPrimitive from \"../primitives/Composer\";\nimport { Timestamp } from \"../primitives/Timestamp\";\nimport { useCurrentUserId } from \"../shared\";\nimport { MENTION_CHARACTER } from \"../slate/plugins/mentions\";\nimport type { CommentAttachmentArgs } from \"../types\";\nimport { classNames } from \"../utils/class-names\";\nimport { download } from \"../utils/download\";\nimport { useRefs } from \"../utils/use-refs\";\nimport { useVisibleCallback } from \"../utils/use-visible\";\nimport { useWindowFocus } from \"../utils/use-window-focus\";\nimport type { ComposerProps } from \"./Composer\";\nimport { Composer } from \"./Composer\";\nimport {\n FileAttachment,\n MediaAttachment,\n separateMediaAttachments,\n} from \"./internal/Attachment\";\nimport { Avatar } from \"./internal/Avatar\";\nimport { Button, CustomButton } from \"./internal/Button\";\nimport { Dropdown, DropdownItem, DropdownTrigger } from \"./internal/Dropdown\";\nimport { Emoji } from \"./internal/Emoji\";\nimport { EmojiPicker, EmojiPickerTrigger } from \"./internal/EmojiPicker\";\nimport { List } from \"./internal/List\";\nimport { ShortcutTooltip, Tooltip, TooltipProvider } from \"./internal/Tooltip\";\nimport { User } from \"./internal/User\";\n\nconst REACTIONS_TRUNCATE = 5;\n\nexport interface CommentProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The comment to display.\n */\n comment: CommentData;\n\n /**\n * How to show or hide the actions.\n */\n showActions?: boolean | \"hover\";\n\n /**\n * Whether to show the comment if it was deleted. If set to `false`, it will render deleted comments as `null`.\n */\n showDeleted?: 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 /**\n * Whether to show the composer's formatting controls when editing the comment.\n */\n showComposerFormattingControls?: ComposerProps[\"showFormattingControls\"];\n\n /**\n * Whether to indent the comment's content.\n */\n indentContent?: boolean;\n\n /**\n * The event handler called when the comment is edited.\n */\n onCommentEdit?: (comment: CommentData) => void;\n\n /**\n * The event handler called when the comment is deleted.\n */\n onCommentDelete?: (comment: CommentData) => void;\n\n /**\n * The event handler called when clicking on the author.\n */\n onAuthorClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a mention.\n */\n onMentionClick?: (userId: string, event: MouseEvent<HTMLElement>) => void;\n\n /**\n * The event handler called when clicking on a comment's attachment.\n */\n onAttachmentClick?: (\n args: CommentAttachmentArgs,\n event: MouseEvent<HTMLElement>\n ) => void;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & CommentOverrides & ComposerOverrides>;\n\n /**\n * @internal\n */\n autoMarkReadThreadId?: string;\n\n /**\n * @internal\n */\n additionalActions?: ReactNode;\n\n /**\n * @internal\n */\n additionalActionsClassName?: string;\n}\n\ninterface CommentReactionButtonProps\n extends ComponentPropsWithoutRef<typeof Button> {\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ninterface CommentReactionProps extends ComponentPropsWithoutRef<\"button\"> {\n comment: CommentData;\n reaction: CommentReactionData;\n overrides?: Partial<GlobalOverrides & CommentOverrides>;\n}\n\ntype CommentNonInteractiveReactionProps = Omit<CommentReactionProps, \"comment\">;\n\ninterface CommentAttachmentProps extends ComponentProps<typeof FileAttachment> {\n attachment: CommentAttachment;\n onAttachmentClick?: CommentProps[\"onAttachmentClick\"];\n}\n\nexport function CommentMention({\n userId,\n className,\n ...props\n}: CommentBodyMentionProps & CommentMentionProps) {\n const currentId = useCurrentUserId();\n return (\n <CommentPrimitive.Mention\n className={classNames(\"lb-comment-mention\", className)}\n data-self={userId === currentId ? \"\" : undefined}\n {...props}\n >\n {MENTION_CHARACTER}\n <User userId={userId} />\n </CommentPrimitive.Mention>\n );\n}\n\nexport function CommentLink({\n href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <CommentPrimitive.Link\n className={classNames(\"lb-comment-link\", className)}\n href={href}\n {...props}\n >\n {children}\n </CommentPrimitive.Link>\n );\n}\n\nexport function CommentNonInteractiveLink({\n href: _href,\n children,\n className,\n ...props\n}: CommentBodyLinkProps & CommentLinkProps) {\n return (\n <span className={classNames(\"lb-comment-link\", className)} {...props}>\n {children}\n </span>\n );\n}\n\nconst CommentReactionButton = forwardRef<\n HTMLButtonElement,\n CommentReactionButtonProps\n>(({ reaction, overrides, className, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n return (\n <CustomButton\n className={classNames(\"lb-comment-reaction\", className)}\n variant=\"outline\"\n aria-label={$.COMMENT_REACTION_DESCRIPTION(\n reaction.emoji,\n reaction.users.length\n )}\n {...props}\n ref={forwardedRef}\n >\n <Emoji className=\"lb-comment-reaction-emoji\" emoji={reaction.emoji} />\n <span className=\"lb-comment-reaction-count\">{reaction.users.length}</span>\n </CustomButton>\n );\n});\n\nexport const CommentReaction = forwardRef<\n HTMLButtonElement,\n CommentReactionProps\n>(({ comment, reaction, overrides, disabled, ...props }, forwardedRef) => {\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n const $ = useOverrides(overrides);\n const tooltipContent = useMemo(\n () => (\n <span>\n {$.COMMENT_REACTION_LIST(\n <List\n values={reaction.users.map((users) => (\n <User key={users.id} userId={users.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={REACTIONS_TRUNCATE}\n locale={$.locale}\n />,\n reaction.emoji,\n reaction.users.length\n )}\n </span>\n ),\n [$, reaction]\n );\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handlePressedChange = useCallback(\n (isPressed: boolean) => {\n if (isPressed) {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n } else {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji: reaction.emoji,\n });\n }\n },\n [addReaction, comment.threadId, comment.id, reaction.emoji, removeReaction]\n );\n\n return (\n <Tooltip\n content={tooltipContent}\n multiline\n className=\"lb-comment-reaction-tooltip\"\n >\n <TogglePrimitive.Root\n asChild\n pressed={isActive}\n onPressedChange={handlePressedChange}\n onClick={stopPropagation}\n disabled={disabled}\n ref={forwardedRef}\n >\n <CommentReactionButton\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n />\n </TogglePrimitive.Root>\n </Tooltip>\n );\n});\n\nexport const CommentNonInteractiveReaction = forwardRef<\n HTMLButtonElement,\n CommentNonInteractiveReactionProps\n>(({ reaction, overrides, ...props }, forwardedRef) => {\n const currentId = useCurrentUserId();\n const isActive = useMemo(() => {\n return reaction.users.some((users) => users.id === currentId);\n }, [currentId, reaction]);\n\n return (\n <CommentReactionButton\n disableable={false}\n data-self={isActive ? \"\" : undefined}\n reaction={reaction}\n overrides={overrides}\n {...props}\n ref={forwardedRef}\n />\n );\n});\n\nfunction openAttachment({ attachment, url }: CommentAttachmentArgs) {\n // Open the attachment in a new tab if the attachment is a PDF,\n // an image, a video, or audio. Otherwise, download it.\n if (\n attachment.mimeType === \"application/pdf\" ||\n attachment.mimeType.startsWith(\"image/\") ||\n attachment.mimeType.startsWith(\"video/\") ||\n attachment.mimeType.startsWith(\"audio/\")\n ) {\n window.open(url, \"_blank\");\n } else {\n download(url, attachment.name);\n }\n}\n\nfunction CommentMediaAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <MediaAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nfunction CommentFileAttachment({\n attachment,\n onAttachmentClick,\n roomId,\n className,\n overrides,\n ...props\n}: CommentAttachmentProps & {\n roomId: string;\n}) {\n const { url } = useRoomAttachmentUrl(attachment.id, roomId);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n if (!url) {\n return;\n }\n\n const args: CommentAttachmentArgs = { attachment, url };\n\n onAttachmentClick?.(args, event);\n\n if (event.isDefaultPrevented()) {\n return;\n }\n\n openAttachment(args);\n },\n [attachment, onAttachmentClick, url]\n );\n\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n {...props}\n attachment={attachment}\n overrides={overrides}\n onClick={url ? handleClick : undefined}\n roomId={roomId}\n />\n );\n}\n\nexport function CommentNonInteractiveFileAttachment({\n className,\n ...props\n}: CommentAttachmentProps) {\n return (\n <FileAttachment\n className={classNames(\"lb-comment-attachment\", className)}\n allowMediaPreview={false}\n {...props}\n />\n );\n}\n\n// A void component (which doesn't render anything) responsible for marking a thread\n// as read when the comment it's used in becomes visible.\n// Moving this logic into a separate component allows us to use the visibility\n// and focus hooks \"conditionally\" by conditionally rendering this component.\nfunction AutoMarkReadThreadIdHandler({\n threadId,\n roomId,\n commentRef,\n}: {\n threadId: string;\n roomId: string;\n commentRef: RefObject<HTMLElement>;\n}) {\n const markThreadAsRead = useMarkRoomThreadAsRead(roomId);\n const isWindowFocused = useWindowFocus();\n\n useVisibleCallback(\n commentRef,\n () => {\n markThreadAsRead(threadId);\n },\n {\n // The underlying IntersectionObserver is only enabled when the window is focused\n enabled: isWindowFocused,\n }\n );\n\n return null;\n}\n\n/**\n * Displays a single comment.\n *\n * @example\n * <>\n * {thread.comments.map((comment) => (\n * <Comment key={comment.id} comment={comment} />\n * ))}\n * </>\n */\nexport const Comment = forwardRef<HTMLDivElement, CommentProps>(\n (\n {\n comment,\n indentContent = true,\n showDeleted,\n showActions = \"hover\",\n showReactions = true,\n showAttachments = true,\n showComposerFormattingControls = true,\n onAuthorClick,\n onMentionClick,\n onAttachmentClick,\n onCommentEdit,\n onCommentDelete,\n overrides,\n className,\n additionalActions,\n additionalActionsClassName,\n autoMarkReadThreadId,\n ...props\n },\n forwardedRef\n ) => {\n const ref = useRef<HTMLDivElement>(null);\n const mergedRefs = useRefs(forwardedRef, ref);\n const currentUserId = useCurrentUserId();\n const deleteComment = useDeleteRoomComment(comment.roomId);\n const editComment = useEditRoomComment(comment.roomId);\n const addReaction = useAddRoomCommentReaction(comment.roomId);\n const removeReaction = useRemoveRoomCommentReaction(comment.roomId);\n const $ = useOverrides(overrides);\n const [isEditing, setEditing] = useState(false);\n const [isTarget, setTarget] = useState(false);\n const [isMoreActionOpen, setMoreActionOpen] = useState(false);\n const [isReactionActionOpen, setReactionActionOpen] = useState(false);\n const { mediaAttachments, fileAttachments } = useMemo(() => {\n return separateMediaAttachments(comment.attachments);\n }, [comment.attachments]);\n\n const stopPropagation = useCallback((event: SyntheticEvent) => {\n event.stopPropagation();\n }, []);\n\n const handleEdit = useCallback(() => {\n setEditing(true);\n }, []);\n\n const handleEditCancel = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setEditing(false);\n },\n []\n );\n\n const handleEditSubmit = useCallback(\n (\n { body, attachments }: ComposerSubmitComment,\n event: FormEvent<HTMLFormElement>\n ) => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentEdit?.(comment);\n\n event.preventDefault();\n setEditing(false);\n editComment({\n commentId: comment.id,\n threadId: comment.threadId,\n body,\n attachments,\n });\n },\n [comment, editComment, onCommentEdit]\n );\n\n const handleDelete = useCallback(() => {\n // TODO: Add a way to preventDefault from within this callback, to override the default behavior (e.g. showing a confirmation dialog)\n onCommentDelete?.(comment);\n\n deleteComment({\n commentId: comment.id,\n threadId: comment.threadId,\n });\n }, [comment, deleteComment, onCommentDelete]);\n\n const handleAuthorClick = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n onAuthorClick?.(comment.userId, event);\n },\n [comment.userId, onAuthorClick]\n );\n\n const handleReactionSelect = useCallback(\n (emoji: string) => {\n const reactionIndex = comment.reactions.findIndex(\n (reaction) => reaction.emoji === emoji\n );\n\n if (\n reactionIndex >= 0 &&\n currentUserId &&\n comment.reactions[reactionIndex]?.users.some(\n (user) => user.id === currentUserId\n )\n ) {\n removeReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n } else {\n addReaction({\n threadId: comment.threadId,\n commentId: comment.id,\n emoji,\n });\n }\n },\n [\n addReaction,\n comment.id,\n comment.reactions,\n comment.threadId,\n removeReaction,\n currentUserId,\n ]\n );\n\n useEffect(() => {\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n if (commentId === comment.id) {\n setTarget(true);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!showDeleted && !comment.body) {\n return null;\n }\n\n return (\n <TooltipProvider>\n {autoMarkReadThreadId && (\n <AutoMarkReadThreadIdHandler\n commentRef={ref}\n threadId={autoMarkReadThreadId}\n roomId={comment.roomId}\n />\n )}\n <div\n id={comment.id}\n className={classNames(\n \"lb-root lb-comment\",\n indentContent && \"lb-comment:indent-content\",\n showActions === \"hover\" && \"lb-comment:show-actions-hover\",\n (isMoreActionOpen || isReactionActionOpen) &&\n \"lb-comment:action-open\",\n className\n )}\n data-deleted={!comment.body ? \"\" : undefined}\n data-editing={isEditing ? \"\" : undefined}\n // In some cases, `:target` doesn't work as expected so we also define it manually.\n data-target={isTarget ? \"\" : undefined}\n dir={$.dir}\n {...props}\n ref={mergedRefs}\n >\n <div className=\"lb-comment-header\">\n <div className=\"lb-comment-details\">\n <Avatar\n className=\"lb-comment-avatar\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-details-labels\">\n <User\n className=\"lb-comment-author\"\n userId={comment.userId}\n onClick={handleAuthorClick}\n />\n <span className=\"lb-comment-date\">\n <Timestamp\n locale={$.locale}\n date={comment.createdAt}\n className=\"lb-date lb-comment-date-created\"\n />\n {comment.editedAt && comment.body && (\n <>\n {\" \"}\n <span className=\"lb-comment-date-edited\">\n {$.COMMENT_EDITED}\n </span>\n </>\n )}\n </span>\n </span>\n </div>\n {showActions && !isEditing && (\n <div\n className={classNames(\n \"lb-comment-actions\",\n additionalActionsClassName\n )}\n >\n {additionalActions ?? null}\n {showReactions && (\n <EmojiPicker\n onEmojiSelect={handleReactionSelect}\n onOpenChange={setReactionActionOpen}\n >\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiPlusIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n )}\n {comment.userId === currentUserId && (\n <Dropdown\n open={isMoreActionOpen}\n onOpenChange={setMoreActionOpen}\n align=\"end\"\n content={\n <>\n <DropdownItem\n onSelect={handleEdit}\n onClick={stopPropagation}\n icon={<EditIcon />}\n >\n {$.COMMENT_EDIT}\n </DropdownItem>\n <DropdownItem\n onSelect={handleDelete}\n onClick={stopPropagation}\n icon={<DeleteIcon />}\n >\n {$.COMMENT_DELETE}\n </DropdownItem>\n </>\n }\n >\n <Tooltip content={$.COMMENT_MORE}>\n <DropdownTrigger asChild>\n <Button\n className=\"lb-comment-action\"\n disabled={!comment.body}\n onClick={stopPropagation}\n aria-label={$.COMMENT_MORE}\n icon={<EllipsisIcon />}\n />\n </DropdownTrigger>\n </Tooltip>\n </Dropdown>\n )}\n </div>\n )}\n </div>\n <div className=\"lb-comment-content\">\n {isEditing ? (\n <Composer\n className=\"lb-comment-composer\"\n onComposerSubmit={handleEditSubmit}\n defaultValue={comment.body}\n defaultAttachments={comment.attachments}\n autoFocus\n showAttribution={false}\n showAttachments={showAttachments}\n showFormattingControls={showComposerFormattingControls}\n actions={\n <>\n <Tooltip\n content={$.COMMENT_EDIT_COMPOSER_CANCEL}\n aria-label={$.COMMENT_EDIT_COMPOSER_CANCEL}\n >\n <Button\n className=\"lb-composer-action\"\n onClick={handleEditCancel}\n icon={<CrossIcon />}\n />\n </Tooltip>\n <ShortcutTooltip\n content={$.COMMENT_EDIT_COMPOSER_SAVE}\n shortcut=\"Enter\"\n >\n <ComposerPrimitive.Submit asChild>\n <Button\n variant=\"primary\"\n className=\"lb-composer-action\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_EDIT_COMPOSER_SAVE}\n icon={<CheckIcon />}\n />\n </ComposerPrimitive.Submit>\n </ShortcutTooltip>\n </>\n }\n overrides={{\n COMPOSER_PLACEHOLDER: $.COMMENT_EDIT_COMPOSER_PLACEHOLDER,\n }}\n roomId={comment.roomId}\n />\n ) : comment.body ? (\n <>\n <CommentPrimitive.Body\n className=\"lb-comment-body\"\n body={comment.body}\n components={{\n Mention: ({ userId }) => (\n <CommentMention\n userId={userId}\n onClick={(event) => onMentionClick?.(userId, event)}\n />\n ),\n Link: CommentLink,\n }}\n />\n {showAttachments &&\n (mediaAttachments.length > 0 || fileAttachments.length > 0) ? (\n <div className=\"lb-comment-attachments\">\n {mediaAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {mediaAttachments.map((attachment) => (\n <CommentMediaAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n {fileAttachments.length > 0 ? (\n <div className=\"lb-attachments\">\n {fileAttachments.map((attachment) => (\n <CommentFileAttachment\n key={attachment.id}\n attachment={attachment}\n overrides={overrides}\n onAttachmentClick={onAttachmentClick}\n roomId={comment.roomId}\n />\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n {showReactions && comment.reactions.length > 0 && (\n <div className=\"lb-comment-reactions\">\n {comment.reactions.map((reaction) => (\n <CommentReaction\n key={reaction.emoji}\n comment={comment}\n reaction={reaction}\n overrides={overrides}\n />\n ))}\n <EmojiPicker onEmojiSelect={handleReactionSelect}>\n <Tooltip content={$.COMMENT_ADD_REACTION}>\n <EmojiPickerTrigger asChild>\n <Button\n className=\"lb-comment-reaction lb-comment-reaction-add\"\n variant=\"outline\"\n onClick={stopPropagation}\n aria-label={$.COMMENT_ADD_REACTION}\n icon={<EmojiPlusIcon />}\n />\n </EmojiPickerTrigger>\n </Tooltip>\n </EmojiPicker>\n </div>\n )}\n </>\n ) : (\n <div className=\"lb-comment-body\">\n <p className=\"lb-comment-deleted\">{$.COMMENT_DELETED}</p>\n </div>\n )}\n </div>\n </div>\n </TooltipProvider>\n );\n }\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA;AA0GO;AAAwB;AAC7B;AACA;AAEF;AACE;AACA;AACG;AACsD;AACd;AACnC;AAEH;AAAA;AACA;AAAK;AAAgB;AAAA;AAG5B;AAEO;AAAqB;AAC1B;AACA;AACA;AAEF;AACE;AACG;AACmD;AAClD;AACI;AAEH;AAGP;AAEO;AAAmC;AAClC;AACN;AACA;AAEF;AACE;AACG;AAAuD;AAAO;AAC5D;AAGP;AAEA;AAIE;AACA;AACG;AACuD;AAC9C;AACM;AACH;AACM;AACjB;AACI;AACC;AAEL;AAAC;AAAgB;AAA4C;AAAO;AACnE;AAAe;AAA4C;AAAO;AAAA;AAGzE;AAEa;AAIX;AACA;AACA;AACA;AACE;AAA4D;AAE9D;AACA;AAAuB;AAElB;AACI;AACA;AAEI;AAAkC;AAAe;AACnD;AACkB;AACT;AACA;AACZ;AACS;AACM;AACjB;AACF;AAEU;AAGd;AACE;AAAsB;AAGxB;AAA4B;AAExB;AACE;AAAY;AACQ;AACC;AACH;AACjB;AAED;AAAe;AACK;AACC;AACH;AACjB;AACH;AACF;AAC0E;AAG5E;AACG;AACU;AACA;AACC;AAET;AACQ;AACE;AACQ;AACR;AACT;AACK;AAEJ;AAC4B;AAC3B;AACA;AACI;AACN;AACF;AAGN;AAEa;AAIX;AACA;AACE;AAA4D;AAG9D;AACG;AACc;AACc;AAC3B;AACA;AACI;AACC;AAGX;AAEA;AAGE;AAME;AAAyB;AAEzB;AAA6B;AAEjC;AAEA;AAAgC;AAC9B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEA;AAA+B;AAC7B;AACA;AACA;AACA;AACA;AAEF;AAGE;AAEA;AAAoB;AAEhB;AACE;AAAA;AAGF;AAEA;AAEA;AACE;AAAA;AAGF;AAAmB;AACrB;AACmC;AAGrC;AACG;AACyD;AACpD;AACJ;AACA;AAC6B;AAC7B;AAGN;AAEO;AAA6C;AAClD;AAEF;AACE;AACG;AACyD;AACrC;AACf;AAGV;AAMA;AAAqC;AACnC;AACA;AAEF;AAKE;AACA;AAEA;AAAA;AACE;AAEE;AAAyB;AAC3B;AACA;AAEW;AACX;AAGF;AACF;AAYO;AAAgB;AAEnB;AACE;AACgB;AAChB;AACc;AACE;AACE;AACe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACG;AAIL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE;AAAmD;AAGrD;AACE;AAAsB;AAGxB;AACE;AAAe;AAGjB;AAAyB;AAErB;AACA;AAAgB;AAClB;AACC;AAGH;AAAyB;AAMrB;AAEA;AACA;AACA;AAAY;AACS;AACD;AAClB;AACA;AACD;AACH;AACoC;AAGtC;AAEE;AAEA;AAAc;AACO;AACD;AACnB;AAGH;AAA0B;AAEtB;AAAqC;AACvC;AAC8B;AAGhC;AAA6B;AAEzB;AAAwC;AACL;AAGnC;AAG0C;AAChB;AAGxB;AAAe;AACK;AACC;AACnB;AACD;AAED;AAAY;AACQ;AACC;AACnB;AACD;AACH;AACF;AACA;AACE;AACQ;AACA;AACA;AACR;AACA;AACF;AAGF;AACE;AACA;AAAsB;AAEtB;AACA;AAEA;AACE;AAAc;AAChB;AAGF;AACE;AAAO;AAGT;AACG;AACE;AACE;AACa;AACF;AACM;AAClB;AAED;AACa;AACD;AACT;AACiB;AACU;AAEzB;AACF;AACF;AACmC;AACJ;AAEF;AACtB;AACH;AACC;AAEL;AAAC;AAAc;AACb;AAAC;AAAc;AACb;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACM;AACP;AACX;AACC;AAAe;AACd;AAAC;AACW;AACI;AACJ;AACZ;AAEE;AACG;AAAA;AACA;AAAe;AACX;AACL;AAAA;AACF;AAAA;AAEJ;AAAA;AACF;AAAA;AACF;AAEG;AACY;AACT;AACA;AACF;AAEC;AAAqB;AAEnB;AACgB;AACD;AAEb;AAAmB;AACjB;AAA0B;AACxB;AACW;AACD;AACK;AACO;AACvB;AACF;AACF;AACF;AAGC;AACO;AACQ;AACR;AAEJ;AACE;AAAC;AACW;AACD;AACO;AAEb;AACL;AACC;AACW;AACD;AACS;AAEf;AACL;AAAA;AACF;AAGD;AAAmB;AACjB;AAAuB;AACrB;AACW;AACS;AACV;AACK;AACM;AACtB;AACF;AACF;AACF;AAAA;AAEJ;AAAA;AAEJ;AACC;AAAc;AAEV;AACW;AACQ;AACI;AACM;AACnB;AACQ;AACjB;AACwB;AAEtB;AACE;AAAC;AACY;AACG;AAEb;AACW;AACD;AACQ;AACnB;AACF;AACC;AACY;AACF;AAER;AAAgC;AAC9B;AACS;AACE;AACD;AACK;AACG;AACnB;AACF;AACF;AAAA;AACF;AAES;AACe;AAC1B;AACgB;AAGlB;AACE;AAAC;AACW;AACI;AACF;AAEP;AACC;AACkD;AACpD;AAEI;AACR;AACF;AAGG;AAAc;AACZ;AACE;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAED;AAAc;AAEV;AAEC;AACA;AACA;AACgB;AAEnB;AAED;AAAA;AAEJ;AAED;AAAc;AACZ;AACE;AAEC;AACA;AACA;AAEH;AACA;AAA2B;AACzB;AAAmB;AACjB;AAA0B;AACxB;AACW;AACF;AACC;AACK;AACO;AACvB;AACF;AACF;AACF;AAAA;AACF;AAAA;AAIH;AAAc;AACZ;AAAY;AAAwB;AAAgB;AACvD;AAEJ;AAAA;AACF;AAAA;AACF;AAGN;;"}
|
package/dist/icon.cjs
CHANGED
|
@@ -3,15 +3,22 @@
|
|
|
3
3
|
require('./icons/index.cjs');
|
|
4
4
|
var ArrowCornerDownRight = require('./icons/ArrowCornerDownRight.cjs');
|
|
5
5
|
var ArrowCornerUpRight = require('./icons/ArrowCornerUpRight.cjs');
|
|
6
|
+
var ArrowDown = require('./icons/ArrowDown.cjs');
|
|
7
|
+
var ArrowUp = require('./icons/ArrowUp.cjs');
|
|
6
8
|
var Attachment = require('./icons/Attachment.cjs');
|
|
7
9
|
var Blockquote = require('./icons/Blockquote.cjs');
|
|
8
10
|
var Bold = require('./icons/Bold.cjs');
|
|
9
11
|
var Check = require('./icons/Check.cjs');
|
|
12
|
+
var ChevronDown = require('./icons/ChevronDown.cjs');
|
|
13
|
+
var ChevronLeft = require('./icons/ChevronLeft.cjs');
|
|
14
|
+
var ChevronRight = require('./icons/ChevronRight.cjs');
|
|
15
|
+
var ChevronUp = require('./icons/ChevronUp.cjs');
|
|
10
16
|
var Code = require('./icons/Code.cjs');
|
|
11
17
|
var Comment = require('./icons/Comment.cjs');
|
|
12
18
|
var Cross = require('./icons/Cross.cjs');
|
|
13
19
|
var Ellipsis = require('./icons/Ellipsis.cjs');
|
|
14
20
|
var Emoji = require('./icons/Emoji.cjs');
|
|
21
|
+
var EmojiPlus = require('./icons/EmojiPlus.cjs');
|
|
15
22
|
var H1 = require('./icons/H1.cjs');
|
|
16
23
|
var H2 = require('./icons/H2.cjs');
|
|
17
24
|
var H3 = require('./icons/H3.cjs');
|
|
@@ -22,6 +29,7 @@ var ListUnordered = require('./icons/ListUnordered.cjs');
|
|
|
22
29
|
var Mention = require('./icons/Mention.cjs');
|
|
23
30
|
var QuestionMark = require('./icons/QuestionMark.cjs');
|
|
24
31
|
var Redo = require('./icons/Redo.cjs');
|
|
32
|
+
var Search = require('./icons/Search.cjs');
|
|
25
33
|
var Send = require('./icons/Send.cjs');
|
|
26
34
|
var Shorten = require('./icons/Shorten.cjs');
|
|
27
35
|
var Sparkles = require('./icons/Sparkles.cjs');
|
|
@@ -37,15 +45,22 @@ var Warning = require('./icons/Warning.cjs');
|
|
|
37
45
|
|
|
38
46
|
exports.ArrowCornerDownRight = ArrowCornerDownRight.ArrowCornerDownRightIcon;
|
|
39
47
|
exports.ArrowCornerUpRight = ArrowCornerUpRight.ArrowCornerUpRightIcon;
|
|
48
|
+
exports.ArrowDown = ArrowDown.ArrowDownIcon;
|
|
49
|
+
exports.ArrowUp = ArrowUp.ArrowUpIcon;
|
|
40
50
|
exports.Attachment = Attachment.AttachmentIcon;
|
|
41
51
|
exports.Blockquote = Blockquote.BlockquoteIcon;
|
|
42
52
|
exports.Bold = Bold.BoldIcon;
|
|
43
53
|
exports.Check = Check.CheckIcon;
|
|
54
|
+
exports.ChevronDown = ChevronDown.ChevronDownIcon;
|
|
55
|
+
exports.ChevronLeft = ChevronLeft.ChevronLeftIcon;
|
|
56
|
+
exports.ChevronRight = ChevronRight.ChevronRightIcon;
|
|
57
|
+
exports.ChevronUp = ChevronUp.ChevronUpIcon;
|
|
44
58
|
exports.Code = Code.CodeIcon;
|
|
45
59
|
exports.Comment = Comment.CommentIcon;
|
|
46
60
|
exports.Cross = Cross.CrossIcon;
|
|
47
61
|
exports.Ellipsis = Ellipsis.EllipsisIcon;
|
|
48
62
|
exports.Emoji = Emoji.EmojiIcon;
|
|
63
|
+
exports.EmojiPlus = EmojiPlus.EmojiPlusIcon;
|
|
49
64
|
exports.H1 = H1.H1Icon;
|
|
50
65
|
exports.H2 = H2.H2Icon;
|
|
51
66
|
exports.H3 = H3.H3Icon;
|
|
@@ -56,6 +71,7 @@ exports.ListUnordered = ListUnordered.ListUnorderedIcon;
|
|
|
56
71
|
exports.Mention = Mention.MentionIcon;
|
|
57
72
|
exports.QuestionMark = QuestionMark.QuestionMarkIcon;
|
|
58
73
|
exports.Redo = Redo.RedoIcon;
|
|
74
|
+
exports.Search = Search.SearchIcon;
|
|
59
75
|
exports.Send = Send.SendIcon;
|
|
60
76
|
exports.Shorten = Shorten.ShortenIcon;
|
|
61
77
|
exports.Sparkles = Sparkles.SparklesIcon;
|
package/dist/icon.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"icon.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/icon.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import './icons/index.js';
|
|
2
2
|
export { ArrowCornerDownRightIcon as ArrowCornerDownRight } from './icons/ArrowCornerDownRight.js';
|
|
3
3
|
export { ArrowCornerUpRightIcon as ArrowCornerUpRight } from './icons/ArrowCornerUpRight.js';
|
|
4
|
+
export { ArrowDownIcon as ArrowDown } from './icons/ArrowDown.js';
|
|
5
|
+
export { ArrowUpIcon as ArrowUp } from './icons/ArrowUp.js';
|
|
4
6
|
export { AttachmentIcon as Attachment } from './icons/Attachment.js';
|
|
5
7
|
export { BlockquoteIcon as Blockquote } from './icons/Blockquote.js';
|
|
6
8
|
export { BoldIcon as Bold } from './icons/Bold.js';
|
|
7
9
|
export { CheckIcon as Check } from './icons/Check.js';
|
|
10
|
+
export { ChevronDownIcon as ChevronDown } from './icons/ChevronDown.js';
|
|
11
|
+
export { ChevronLeftIcon as ChevronLeft } from './icons/ChevronLeft.js';
|
|
12
|
+
export { ChevronRightIcon as ChevronRight } from './icons/ChevronRight.js';
|
|
13
|
+
export { ChevronUpIcon as ChevronUp } from './icons/ChevronUp.js';
|
|
8
14
|
export { CodeIcon as Code } from './icons/Code.js';
|
|
9
15
|
export { CommentIcon as Comment } from './icons/Comment.js';
|
|
10
16
|
export { CrossIcon as Cross } from './icons/Cross.js';
|
|
11
17
|
export { EllipsisIcon as Ellipsis } from './icons/Ellipsis.js';
|
|
12
18
|
export { EmojiIcon as Emoji } from './icons/Emoji.js';
|
|
19
|
+
export { EmojiPlusIcon as EmojiPlus } from './icons/EmojiPlus.js';
|
|
13
20
|
export { H1Icon as H1 } from './icons/H1.js';
|
|
14
21
|
export { H2Icon as H2 } from './icons/H2.js';
|
|
15
22
|
export { H3Icon as H3 } from './icons/H3.js';
|
|
@@ -20,6 +27,7 @@ export { ListUnorderedIcon as ListUnordered } from './icons/ListUnordered.js';
|
|
|
20
27
|
export { MentionIcon as Mention } from './icons/Mention.js';
|
|
21
28
|
export { QuestionMarkIcon as QuestionMark } from './icons/QuestionMark.js';
|
|
22
29
|
export { RedoIcon as Redo } from './icons/Redo.js';
|
|
30
|
+
export { SearchIcon as Search } from './icons/Search.js';
|
|
23
31
|
export { SendIcon as Send } from './icons/Send.js';
|
|
24
32
|
export { ShortenIcon as Shorten } from './icons/Shorten.js';
|
|
25
33
|
export { SparklesIcon as Sparkles } from './icons/Sparkles.js';
|
package/dist/icon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"icon.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var Icon = require('../components/internal/Icon.cjs');
|
|
5
5
|
|
|
6
|
-
function
|
|
6
|
+
function EmojiPlusIcon(props) {
|
|
7
7
|
return /* @__PURE__ */ jsxRuntime.jsxs(Icon.Icon, {
|
|
8
8
|
...props,
|
|
9
9
|
children: [
|
|
@@ -33,5 +33,5 @@ function EmojiAddIcon(props) {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
exports.
|
|
37
|
-
//# sourceMappingURL=
|
|
36
|
+
exports.EmojiPlusIcon = EmojiPlusIcon;
|
|
37
|
+
//# sourceMappingURL=EmojiPlus.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmojiPlus.cjs","sources":["../../src/icons/EmojiPlus.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function EmojiPlusIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M11 3.07A7 7 0 1 0 16.93 9\" />\n <path d=\"M7.5 11.5S8.25 13 10 13s2.5-1.5 2.5-1.5M8 8h0\" />\n <path d=\"M12 8h0\" />\n <path d=\"M13 5h4m-2-2v4\" />\n <circle cx=\"8\" cy=\"8\" r=\".25\" />\n <circle cx=\"12\" cy=\"8\" r=\".25\" />\n </Icon>\n );\n}\n"],"names":["jsxs","Icon","jsx"],"mappings":";;;;;AAIO,SAAS,cAAc,KAA8B,EAAA;AAC1D,EAAA,uBACGA,eAAA,CAAAC,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAACC,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,4BAAA;AAAA,OAA6B,CAAA;AAAA,sBACpCA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,+CAAA;AAAA,OAAgD,CAAA;AAAA,sBACvDA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,SAAA;AAAA,OAAU,CAAA;AAAA,sBACjBA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,gBAAA;AAAA,OAAiB,CAAA;AAAA,sBACxBA,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,GAAA;AAAA,QAAI,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,sBAC7BA,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,IAAA;AAAA,QAAK,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,KAAA;AAAA,GACjC,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Icon } from '../components/internal/Icon.js';
|
|
3
3
|
|
|
4
|
-
function
|
|
4
|
+
function EmojiPlusIcon(props) {
|
|
5
5
|
return /* @__PURE__ */ jsxs(Icon, {
|
|
6
6
|
...props,
|
|
7
7
|
children: [
|
|
@@ -31,5 +31,5 @@ function EmojiAddIcon(props) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export {
|
|
35
|
-
//# sourceMappingURL=
|
|
34
|
+
export { EmojiPlusIcon };
|
|
35
|
+
//# sourceMappingURL=EmojiPlus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmojiPlus.js","sources":["../../src/icons/EmojiPlus.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function EmojiPlusIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M11 3.07A7 7 0 1 0 16.93 9\" />\n <path d=\"M7.5 11.5S8.25 13 10 13s2.5-1.5 2.5-1.5M8 8h0\" />\n <path d=\"M12 8h0\" />\n <path d=\"M13 5h4m-2-2v4\" />\n <circle cx=\"8\" cy=\"8\" r=\".25\" />\n <circle cx=\"12\" cy=\"8\" r=\".25\" />\n </Icon>\n );\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,cAAc,KAA8B,EAAA;AAC1D,EAAA,uBACG,IAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,4BAAA;AAAA,OAA6B,CAAA;AAAA,sBACpC,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,+CAAA;AAAA,OAAgD,CAAA;AAAA,sBACvD,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,SAAA;AAAA,OAAU,CAAA;AAAA,sBACjB,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,gBAAA;AAAA,OAAiB,CAAA;AAAA,sBACxB,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,GAAA;AAAA,QAAI,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,sBAC7B,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,IAAA;AAAA,QAAK,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,KAAA;AAAA,GACjC,CAAA,CAAA;AAEJ;;;;"}
|
package/dist/icons/index.cjs
CHANGED
|
@@ -19,7 +19,7 @@ var Delete = require('./Delete.cjs');
|
|
|
19
19
|
var Edit = require('./Edit.cjs');
|
|
20
20
|
var Ellipsis = require('./Ellipsis.cjs');
|
|
21
21
|
var Emoji = require('./Emoji.cjs');
|
|
22
|
-
var
|
|
22
|
+
var EmojiPlus = require('./EmojiPlus.cjs');
|
|
23
23
|
var H1 = require('./H1.cjs');
|
|
24
24
|
var H2 = require('./H2.cjs');
|
|
25
25
|
var H3 = require('./H3.cjs');
|
|
@@ -67,7 +67,7 @@ exports.DeleteIcon = Delete.DeleteIcon;
|
|
|
67
67
|
exports.EditIcon = Edit.EditIcon;
|
|
68
68
|
exports.EllipsisIcon = Ellipsis.EllipsisIcon;
|
|
69
69
|
exports.EmojiIcon = Emoji.EmojiIcon;
|
|
70
|
-
exports.
|
|
70
|
+
exports.EmojiPlusIcon = EmojiPlus.EmojiPlusIcon;
|
|
71
71
|
exports.H1Icon = H1.H1Icon;
|
|
72
72
|
exports.H2Icon = H2.H2Icon;
|
|
73
73
|
exports.H3Icon = H3.H3Icon;
|
package/dist/icons/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export { DeleteIcon } from './Delete.js';
|
|
|
17
17
|
export { EditIcon } from './Edit.js';
|
|
18
18
|
export { EllipsisIcon } from './Ellipsis.js';
|
|
19
19
|
export { EmojiIcon } from './Emoji.js';
|
|
20
|
-
export {
|
|
20
|
+
export { EmojiPlusIcon } from './EmojiPlus.js';
|
|
21
21
|
export { H1Icon } from './H1.js';
|
|
22
22
|
export { H2Icon } from './H2.js';
|
|
23
23
|
export { H3Icon } from './H3.js';
|
package/dist/index.d.cts
CHANGED
|
@@ -669,6 +669,10 @@ declare function ArrowCornerDownRightIcon(props: ComponentProps<"svg">): react_j
|
|
|
669
669
|
|
|
670
670
|
declare function ArrowCornerUpRightIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
671
671
|
|
|
672
|
+
declare function ArrowDownIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
673
|
+
|
|
674
|
+
declare function ArrowUpIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
675
|
+
|
|
672
676
|
declare function AttachmentIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
673
677
|
|
|
674
678
|
declare function BlockquoteIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -677,6 +681,14 @@ declare function BoldIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.E
|
|
|
677
681
|
|
|
678
682
|
declare function CheckIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
679
683
|
|
|
684
|
+
declare function ChevronDownIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
685
|
+
|
|
686
|
+
declare function ChevronLeftIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
687
|
+
|
|
688
|
+
declare function ChevronRightIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
689
|
+
|
|
690
|
+
declare function ChevronUpIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
691
|
+
|
|
680
692
|
declare function CodeIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
681
693
|
|
|
682
694
|
declare function CommentIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -687,6 +699,8 @@ declare function EllipsisIcon(props: ComponentProps<"svg">): react_jsx_runtime.J
|
|
|
687
699
|
|
|
688
700
|
declare function EmojiIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
689
701
|
|
|
702
|
+
declare function EmojiPlusIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
703
|
+
|
|
690
704
|
declare function H1Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
691
705
|
|
|
692
706
|
declare function H2Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -707,6 +721,8 @@ declare function QuestionMarkIcon(props: ComponentProps<"svg">): react_jsx_runti
|
|
|
707
721
|
|
|
708
722
|
declare function RedoIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
709
723
|
|
|
724
|
+
declare function SearchIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
725
|
+
|
|
710
726
|
declare function SendIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
711
727
|
|
|
712
728
|
declare function ShortenIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -731,15 +747,22 @@ declare namespace icon {
|
|
|
731
747
|
export {
|
|
732
748
|
ArrowCornerDownRightIcon as ArrowCornerDownRight,
|
|
733
749
|
ArrowCornerUpRightIcon as ArrowCornerUpRight,
|
|
750
|
+
ArrowDownIcon as ArrowDown,
|
|
751
|
+
ArrowUpIcon as ArrowUp,
|
|
734
752
|
AttachmentIcon as Attachment,
|
|
735
753
|
BlockquoteIcon as Blockquote,
|
|
736
754
|
BoldIcon as Bold,
|
|
737
755
|
CheckIcon as Check,
|
|
756
|
+
ChevronDownIcon as ChevronDown,
|
|
757
|
+
ChevronLeftIcon as ChevronLeft,
|
|
758
|
+
ChevronRightIcon as ChevronRight,
|
|
759
|
+
ChevronUpIcon as ChevronUp,
|
|
738
760
|
CodeIcon as Code,
|
|
739
761
|
CommentIcon as Comment,
|
|
740
762
|
CrossIcon as Cross,
|
|
741
763
|
EllipsisIcon as Ellipsis,
|
|
742
764
|
EmojiIcon as Emoji,
|
|
765
|
+
EmojiPlusIcon as EmojiPlus,
|
|
743
766
|
H1Icon as H1,
|
|
744
767
|
H2Icon as H2,
|
|
745
768
|
H3Icon as H3,
|
|
@@ -750,6 +773,7 @@ declare namespace icon {
|
|
|
750
773
|
MentionIcon as Mention,
|
|
751
774
|
QuestionMarkIcon as QuestionMark,
|
|
752
775
|
RedoIcon as Redo,
|
|
776
|
+
SearchIcon as Search,
|
|
753
777
|
SendIcon as Send,
|
|
754
778
|
ShortenIcon as Shorten,
|
|
755
779
|
SparklesIcon as Sparkles,
|
package/dist/index.d.ts
CHANGED
|
@@ -669,6 +669,10 @@ declare function ArrowCornerDownRightIcon(props: ComponentProps<"svg">): react_j
|
|
|
669
669
|
|
|
670
670
|
declare function ArrowCornerUpRightIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
671
671
|
|
|
672
|
+
declare function ArrowDownIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
673
|
+
|
|
674
|
+
declare function ArrowUpIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
675
|
+
|
|
672
676
|
declare function AttachmentIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
673
677
|
|
|
674
678
|
declare function BlockquoteIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -677,6 +681,14 @@ declare function BoldIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.E
|
|
|
677
681
|
|
|
678
682
|
declare function CheckIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
679
683
|
|
|
684
|
+
declare function ChevronDownIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
685
|
+
|
|
686
|
+
declare function ChevronLeftIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
687
|
+
|
|
688
|
+
declare function ChevronRightIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
689
|
+
|
|
690
|
+
declare function ChevronUpIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
691
|
+
|
|
680
692
|
declare function CodeIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
681
693
|
|
|
682
694
|
declare function CommentIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -687,6 +699,8 @@ declare function EllipsisIcon(props: ComponentProps<"svg">): react_jsx_runtime.J
|
|
|
687
699
|
|
|
688
700
|
declare function EmojiIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
689
701
|
|
|
702
|
+
declare function EmojiPlusIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
703
|
+
|
|
690
704
|
declare function H1Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
691
705
|
|
|
692
706
|
declare function H2Icon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -707,6 +721,8 @@ declare function QuestionMarkIcon(props: ComponentProps<"svg">): react_jsx_runti
|
|
|
707
721
|
|
|
708
722
|
declare function RedoIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
709
723
|
|
|
724
|
+
declare function SearchIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
725
|
+
|
|
710
726
|
declare function SendIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
711
727
|
|
|
712
728
|
declare function ShortenIcon(props: ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
|
|
@@ -731,15 +747,22 @@ declare namespace icon {
|
|
|
731
747
|
export {
|
|
732
748
|
ArrowCornerDownRightIcon as ArrowCornerDownRight,
|
|
733
749
|
ArrowCornerUpRightIcon as ArrowCornerUpRight,
|
|
750
|
+
ArrowDownIcon as ArrowDown,
|
|
751
|
+
ArrowUpIcon as ArrowUp,
|
|
734
752
|
AttachmentIcon as Attachment,
|
|
735
753
|
BlockquoteIcon as Blockquote,
|
|
736
754
|
BoldIcon as Bold,
|
|
737
755
|
CheckIcon as Check,
|
|
756
|
+
ChevronDownIcon as ChevronDown,
|
|
757
|
+
ChevronLeftIcon as ChevronLeft,
|
|
758
|
+
ChevronRightIcon as ChevronRight,
|
|
759
|
+
ChevronUpIcon as ChevronUp,
|
|
738
760
|
CodeIcon as Code,
|
|
739
761
|
CommentIcon as Comment,
|
|
740
762
|
CrossIcon as Cross,
|
|
741
763
|
EllipsisIcon as Ellipsis,
|
|
742
764
|
EmojiIcon as Emoji,
|
|
765
|
+
EmojiPlusIcon as EmojiPlus,
|
|
743
766
|
H1Icon as H1,
|
|
744
767
|
H2Icon as H2,
|
|
745
768
|
H3Icon as H3,
|
|
@@ -750,6 +773,7 @@ declare namespace icon {
|
|
|
750
773
|
MentionIcon as Mention,
|
|
751
774
|
QuestionMarkIcon as QuestionMark,
|
|
752
775
|
RedoIcon as Redo,
|
|
776
|
+
SearchIcon as Search,
|
|
753
777
|
SendIcon as Send,
|
|
754
778
|
ShortenIcon as Shorten,
|
|
755
779
|
SparklesIcon as Sparkles,
|
package/dist/version.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PKG_NAME = "@liveblocks/react-ui";
|
|
4
|
-
const PKG_VERSION = typeof "2.
|
|
4
|
+
const PKG_VERSION = typeof "2.22.1" === "string" && "2.22.1";
|
|
5
5
|
const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
|
|
6
6
|
|
|
7
7
|
exports.PKG_FORMAT = PKG_FORMAT;
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const PKG_NAME = "@liveblocks/react-ui";
|
|
2
|
-
const PKG_VERSION = typeof "2.
|
|
2
|
+
const PKG_VERSION = typeof "2.22.1" === "string" && "2.22.1";
|
|
3
3
|
const PKG_FORMAT = typeof "esm" === "string" && "esm";
|
|
4
4
|
|
|
5
5
|
export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.1",
|
|
4
4
|
"description": "A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@floating-ui/react-dom": "^2.1.2",
|
|
79
|
-
"@liveblocks/client": "2.
|
|
80
|
-
"@liveblocks/core": "2.
|
|
81
|
-
"@liveblocks/react": "2.
|
|
79
|
+
"@liveblocks/client": "2.22.1",
|
|
80
|
+
"@liveblocks/core": "2.22.1",
|
|
81
|
+
"@liveblocks/react": "2.22.1",
|
|
82
82
|
"@radix-ui/react-dropdown-menu": "^2.1.2",
|
|
83
83
|
"@radix-ui/react-popover": "^1.1.2",
|
|
84
84
|
"@radix-ui/react-slot": "^1.1.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EmojiAdd.cjs","sources":["../../src/icons/EmojiAdd.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function EmojiAddIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M11 3.07A7 7 0 1 0 16.93 9\" />\n <path d=\"M7.5 11.5S8.25 13 10 13s2.5-1.5 2.5-1.5M8 8h0\" />\n <path d=\"M12 8h0\" />\n <path d=\"M13 5h4m-2-2v4\" />\n <circle cx=\"8\" cy=\"8\" r=\".25\" />\n <circle cx=\"12\" cy=\"8\" r=\".25\" />\n </Icon>\n );\n}\n"],"names":["jsxs","Icon","jsx"],"mappings":";;;;;AAIO,SAAS,aAAa,KAA8B,EAAA;AACzD,EAAA,uBACGA,eAAA,CAAAC,SAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAACC,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,4BAAA;AAAA,OAA6B,CAAA;AAAA,sBACpCA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,+CAAA;AAAA,OAAgD,CAAA;AAAA,sBACvDA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,SAAA;AAAA,OAAU,CAAA;AAAA,sBACjBA,cAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,gBAAA;AAAA,OAAiB,CAAA;AAAA,sBACxBA,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,GAAA;AAAA,QAAI,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,sBAC7BA,cAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,IAAA;AAAA,QAAK,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,KAAA;AAAA,GACjC,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EmojiAdd.js","sources":["../../src/icons/EmojiAdd.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\n\nimport { Icon } from \"../components/internal/Icon\";\n\nexport function EmojiAddIcon(props: ComponentProps<\"svg\">) {\n return (\n <Icon {...props}>\n <path d=\"M11 3.07A7 7 0 1 0 16.93 9\" />\n <path d=\"M7.5 11.5S8.25 13 10 13s2.5-1.5 2.5-1.5M8 8h0\" />\n <path d=\"M12 8h0\" />\n <path d=\"M13 5h4m-2-2v4\" />\n <circle cx=\"8\" cy=\"8\" r=\".25\" />\n <circle cx=\"12\" cy=\"8\" r=\".25\" />\n </Icon>\n );\n}\n"],"names":[],"mappings":";;;AAIO,SAAS,aAAa,KAA8B,EAAA;AACzD,EAAA,uBACG,IAAA,CAAA,IAAA,EAAA;AAAA,IAAM,GAAG,KAAA;AAAA,IACR,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,4BAAA;AAAA,OAA6B,CAAA;AAAA,sBACpC,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,+CAAA;AAAA,OAAgD,CAAA;AAAA,sBACvD,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,SAAA;AAAA,OAAU,CAAA;AAAA,sBACjB,GAAA,CAAA,MAAA,EAAA;AAAA,QAAK,CAAE,EAAA,gBAAA;AAAA,OAAiB,CAAA;AAAA,sBACxB,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,GAAA;AAAA,QAAI,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,sBAC7B,GAAA,CAAA,QAAA,EAAA;AAAA,QAAO,EAAG,EAAA,IAAA;AAAA,QAAK,EAAG,EAAA,GAAA;AAAA,QAAI,CAAE,EAAA,KAAA;AAAA,OAAM,CAAA;AAAA,KAAA;AAAA,GACjC,CAAA,CAAA;AAEJ;;;;"}
|