@liveblocks/react-lexical 3.9.1 → 3.9.2-tiptap1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/comments/anchored-threads.cjs +55 -42
  2. package/dist/comments/anchored-threads.cjs.map +1 -1
  3. package/dist/comments/anchored-threads.js +55 -42
  4. package/dist/comments/anchored-threads.js.map +1 -1
  5. package/dist/comments/comment-plugin-provider.cjs +1 -13
  6. package/dist/comments/comment-plugin-provider.cjs.map +1 -1
  7. package/dist/comments/comment-plugin-provider.js +1 -13
  8. package/dist/comments/comment-plugin-provider.js.map +1 -1
  9. package/dist/comments/floating-composer.cjs +57 -52
  10. package/dist/comments/floating-composer.cjs.map +1 -1
  11. package/dist/comments/floating-composer.js +57 -52
  12. package/dist/comments/floating-composer.js.map +1 -1
  13. package/dist/comments/floating-threads.cjs +39 -33
  14. package/dist/comments/floating-threads.cjs.map +1 -1
  15. package/dist/comments/floating-threads.js +39 -33
  16. package/dist/comments/floating-threads.js.map +1 -1
  17. package/dist/comments/thread-mark-node.cjs +2 -0
  18. package/dist/comments/thread-mark-node.cjs.map +1 -1
  19. package/dist/comments/thread-mark-node.js +2 -0
  20. package/dist/comments/thread-mark-node.js.map +1 -1
  21. package/dist/comments/unwrap-thread-mark-node.cjs.map +1 -1
  22. package/dist/comments/unwrap-thread-mark-node.js.map +1 -1
  23. package/dist/comments/wrap-selection-in-thread-mark-node.cjs.map +1 -1
  24. package/dist/comments/wrap-selection-in-thread-mark-node.js.map +1 -1
  25. package/dist/create-dom-range.cjs.map +1 -1
  26. package/dist/create-dom-range.js.map +1 -1
  27. package/dist/create-rects-from-dom-range.cjs.map +1 -1
  28. package/dist/create-rects-from-dom-range.js.map +1 -1
  29. package/dist/liveblocks-config.cjs +1 -0
  30. package/dist/liveblocks-config.cjs.map +1 -1
  31. package/dist/liveblocks-config.js +1 -0
  32. package/dist/liveblocks-config.js.map +1 -1
  33. package/dist/liveblocks-plugin-provider.cjs +15 -12
  34. package/dist/liveblocks-plugin-provider.cjs.map +1 -1
  35. package/dist/liveblocks-plugin-provider.js +15 -12
  36. package/dist/liveblocks-plugin-provider.js.map +1 -1
  37. package/dist/mentions/group-mention-node.cjs +5 -13
  38. package/dist/mentions/group-mention-node.cjs.map +1 -1
  39. package/dist/mentions/group-mention-node.js +5 -13
  40. package/dist/mentions/group-mention-node.js.map +1 -1
  41. package/dist/mentions/mention-component.cjs +11 -8
  42. package/dist/mentions/mention-component.cjs.map +1 -1
  43. package/dist/mentions/mention-component.js +11 -8
  44. package/dist/mentions/mention-component.js.map +1 -1
  45. package/dist/mentions/mention-node.cjs +4 -12
  46. package/dist/mentions/mention-node.cjs.map +1 -1
  47. package/dist/mentions/mention-node.js +4 -12
  48. package/dist/mentions/mention-node.js.map +1 -1
  49. package/dist/mentions/mention-plugin.cjs +64 -48
  50. package/dist/mentions/mention-plugin.cjs.map +1 -1
  51. package/dist/mentions/mention-plugin.js +64 -48
  52. package/dist/mentions/mention-plugin.js.map +1 -1
  53. package/dist/mentions/suggestions.cjs +19 -18
  54. package/dist/mentions/suggestions.cjs.map +1 -1
  55. package/dist/mentions/suggestions.js +19 -18
  56. package/dist/mentions/suggestions.js.map +1 -1
  57. package/dist/toolbar/floating-toolbar.cjs +59 -47
  58. package/dist/toolbar/floating-toolbar.cjs.map +1 -1
  59. package/dist/toolbar/floating-toolbar.js +59 -47
  60. package/dist/toolbar/floating-toolbar.js.map +1 -1
  61. package/dist/toolbar/shared.cjs +12 -11
  62. package/dist/toolbar/shared.cjs.map +1 -1
  63. package/dist/toolbar/shared.js +12 -11
  64. package/dist/toolbar/shared.js.map +1 -1
  65. package/dist/toolbar/toolbar.cjs +153 -117
  66. package/dist/toolbar/toolbar.cjs.map +1 -1
  67. package/dist/toolbar/toolbar.js +153 -117
  68. package/dist/toolbar/toolbar.js.map +1 -1
  69. package/dist/version-history/history-version-preview.cjs +36 -53
  70. package/dist/version-history/history-version-preview.cjs.map +1 -1
  71. package/dist/version-history/history-version-preview.js +36 -53
  72. package/dist/version-history/history-version-preview.js.map +1 -1
  73. package/dist/version.cjs +1 -1
  74. package/dist/version.cjs.map +1 -1
  75. package/dist/version.js +1 -1
  76. package/dist/version.js.map +1 -1
  77. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { shallow } from \"@liveblocks/client\";\nimport { useClient, useErrorListener, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useSignal,\n} from \"@liveblocks/react/_private\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useErrorListener((err) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (\n err.context.type === \"CREATE_THREAD_ERROR\" &&\n err.context.roomId === room.id\n ) {\n handleThreadDelete(err.context.threadId);\n }\n });\n\n const store = getUmbrellaStoreForClient(client);\n\n const roomId = room.id;\n const threadIds = useSignal(\n store.outputs.threads,\n useCallback(\n (state) =>\n state\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => thread.id),\n [roomId]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threadIds) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threadIds]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .some((thread) => thread.id === id);\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.outputs.threads.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, roomId, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["threadIds","activeElements"],"mappings":"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"}
1
+ {"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { shallow } from \"@liveblocks/client\";\nimport { useClient, useErrorListener, useRoom } from \"@liveblocks/react\";\nimport {\n getUmbrellaStoreForClient,\n useSignal,\n} from \"@liveblocks/react/_private\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useErrorListener((err) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (\n err.context.type === \"CREATE_THREAD_ERROR\" &&\n err.context.roomId === room.id\n ) {\n handleThreadDelete(err.context.threadId);\n }\n });\n\n const store = getUmbrellaStoreForClient(client);\n\n const roomId = room.id;\n const threadIds = useSignal(\n store.outputs.threads,\n useCallback(\n (state) =>\n state\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .map((thread) => thread.id),\n [roomId]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threadIds) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threadIds]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return store.outputs.threads\n .get()\n .findMany(roomId, { resolved: false }, \"asc\", undefined)\n .some((thread) => thread.id === id);\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.outputs.threads.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, roomId, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["threadIds","activeElements"],"mappings":"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"}
@@ -45,12 +45,15 @@ const FloatingComposer = react.forwardRef(function FloatingComposer2(props, forw
45
45
  }, [editor]);
46
46
  if (range === null)
47
47
  return null;
48
- return /* @__PURE__ */ jsxRuntime.jsx(FloatingComposerImpl, {
49
- ref: forwardedRef,
50
- ...props,
51
- range,
52
- onRangeChange: setRange
53
- });
48
+ return /* @__PURE__ */ jsxRuntime.jsx(
49
+ FloatingComposerImpl,
50
+ {
51
+ ref: forwardedRef,
52
+ ...props,
53
+ range,
54
+ onRangeChange: setRange
55
+ }
56
+ );
54
57
  });
55
58
  const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props, forwardedRef) {
56
59
  const {
@@ -130,25 +133,19 @@ const FloatingComposerImpl = react.forwardRef(function FloatingComposer3(props,
130
133
  editor.focus();
131
134
  }
132
135
  }
133
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
134
- children: [
135
- /* @__PURE__ */ jsxRuntime.jsx(ActiveSelectionPortal, {
136
- range,
137
- container: document.body
138
- }),
139
- /* @__PURE__ */ jsxRuntime.jsx(FloatingComposerPortal, {
140
- range,
141
- container: document.body,
142
- children: /* @__PURE__ */ jsxRuntime.jsx(Composer, {
143
- autoFocus: true,
144
- ...composerProps,
145
- onKeyDown: handleKeyDown,
146
- onComposerSubmit: handleComposerSubmit,
147
- ref: forwardedRef
148
- })
149
- })
150
- ]
151
- });
136
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
137
+ /* @__PURE__ */ jsxRuntime.jsx(ActiveSelectionPortal, { range, container: document.body }),
138
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingComposerPortal, { range, container: document.body, children: /* @__PURE__ */ jsxRuntime.jsx(
139
+ Composer,
140
+ {
141
+ autoFocus: true,
142
+ ...composerProps,
143
+ onKeyDown: handleKeyDown,
144
+ onComposerSubmit: handleComposerSubmit,
145
+ ref: forwardedRef
146
+ }
147
+ ) })
148
+ ] });
152
149
  });
153
150
  function ActiveSelectionPortal({
154
151
  range,
@@ -175,8 +172,9 @@ function ActiveSelectionPortal({
175
172
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
176
173
  const rects = createRectsFromDomRange.createRectsFromDOMRange(editor, range);
177
174
  return reactDom$1.createPortal(
178
- /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {
179
- children: /* @__PURE__ */ jsxRuntime.jsx("span", {
175
+ /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
176
+ "span",
177
+ {
180
178
  ref: setFloating,
181
179
  style: {
182
180
  position: strategy,
@@ -189,20 +187,24 @@ function ActiveSelectionPortal({
189
187
  pointerEvents: "none"
190
188
  },
191
189
  className: "lb-root lb-portal",
192
- children: rects.map((rect) => /* @__PURE__ */ jsxRuntime.jsx("span", {
193
- style: {
194
- position: "absolute",
195
- top: rect.top - range.getBoundingClientRect().top,
196
- left: rect.left - range.getBoundingClientRect().left,
197
- width: rect.width,
198
- height: rect.height,
199
- backgroundColor: "var(--lb-selection, rgba(0, 0, 255, 0.2))",
200
- pointerEvents: "none"
190
+ children: rects.map((rect) => /* @__PURE__ */ jsxRuntime.jsx(
191
+ "span",
192
+ {
193
+ style: {
194
+ position: "absolute",
195
+ top: rect.top - range.getBoundingClientRect().top,
196
+ left: rect.left - range.getBoundingClientRect().left,
197
+ width: rect.width,
198
+ height: rect.height,
199
+ backgroundColor: "var(--lb-selection, rgba(0, 0, 255, 0.2))",
200
+ pointerEvents: "none"
201
+ },
202
+ className: "lb-selection lb-lexical-active-selection"
201
203
  },
202
- className: "lb-selection lb-lexical-active-selection"
203
- }, JSON.stringify(rect)))
204
- })
205
- }),
204
+ JSON.stringify(rect)
205
+ ))
206
+ }
207
+ ) }),
206
208
  container
207
209
  );
208
210
  }
@@ -241,18 +243,21 @@ function FloatingComposerPortal({
241
243
  setReference(range);
242
244
  }, [range, setReference]);
243
245
  return reactDom$1.createPortal(
244
- /* @__PURE__ */ jsxRuntime.jsx("div", {
245
- ref: setFloating,
246
- style: {
247
- position: strategy,
248
- top: 0,
249
- left: 0,
250
- transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
251
- minWidth: "max-content"
252
- },
253
- className: "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer",
254
- children
255
- }),
246
+ /* @__PURE__ */ jsxRuntime.jsx(
247
+ "div",
248
+ {
249
+ ref: setFloating,
250
+ style: {
251
+ position: strategy,
252
+ top: 0,
253
+ left: 0,
254
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
255
+ minWidth: "max-content"
256
+ },
257
+ className: "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer",
258
+ children
259
+ }
260
+ ),
256
261
  container
257
262
  );
258
263
  }
@@ -1 +1 @@
1
- {"version":3,"file":"floating-composer.cjs","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentType, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\n/**\n * Dispatching ATTACH_THREAD_COMMAND will attach a comment to the current selection.\n */\nexport const ATTACH_THREAD_COMMAND: LexicalCommand<string> = createCommand(\n \"ATTACH_THREAD_COMMAND\"\n);\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n};\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\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 setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n HTMLFormElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n components,\n ...composerProps\n } = props;\n const Composer = components?.Composer ?? DefaultComposer;\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n // Create a new ThreadMarkNode from a thread ID and wrap the selected content in it.\n useEffect(() => {\n return editor.registerCommand(\n ATTACH_THREAD_COMMAND,\n (threadId: string) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return false;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id);\n },\n [onComposerSubmit, props.metadata, createThread, editor]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\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 width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\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-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["createCommand","forwardRef","FloatingComposer","useState","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","range","createDOMRange","COMMAND_PRIORITY_EDITOR","jsx","DefaultComposer","useCreateThread","useCallback","$wrapSelectionInThreadMarkNode","$setSelection","jsxs","Fragment","useFloating","offset","autoUpdate","useLayoutEffect","createRectsFromDOMRange","createPortal","inline","flip","hide","shift","limitShift","size"],"mappings":"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"}
1
+ {"version":3,"file":"floating-composer.cjs","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentType, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\n/**\n * Dispatching ATTACH_THREAD_COMMAND will attach a comment to the current selection.\n */\nexport const ATTACH_THREAD_COMMAND: LexicalCommand<string> = createCommand(\n \"ATTACH_THREAD_COMMAND\"\n);\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n};\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\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 setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n HTMLFormElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n components,\n ...composerProps\n } = props;\n const Composer = components?.Composer ?? DefaultComposer;\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n // Create a new ThreadMarkNode from a thread ID and wrap the selected content in it.\n useEffect(() => {\n return editor.registerCommand(\n ATTACH_THREAD_COMMAND,\n (threadId: string) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return false;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id);\n },\n [onComposerSubmit, props.metadata, createThread, editor]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\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 width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\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-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["createCommand","forwardRef","FloatingComposer","useState","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","range","createDOMRange","COMMAND_PRIORITY_EDITOR","jsx","DefaultComposer","useCreateThread","useCallback","$wrapSelectionInThreadMarkNode","$setSelection","jsxs","Fragment","useFloating","offset","autoUpdate","useLayoutEffect","createRectsFromDOMRange","createPortal","inline","flip","hide","shift","limitShift","size"],"mappings":"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"}
@@ -43,12 +43,15 @@ const FloatingComposer = forwardRef(function FloatingComposer2(props, forwardedR
43
43
  }, [editor]);
44
44
  if (range === null)
45
45
  return null;
46
- return /* @__PURE__ */ jsx(FloatingComposerImpl, {
47
- ref: forwardedRef,
48
- ...props,
49
- range,
50
- onRangeChange: setRange
51
- });
46
+ return /* @__PURE__ */ jsx(
47
+ FloatingComposerImpl,
48
+ {
49
+ ref: forwardedRef,
50
+ ...props,
51
+ range,
52
+ onRangeChange: setRange
53
+ }
54
+ );
52
55
  });
53
56
  const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwardedRef) {
54
57
  const {
@@ -128,25 +131,19 @@ const FloatingComposerImpl = forwardRef(function FloatingComposer3(props, forwar
128
131
  editor.focus();
129
132
  }
130
133
  }
131
- return /* @__PURE__ */ jsxs(Fragment, {
132
- children: [
133
- /* @__PURE__ */ jsx(ActiveSelectionPortal, {
134
- range,
135
- container: document.body
136
- }),
137
- /* @__PURE__ */ jsx(FloatingComposerPortal, {
138
- range,
139
- container: document.body,
140
- children: /* @__PURE__ */ jsx(Composer$1, {
141
- autoFocus: true,
142
- ...composerProps,
143
- onKeyDown: handleKeyDown,
144
- onComposerSubmit: handleComposerSubmit,
145
- ref: forwardedRef
146
- })
147
- })
148
- ]
149
- });
134
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
135
+ /* @__PURE__ */ jsx(ActiveSelectionPortal, { range, container: document.body }),
136
+ /* @__PURE__ */ jsx(FloatingComposerPortal, { range, container: document.body, children: /* @__PURE__ */ jsx(
137
+ Composer$1,
138
+ {
139
+ autoFocus: true,
140
+ ...composerProps,
141
+ onKeyDown: handleKeyDown,
142
+ onComposerSubmit: handleComposerSubmit,
143
+ ref: forwardedRef
144
+ }
145
+ ) })
146
+ ] });
150
147
  });
151
148
  function ActiveSelectionPortal({
152
149
  range,
@@ -173,8 +170,9 @@ function ActiveSelectionPortal({
173
170
  const [editor] = useLexicalComposerContext();
174
171
  const rects = createRectsFromDOMRange(editor, range);
175
172
  return createPortal(
176
- /* @__PURE__ */ jsx(Fragment, {
177
- children: /* @__PURE__ */ jsx("span", {
173
+ /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
174
+ "span",
175
+ {
178
176
  ref: setFloating,
179
177
  style: {
180
178
  position: strategy,
@@ -187,20 +185,24 @@ function ActiveSelectionPortal({
187
185
  pointerEvents: "none"
188
186
  },
189
187
  className: "lb-root lb-portal",
190
- children: rects.map((rect) => /* @__PURE__ */ jsx("span", {
191
- style: {
192
- position: "absolute",
193
- top: rect.top - range.getBoundingClientRect().top,
194
- left: rect.left - range.getBoundingClientRect().left,
195
- width: rect.width,
196
- height: rect.height,
197
- backgroundColor: "var(--lb-selection, rgba(0, 0, 255, 0.2))",
198
- pointerEvents: "none"
188
+ children: rects.map((rect) => /* @__PURE__ */ jsx(
189
+ "span",
190
+ {
191
+ style: {
192
+ position: "absolute",
193
+ top: rect.top - range.getBoundingClientRect().top,
194
+ left: rect.left - range.getBoundingClientRect().left,
195
+ width: rect.width,
196
+ height: rect.height,
197
+ backgroundColor: "var(--lb-selection, rgba(0, 0, 255, 0.2))",
198
+ pointerEvents: "none"
199
+ },
200
+ className: "lb-selection lb-lexical-active-selection"
199
201
  },
200
- className: "lb-selection lb-lexical-active-selection"
201
- }, JSON.stringify(rect)))
202
- })
203
- }),
202
+ JSON.stringify(rect)
203
+ ))
204
+ }
205
+ ) }),
204
206
  container
205
207
  );
206
208
  }
@@ -239,18 +241,21 @@ function FloatingComposerPortal({
239
241
  setReference(range);
240
242
  }, [range, setReference]);
241
243
  return createPortal(
242
- /* @__PURE__ */ jsx("div", {
243
- ref: setFloating,
244
- style: {
245
- position: strategy,
246
- top: 0,
247
- left: 0,
248
- transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
249
- minWidth: "max-content"
250
- },
251
- className: "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer",
252
- children
253
- }),
244
+ /* @__PURE__ */ jsx(
245
+ "div",
246
+ {
247
+ ref: setFloating,
248
+ style: {
249
+ position: strategy,
250
+ top: 0,
251
+ left: 0,
252
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
253
+ minWidth: "max-content"
254
+ },
255
+ className: "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-composer",
256
+ children
257
+ }
258
+ ),
254
259
  container
255
260
  );
256
261
  }
@@ -1 +1 @@
1
- {"version":3,"file":"floating-composer.js","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentType, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\n/**\n * Dispatching ATTACH_THREAD_COMMAND will attach a comment to the current selection.\n */\nexport const ATTACH_THREAD_COMMAND: LexicalCommand<string> = createCommand(\n \"ATTACH_THREAD_COMMAND\"\n);\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n};\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\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 setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n HTMLFormElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n components,\n ...composerProps\n } = props;\n const Composer = components?.Composer ?? DefaultComposer;\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n // Create a new ThreadMarkNode from a thread ID and wrap the selected content in it.\n useEffect(() => {\n return editor.registerCommand(\n ATTACH_THREAD_COMMAND,\n (threadId: string) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return false;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id);\n },\n [onComposerSubmit, props.metadata, createThread, editor]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\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 width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\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-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["FloatingComposer","range","Composer","DefaultComposer"],"mappings":"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"}
1
+ {"version":3,"file":"floating-composer.js","sources":["../../src/comments/floating-composer.tsx"],"sourcesContent":["import {\n autoUpdate,\n flip,\n hide,\n inline,\n limitShift,\n offset,\n shift,\n size,\n useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { BaseMetadata } from \"@liveblocks/client\";\nimport type { DM } from \"@liveblocks/core\";\nimport { useCreateThread } from \"@liveblocks/react\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport type {\n ComposerProps,\n ComposerSubmitComment,\n} from \"@liveblocks/react-ui\";\nimport { Composer as DefaultComposer } from \"@liveblocks/react-ui\";\nimport type { LexicalCommand } from \"lexical\";\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n COMMAND_PRIORITY_EDITOR,\n createCommand,\n} from \"lexical\";\nimport type { ComponentType, FormEvent, KeyboardEvent, ReactNode } from \"react\";\nimport { forwardRef, useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { createDOMRange } from \"../create-dom-range\";\nimport { createRectsFromDOMRange } from \"../create-rects-from-dom-range\";\nimport $wrapSelectionInThreadMarkNode from \"./wrap-selection-in-thread-mark-node\";\n\ntype FloatingComposerComponents = {\n Composer: ComponentType<Omit<ComposerProps, \"threadId\" | \"commentId\">>;\n};\n\n/**\n * Dispatching OPEN_FLOATING_COMPOSER_COMMAND will display the FloatingComposer\n *\n * @example\n * import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n * import { OPEN_FLOATING_COMPOSER_COMMAND } from \"@liveblocks/react-lexical\";\n *\n * function Toolbar() {\n * const [editor] = useLexicalComposerContext();\n *\n * return (\n * <button\n * onClick={() => {\n * editor.dispatchCommand(OPEN_FLOATING_COMPOSER_COMMAND);\n * }}\n * >\n * 💬 New comment\n * </button>\n * );\n * }\n */\nexport const OPEN_FLOATING_COMPOSER_COMMAND: LexicalCommand<void> =\n createCommand(\"OPEN_FLOATING_COMPOSER_COMMAND\");\n\n/**\n * Dispatching ATTACH_THREAD_COMMAND will attach a comment to the current selection.\n */\nexport const ATTACH_THREAD_COMMAND: LexicalCommand<string> = createCommand(\n \"ATTACH_THREAD_COMMAND\"\n);\n\nexport type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<\n ComposerProps<M>,\n \"threadId\" | \"commentId\"\n> & {\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingComposerComponents>;\n};\n\n/**\n * Displays a `Composer` near the current lexical selection.\n *\n * To open it, dispatch `OPEN_FLOATING_COMPOSER_COMMAND`.\n *\n * Submitting a comment will attach an annotation thread at the current selection.\n * Should be nested inside `LiveblocksPlugin`.\n */\nexport const FloatingComposer = forwardRef<\n HTMLFormElement,\n FloatingComposerProps\n>(function FloatingComposer(props, forwardedRef) {\n const [range, setRange] = useState<Range | null>(null);\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_FLOATING_COMPOSER_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n if (selection.isCollapsed()) return false;\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 setRange(range);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n if (range === null) return null;\n\n return (\n <FloatingComposerImpl\n ref={forwardedRef}\n {...props}\n range={range}\n onRangeChange={setRange}\n />\n );\n});\n\ninterface FloatingComposerImplProps extends FloatingComposerProps {\n range: Range;\n onRangeChange: (range: Range | null) => void;\n}\n\nconst FloatingComposerImpl = forwardRef<\n HTMLFormElement,\n FloatingComposerImplProps\n>(function FloatingComposer(props, forwardedRef) {\n const {\n range,\n onRangeChange,\n onKeyDown,\n onComposerSubmit,\n components,\n ...composerProps\n } = props;\n const Composer = components?.Composer ?? DefaultComposer;\n const [editor] = useLexicalComposerContext();\n const createThread = useCreateThread();\n\n const $onStateRead = useCallback((): Range | null => {\n const selection = $getSelection();\n\n // If the selection is not a range selection or is collapsed, clear the range so the composer is no longer displayed.\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n return null;\n }\n\n const { anchor, focus } = selection;\n const range = createDOMRange(\n editor,\n anchor.getNode(),\n anchor.offset,\n focus.getNode(),\n focus.offset\n );\n\n return range;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState: state, tags }) => {\n // If the update is not related to collaboration, clear the range so the composer is no longer displayed.\n if (!tags.has(\"collaboration\")) {\n onRangeChange(null);\n return;\n }\n\n const range = state.read(() => $onStateRead());\n onRangeChange(range);\n });\n }, [editor, range, onRangeChange, $onStateRead]);\n\n // Create a new ThreadMarkNode from a thread ID and wrap the selected content in it.\n useEffect(() => {\n return editor.registerCommand(\n ATTACH_THREAD_COMMAND,\n (threadId: string) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n // If the selection is collapsed, we do not create a new thread node in the editor.\n if (selection.isCollapsed()) return false;\n\n const isBackward = selection.isBackward();\n // Wrap content in a ThreadMarkNode\n $wrapSelectionInThreadMarkNode(selection, isBackward, threadId);\n\n // Clear the selection after wrapping\n $setSelection(null);\n\n return true;\n },\n COMMAND_PRIORITY_EDITOR\n );\n }, [editor]);\n\n const handleComposerSubmit = useCallback(\n (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => {\n onComposerSubmit?.(comment, event);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n\n const thread = createThread({\n body: comment.body,\n attachments: comment.attachments,\n metadata: props.metadata ?? {},\n });\n\n editor.dispatchCommand(ATTACH_THREAD_COMMAND, thread.id);\n },\n [onComposerSubmit, props.metadata, createThread, editor]\n );\n\n function handleKeyDown(event: KeyboardEvent<HTMLFormElement>) {\n onKeyDown?.(event);\n\n if (event.isDefaultPrevented()) return;\n\n if (event.key === \"Escape\") {\n onRangeChange(null);\n editor.focus();\n }\n }\n\n return (\n <>\n <ActiveSelectionPortal range={range} container={document.body} />\n\n <FloatingComposerPortal range={range} container={document.body}>\n <Composer\n autoFocus\n {...composerProps}\n onKeyDown={handleKeyDown}\n onComposerSubmit={handleComposerSubmit}\n ref={forwardedRef}\n />\n </FloatingComposerPortal>\n </>\n );\n});\n\nfunction ActiveSelectionPortal({\n range,\n container,\n}: {\n range: Range;\n container: HTMLElement;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [offset(-range.getBoundingClientRect().height)],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [setReference, range]);\n\n const [editor] = useLexicalComposerContext();\n const rects = createRectsFromDOMRange(editor, range);\n\n return createPortal(\n <>\n <span\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 width: range.getBoundingClientRect().width,\n height: range.getBoundingClientRect().height,\n pointerEvents: \"none\",\n }}\n className=\"lb-root lb-portal\"\n >\n {rects.map((rect) => (\n <span\n key={JSON.stringify(rect)}\n style={{\n position: \"absolute\",\n top: rect.top - range.getBoundingClientRect().top,\n left: rect.left - range.getBoundingClientRect().left,\n width: rect.width,\n height: rect.height,\n backgroundColor: \"var(--lb-selection, rgba(0, 0, 255, 0.2))\",\n pointerEvents: \"none\",\n }}\n className=\"lb-selection lb-lexical-active-selection\"\n />\n ))}\n </span>\n </>,\n container\n );\n}\n\nexport const FLOATING_COMPOSER_COLLISION_PADDING = 10;\n\nfunction FloatingComposerPortal({\n container,\n range,\n children,\n}: {\n container: HTMLElement;\n range: Range;\n children: ReactNode;\n}) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n middleware: [\n inline({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n flip({ padding: FLOATING_COMPOSER_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n shift({\n padding: FLOATING_COMPOSER_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({ padding: FLOATING_COMPOSER_COLLISION_PADDING }),\n ],\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n useLayoutEffect(() => {\n setReference(range);\n }, [range, setReference]);\n\n return createPortal(\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-floating lb-lexical-floating-composer\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["FloatingComposer","range","Composer","DefaultComposer"],"mappings":"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"}