@liveblocks/react-lexical 3.18.2 → 3.18.3-test2
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/LICENSE +16 -0
- package/dist/comments/anchored-threads.cjs +15 -30
- package/dist/comments/anchored-threads.cjs.map +1 -1
- package/dist/comments/anchored-threads.js +15 -30
- package/dist/comments/anchored-threads.js.map +1 -1
- package/dist/comments/comment-plugin-provider.cjs +10 -20
- package/dist/comments/comment-plugin-provider.cjs.map +1 -1
- package/dist/comments/comment-plugin-provider.js +10 -20
- package/dist/comments/comment-plugin-provider.js.map +1 -1
- package/dist/comments/floating-composer.cjs +7 -14
- package/dist/comments/floating-composer.cjs.map +1 -1
- package/dist/comments/floating-composer.js +7 -14
- package/dist/comments/floating-composer.js.map +1 -1
- package/dist/comments/floating-threads.cjs +6 -12
- package/dist/comments/floating-threads.cjs.map +1 -1
- package/dist/comments/floating-threads.js +6 -12
- package/dist/comments/floating-threads.js.map +1 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.cjs +5 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.cjs.map +1 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.js +5 -1
- package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -1
- package/dist/create-dom-range.cjs +1 -1
- package/dist/create-dom-range.cjs.map +1 -1
- package/dist/create-dom-range.js +1 -1
- package/dist/create-dom-range.js.map +1 -1
- package/dist/liveblocks-plugin-provider.cjs +3 -5
- package/dist/liveblocks-plugin-provider.cjs.map +1 -1
- package/dist/liveblocks-plugin-provider.js +3 -5
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/mentions/mention-component.cjs +1 -2
- package/dist/mentions/mention-component.cjs.map +1 -1
- package/dist/mentions/mention-component.js +1 -2
- package/dist/mentions/mention-component.js.map +1 -1
- package/dist/mentions/mention-plugin.cjs +29 -57
- package/dist/mentions/mention-plugin.cjs.map +1 -1
- package/dist/mentions/mention-plugin.js +29 -57
- package/dist/mentions/mention-plugin.js.map +1 -1
- package/dist/mentions/suggestions.cjs +12 -24
- package/dist/mentions/suggestions.cjs.map +1 -1
- package/dist/mentions/suggestions.js +12 -24
- package/dist/mentions/suggestions.js.map +1 -1
- package/dist/toolbar/floating-toolbar.cjs +1 -2
- package/dist/toolbar/floating-toolbar.cjs.map +1 -1
- package/dist/toolbar/floating-toolbar.js +1 -2
- package/dist/toolbar/floating-toolbar.js.map +1 -1
- package/dist/toolbar/toolbar.cjs +1 -2
- package/dist/toolbar/toolbar.cjs.map +1 -1
- package/dist/toolbar/toolbar.js +1 -2
- package/dist/toolbar/toolbar.js.map +1 -1
- package/dist/version-history/history-version-preview.cjs.map +1 -1
- package/dist/version-history/history-version-preview.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +11 -35
- package/src/styles/index.css +3 -3
- package/styles.css +1 -1
- package/styles.css.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mention-plugin.js","sources":["../../src/mentions/mention-plugin.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n assertNever,\n MENTION_CHARACTER,\n type MentionData,\n} from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport {\n useCreateTextMention,\n useDeleteTextMention,\n useLayoutEffect,\n useMentionSuggestions,\n} from \"@liveblocks/react/_private\";\nimport {\n Group,\n GroupAvatar,\n GroupDescription,\n Portal,\n User,\n UserAvatar,\n UsersIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport type { EditorState, NodeKey, NodeMutation, TextNode } from \"lexical\";\nimport {\n $createRangeSelection,\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $isElementNode,\n $isNodeSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n} from \"lexical\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport {\n $createGroupMentionNode,\n $isGroupMentionNode,\n GroupMentionNode,\n} from \"./group-mention-node\";\nimport {\n $createMentionNode,\n $isMentionNode,\n MentionNode,\n} from \"./mention-node\";\nimport * as Suggestions from \"./suggestions\";\nimport {\n OnResetMatchCallbackContext,\n OnSuggestionSelectCallbackContext,\n SuggestionsContext,\n} from \"./suggestions\";\n\nconst PUNCTUATIONS =\n \"\\\\.,\\\\+\\\\*\\\\?\\\\$\\\\@\\\\|#{}\\\\(\\\\)\\\\^\\\\-\\\\[\\\\]\\\\\\\\/!%'\\\"~=<>_:;\";\n\n// Characters we expect to see in a mention (non-space, non-punctuation).\nconst VALID_CHARACTERS = \"[^\" + MENTION_CHARACTER + PUNCTUATIONS + \"\\\\s]\";\n\nconst VALID_JOINS =\n \"(?:\" +\n \"\\\\.[ |$]|\" + // E.g. \"r. \" in \"Mr. Smith\"\n \" |\" + // E.g. \" \" in \"Josh Duck\"\n \"[\" +\n PUNCTUATIONS +\n \"]|\" + // E.g. \"-' in \"Salier-Hellendag\"\n \")\";\n\nconst LENGTH_LIMIT = 75;\n\nconst MentionRegex = new RegExp(\n \"(^|\\\\s|\\\\()(\" +\n \"[\" +\n MENTION_CHARACTER +\n \"]\" +\n \"((?:\" +\n VALID_CHARACTERS +\n VALID_JOINS +\n \"){0,\" +\n LENGTH_LIMIT +\n \"})\" +\n \")$\"\n);\n\nfunction $getAnchorNodeTextContent(): string | null {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return null;\n\n const anchor = selection.anchor;\n if (anchor.type !== \"text\") return null;\n const anchorNode = anchor.getNode();\n if (!anchorNode.isSimpleText()) return null;\n const anchorOffset = anchor.offset;\n return anchorNode.getTextContent().slice(0, anchorOffset);\n}\n\n/**\n * Walk backwards along user input and forward through entity title to try and replace more of the user's text with entity.\n */\nfunction getFullMatchOffset(\n documentText: string,\n entryText: string,\n offset: number\n): number {\n let triggerOffset = offset;\n for (let i = triggerOffset; i <= entryText.length; i++) {\n if (documentText.substr(-i) === entryText.substr(0, i)) {\n triggerOffset = i;\n }\n }\n return triggerOffset;\n}\n\nfunction $isCurrentSelectionAtBoundary(offset: number): boolean {\n // If the offset is not zero, i.e. not at the beginning of the text node, the selection is somewhere in the middle of the entity, i.e. not at the boundary.\n if (offset !== 0) return false;\n\n // Othewise (if the offset is zero), it means the selection could be at the start of an entity. It could also be at the end of the previous entity, or it could be in a position where there are no entities at all.\n // So, we check if the previous sibling of the node at the anchor of the selection is a text entity. If it is, then the selection is at the boundary of the entity.\n const selection = $getSelection();\n\n if (!$isRangeSelection(selection)) return false;\n\n const anchor = selection.anchor.getNode();\n const prevSibling = anchor.getPreviousSibling();\n\n if (!$isTextNode(prevSibling)) return false;\n if (!prevSibling.isTextEntity()) return false;\n\n return true;\n}\n\nfunction $getRangeAtMatch(match: RegExpExecArray): globalThis.Range | null {\n const offsetWithWhitespaces = match.index + match[1].length;\n\n if ($isCurrentSelectionAtBoundary(offsetWithWhitespaces)) return null;\n\n const selection = window.getSelection();\n if (selection === null) return null;\n if (!selection.isCollapsed) return null;\n\n const anchor = selection.anchorNode;\n if (anchor === null) return null;\n\n const endOffset = selection.anchorOffset;\n if (endOffset === null) return null;\n\n const range = document.createRange();\n\n try {\n range.setStart(anchor, offsetWithWhitespaces);\n range.setEnd(anchor, endOffset);\n return range;\n } catch (error) {\n return null;\n }\n}\n\nexport function MentionPlugin() {\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [match, setMatch] = useState<RegExpExecArray | null>(null); // Represents the current match of the mention regex. A `null` value means there is no match.\n const matchingString = match?.[3];\n\n const suggestions = useMentionSuggestions(room.id, matchingString);\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n useEffect(() => {\n function $handleMentionMutation(\n mutations: Map<NodeKey, NodeMutation>,\n {\n prevEditorState,\n }: {\n prevEditorState: EditorState;\n }\n ) {\n for (const [key, mutation] of mutations) {\n if (mutation === \"created\") {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isMentionNode(node)) {\n createTextMention(node.getId(), {\n kind: \"user\",\n id: node.getUserId(),\n });\n }\n });\n } else if (mutation === \"destroyed\") {\n prevEditorState.read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isMentionNode(node)) {\n deleteTextMention(node.getId());\n }\n });\n }\n }\n }\n\n function $handleGroupMentionMutation(\n mutations: Map<NodeKey, NodeMutation>,\n {\n prevEditorState,\n }: {\n prevEditorState: EditorState;\n }\n ) {\n for (const [key, mutation] of mutations) {\n if (mutation === \"created\") {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isGroupMentionNode(node)) {\n createTextMention(node.getId(), {\n kind: \"group\",\n id: node.getGroupId(),\n userIds: node.getUserIds(),\n });\n }\n });\n } else if (mutation === \"destroyed\") {\n prevEditorState.read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isGroupMentionNode(node)) {\n deleteTextMention(node.getId());\n }\n });\n }\n }\n }\n\n const unsubscribeMentionMutationListener = editor.registerMutationListener(\n MentionNode,\n (mutations, payload) => {\n // Ignore mutations to MentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n if (\n payload.updateTags.has(\"collaboration\") ||\n payload.updateTags.has(\"history-merge\")\n ) {\n return;\n }\n\n $handleMentionMutation(mutations, payload);\n }\n );\n\n const unsubscribeGroupMentionMutationListener =\n editor.registerMutationListener(\n GroupMentionNode,\n (mutations, payload) => {\n // Ignore mutations to GroupMentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n if (\n payload.updateTags.has(\"collaboration\") ||\n payload.updateTags.has(\"history-merge\")\n ) {\n return;\n }\n\n $handleGroupMentionMutation(mutations, payload);\n }\n );\n\n return () => {\n unsubscribeMentionMutationListener();\n unsubscribeGroupMentionMutationListener();\n };\n }, [editor, createTextMention, deleteTextMention]);\n\n useEffect(() => {\n function $onStateRead() {\n const text = $getAnchorNodeTextContent();\n if (text === null) {\n setMatch(null);\n return;\n }\n\n const match = MentionRegex.exec(text);\n setMatch(match);\n }\n\n return editor.registerUpdateListener(({ editorState: state }) => {\n state.read($onStateRead);\n });\n }, [editor]);\n\n useEffect(() => {\n function $handleBackspace(event: KeyboardEvent): boolean {\n const selection = $getSelection();\n\n if (selection === null) return false;\n\n // If the selection is a node selection and the only node selected is a mention node, then we replace the mention node with a text node containing \"@\" and set the selection at the end of the text node.\n if ($isNodeSelection(selection)) {\n const nodes = selection.getNodes();\n if (nodes.length !== 1) return false;\n\n const node = nodes[0];\n if (!$isMentionNode(node) && !$isGroupMentionNode(node)) {\n return false;\n }\n\n const text = $createTextNode(\"@\");\n node.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n } else if ($isRangeSelection(selection)) {\n if (!selection.isCollapsed()) return false;\n\n const anchor = selection.anchor.getNode();\n const prevSibling = anchor.getPreviousSibling();\n if (\n selection.anchor.offset === 0 &&\n ($isMentionNode(prevSibling) || $isGroupMentionNode(prevSibling))\n ) {\n const text = $createTextNode(\"@\");\n prevSibling.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n } else if ($isElementNode(anchor)) {\n const child = anchor.getChildAtIndex(selection.anchor.offset - 1);\n if (!$isMentionNode(child) && !$isGroupMentionNode(child)) {\n return false;\n }\n\n const text = $createTextNode(\"@\");\n child.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n }\n\n return false;\n }\n\n return false;\n }\n\n return editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n $handleBackspace,\n COMMAND_PRIORITY_LOW\n );\n }, [editor]);\n\n const handleSuggestionSelect = useCallback(\n (mention: MentionData) => {\n function $onValueSelect() {\n if (match === null) return;\n\n setMatch(null);\n\n const selection = $getSelection();\n\n if (!$isRangeSelection(selection)) return;\n if (!selection.isCollapsed()) return;\n\n const anchor = selection.anchor;\n if (anchor.type !== \"text\") return;\n\n const anchorNode: TextNode = anchor.getNode();\n if (!anchorNode.isSimpleText()) return;\n\n const selectionOffset = anchor.offset;\n const text = anchorNode.getTextContent().slice(0, selectionOffset);\n\n const characterOffset = match[2].length;\n const queryOffset = getFullMatchOffset(text, match[2], characterOffset);\n const startOffset = selectionOffset - queryOffset;\n if (startOffset < 0) return;\n\n let mentionNode: MentionNode | GroupMentionNode;\n\n switch (mention.kind) {\n case \"user\":\n mentionNode = $createMentionNode(mention.id);\n break;\n\n case \"group\":\n mentionNode = $createGroupMentionNode(mention.id, mention.userIds);\n break;\n\n default:\n return assertNever(mention, \"Unhandled mention kind\");\n }\n\n // Split the anchor (text) node and create a new text node only containing matched text.\n if (startOffset === 0) {\n const [node] = anchorNode.splitText(selectionOffset);\n node.replace(mentionNode);\n } else {\n const [, node] = anchorNode.splitText(startOffset, selectionOffset);\n node.replace(mentionNode);\n }\n }\n\n editor.update($onValueSelect);\n },\n [editor, match]\n );\n\n if (match === null || matchingString === undefined) return null;\n\n if (suggestions === undefined || suggestions.length === 0) return null;\n\n const range = editor.getEditorState().read(() => $getRangeAtMatch(match));\n\n if (range === null) return null;\n\n return (\n <SuggestionsContext.Provider value={suggestions}>\n <OnSuggestionSelectCallbackContext.Provider\n value={handleSuggestionSelect}\n >\n <OnResetMatchCallbackContext.Provider value={() => setMatch(null)}>\n <SuggestionsPortal range={range} key={matchingString}>\n <Suggestions.List className=\"lb-lexical-suggestions-list lb-lexical-mention-suggestions-list\">\n {suggestions.map((mention) => {\n return (\n <Suggestions.Item\n key={mention.id}\n value={mention.id}\n className=\"lb-lexical-suggestions-list-item lb-lexical-mention-suggestion\"\n >\n {mention.kind === \"user\" ? (\n <>\n <UserAvatar\n userId={mention.id}\n className=\"lb-lexical-mention-suggestion-avatar\"\n />\n <User\n userId={mention.id}\n className=\"lb-lexical-mention-suggestion-user\"\n />\n </>\n ) : mention.kind === \"group\" ? (\n <>\n <GroupAvatar\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-avatar\"\n icon={<UsersIcon />}\n />\n <Group\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-group\"\n >\n <GroupDescription\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-group-description\"\n />\n </Group>\n </>\n ) : (\n assertNever(mention, \"Unhandled mention kind\")\n )}\n </Suggestions.Item>\n );\n })}\n </Suggestions.List>\n </SuggestionsPortal>\n </OnResetMatchCallbackContext.Provider>\n </OnSuggestionSelectCallbackContext.Provider>\n </SuggestionsContext.Provider>\n );\n}\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nfunction SuggestionsPortal({\n children,\n range,\n}: {\n children: ReactNode;\n range: Range;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return (\n <Portal asChild>\n <div\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className=\"lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions\"\n >\n {children}\n </div>\n </Portal>\n );\n}\n"],"names":["offset","match","Suggestions.List","Suggestions.Item"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mention-plugin.js","sources":["../../src/mentions/mention-plugin.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n assertNever,\n MENTION_CHARACTER,\n type MentionData,\n} from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport {\n useCreateTextMention,\n useDeleteTextMention,\n useLayoutEffect,\n useMentionSuggestions,\n} from \"@liveblocks/react/_private\";\nimport {\n Group,\n GroupAvatar,\n GroupDescription,\n Portal,\n User,\n UserAvatar,\n UsersIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport type { EditorState, NodeKey, NodeMutation, TextNode } from \"lexical\";\nimport {\n $createRangeSelection,\n $createTextNode,\n $getNodeByKey,\n $getSelection,\n $isElementNode,\n $isNodeSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n} from \"lexical\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport {\n $createGroupMentionNode,\n $isGroupMentionNode,\n GroupMentionNode,\n} from \"./group-mention-node\";\nimport {\n $createMentionNode,\n $isMentionNode,\n MentionNode,\n} from \"./mention-node\";\nimport * as Suggestions from \"./suggestions\";\nimport {\n OnResetMatchCallbackContext,\n OnSuggestionSelectCallbackContext,\n SuggestionsContext,\n} from \"./suggestions\";\n\nconst PUNCTUATIONS =\n \"\\\\.,\\\\+\\\\*\\\\?\\\\$\\\\@\\\\|#{}\\\\(\\\\)\\\\^\\\\-\\\\[\\\\]\\\\\\\\/!%'\\\"~=<>_:;\";\n\n// Characters we expect to see in a mention (non-space, non-punctuation).\nconst VALID_CHARACTERS = \"[^\" + MENTION_CHARACTER + PUNCTUATIONS + \"\\\\s]\";\n\nconst VALID_JOINS =\n \"(?:\" +\n \"\\\\.[ |$]|\" + // E.g. \"r. \" in \"Mr. Smith\"\n \" |\" + // E.g. \" \" in \"Josh Duck\"\n \"[\" +\n PUNCTUATIONS +\n \"]|\" + // E.g. \"-' in \"Salier-Hellendag\"\n \")\";\n\nconst LENGTH_LIMIT = 75;\n\nconst MentionRegex = new RegExp(\n \"(^|\\\\s|\\\\()(\" +\n \"[\" +\n MENTION_CHARACTER +\n \"]\" +\n \"((?:\" +\n VALID_CHARACTERS +\n VALID_JOINS +\n \"){0,\" +\n LENGTH_LIMIT +\n \"})\" +\n \")$\"\n);\n\nfunction $getAnchorNodeTextContent(): string | null {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return null;\n\n const anchor = selection.anchor;\n if (anchor.type !== \"text\") return null;\n const anchorNode = anchor.getNode();\n if (!anchorNode.isSimpleText()) return null;\n const anchorOffset = anchor.offset;\n return anchorNode.getTextContent().slice(0, anchorOffset);\n}\n\n/**\n * Walk backwards along user input and forward through entity title to try and replace more of the user's text with entity.\n */\nfunction getFullMatchOffset(\n documentText: string,\n entryText: string,\n offset: number\n): number {\n let triggerOffset = offset;\n for (let i = triggerOffset; i <= entryText.length; i++) {\n if (documentText.substr(-i) === entryText.substr(0, i)) {\n triggerOffset = i;\n }\n }\n return triggerOffset;\n}\n\nfunction $isCurrentSelectionAtBoundary(offset: number): boolean {\n // If the offset is not zero, i.e. not at the beginning of the text node, the selection is somewhere in the middle of the entity, i.e. not at the boundary.\n if (offset !== 0) return false;\n\n // Othewise (if the offset is zero), it means the selection could be at the start of an entity. It could also be at the end of the previous entity, or it could be in a position where there are no entities at all.\n // So, we check if the previous sibling of the node at the anchor of the selection is a text entity. If it is, then the selection is at the boundary of the entity.\n const selection = $getSelection();\n\n if (!$isRangeSelection(selection)) return false;\n\n const anchor = selection.anchor.getNode();\n const prevSibling = anchor.getPreviousSibling();\n\n if (!$isTextNode(prevSibling)) return false;\n if (!prevSibling.isTextEntity()) return false;\n\n return true;\n}\n\nfunction $getRangeAtMatch(match: RegExpExecArray): globalThis.Range | null {\n const offsetWithWhitespaces = match.index + match[1].length;\n\n if ($isCurrentSelectionAtBoundary(offsetWithWhitespaces)) return null;\n\n const selection = window.getSelection();\n if (selection === null) return null;\n if (!selection.isCollapsed) return null;\n\n const anchor = selection.anchorNode;\n if (anchor === null) return null;\n\n const endOffset = selection.anchorOffset;\n if (endOffset === null) return null;\n\n const range = document.createRange();\n\n try {\n range.setStart(anchor, offsetWithWhitespaces);\n range.setEnd(anchor, endOffset);\n return range;\n } catch {\n return null;\n }\n}\n\nexport function MentionPlugin() {\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n const [match, setMatch] = useState<RegExpExecArray | null>(null); // Represents the current match of the mention regex. A `null` value means there is no match.\n const matchingString = match?.[3];\n\n const suggestions = useMentionSuggestions(room.id, matchingString);\n const createTextMention = useCreateTextMention();\n const deleteTextMention = useDeleteTextMention();\n\n useEffect(() => {\n function $handleMentionMutation(\n mutations: Map<NodeKey, NodeMutation>,\n {\n prevEditorState,\n }: {\n prevEditorState: EditorState;\n }\n ) {\n for (const [key, mutation] of mutations) {\n if (mutation === \"created\") {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isMentionNode(node)) {\n createTextMention(node.getId(), {\n kind: \"user\",\n id: node.getUserId(),\n });\n }\n });\n } else if (mutation === \"destroyed\") {\n prevEditorState.read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isMentionNode(node)) {\n deleteTextMention(node.getId());\n }\n });\n }\n }\n }\n\n function $handleGroupMentionMutation(\n mutations: Map<NodeKey, NodeMutation>,\n {\n prevEditorState,\n }: {\n prevEditorState: EditorState;\n }\n ) {\n for (const [key, mutation] of mutations) {\n if (mutation === \"created\") {\n editor.getEditorState().read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isGroupMentionNode(node)) {\n createTextMention(node.getId(), {\n kind: \"group\",\n id: node.getGroupId(),\n userIds: node.getUserIds(),\n });\n }\n });\n } else if (mutation === \"destroyed\") {\n prevEditorState.read(() => {\n const node = $getNodeByKey(key);\n if (node === null) return;\n\n if ($isGroupMentionNode(node)) {\n deleteTextMention(node.getId());\n }\n });\n }\n }\n }\n\n const unsubscribeMentionMutationListener = editor.registerMutationListener(\n MentionNode,\n (mutations, payload) => {\n // Ignore mutations to MentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n if (\n payload.updateTags.has(\"collaboration\") ||\n payload.updateTags.has(\"history-merge\")\n ) {\n return;\n }\n\n $handleMentionMutation(mutations, payload);\n }\n );\n\n const unsubscribeGroupMentionMutationListener =\n editor.registerMutationListener(\n GroupMentionNode,\n (mutations, payload) => {\n // Ignore mutations to GroupMentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n if (\n payload.updateTags.has(\"collaboration\") ||\n payload.updateTags.has(\"history-merge\")\n ) {\n return;\n }\n\n $handleGroupMentionMutation(mutations, payload);\n }\n );\n\n return () => {\n unsubscribeMentionMutationListener();\n unsubscribeGroupMentionMutationListener();\n };\n }, [editor, createTextMention, deleteTextMention]);\n\n useEffect(() => {\n function $onStateRead() {\n const text = $getAnchorNodeTextContent();\n if (text === null) {\n setMatch(null);\n return;\n }\n\n const match = MentionRegex.exec(text);\n setMatch(match);\n }\n\n return editor.registerUpdateListener(({ editorState: state }) => {\n state.read($onStateRead);\n });\n }, [editor]);\n\n useEffect(() => {\n function $handleBackspace(event: KeyboardEvent): boolean {\n const selection = $getSelection();\n\n if (selection === null) return false;\n\n // If the selection is a node selection and the only node selected is a mention node, then we replace the mention node with a text node containing \"@\" and set the selection at the end of the text node.\n if ($isNodeSelection(selection)) {\n const nodes = selection.getNodes();\n if (nodes.length !== 1) return false;\n\n const node = nodes[0];\n if (!$isMentionNode(node) && !$isGroupMentionNode(node)) {\n return false;\n }\n\n const text = $createTextNode(\"@\");\n node.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n } else if ($isRangeSelection(selection)) {\n if (!selection.isCollapsed()) return false;\n\n const anchor = selection.anchor.getNode();\n const prevSibling = anchor.getPreviousSibling();\n if (\n selection.anchor.offset === 0 &&\n ($isMentionNode(prevSibling) || $isGroupMentionNode(prevSibling))\n ) {\n const text = $createTextNode(\"@\");\n prevSibling.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n } else if ($isElementNode(anchor)) {\n const child = anchor.getChildAtIndex(selection.anchor.offset - 1);\n if (!$isMentionNode(child) && !$isGroupMentionNode(child)) {\n return false;\n }\n\n const text = $createTextNode(\"@\");\n child.replace(text);\n\n const newSelection = $createRangeSelection();\n newSelection.setTextNodeRange(text, 1, text, 1);\n $setSelection(newSelection);\n\n event.preventDefault();\n return true;\n }\n\n return false;\n }\n\n return false;\n }\n\n return editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n $handleBackspace,\n COMMAND_PRIORITY_LOW\n );\n }, [editor]);\n\n const handleSuggestionSelect = useCallback(\n (mention: MentionData) => {\n function $onValueSelect() {\n if (match === null) return;\n\n setMatch(null);\n\n const selection = $getSelection();\n\n if (!$isRangeSelection(selection)) return;\n if (!selection.isCollapsed()) return;\n\n const anchor = selection.anchor;\n if (anchor.type !== \"text\") return;\n\n const anchorNode: TextNode = anchor.getNode();\n if (!anchorNode.isSimpleText()) return;\n\n const selectionOffset = anchor.offset;\n const text = anchorNode.getTextContent().slice(0, selectionOffset);\n\n const characterOffset = match[2].length;\n const queryOffset = getFullMatchOffset(text, match[2], characterOffset);\n const startOffset = selectionOffset - queryOffset;\n if (startOffset < 0) return;\n\n let mentionNode: MentionNode | GroupMentionNode;\n\n switch (mention.kind) {\n case \"user\":\n mentionNode = $createMentionNode(mention.id);\n break;\n\n case \"group\":\n mentionNode = $createGroupMentionNode(mention.id, mention.userIds);\n break;\n\n default:\n return assertNever(mention, \"Unhandled mention kind\");\n }\n\n // Split the anchor (text) node and create a new text node only containing matched text.\n if (startOffset === 0) {\n const [node] = anchorNode.splitText(selectionOffset);\n node.replace(mentionNode);\n } else {\n const [, node] = anchorNode.splitText(startOffset, selectionOffset);\n node.replace(mentionNode);\n }\n }\n\n editor.update($onValueSelect);\n },\n [editor, match]\n );\n\n if (match === null || matchingString === undefined) return null;\n\n if (suggestions === undefined || suggestions.length === 0) return null;\n\n const range = editor.getEditorState().read(() => $getRangeAtMatch(match));\n\n if (range === null) return null;\n\n return (\n <SuggestionsContext.Provider value={suggestions}>\n <OnSuggestionSelectCallbackContext.Provider\n value={handleSuggestionSelect}\n >\n <OnResetMatchCallbackContext.Provider value={() => setMatch(null)}>\n <SuggestionsPortal range={range} key={matchingString}>\n <Suggestions.List className=\"lb-lexical-suggestions-list lb-lexical-mention-suggestions-list\">\n {suggestions.map((mention) => {\n return (\n <Suggestions.Item\n key={mention.id}\n value={mention.id}\n className=\"lb-lexical-suggestions-list-item lb-lexical-mention-suggestion\"\n >\n {mention.kind === \"user\" ? (\n <>\n <UserAvatar\n userId={mention.id}\n className=\"lb-lexical-mention-suggestion-avatar\"\n />\n <User\n userId={mention.id}\n className=\"lb-lexical-mention-suggestion-user\"\n />\n </>\n ) : mention.kind === \"group\" ? (\n <>\n <GroupAvatar\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-avatar\"\n icon={<UsersIcon />}\n />\n <Group\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-group\"\n >\n <GroupDescription\n groupId={mention.id}\n className=\"lb-lexical-mention-suggestion-group-description\"\n />\n </Group>\n </>\n ) : (\n assertNever(mention, \"Unhandled mention kind\")\n )}\n </Suggestions.Item>\n );\n })}\n </Suggestions.List>\n </SuggestionsPortal>\n </OnResetMatchCallbackContext.Provider>\n </OnSuggestionSelectCallbackContext.Provider>\n </SuggestionsContext.Provider>\n );\n}\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nfunction SuggestionsPortal({\n children,\n range,\n}: {\n children: ReactNode;\n range: Range;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"top-start\",\n middleware: [\n flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),\n size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference({\n getBoundingClientRect: () => range.getBoundingClientRect(),\n });\n }, [setReference, range]);\n\n return (\n <Portal asChild>\n <div\n ref={setFloating}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n className=\"lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions\"\n >\n {children}\n </div>\n </Portal>\n );\n}\n"],"names":["offset","match","Suggestions.List","Suggestions.Item"],"mappings":"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"}
|
|
@@ -21,10 +21,8 @@ const List = react.forwardRef(
|
|
|
21
21
|
const onEscapeKeyDown = useOnResetMatchCallback();
|
|
22
22
|
react.useEffect(() => {
|
|
23
23
|
function onKeyArrowDown(event) {
|
|
24
|
-
if (suggestions.length === 0)
|
|
25
|
-
|
|
26
|
-
if (highlightedIndex === null)
|
|
27
|
-
return true;
|
|
24
|
+
if (suggestions.length === 0) return true;
|
|
25
|
+
if (highlightedIndex === null) return true;
|
|
28
26
|
const nextIndex = highlightedIndex === suggestions.length - 1 ? 0 : highlightedIndex + 1;
|
|
29
27
|
setHighlightedIndex(nextIndex);
|
|
30
28
|
event.preventDefault();
|
|
@@ -39,10 +37,8 @@ const List = react.forwardRef(
|
|
|
39
37
|
}, [editor, highlightedIndex, suggestions]);
|
|
40
38
|
react.useEffect(() => {
|
|
41
39
|
function onKeyArrowUp(event) {
|
|
42
|
-
if (suggestions.length === 0)
|
|
43
|
-
|
|
44
|
-
if (highlightedIndex === null)
|
|
45
|
-
return true;
|
|
40
|
+
if (suggestions.length === 0) return true;
|
|
41
|
+
if (highlightedIndex === null) return true;
|
|
46
42
|
const nextIndex = highlightedIndex === 0 ? suggestions.length - 1 : highlightedIndex - 1;
|
|
47
43
|
setHighlightedIndex(nextIndex);
|
|
48
44
|
event.preventDefault();
|
|
@@ -70,11 +66,9 @@ const List = react.forwardRef(
|
|
|
70
66
|
}, [editor, onEscapeKeyDown]);
|
|
71
67
|
react.useEffect(() => {
|
|
72
68
|
function onKeyEnter(event) {
|
|
73
|
-
if (suggestions.length === 0)
|
|
74
|
-
return true;
|
|
69
|
+
if (suggestions.length === 0) return true;
|
|
75
70
|
onSuggestionSelect(suggestions[highlightedIndex]);
|
|
76
|
-
if (event === null)
|
|
77
|
-
return true;
|
|
71
|
+
if (event === null) return true;
|
|
78
72
|
event.preventDefault();
|
|
79
73
|
event.stopImmediatePropagation();
|
|
80
74
|
return true;
|
|
@@ -87,8 +81,7 @@ const List = react.forwardRef(
|
|
|
87
81
|
}, [editor, onSuggestionSelect, highlightedIndex, suggestions]);
|
|
88
82
|
react.useEffect(() => {
|
|
89
83
|
const root = editor.getRootElement();
|
|
90
|
-
if (root === null)
|
|
91
|
-
return;
|
|
84
|
+
if (root === null) return;
|
|
92
85
|
root.setAttribute(
|
|
93
86
|
"aria-activedescendant",
|
|
94
87
|
`typeahead-item-${highlightedIndex}`
|
|
@@ -119,28 +112,23 @@ const Item = react.forwardRef(
|
|
|
119
112
|
() => divRef.current
|
|
120
113
|
);
|
|
121
114
|
react.useEffect(() => {
|
|
122
|
-
if (!isHighlighted)
|
|
123
|
-
return;
|
|
115
|
+
if (!isHighlighted) return;
|
|
124
116
|
const div = divRef.current;
|
|
125
|
-
if (div === null)
|
|
126
|
-
return;
|
|
117
|
+
if (div === null) return;
|
|
127
118
|
div.scrollIntoView({ block: "nearest" });
|
|
128
119
|
}, [isHighlighted]);
|
|
129
120
|
function handleMouseEnter(event) {
|
|
130
121
|
onMouseEnter?.(event);
|
|
131
|
-
if (event.isDefaultPrevented())
|
|
132
|
-
return;
|
|
122
|
+
if (event.isDefaultPrevented()) return;
|
|
133
123
|
const index = suggestions.findIndex(
|
|
134
124
|
(suggestion) => suggestion.id === value
|
|
135
125
|
);
|
|
136
|
-
if (index === -1)
|
|
137
|
-
return;
|
|
126
|
+
if (index === -1) return;
|
|
138
127
|
setHighlightedIndex(index);
|
|
139
128
|
}
|
|
140
129
|
function handleClick(event) {
|
|
141
130
|
onClick?.(event);
|
|
142
|
-
if (event.isDefaultPrevented())
|
|
143
|
-
return;
|
|
131
|
+
if (event.isDefaultPrevented()) return;
|
|
144
132
|
onSuggestionSelect(suggestions[highlightedIndex]);
|
|
145
133
|
}
|
|
146
134
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suggestions.cjs","sources":["../../src/mentions/suggestions.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { MentionData } from \"@liveblocks/core\";\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport type {\n Dispatch,\n HTMLAttributes,\n MouseEvent,\n ReactNode,\n SetStateAction,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nexport const SuggestionsContext = createContext<MentionData[] | null>(null);\n\nexport const OnSuggestionSelectCallbackContext = createContext<\n ((mention: MentionData) => void) | null\n>(null);\n\nexport const OnResetMatchCallbackContext = createContext<(() => void) | null>(\n null\n);\n\nconst HighlightedIndexContext = createContext<\n [number, Dispatch<SetStateAction<number>>] | null\n>(null);\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst List = forwardRef<HTMLDivElement, ListProps>(\n function (props, forwardedRef) {\n const { children, ...divProps } = props;\n const [editor] = useLexicalComposerContext();\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n const onEscapeKeyDown = useOnResetMatchCallback();\n\n useEffect(() => {\n function onKeyArrowDown(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the last suggestion, then we loop back to the first suggestion, otherwise we increment the index.\n const nextIndex =\n highlightedIndex === suggestions.length - 1\n ? 0\n : highlightedIndex + 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n onKeyArrowDown,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyArrowUp(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the first suggestion, then we loop back to the last suggestion, otherwise we decrement the index.\n const nextIndex =\n highlightedIndex === 0\n ? suggestions.length - 1\n : highlightedIndex - 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n onKeyArrowUp,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyEscape(event: KeyboardEvent): boolean {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n onEscapeKeyDown();\n return true;\n }\n\n return editor.registerCommand<KeyboardEvent>(\n KEY_ESCAPE_COMMAND,\n onKeyEscape,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onEscapeKeyDown]);\n\n useEffect(() => {\n function onKeyEnter(event: KeyboardEvent | null): boolean {\n if (suggestions.length === 0) return true;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n\n if (event === null) return true;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n onKeyEnter,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onSuggestionSelect, highlightedIndex, suggestions]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n if (root === null) return;\n\n root.setAttribute(\n \"aria-activedescendant\",\n `typeahead-item-${highlightedIndex}`\n );\n\n return () => {\n root.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, highlightedIndex]);\n\n return (\n <HighlightedIndexContext.Provider\n value={[highlightedIndex, setHighlightedIndex]}\n >\n <div role=\"listbox\" {...divProps} ref={forwardedRef}>\n {children}\n </div>\n </HighlightedIndexContext.Provider>\n );\n }\n);\n\ninterface ItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nconst Item = forwardRef<HTMLDivElement | null, ItemProps>(\n function Item(props, forwardedRef) {\n const { children, value, onMouseEnter, onClick, ...divProps } = props;\n const divRef = useRef<HTMLDivElement>(null);\n\n const [highlightedIndex, setHighlightedIndex] = useHighlightedIndex();\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n\n const isHighlighted = suggestions[highlightedIndex].id === value;\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n if (!isHighlighted) return;\n\n const div = divRef.current;\n if (div === null) return;\n\n div.scrollIntoView({ block: \"nearest\" });\n }, [isHighlighted]);\n\n function handleMouseEnter(event: MouseEvent<HTMLDivElement>) {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n const index = suggestions.findIndex(\n (suggestion) => suggestion.id === value\n );\n if (index === -1) return;\n\n setHighlightedIndex(index);\n }\n\n function handleClick(event: MouseEvent<HTMLDivElement>) {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n }\n\n return (\n <div\n role=\"option\"\n data-highlighted={isHighlighted || undefined}\n onMouseEnter={handleMouseEnter}\n onClick={handleClick}\n {...divProps}\n ref={divRef}\n >\n {children}\n </div>\n );\n }\n);\n\nfunction useHighlightedIndex(): [number, Dispatch<SetStateAction<number>>] {\n const context = useContext(HighlightedIndexContext);\n if (context === null) {\n throw new Error(\n \"useHighlightedIndex must be used within a HighlightedIndexProvider\"\n );\n }\n return context;\n}\n\nfunction useSuggestions(): MentionData[] {\n const suggestions = useContext(SuggestionsContext);\n if (suggestions === null) {\n throw new Error(\"useSuggestions: SuggestionsContext not found\");\n }\n\n return suggestions;\n}\n\nfunction useOnSuggestionSelectCallback(): (mention: MentionData) => void {\n const onSuggestionSelect = useContext(OnSuggestionSelectCallbackContext);\n if (onSuggestionSelect === null) {\n throw new Error(\n \"useOnSuggestionSelectCallback: OnSuggestionSelectContext not found\"\n );\n }\n\n return onSuggestionSelect;\n}\n\nfunction useOnResetMatchCallback(): () => void {\n const onResetMatch = useContext(OnResetMatchCallbackContext);\n if (onResetMatch === null) {\n throw new Error(\"useOnResetMatchCallback: OnResetMatchContext not found\");\n }\n\n return onResetMatch;\n}\n\nexport { Item, List };\n"],"names":["createContext","forwardRef","useLexicalComposerContext","useState","useEffect","KEY_ARROW_DOWN_COMMAND","COMMAND_PRIORITY_LOW","KEY_ARROW_UP_COMMAND","KEY_ESCAPE_COMMAND","KEY_ENTER_COMMAND","jsx","Item","useRef","useImperativeHandle","useContext"],"mappings":";;;;;;;AA0Ba,MAAA,kBAAA,GAAqBA,oBAAoC,IAAI,EAAA;AAE7D,MAAA,iCAAA,GAAoCA,oBAE/C,IAAI,EAAA;AAEC,MAAM,2BAA8B,GAAAA,mBAAA;AAAA,EACzC,IAAA;AACF,EAAA;AAEA,MAAM,uBAAA,GAA0BA,oBAE9B,IAAI,CAAA,CAAA;AAMN,MAAM,IAAO,GAAAC,gBAAA;AAAA,EACX,SAAU,OAAO,YAAc,EAAA;AAC7B,IAAA,MAAM,EAAE,QAAA,EAAU,GAAG,QAAA,EAAa,GAAA,KAAA,CAAA;AAClC,IAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAC3C,IAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIC,eAAS,CAAC,CAAA,CAAA;AAC1D,IAAA,MAAM,cAAc,cAAe,EAAA,CAAA;AACnC,IAAA,MAAM,qBAAqB,6BAA8B,EAAA,CAAA;AACzD,IAAA,MAAM,kBAAkB,uBAAwB,EAAA,CAAA;AAEhD,IAAAC,eAAA,CAAU,MAAM;AACd,MAAA,SAAS,eAAe,KAA+B,EAAA;AACrD,QAAA,IAAI,YAAY,MAAW,KAAA,CAAA;AAAG,UAAO,OAAA,IAAA,CAAA;AACrC,QAAA,IAAI,gBAAqB,KAAA,IAAA;AAAM,UAAO,OAAA,IAAA,CAAA;AAGtC,QAAA,MAAM,YACJ,gBAAqB,KAAA,WAAA,CAAY,MAAS,GAAA,CAAA,GACtC,IACA,gBAAmB,GAAA,CAAA,CAAA;AACzB,QAAA,mBAAA,CAAoB,SAAS,CAAA,CAAA;AAE7B,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,wBAAyB,EAAA,CAAA;AAE/B,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAA,OAAO,MAAO,CAAA,eAAA;AAAA,QACZC,8BAAA;AAAA,QACA,cAAA;AAAA,QACAC,4BAAA;AAAA,OACF,CAAA;AAAA,KACC,EAAA,CAAC,MAAQ,EAAA,gBAAA,EAAkB,WAAW,CAAC,CAAA,CAAA;AAE1C,IAAAF,eAAA,CAAU,MAAM;AACd,MAAA,SAAS,aAAa,KAA+B,EAAA;AACnD,QAAA,IAAI,YAAY,MAAW,KAAA,CAAA;AAAG,UAAO,OAAA,IAAA,CAAA;AACrC,QAAA,IAAI,gBAAqB,KAAA,IAAA;AAAM,UAAO,OAAA,IAAA,CAAA;AAGtC,QAAA,MAAM,YACJ,gBAAqB,KAAA,CAAA,GACjB,WAAY,CAAA,MAAA,GAAS,IACrB,gBAAmB,GAAA,CAAA,CAAA;AACzB,QAAA,mBAAA,CAAoB,SAAS,CAAA,CAAA;AAE7B,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,wBAAyB,EAAA,CAAA;AAC/B,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAA,OAAO,MAAO,CAAA,eAAA;AAAA,QACZG,4BAAA;AAAA,QACA,YAAA;AAAA,QACAD,4BAAA;AAAA,OACF,CAAA;AAAA,KACC,EAAA,CAAC,MAAQ,EAAA,gBAAA,EAAkB,WAAW,CAAC,CAAA,CAAA;AAE1C,IAAAF,eAAA,CAAU,MAAM;AACd,MAAA,SAAS,YAAY,KAA+B,EAAA;AAClD,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,wBAAyB,EAAA,CAAA;AAE/B,QAAgB,eAAA,EAAA,CAAA;AAChB,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAA,OAAO,MAAO,CAAA,eAAA;AAAA,QACZI,0BAAA;AAAA,QACA,WAAA;AAAA,QACAF,4BAAA;AAAA,OACF,CAAA;AAAA,KACC,EAAA,CAAC,MAAQ,EAAA,eAAe,CAAC,CAAA,CAAA;AAE5B,IAAAF,eAAA,CAAU,MAAM;AACd,MAAA,SAAS,WAAW,KAAsC,EAAA;AACxD,QAAA,IAAI,YAAY,MAAW,KAAA,CAAA;AAAG,UAAO,OAAA,IAAA,CAAA;AAErC,QAAmB,kBAAA,CAAA,WAAA,CAAY,gBAAgB,CAAC,CAAA,CAAA;AAEhD,QAAA,IAAI,KAAU,KAAA,IAAA;AAAM,UAAO,OAAA,IAAA,CAAA;AAE3B,QAAA,KAAA,CAAM,cAAe,EAAA,CAAA;AACrB,QAAA,KAAA,CAAM,wBAAyB,EAAA,CAAA;AAC/B,QAAO,OAAA,IAAA,CAAA;AAAA,OACT;AAEA,MAAA,OAAO,MAAO,CAAA,eAAA;AAAA,QACZK,yBAAA;AAAA,QACA,UAAA;AAAA,QACAH,4BAAA;AAAA,OACF,CAAA;AAAA,OACC,CAAC,MAAA,EAAQ,kBAAoB,EAAA,gBAAA,EAAkB,WAAW,CAAC,CAAA,CAAA;AAE9D,IAAAF,eAAA,CAAU,MAAM;AACd,MAAM,MAAA,IAAA,GAAO,OAAO,cAAe,EAAA,CAAA;AACnC,MAAA,IAAI,IAAS,KAAA,IAAA;AAAM,QAAA,OAAA;AAEnB,MAAK,IAAA,CAAA,YAAA;AAAA,QACH,uBAAA;AAAA,QACA,kBAAkB,gBAAgB,CAAA,CAAA;AAAA,OACpC,CAAA;AAEA,MAAA,OAAO,MAAM;AACX,QAAA,IAAA,CAAK,gBAAgB,uBAAuB,CAAA,CAAA;AAAA,OAC9C,CAAA;AAAA,KACC,EAAA,CAAC,MAAQ,EAAA,gBAAgB,CAAC,CAAA,CAAA;AAE7B,IACE,uBAAAM,cAAA;AAAA,MAAC,uBAAwB,CAAA,QAAA;AAAA,MAAxB;AAAA,QACC,KAAA,EAAO,CAAC,gBAAA,EAAkB,mBAAmB,CAAA;AAAA,QAE7C,QAAA,kBAAAA,cAAA,CAAC,SAAI,IAAK,EAAA,SAAA,EAAW,GAAG,QAAU,EAAA,GAAA,EAAK,cACpC,QACH,EAAA,CAAA;AAAA,OAAA;AAAA,KACF,CAAA;AAAA,GAEJ;AACF,EAAA;AAMA,MAAM,IAAO,GAAAT,gBAAA;AAAA,EACX,SAASU,KAAK,CAAA,KAAA,EAAO,YAAc,EAAA;AACjC,IAAA,MAAM,EAAE,QAAU,EAAA,KAAA,EAAO,cAAc,OAAS,EAAA,GAAG,UAAa,GAAA,KAAA,CAAA;AAChE,IAAM,MAAA,MAAA,GAASC,aAAuB,IAAI,CAAA,CAAA;AAE1C,IAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,mBAAoB,EAAA,CAAA;AACpE,IAAA,MAAM,cAAc,cAAe,EAAA,CAAA;AACnC,IAAA,MAAM,qBAAqB,6BAA8B,EAAA,CAAA;AAEzD,IAAA,MAAM,aAAgB,GAAA,WAAA,CAAY,gBAAgB,CAAA,CAAE,EAAO,KAAA,KAAA,CAAA;AAE3D,IAAAC,yBAAA;AAAA,MACE,YAAA;AAAA,MACA,MAAM,MAAO,CAAA,OAAA;AAAA,KACf,CAAA;AAEA,IAAAT,eAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,aAAA;AAAe,QAAA,OAAA;AAEpB,MAAA,MAAM,MAAM,MAAO,CAAA,OAAA,CAAA;AACnB,MAAA,IAAI,GAAQ,KAAA,IAAA;AAAM,QAAA,OAAA;AAElB,MAAA,GAAA,CAAI,cAAe,CAAA,EAAE,KAAO,EAAA,SAAA,EAAW,CAAA,CAAA;AAAA,KACzC,EAAG,CAAC,aAAa,CAAC,CAAA,CAAA;AAElB,IAAA,SAAS,iBAAiB,KAAmC,EAAA;AAC3D,MAAA,YAAA,GAAe,KAAK,CAAA,CAAA;AAEpB,MAAA,IAAI,MAAM,kBAAmB,EAAA;AAAG,QAAA,OAAA;AAEhC,MAAA,MAAM,QAAQ,WAAY,CAAA,SAAA;AAAA,QACxB,CAAC,UAAe,KAAA,UAAA,CAAW,EAAO,KAAA,KAAA;AAAA,OACpC,CAAA;AACA,MAAA,IAAI,KAAU,KAAA,CAAA,CAAA;AAAI,QAAA,OAAA;AAElB,MAAA,mBAAA,CAAoB,KAAK,CAAA,CAAA;AAAA,KAC3B;AAEA,IAAA,SAAS,YAAY,KAAmC,EAAA;AACtD,MAAA,OAAA,GAAU,KAAK,CAAA,CAAA;AAEf,MAAA,IAAI,MAAM,kBAAmB,EAAA;AAAG,QAAA,OAAA;AAEhC,MAAmB,kBAAA,CAAA,WAAA,CAAY,gBAAgB,CAAC,CAAA,CAAA;AAAA,KAClD;AAEA,IACE,uBAAAM,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,QAAA;AAAA,QACL,oBAAkB,aAAiB,IAAA,KAAA,CAAA;AAAA,QACnC,YAAc,EAAA,gBAAA;AAAA,QACd,OAAS,EAAA,WAAA;AAAA,QACR,GAAG,QAAA;AAAA,QACJ,GAAK,EAAA,MAAA;AAAA,QAEJ,QAAA;AAAA,OAAA;AAAA,KACH,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,SAAS,mBAAkE,GAAA;AACzE,EAAM,MAAA,OAAA,GAAUI,iBAAW,uBAAuB,CAAA,CAAA;AAClD,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,oEAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAO,OAAA,OAAA,CAAA;AACT,CAAA;AAEA,SAAS,cAAgC,GAAA;AACvC,EAAM,MAAA,WAAA,GAAcA,iBAAW,kBAAkB,CAAA,CAAA;AACjD,EAAA,IAAI,gBAAgB,IAAM,EAAA;AACxB,IAAM,MAAA,IAAI,MAAM,8CAA8C,CAAA,CAAA;AAAA,GAChE;AAEA,EAAO,OAAA,WAAA,CAAA;AACT,CAAA;AAEA,SAAS,6BAAgE,GAAA;AACvE,EAAM,MAAA,kBAAA,GAAqBA,iBAAW,iCAAiC,CAAA,CAAA;AACvE,EAAA,IAAI,uBAAuB,IAAM,EAAA;AAC/B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,oEAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,kBAAA,CAAA;AACT,CAAA;AAEA,SAAS,uBAAsC,GAAA;AAC7C,EAAM,MAAA,YAAA,GAAeA,iBAAW,2BAA2B,CAAA,CAAA;AAC3D,EAAA,IAAI,iBAAiB,IAAM,EAAA;AACzB,IAAM,MAAA,IAAI,MAAM,wDAAwD,CAAA,CAAA;AAAA,GAC1E;AAEA,EAAO,OAAA,YAAA,CAAA;AACT;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"suggestions.cjs","sources":["../../src/mentions/suggestions.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { MentionData } from \"@liveblocks/core\";\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport type {\n Dispatch,\n HTMLAttributes,\n MouseEvent,\n ReactNode,\n SetStateAction,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nexport const SuggestionsContext = createContext<MentionData[] | null>(null);\n\nexport const OnSuggestionSelectCallbackContext = createContext<\n ((mention: MentionData) => void) | null\n>(null);\n\nexport const OnResetMatchCallbackContext = createContext<(() => void) | null>(\n null\n);\n\nconst HighlightedIndexContext = createContext<\n [number, Dispatch<SetStateAction<number>>] | null\n>(null);\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst List = forwardRef<HTMLDivElement, ListProps>(\n function (props, forwardedRef) {\n const { children, ...divProps } = props;\n const [editor] = useLexicalComposerContext();\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n const onEscapeKeyDown = useOnResetMatchCallback();\n\n useEffect(() => {\n function onKeyArrowDown(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the last suggestion, then we loop back to the first suggestion, otherwise we increment the index.\n const nextIndex =\n highlightedIndex === suggestions.length - 1\n ? 0\n : highlightedIndex + 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n onKeyArrowDown,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyArrowUp(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the first suggestion, then we loop back to the last suggestion, otherwise we decrement the index.\n const nextIndex =\n highlightedIndex === 0\n ? suggestions.length - 1\n : highlightedIndex - 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n onKeyArrowUp,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyEscape(event: KeyboardEvent): boolean {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n onEscapeKeyDown();\n return true;\n }\n\n return editor.registerCommand<KeyboardEvent>(\n KEY_ESCAPE_COMMAND,\n onKeyEscape,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onEscapeKeyDown]);\n\n useEffect(() => {\n function onKeyEnter(event: KeyboardEvent | null): boolean {\n if (suggestions.length === 0) return true;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n\n if (event === null) return true;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n onKeyEnter,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onSuggestionSelect, highlightedIndex, suggestions]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n if (root === null) return;\n\n root.setAttribute(\n \"aria-activedescendant\",\n `typeahead-item-${highlightedIndex}`\n );\n\n return () => {\n root.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, highlightedIndex]);\n\n return (\n <HighlightedIndexContext.Provider\n value={[highlightedIndex, setHighlightedIndex]}\n >\n <div role=\"listbox\" {...divProps} ref={forwardedRef}>\n {children}\n </div>\n </HighlightedIndexContext.Provider>\n );\n }\n);\n\ninterface ItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nconst Item = forwardRef<HTMLDivElement | null, ItemProps>(\n function Item(props, forwardedRef) {\n const { children, value, onMouseEnter, onClick, ...divProps } = props;\n const divRef = useRef<HTMLDivElement>(null);\n\n const [highlightedIndex, setHighlightedIndex] = useHighlightedIndex();\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n\n const isHighlighted = suggestions[highlightedIndex].id === value;\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n if (!isHighlighted) return;\n\n const div = divRef.current;\n if (div === null) return;\n\n div.scrollIntoView({ block: \"nearest\" });\n }, [isHighlighted]);\n\n function handleMouseEnter(event: MouseEvent<HTMLDivElement>) {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n const index = suggestions.findIndex(\n (suggestion) => suggestion.id === value\n );\n if (index === -1) return;\n\n setHighlightedIndex(index);\n }\n\n function handleClick(event: MouseEvent<HTMLDivElement>) {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n }\n\n return (\n <div\n role=\"option\"\n data-highlighted={isHighlighted || undefined}\n onMouseEnter={handleMouseEnter}\n onClick={handleClick}\n {...divProps}\n ref={divRef}\n >\n {children}\n </div>\n );\n }\n);\n\nfunction useHighlightedIndex(): [number, Dispatch<SetStateAction<number>>] {\n const context = useContext(HighlightedIndexContext);\n if (context === null) {\n throw new Error(\n \"useHighlightedIndex must be used within a HighlightedIndexProvider\"\n );\n }\n return context;\n}\n\nfunction useSuggestions(): MentionData[] {\n const suggestions = useContext(SuggestionsContext);\n if (suggestions === null) {\n throw new Error(\"useSuggestions: SuggestionsContext not found\");\n }\n\n return suggestions;\n}\n\nfunction useOnSuggestionSelectCallback(): (mention: MentionData) => void {\n const onSuggestionSelect = useContext(OnSuggestionSelectCallbackContext);\n if (onSuggestionSelect === null) {\n throw new Error(\n \"useOnSuggestionSelectCallback: OnSuggestionSelectContext not found\"\n );\n }\n\n return onSuggestionSelect;\n}\n\nfunction useOnResetMatchCallback(): () => void {\n const onResetMatch = useContext(OnResetMatchCallbackContext);\n if (onResetMatch === null) {\n throw new Error(\"useOnResetMatchCallback: OnResetMatchContext not found\");\n }\n\n return onResetMatch;\n}\n\nexport { Item, List };\n"],"names":["createContext","forwardRef","useLexicalComposerContext","useState","useEffect","KEY_ARROW_DOWN_COMMAND","COMMAND_PRIORITY_LOW","KEY_ARROW_UP_COMMAND","KEY_ESCAPE_COMMAND","KEY_ENTER_COMMAND","jsx","Item","useRef","useImperativeHandle","useContext"],"mappings":"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"}
|
|
@@ -19,10 +19,8 @@ const List = forwardRef(
|
|
|
19
19
|
const onEscapeKeyDown = useOnResetMatchCallback();
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
function onKeyArrowDown(event) {
|
|
22
|
-
if (suggestions.length === 0)
|
|
23
|
-
|
|
24
|
-
if (highlightedIndex === null)
|
|
25
|
-
return true;
|
|
22
|
+
if (suggestions.length === 0) return true;
|
|
23
|
+
if (highlightedIndex === null) return true;
|
|
26
24
|
const nextIndex = highlightedIndex === suggestions.length - 1 ? 0 : highlightedIndex + 1;
|
|
27
25
|
setHighlightedIndex(nextIndex);
|
|
28
26
|
event.preventDefault();
|
|
@@ -37,10 +35,8 @@ const List = forwardRef(
|
|
|
37
35
|
}, [editor, highlightedIndex, suggestions]);
|
|
38
36
|
useEffect(() => {
|
|
39
37
|
function onKeyArrowUp(event) {
|
|
40
|
-
if (suggestions.length === 0)
|
|
41
|
-
|
|
42
|
-
if (highlightedIndex === null)
|
|
43
|
-
return true;
|
|
38
|
+
if (suggestions.length === 0) return true;
|
|
39
|
+
if (highlightedIndex === null) return true;
|
|
44
40
|
const nextIndex = highlightedIndex === 0 ? suggestions.length - 1 : highlightedIndex - 1;
|
|
45
41
|
setHighlightedIndex(nextIndex);
|
|
46
42
|
event.preventDefault();
|
|
@@ -68,11 +64,9 @@ const List = forwardRef(
|
|
|
68
64
|
}, [editor, onEscapeKeyDown]);
|
|
69
65
|
useEffect(() => {
|
|
70
66
|
function onKeyEnter(event) {
|
|
71
|
-
if (suggestions.length === 0)
|
|
72
|
-
return true;
|
|
67
|
+
if (suggestions.length === 0) return true;
|
|
73
68
|
onSuggestionSelect(suggestions[highlightedIndex]);
|
|
74
|
-
if (event === null)
|
|
75
|
-
return true;
|
|
69
|
+
if (event === null) return true;
|
|
76
70
|
event.preventDefault();
|
|
77
71
|
event.stopImmediatePropagation();
|
|
78
72
|
return true;
|
|
@@ -85,8 +79,7 @@ const List = forwardRef(
|
|
|
85
79
|
}, [editor, onSuggestionSelect, highlightedIndex, suggestions]);
|
|
86
80
|
useEffect(() => {
|
|
87
81
|
const root = editor.getRootElement();
|
|
88
|
-
if (root === null)
|
|
89
|
-
return;
|
|
82
|
+
if (root === null) return;
|
|
90
83
|
root.setAttribute(
|
|
91
84
|
"aria-activedescendant",
|
|
92
85
|
`typeahead-item-${highlightedIndex}`
|
|
@@ -117,28 +110,23 @@ const Item = forwardRef(
|
|
|
117
110
|
() => divRef.current
|
|
118
111
|
);
|
|
119
112
|
useEffect(() => {
|
|
120
|
-
if (!isHighlighted)
|
|
121
|
-
return;
|
|
113
|
+
if (!isHighlighted) return;
|
|
122
114
|
const div = divRef.current;
|
|
123
|
-
if (div === null)
|
|
124
|
-
return;
|
|
115
|
+
if (div === null) return;
|
|
125
116
|
div.scrollIntoView({ block: "nearest" });
|
|
126
117
|
}, [isHighlighted]);
|
|
127
118
|
function handleMouseEnter(event) {
|
|
128
119
|
onMouseEnter?.(event);
|
|
129
|
-
if (event.isDefaultPrevented())
|
|
130
|
-
return;
|
|
120
|
+
if (event.isDefaultPrevented()) return;
|
|
131
121
|
const index = suggestions.findIndex(
|
|
132
122
|
(suggestion) => suggestion.id === value
|
|
133
123
|
);
|
|
134
|
-
if (index === -1)
|
|
135
|
-
return;
|
|
124
|
+
if (index === -1) return;
|
|
136
125
|
setHighlightedIndex(index);
|
|
137
126
|
}
|
|
138
127
|
function handleClick(event) {
|
|
139
128
|
onClick?.(event);
|
|
140
|
-
if (event.isDefaultPrevented())
|
|
141
|
-
return;
|
|
129
|
+
if (event.isDefaultPrevented()) return;
|
|
142
130
|
onSuggestionSelect(suggestions[highlightedIndex]);
|
|
143
131
|
}
|
|
144
132
|
return /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suggestions.js","sources":["../../src/mentions/suggestions.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { MentionData } from \"@liveblocks/core\";\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport type {\n Dispatch,\n HTMLAttributes,\n MouseEvent,\n ReactNode,\n SetStateAction,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nexport const SuggestionsContext = createContext<MentionData[] | null>(null);\n\nexport const OnSuggestionSelectCallbackContext = createContext<\n ((mention: MentionData) => void) | null\n>(null);\n\nexport const OnResetMatchCallbackContext = createContext<(() => void) | null>(\n null\n);\n\nconst HighlightedIndexContext = createContext<\n [number, Dispatch<SetStateAction<number>>] | null\n>(null);\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst List = forwardRef<HTMLDivElement, ListProps>(\n function (props, forwardedRef) {\n const { children, ...divProps } = props;\n const [editor] = useLexicalComposerContext();\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n const onEscapeKeyDown = useOnResetMatchCallback();\n\n useEffect(() => {\n function onKeyArrowDown(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the last suggestion, then we loop back to the first suggestion, otherwise we increment the index.\n const nextIndex =\n highlightedIndex === suggestions.length - 1\n ? 0\n : highlightedIndex + 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n onKeyArrowDown,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyArrowUp(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the first suggestion, then we loop back to the last suggestion, otherwise we decrement the index.\n const nextIndex =\n highlightedIndex === 0\n ? suggestions.length - 1\n : highlightedIndex - 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n onKeyArrowUp,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyEscape(event: KeyboardEvent): boolean {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n onEscapeKeyDown();\n return true;\n }\n\n return editor.registerCommand<KeyboardEvent>(\n KEY_ESCAPE_COMMAND,\n onKeyEscape,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onEscapeKeyDown]);\n\n useEffect(() => {\n function onKeyEnter(event: KeyboardEvent | null): boolean {\n if (suggestions.length === 0) return true;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n\n if (event === null) return true;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n onKeyEnter,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onSuggestionSelect, highlightedIndex, suggestions]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n if (root === null) return;\n\n root.setAttribute(\n \"aria-activedescendant\",\n `typeahead-item-${highlightedIndex}`\n );\n\n return () => {\n root.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, highlightedIndex]);\n\n return (\n <HighlightedIndexContext.Provider\n value={[highlightedIndex, setHighlightedIndex]}\n >\n <div role=\"listbox\" {...divProps} ref={forwardedRef}>\n {children}\n </div>\n </HighlightedIndexContext.Provider>\n );\n }\n);\n\ninterface ItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nconst Item = forwardRef<HTMLDivElement | null, ItemProps>(\n function Item(props, forwardedRef) {\n const { children, value, onMouseEnter, onClick, ...divProps } = props;\n const divRef = useRef<HTMLDivElement>(null);\n\n const [highlightedIndex, setHighlightedIndex] = useHighlightedIndex();\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n\n const isHighlighted = suggestions[highlightedIndex].id === value;\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n if (!isHighlighted) return;\n\n const div = divRef.current;\n if (div === null) return;\n\n div.scrollIntoView({ block: \"nearest\" });\n }, [isHighlighted]);\n\n function handleMouseEnter(event: MouseEvent<HTMLDivElement>) {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n const index = suggestions.findIndex(\n (suggestion) => suggestion.id === value\n );\n if (index === -1) return;\n\n setHighlightedIndex(index);\n }\n\n function handleClick(event: MouseEvent<HTMLDivElement>) {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n }\n\n return (\n <div\n role=\"option\"\n data-highlighted={isHighlighted || undefined}\n onMouseEnter={handleMouseEnter}\n onClick={handleClick}\n {...divProps}\n ref={divRef}\n >\n {children}\n </div>\n );\n }\n);\n\nfunction useHighlightedIndex(): [number, Dispatch<SetStateAction<number>>] {\n const context = useContext(HighlightedIndexContext);\n if (context === null) {\n throw new Error(\n \"useHighlightedIndex must be used within a HighlightedIndexProvider\"\n );\n }\n return context;\n}\n\nfunction useSuggestions(): MentionData[] {\n const suggestions = useContext(SuggestionsContext);\n if (suggestions === null) {\n throw new Error(\"useSuggestions: SuggestionsContext not found\");\n }\n\n return suggestions;\n}\n\nfunction useOnSuggestionSelectCallback(): (mention: MentionData) => void {\n const onSuggestionSelect = useContext(OnSuggestionSelectCallbackContext);\n if (onSuggestionSelect === null) {\n throw new Error(\n \"useOnSuggestionSelectCallback: OnSuggestionSelectContext not found\"\n );\n }\n\n return onSuggestionSelect;\n}\n\nfunction useOnResetMatchCallback(): () => void {\n const onResetMatch = useContext(OnResetMatchCallbackContext);\n if (onResetMatch === null) {\n throw new Error(\"useOnResetMatchCallback: OnResetMatchContext not found\");\n }\n\n return onResetMatch;\n}\n\nexport { Item, List };\n"],"names":["Item"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"suggestions.js","sources":["../../src/mentions/suggestions.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { MentionData } from \"@liveblocks/core\";\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport type {\n Dispatch,\n HTMLAttributes,\n MouseEvent,\n ReactNode,\n SetStateAction,\n} from \"react\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nexport const SuggestionsContext = createContext<MentionData[] | null>(null);\n\nexport const OnSuggestionSelectCallbackContext = createContext<\n ((mention: MentionData) => void) | null\n>(null);\n\nexport const OnResetMatchCallbackContext = createContext<(() => void) | null>(\n null\n);\n\nconst HighlightedIndexContext = createContext<\n [number, Dispatch<SetStateAction<number>>] | null\n>(null);\n\nexport interface ListProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst List = forwardRef<HTMLDivElement, ListProps>(\n function (props, forwardedRef) {\n const { children, ...divProps } = props;\n const [editor] = useLexicalComposerContext();\n const [highlightedIndex, setHighlightedIndex] = useState(0);\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n const onEscapeKeyDown = useOnResetMatchCallback();\n\n useEffect(() => {\n function onKeyArrowDown(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the last suggestion, then we loop back to the first suggestion, otherwise we increment the index.\n const nextIndex =\n highlightedIndex === suggestions.length - 1\n ? 0\n : highlightedIndex + 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n onKeyArrowDown,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyArrowUp(event: KeyboardEvent): boolean {\n if (suggestions.length === 0) return true;\n if (highlightedIndex === null) return true;\n\n // If the highlighted index is at the first suggestion, then we loop back to the last suggestion, otherwise we decrement the index.\n const nextIndex =\n highlightedIndex === 0\n ? suggestions.length - 1\n : highlightedIndex - 1;\n setHighlightedIndex(nextIndex);\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n onKeyArrowUp,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, highlightedIndex, suggestions]);\n\n useEffect(() => {\n function onKeyEscape(event: KeyboardEvent): boolean {\n event.preventDefault();\n event.stopImmediatePropagation();\n\n onEscapeKeyDown();\n return true;\n }\n\n return editor.registerCommand<KeyboardEvent>(\n KEY_ESCAPE_COMMAND,\n onKeyEscape,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onEscapeKeyDown]);\n\n useEffect(() => {\n function onKeyEnter(event: KeyboardEvent | null): boolean {\n if (suggestions.length === 0) return true;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n\n if (event === null) return true;\n\n event.preventDefault();\n event.stopImmediatePropagation();\n return true;\n }\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n onKeyEnter,\n COMMAND_PRIORITY_LOW\n );\n }, [editor, onSuggestionSelect, highlightedIndex, suggestions]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n if (root === null) return;\n\n root.setAttribute(\n \"aria-activedescendant\",\n `typeahead-item-${highlightedIndex}`\n );\n\n return () => {\n root.removeAttribute(\"aria-activedescendant\");\n };\n }, [editor, highlightedIndex]);\n\n return (\n <HighlightedIndexContext.Provider\n value={[highlightedIndex, setHighlightedIndex]}\n >\n <div role=\"listbox\" {...divProps} ref={forwardedRef}>\n {children}\n </div>\n </HighlightedIndexContext.Provider>\n );\n }\n);\n\ninterface ItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n}\n\nconst Item = forwardRef<HTMLDivElement | null, ItemProps>(\n function Item(props, forwardedRef) {\n const { children, value, onMouseEnter, onClick, ...divProps } = props;\n const divRef = useRef<HTMLDivElement>(null);\n\n const [highlightedIndex, setHighlightedIndex] = useHighlightedIndex();\n const suggestions = useSuggestions();\n const onSuggestionSelect = useOnSuggestionSelectCallback();\n\n const isHighlighted = suggestions[highlightedIndex].id === value;\n\n useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n forwardedRef,\n () => divRef.current\n );\n\n useEffect(() => {\n if (!isHighlighted) return;\n\n const div = divRef.current;\n if (div === null) return;\n\n div.scrollIntoView({ block: \"nearest\" });\n }, [isHighlighted]);\n\n function handleMouseEnter(event: MouseEvent<HTMLDivElement>) {\n onMouseEnter?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n const index = suggestions.findIndex(\n (suggestion) => suggestion.id === value\n );\n if (index === -1) return;\n\n setHighlightedIndex(index);\n }\n\n function handleClick(event: MouseEvent<HTMLDivElement>) {\n onClick?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n onSuggestionSelect(suggestions[highlightedIndex]);\n }\n\n return (\n <div\n role=\"option\"\n data-highlighted={isHighlighted || undefined}\n onMouseEnter={handleMouseEnter}\n onClick={handleClick}\n {...divProps}\n ref={divRef}\n >\n {children}\n </div>\n );\n }\n);\n\nfunction useHighlightedIndex(): [number, Dispatch<SetStateAction<number>>] {\n const context = useContext(HighlightedIndexContext);\n if (context === null) {\n throw new Error(\n \"useHighlightedIndex must be used within a HighlightedIndexProvider\"\n );\n }\n return context;\n}\n\nfunction useSuggestions(): MentionData[] {\n const suggestions = useContext(SuggestionsContext);\n if (suggestions === null) {\n throw new Error(\"useSuggestions: SuggestionsContext not found\");\n }\n\n return suggestions;\n}\n\nfunction useOnSuggestionSelectCallback(): (mention: MentionData) => void {\n const onSuggestionSelect = useContext(OnSuggestionSelectCallbackContext);\n if (onSuggestionSelect === null) {\n throw new Error(\n \"useOnSuggestionSelectCallback: OnSuggestionSelectContext not found\"\n );\n }\n\n return onSuggestionSelect;\n}\n\nfunction useOnResetMatchCallback(): () => void {\n const onResetMatch = useContext(OnResetMatchCallbackContext);\n if (onResetMatch === null) {\n throw new Error(\"useOnResetMatchCallback: OnResetMatchContext not found\");\n }\n\n return onResetMatch;\n}\n\nexport { Item, List };\n"],"names":["Item"],"mappings":"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"}
|
|
@@ -194,8 +194,7 @@ const FloatingToolbar = Object.assign(
|
|
|
194
194
|
react.useEffect(() => {
|
|
195
195
|
const unregister = editor.registerUpdateListener(({ tags }) => {
|
|
196
196
|
return editor.getEditorState().read(() => {
|
|
197
|
-
if (tags.has("collaboration"))
|
|
198
|
-
return;
|
|
197
|
+
if (tags.has("collaboration")) return;
|
|
199
198
|
setManuallyClosed(false);
|
|
200
199
|
const selection = lexical.$getSelection();
|
|
201
200
|
if (!lexical.$isRangeSelection(selection) || selection.isCollapsed()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-toolbar.cjs","sources":["../../src/toolbar/floating-toolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n cn,\n Portal,\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND } from \"lexical\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { OPEN_FLOATING_COMPOSER_COMMAND } from \"../comments/floating-composer\";\nimport { createDOMRange } from \"../create-dom-range\";\nimport { useIsCommandRegistered } from \"../is-command-registered\";\nimport type { FloatingPosition } from \"../types\";\nimport { useRootElement } from \"../use-root-element\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./toolbar\";\n\nexport interface FloatingToolbarProps\n extends Omit<ComponentProps<\"div\">, \"children\"> {\n /**\n * The vertical position of the floating toolbar.\n */\n position?: FloatingPosition;\n\n /**\n * The vertical offset of the floating toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The content of the floating toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the floating toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the floating toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent() {\n const supportsTextFormat = useIsCommandRegistered(FORMAT_TEXT_COMMAND);\n const supportsThread = useIsCommandRegistered(OPEN_FLOATING_COMPOSER_COMMAND);\n\n return (\n <>\n {supportsTextFormat ? (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n </>\n ) : null}\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A floating toolbar attached to the selection and containing actions and values related to the editor.\n *\n * @example\n * <FloatingToolbar />\n *\n * @example\n * <FloatingToolbar>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </FloatingToolbar>\n */\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [editor] = useLexicalComposerContext();\n const root = useRootElement();\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const [hasSelectionRange, setHasSelectionRange] = useState(false);\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n setManuallyClosed(false);\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!root) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === root) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n root.addEventListener(\"focus\", handleFocus);\n root.addEventListener(\"blur\", handleBlur);\n\n return () => {\n root.removeEventListener(\"focus\", handleFocus);\n root.removeEventListener(\"blur\", handleBlur);\n };\n }, [root, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === root) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, root, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n if (!root) {\n return;\n }\n\n root.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"pointercancel\", handlePointerUp);\n document.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n root.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"pointercancel\", handlePointerUp);\n document.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [root]);\n\n useEffect(() => {\n const unregister = editor.registerUpdateListener(({ tags }) => {\n return editor.getEditorState().read(() => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n\n setManuallyClosed(false);\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n setHasSelectionRange(false);\n setReference(null);\n return;\n }\n\n const { anchor, focus } = selection;\n\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n setHasSelectionRange(true);\n setReference(range);\n });\n });\n\n return unregister;\n }, [editor, setReference]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n\n if (!root || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== root && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.focus();\n setManuallyClosed(true);\n }\n };\n\n root.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n root.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n editor.focus();\n setManuallyClosed(true);\n }, [editor, setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <Portal asChild>\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating-toolbar lb-lexical-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n <TooltipProvider>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </FloatingToolbarContext.Provider>\n </TooltipProvider>\n </div>\n </Portal>\n );\n }\n ),\n {\n /**\n * A component that can be wrapped around elements which are rendered outside of the floating\n * toolbar (e.g. portals) to prevent the toolbar from closing when clicking/focusing within them.\n *\n * @example\n * <FloatingToolbar>\n * <Popover.Root>\n * <Popover.Trigger asChild>\n * <Toolbar.Button>Open popover</Toolbar.Button>\n * </Popover.Trigger>\n * <Popover.Portal>\n * <FloatingToolbar.External>\n * <Popover.Content>\n * This popover is rendered outside of the floating toolbar, but the toolbar will not close when clicking/focusing within it.\n * </Popover.Content>\n * </FloatingToolbar.External>\n * </Popover.Portal>\n * </Popover.Root>\n * </FloatingToolbar>\n */\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["useIsCommandRegistered","FORMAT_TEXT_COMMAND","OPEN_FLOATING_COMPOSER_COMMAND","jsxs","Fragment","jsx","Toolbar","forwardRef","useRef","useInitial","useState","useLexicalComposerContext","useRootElement","useEffect","handleFocus","handleBlur","useCallback","useMemo","inline","flip","hide","shift","limitShift","offset","size","autoUpdate","useFloating","useRefs","handlePointerDown","$getSelection","$isRangeSelection","createDOMRange","root","Portal","cn","TooltipProvider","FloatingToolbarContext","applyToolbarSlot","FloatingToolbarExternal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating-toolbar.cjs","sources":["../../src/toolbar/floating-toolbar.tsx"],"sourcesContent":["import {\n autoUpdate,\n type DetectOverflowOptions,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n type UseFloatingOptions,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n cn,\n Portal,\n TooltipProvider,\n useInitial,\n useRefs,\n} from \"@liveblocks/react-ui/_private\";\nimport { $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND } from \"lexical\";\nimport type {\n ComponentProps,\n FocusEvent as ReactFocusEvent,\n PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { OPEN_FLOATING_COMPOSER_COMMAND } from \"../comments/floating-composer\";\nimport { createDOMRange } from \"../create-dom-range\";\nimport { useIsCommandRegistered } from \"../is-command-registered\";\nimport type { FloatingPosition } from \"../types\";\nimport { useRootElement } from \"../use-root-element\";\nimport { FloatingToolbarContext, FloatingToolbarExternal } from \"./shared\";\nimport {\n applyToolbarSlot,\n Toolbar,\n type ToolbarSlot,\n type ToolbarSlotProps,\n} from \"./toolbar\";\n\nexport interface FloatingToolbarProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /**\n * The vertical position of the floating toolbar.\n */\n position?: FloatingPosition;\n\n /**\n * The vertical offset of the floating toolbar from the selection.\n */\n offset?: number;\n\n /**\n * The content of the floating toolbar, overriding the default content.\n * Use the `before` and `after` props if you want to keep and extend the default content.\n */\n children?: ToolbarSlot;\n\n /**\n * The content to display at the start of the floating toolbar.\n */\n before?: ToolbarSlot;\n\n /**\n * The content to display at the end of the floating toolbar.\n */\n after?: ToolbarSlot;\n}\n\nexport const FLOATING_TOOLBAR_COLLISION_PADDING = 10;\nconst FLOATING_TOOLBAR_OPEN_DELAY = 50;\n\nfunction DefaultFloatingToolbarContent() {\n const supportsTextFormat = useIsCommandRegistered(FORMAT_TEXT_COMMAND);\n const supportsThread = useIsCommandRegistered(OPEN_FLOATING_COMPOSER_COMMAND);\n\n return (\n <>\n {supportsTextFormat ? (\n <>\n <Toolbar.BlockSelector />\n <Toolbar.SectionInline />\n </>\n ) : null}\n {supportsThread ? (\n <>\n <Toolbar.Separator />\n <Toolbar.SectionCollaboration />\n </>\n ) : null}\n </>\n );\n}\n\n/**\n * A floating toolbar attached to the selection and containing actions and values related to the editor.\n *\n * @example\n * <FloatingToolbar />\n *\n * @example\n * <FloatingToolbar>\n * <Toolbar.BlockSelector />\n * <Toolbar.Separator />\n * <Toolbar.SectionInline />\n * <Toolbar.Separator />\n * <Toolbar.Button name=\"Custom action\" onClick={() => { ... }} icon={<Icon.QuestionMark />} />\n * </FloatingToolbar>\n */\nexport const FloatingToolbar = Object.assign(\n forwardRef<HTMLDivElement, FloatingToolbarProps>(\n (\n {\n children = DefaultFloatingToolbarContent,\n before,\n after,\n position = \"top\",\n offset: sideOffset = 6,\n onPointerDown,\n onFocus,\n onBlur,\n className,\n ...props\n },\n forwardedRef\n ) => {\n const toolbarRef = useRef<HTMLDivElement>(null);\n const externalIds = useInitial<Set<string>>(() => new Set());\n const [isPointerDown, setPointerDown] = useState(false);\n const [editor] = useLexicalComposerContext();\n const root = useRootElement();\n const [isFocused, setFocused] = useState(false);\n const [isManuallyClosed, setManuallyClosed] = useState(false);\n const [hasSelectionRange, setHasSelectionRange] = useState(false);\n\n const isOpen =\n isFocused && !isPointerDown && hasSelectionRange && !isManuallyClosed;\n const [delayedIsOpen, setDelayedIsOpen] = useState(isOpen);\n const delayedIsOpenTimeoutRef = useRef<number>();\n\n // Reset the manually closed state when there's another change\n useEffect(() => {\n setManuallyClosed(false);\n }, [isFocused, hasSelectionRange, editor]);\n\n // Don't close when the focus moves from the editor to the toolbar\n useEffect(() => {\n if (!root) {\n return;\n }\n\n const handleFocus = () => {\n setFocused(true);\n };\n\n const handleBlur = (event: FocusEvent) => {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === root) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n };\n\n root.addEventListener(\"focus\", handleFocus);\n root.addEventListener(\"blur\", handleBlur);\n\n return () => {\n root.removeEventListener(\"focus\", handleFocus);\n root.removeEventListener(\"blur\", handleBlur);\n };\n }, [root, externalIds]);\n\n const handleFocus = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onFocus?.(event);\n\n if (!event.isDefaultPrevented()) {\n setFocused(true);\n }\n },\n [onFocus]\n );\n\n // Close the toolbar when the it loses focus to something else than the editor\n const handleBlur = useCallback(\n (event: ReactFocusEvent<HTMLDivElement>) => {\n onBlur?.(event);\n\n if (!event.isDefaultPrevented()) {\n if (\n event.relatedTarget &&\n toolbarRef.current?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n if (event.relatedTarget === root) {\n return;\n }\n\n for (const externalId of externalIds) {\n if (\n document\n .getElementById(externalId)\n ?.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n }\n\n setFocused(false);\n }\n },\n [onBlur, root, externalIds]\n );\n\n // Delay the opening of the toolbar to avoid flickering issues\n useEffect(() => {\n if (isOpen) {\n delayedIsOpenTimeoutRef.current = window.setTimeout(() => {\n setDelayedIsOpen(true);\n }, FLOATING_TOOLBAR_OPEN_DELAY);\n } else {\n setDelayedIsOpen(false);\n }\n\n return () => {\n window.clearTimeout(delayedIsOpenTimeoutRef.current);\n };\n }, [isOpen]);\n\n const floatingOptions: UseFloatingOptions = useMemo(() => {\n const detectOverflowOptions: DetectOverflowOptions = {\n padding: FLOATING_TOOLBAR_COLLISION_PADDING,\n };\n\n return {\n strategy: \"fixed\",\n placement: position,\n middleware: [\n inline(detectOverflowOptions),\n flip({ ...detectOverflowOptions, crossAxis: false }),\n hide(detectOverflowOptions),\n shift({\n ...detectOverflowOptions,\n limiter: limitShift(),\n }),\n offset(sideOffset),\n size(detectOverflowOptions),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n };\n }, [position, sideOffset]);\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n isPositioned,\n } = useFloating({\n ...floatingOptions,\n open: delayedIsOpen,\n });\n const mergedRefs = useRefs(forwardedRef, toolbarRef, setFloating);\n\n const handlePointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n\n event.stopPropagation();\n\n // Prevent the toolbar from closing when clicking on the toolbar itself\n if (event.target === toolbarRef.current) {\n event.preventDefault();\n }\n },\n [onPointerDown]\n );\n\n useEffect(() => {\n const handlePointerDown = () => {\n setPointerDown(true);\n };\n const handlePointerUp = () => {\n setPointerDown(false);\n };\n\n if (!root) {\n return;\n }\n\n root.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"pointercancel\", handlePointerUp);\n document.addEventListener(\"pointerup\", handlePointerUp);\n\n return () => {\n root.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"pointercancel\", handlePointerUp);\n document.removeEventListener(\"pointerup\", handlePointerUp);\n };\n }, [root]);\n\n useEffect(() => {\n const unregister = editor.registerUpdateListener(({ tags }) => {\n return editor.getEditorState().read(() => {\n // Ignore selection updates related to collaboration\n if (tags.has(\"collaboration\")) return;\n\n setManuallyClosed(false);\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n setHasSelectionRange(false);\n setReference(null);\n return;\n }\n\n const { anchor, focus } = selection;\n\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n setHasSelectionRange(true);\n setReference(range);\n });\n });\n\n return unregister;\n }, [editor, setReference]);\n\n useEffect(() => {\n const root = editor.getRootElement();\n\n if (!root || !delayedIsOpen) {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.target !== root && event.defaultPrevented) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n\n editor.focus();\n setManuallyClosed(true);\n }\n };\n\n root.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n root.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [editor, delayedIsOpen]);\n\n const close = useCallback(() => {\n editor.focus();\n setManuallyClosed(true);\n }, [editor, setManuallyClosed]);\n\n const registerExternal = useCallback(\n (id: string) => {\n externalIds.add(id);\n\n return () => {\n externalIds.delete(id);\n };\n },\n [externalIds]\n );\n\n if (!delayedIsOpen) {\n return null;\n }\n\n const slotProps: ToolbarSlotProps = { editor };\n\n return (\n <Portal asChild>\n <div\n role=\"toolbar\"\n aria-label=\"Floating toolbar\"\n aria-orientation=\"horizontal\"\n className={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating-toolbar lb-lexical-toolbar\",\n className\n )}\n ref={mergedRefs}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: isPositioned\n ? `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`\n : \"translate3d(0, -200%, 0)\",\n minWidth: \"max-content\",\n }}\n onPointerDown={handlePointerDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n <TooltipProvider>\n <FloatingToolbarContext.Provider\n value={{ close, registerExternal }}\n >\n {applyToolbarSlot(before, slotProps)}\n {applyToolbarSlot(children, slotProps)}\n {applyToolbarSlot(after, slotProps)}\n </FloatingToolbarContext.Provider>\n </TooltipProvider>\n </div>\n </Portal>\n );\n }\n ),\n {\n /**\n * A component that can be wrapped around elements which are rendered outside of the floating\n * toolbar (e.g. portals) to prevent the toolbar from closing when clicking/focusing within them.\n *\n * @example\n * <FloatingToolbar>\n * <Popover.Root>\n * <Popover.Trigger asChild>\n * <Toolbar.Button>Open popover</Toolbar.Button>\n * </Popover.Trigger>\n * <Popover.Portal>\n * <FloatingToolbar.External>\n * <Popover.Content>\n * This popover is rendered outside of the floating toolbar, but the toolbar will not close when clicking/focusing within it.\n * </Popover.Content>\n * </FloatingToolbar.External>\n * </Popover.Portal>\n * </Popover.Root>\n * </FloatingToolbar>\n */\n External: FloatingToolbarExternal,\n }\n);\n"],"names":["useIsCommandRegistered","FORMAT_TEXT_COMMAND","OPEN_FLOATING_COMPOSER_COMMAND","jsxs","Fragment","jsx","Toolbar","forwardRef","useRef","useInitial","useState","useLexicalComposerContext","useRootElement","useEffect","handleFocus","handleBlur","useCallback","useMemo","inline","flip","hide","shift","limitShift","offset","size","autoUpdate","useFloating","useRefs","handlePointerDown","$getSelection","$isRangeSelection","createDOMRange","root","Portal","cn","TooltipProvider","FloatingToolbarContext","applyToolbarSlot","FloatingToolbarExternal"],"mappings":"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"}
|
|
@@ -192,8 +192,7 @@ const FloatingToolbar = Object.assign(
|
|
|
192
192
|
useEffect(() => {
|
|
193
193
|
const unregister = editor.registerUpdateListener(({ tags }) => {
|
|
194
194
|
return editor.getEditorState().read(() => {
|
|
195
|
-
if (tags.has("collaboration"))
|
|
196
|
-
return;
|
|
195
|
+
if (tags.has("collaboration")) return;
|
|
197
196
|
setManuallyClosed(false);
|
|
198
197
|
const selection = $getSelection();
|
|
199
198
|
if (!$isRangeSelection(selection) || selection.isCollapsed()) {
|