@liveblocks/react-lexical 3.14.0-types2 → 3.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"floating-threads.cjs","sources":["../../src/comments/floating-threads.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 type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn } from \"@liveblocks/react-ui/_private\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.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 const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...props}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\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 createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\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={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["DefaultThread","useLexicalComposerContext","useState","useCallback","activeElements","compareNodes","range","useEffect","KEY_ESCAPE_COMMAND","COMMAND_PRIORITY_HIGH","jsx","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","cn","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"mappings":"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"}
1
+ {"version":3,"file":"floating-threads.cjs","sources":["../../src/comments/floating-threads.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 type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn, Portal } from \"@liveblocks/react-ui/_private\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.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 const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal range={range.range} {...props}>\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\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 {...props}\n style={{\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={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>\n </Portal>\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["DefaultThread","useLexicalComposerContext","useState","useCallback","activeElements","compareNodes","range","useEffect","KEY_ESCAPE_COMMAND","COMMAND_PRIORITY_HIGH","jsx","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","Portal","cn","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"mappings":"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"}
@@ -3,10 +3,9 @@ import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate }
3
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
4
  import { useLayoutEffect } from '@liveblocks/react/_private';
5
5
  import { Thread } from '@liveblocks/react-ui';
6
- import { cn } from '@liveblocks/react-ui/_private';
6
+ import { Portal, cn } from '@liveblocks/react-ui/_private';
7
7
  import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_HIGH, $getSelection } from 'lexical';
8
8
  import { useState, useCallback, useEffect, useContext, useSyncExternalStore } from 'react';
9
- import { createPortal } from 'react-dom';
10
9
  import { compareNodes } from './anchored-threads.js';
11
10
  import { ThreadToNodesContext, ActiveThreadsContext } from './comment-plugin-provider.js';
12
11
 
@@ -78,28 +77,19 @@ function FloatingThreads({
78
77
  const isCollapsed = useIsSelectionCollapsed();
79
78
  if (range === null || isCollapsed === null || !isCollapsed)
80
79
  return null;
81
- return /* @__PURE__ */ jsx(
82
- FloatingThreadPortal,
80
+ return /* @__PURE__ */ jsx(FloatingThreadPortal, { range: range.range, ...props, children: range.threads.map((thread) => /* @__PURE__ */ jsx(
81
+ ThreadWrapper,
83
82
  {
84
- range: range.range,
85
- container: document.body,
86
- ...props,
87
- children: range.threads.map((thread) => /* @__PURE__ */ jsx(
88
- ThreadWrapper,
89
- {
90
- thread,
91
- Thread: Thread$1,
92
- onEscapeKeydown: handleEscapeKeydown,
93
- className: "lb-lexical-floating-threads-thread"
94
- },
95
- thread.id
96
- ))
97
- }
98
- );
83
+ thread,
84
+ Thread: Thread$1,
85
+ onEscapeKeydown: handleEscapeKeydown,
86
+ className: "lb-lexical-floating-threads-thread"
87
+ },
88
+ thread.id
89
+ )) });
99
90
  }
100
91
  const FLOATING_THREAD_COLLISION_PADDING = 10;
101
92
  function FloatingThreadPortal({
102
- container,
103
93
  range,
104
94
  children,
105
95
  className,
@@ -147,29 +137,26 @@ function FloatingThreadPortal({
147
137
  getBoundingClientRect: () => range.getBoundingClientRect()
148
138
  });
149
139
  }, [setReference, range]);
150
- return createPortal(
151
- /* @__PURE__ */ jsx(
152
- "div",
153
- {
154
- ref: setFloating,
155
- ...props,
156
- style: {
157
- ...style,
158
- position: strategy,
159
- top: 0,
160
- left: 0,
161
- transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
162
- minWidth: "max-content"
163
- },
164
- className: cn(
165
- "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
166
- className
167
- ),
168
- children
169
- }
170
- ),
171
- container
172
- );
140
+ return /* @__PURE__ */ jsx(Portal, { asChild: true, children: /* @__PURE__ */ jsx(
141
+ "div",
142
+ {
143
+ ref: setFloating,
144
+ ...props,
145
+ style: {
146
+ ...style,
147
+ position: strategy,
148
+ top: 0,
149
+ left: 0,
150
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
151
+ minWidth: "max-content"
152
+ },
153
+ className: cn(
154
+ "lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
155
+ className
156
+ ),
157
+ children
158
+ }
159
+ ) });
173
160
  }
174
161
  function ThreadWrapper({
175
162
  thread,
@@ -1 +1 @@
1
- {"version":3,"file":"floating-threads.js","sources":["../../src/comments/floating-threads.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 type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn } from \"@liveblocks/react-ui/_private\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.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 const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal\n range={range.range}\n container={document.body}\n {...props}\n >\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n container: HTMLElement;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n container,\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\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 createPortal(\n <div\n ref={setFloating}\n {...props}\n style={{\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={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>,\n container\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["Thread","DefaultThread","activeElements","range"],"mappings":"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"}
1
+ {"version":3,"file":"floating-threads.js","sources":["../../src/comments/floating-threads.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 type { BaseMetadata, ThreadData } from \"@liveblocks/client\";\nimport type { DCM, DTM } from \"@liveblocks/core\";\nimport { useLayoutEffect } from \"@liveblocks/react/_private\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport { cn, Portal } from \"@liveblocks/react-ui/_private\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype FloatingThreadsComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<\n TM extends BaseMetadata = DTM,\n CM extends BaseMetadata = DCM,\n> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<TM, CM>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<FloatingThreadsComponents>;\n}\n\nexport function FloatingThreads({\n threads,\n components,\n ...props\n}: FloatingThreadsProps) {\n const activeThreads = useActiveThreads();\n\n const Thread = components?.Thread ?? DefaultThread;\n\n const [editor] = useLexicalComposerContext();\n const nodes = useThreadToNodes(); // A map of thread ids to a set of thread mark nodes associated with the thread\n\n const [range, setRange] = useState<{\n range: Range;\n threads: ThreadData[];\n } | null>(null);\n\n const handleUpdateRange = useCallback(() => {\n function getActiveRange(): Range | null {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = nodes.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 const sortedElements = Array.from(activeElements).sort(compareNodes);\n if (sortedElements.length === 0) return null;\n\n const range = document.createRange();\n range.setStartBefore(sortedElements[0]);\n range.setEndAfter(sortedElements[sortedElements.length - 1]);\n\n return range;\n }\n\n const active = (threads ?? []).filter((thread) =>\n activeThreads.includes(thread.id)\n );\n\n const range = getActiveRange();\n if (range === null) {\n setRange(null);\n return;\n }\n\n setRange({ range, threads: active });\n }, [activeThreads, nodes, editor, threads]);\n\n useEffect(() => {\n handleUpdateRange();\n }, [handleUpdateRange]);\n\n useEffect(() => {\n return editor.registerUpdateListener(handleUpdateRange);\n }, [editor, handleUpdateRange]);\n\n const handleEscapeKeydown = useCallback((): boolean => {\n if (range === null) return false;\n setRange(null);\n return true;\n }, [range]);\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n handleEscapeKeydown,\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, handleEscapeKeydown]);\n\n const isCollapsed = useIsSelectionCollapsed();\n\n if (range === null || isCollapsed === null || !isCollapsed) return null;\n\n return (\n <FloatingThreadPortal range={range.range} {...props}>\n {range.threads.map((thread) => (\n <ThreadWrapper\n key={thread.id}\n thread={thread}\n Thread={Thread}\n onEscapeKeydown={handleEscapeKeydown}\n className=\"lb-lexical-floating-threads-thread\"\n />\n ))}\n </FloatingThreadPortal>\n );\n}\n\ninterface FloatingThreadPortalProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n range: Range;\n children: ReactNode;\n}\n\nexport const FLOATING_THREAD_COLLISION_PADDING = 10;\n\nfunction FloatingThreadPortal({\n range,\n children,\n className,\n style,\n ...props\n}: FloatingThreadPortalProps) {\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"absolute\",\n placement: \"bottom\",\n middleware: [\n flip({ padding: FLOATING_THREAD_COLLISION_PADDING, crossAxis: false }),\n offset(10),\n hide({ padding: FLOATING_THREAD_COLLISION_PADDING }),\n shift({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n limiter: limitShift(),\n }),\n size({\n padding: FLOATING_THREAD_COLLISION_PADDING,\n apply({ availableWidth, availableHeight, elements }) {\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-width\",\n `${availableWidth}px`\n );\n elements.floating.style.setProperty(\n \"--lb-lexical-floating-threads-available-height\",\n `${availableHeight}px`\n );\n },\n }),\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 {...props}\n style={{\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={cn(\n \"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads\",\n className\n )}\n >\n {children}\n </div>\n </Portal>\n );\n}\n\ninterface ThreadWrapperProps extends ThreadProps {\n thread: ThreadData;\n Thread: ComponentType<ThreadProps>;\n onEscapeKeydown: () => void;\n}\n\nfunction ThreadWrapper({\n thread,\n Thread,\n onEscapeKeydown,\n onKeyDown,\n ...threadProps\n}: ThreadWrapperProps) {\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n // TODO: Add ability to preventDefault on keydown to override the default behavior, e.g. to show an alert dialog\n if (event.key === \"Escape\") {\n onEscapeKeydown();\n }\n },\n [onEscapeKeydown, onKeyDown]\n );\n\n return <Thread thread={thread} onKeyDown={handleKeyDown} {...threadProps} />;\n}\n\nfunction useThreadToNodes(): ThreadToNodesMap {\n const threadToNodes = useContext(ThreadToNodesContext);\n if (threadToNodes === null) {\n throw new Error(\n \"FloatingThreads component must be used within a LiveblocksPlugin component.\"\n );\n }\n return threadToNodes;\n}\n\nfunction useIsSelectionCollapsed(): boolean | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerUpdateListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (selection === null) return null;\n return selection.isCollapsed();\n });\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nfunction useActiveThreads() {\n const activeThreads = useContext(ActiveThreadsContext);\n if (activeThreads === null) {\n throw new Error(\n \"FloatingThreads component must be used within LiveblocksPlugin.\"\n );\n }\n\n return activeThreads;\n}\n"],"names":["Thread","DefaultThread","activeElements","range"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var reactDom$1 = require('@floating-ui/react-dom');
4
+ var reactDom = require('@floating-ui/react-dom');
5
5
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
6
6
  var core = require('@liveblocks/core');
7
7
  var react = require('@liveblocks/react');
@@ -9,7 +9,6 @@ var _private = require('@liveblocks/react/_private');
9
9
  var _private$1 = require('@liveblocks/react-ui/_private');
10
10
  var lexical = require('lexical');
11
11
  var react$1 = require('react');
12
- var reactDom = require('react-dom');
13
12
  var groupMentionNode = require('./group-mention-node.cjs');
14
13
  var mentionNode = require('./mention-node.cjs');
15
14
  var suggestions = require('./suggestions.cjs');
@@ -294,96 +293,84 @@ function MentionPlugin() {
294
293
  const range = editor.getEditorState().read(() => $getRangeAtMatch(match));
295
294
  if (range === null)
296
295
  return null;
297
- return reactDom.createPortal(
298
- /* @__PURE__ */ jsxRuntime.jsx(suggestions.SuggestionsContext.Provider, { value: suggestions$1, children: /* @__PURE__ */ jsxRuntime.jsx(
299
- suggestions.OnSuggestionSelectCallbackContext.Provider,
300
- {
301
- value: handleSuggestionSelect,
302
- children: /* @__PURE__ */ jsxRuntime.jsx(suggestions.OnResetMatchCallbackContext.Provider, { value: () => setMatch(null), children: /* @__PURE__ */ jsxRuntime.jsx(
303
- SuggestionsPortal,
296
+ return /* @__PURE__ */ jsxRuntime.jsx(suggestions.SuggestionsContext.Provider, { value: suggestions$1, children: /* @__PURE__ */ jsxRuntime.jsx(
297
+ suggestions.OnSuggestionSelectCallbackContext.Provider,
298
+ {
299
+ value: handleSuggestionSelect,
300
+ children: /* @__PURE__ */ jsxRuntime.jsx(suggestions.OnResetMatchCallbackContext.Provider, { value: () => setMatch(null), children: /* @__PURE__ */ jsxRuntime.jsx(SuggestionsPortal, { range, children: /* @__PURE__ */ jsxRuntime.jsx(suggestions.List, { className: "lb-lexical-suggestions-list lb-lexical-mention-suggestions-list", children: suggestions$1.map((mention) => {
301
+ return /* @__PURE__ */ jsxRuntime.jsx(
302
+ suggestions.Item,
304
303
  {
305
- range,
306
- container: document.body,
307
- children: /* @__PURE__ */ jsxRuntime.jsx(suggestions.List, { className: "lb-lexical-suggestions-list lb-lexical-mention-suggestions-list", children: suggestions$1.map((mention) => {
308
- return /* @__PURE__ */ jsxRuntime.jsx(
309
- suggestions.Item,
304
+ value: mention.id,
305
+ className: "lb-lexical-suggestions-list-item lb-lexical-mention-suggestion",
306
+ children: mention.kind === "user" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
307
+ /* @__PURE__ */ jsxRuntime.jsx(
308
+ _private$1.Avatar,
310
309
  {
311
- value: mention.id,
312
- className: "lb-lexical-suggestions-list-item lb-lexical-mention-suggestion",
313
- children: mention.kind === "user" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
314
- /* @__PURE__ */ jsxRuntime.jsx(
315
- _private$1.Avatar,
316
- {
317
- userId: mention.id,
318
- className: "lb-lexical-mention-suggestion-avatar"
319
- }
320
- ),
321
- /* @__PURE__ */ jsxRuntime.jsx(
322
- _private$1.User,
323
- {
324
- userId: mention.id,
325
- className: "lb-lexical-mention-suggestion-user"
326
- }
327
- )
328
- ] }) : mention.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
329
- /* @__PURE__ */ jsxRuntime.jsx(
330
- _private$1.Avatar,
331
- {
332
- groupId: mention.id,
333
- className: "lb-lexical-mention-suggestion-avatar",
334
- icon: /* @__PURE__ */ jsxRuntime.jsx(_private$1.UsersIcon, {})
335
- }
336
- ),
337
- /* @__PURE__ */ jsxRuntime.jsx(
338
- _private$1.Group,
339
- {
340
- groupId: mention.id,
341
- className: "lb-lexical-mention-suggestion-group",
342
- children: /* @__PURE__ */ jsxRuntime.jsx(
343
- _private$1.GroupDescription,
344
- {
345
- groupId: mention.id,
346
- className: "lb-lexical-mention-suggestion-group-description"
347
- }
348
- )
349
- }
350
- )
351
- ] }) : core.assertNever(mention, "Unhandled mention kind")
352
- },
353
- mention.id
354
- );
355
- }) })
310
+ userId: mention.id,
311
+ className: "lb-lexical-mention-suggestion-avatar"
312
+ }
313
+ ),
314
+ /* @__PURE__ */ jsxRuntime.jsx(
315
+ _private$1.User,
316
+ {
317
+ userId: mention.id,
318
+ className: "lb-lexical-mention-suggestion-user"
319
+ }
320
+ )
321
+ ] }) : mention.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
322
+ /* @__PURE__ */ jsxRuntime.jsx(
323
+ _private$1.Avatar,
324
+ {
325
+ groupId: mention.id,
326
+ className: "lb-lexical-mention-suggestion-avatar",
327
+ icon: /* @__PURE__ */ jsxRuntime.jsx(_private$1.UsersIcon, {})
328
+ }
329
+ ),
330
+ /* @__PURE__ */ jsxRuntime.jsx(
331
+ _private$1.Group,
332
+ {
333
+ groupId: mention.id,
334
+ className: "lb-lexical-mention-suggestion-group",
335
+ children: /* @__PURE__ */ jsxRuntime.jsx(
336
+ _private$1.GroupDescription,
337
+ {
338
+ groupId: mention.id,
339
+ className: "lb-lexical-mention-suggestion-group-description"
340
+ }
341
+ )
342
+ }
343
+ )
344
+ ] }) : core.assertNever(mention, "Unhandled mention kind")
356
345
  },
357
- matchingString
358
- ) })
359
- }
360
- ) }),
361
- document.body
362
- );
346
+ mention.id
347
+ );
348
+ }) }) }, matchingString) })
349
+ }
350
+ ) });
363
351
  }
364
352
  const SUGGESTIONS_COLLISION_PADDING = 10;
365
353
  function SuggestionsPortal({
366
354
  children,
367
- range,
368
- container
355
+ range
369
356
  }) {
370
357
  const {
371
358
  refs: { setReference, setFloating },
372
359
  strategy,
373
360
  x,
374
361
  y
375
- } = reactDom$1.useFloating({
362
+ } = reactDom.useFloating({
376
363
  strategy: "fixed",
377
364
  placement: "top-start",
378
365
  middleware: [
379
- reactDom$1.flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
380
- reactDom$1.offset(10),
381
- reactDom$1.hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
382
- reactDom$1.shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: reactDom$1.limitShift() }),
383
- reactDom$1.size({ padding: SUGGESTIONS_COLLISION_PADDING })
366
+ reactDom.flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
367
+ reactDom.offset(10),
368
+ reactDom.hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
369
+ reactDom.shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: reactDom.limitShift() }),
370
+ reactDom.size({ padding: SUGGESTIONS_COLLISION_PADDING })
384
371
  ],
385
372
  whileElementsMounted: (...args) => {
386
- return reactDom$1.autoUpdate(...args, {
373
+ return reactDom.autoUpdate(...args, {
387
374
  animationFrame: true
388
375
  });
389
376
  }
@@ -393,24 +380,21 @@ function SuggestionsPortal({
393
380
  getBoundingClientRect: () => range.getBoundingClientRect()
394
381
  });
395
382
  }, [setReference, range]);
396
- return reactDom.createPortal(
397
- /* @__PURE__ */ jsxRuntime.jsx(
398
- "div",
399
- {
400
- ref: setFloating,
401
- style: {
402
- position: strategy,
403
- top: 0,
404
- left: 0,
405
- transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
406
- minWidth: "max-content"
407
- },
408
- className: "lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions",
409
- children
410
- }
411
- ),
412
- container
413
- );
383
+ return /* @__PURE__ */ jsxRuntime.jsx(_private$1.Portal, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
384
+ "div",
385
+ {
386
+ ref: setFloating,
387
+ style: {
388
+ position: strategy,
389
+ top: 0,
390
+ left: 0,
391
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
392
+ minWidth: "max-content"
393
+ },
394
+ className: "lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions",
395
+ children
396
+ }
397
+ ) });
414
398
  }
415
399
 
416
400
  exports.MentionPlugin = MentionPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"mention-plugin.cjs","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 Avatar,\n Group,\n GroupDescription,\n User,\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\";\nimport { createPortal } from \"react-dom\";\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 createPortal(\n <SuggestionsContext.Provider value={suggestions}>\n <OnSuggestionSelectCallbackContext.Provider\n value={handleSuggestionSelect}\n >\n <OnResetMatchCallbackContext.Provider value={() => setMatch(null)}>\n <SuggestionsPortal\n range={range}\n container={document.body}\n key={matchingString}\n >\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 <Avatar\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 <Avatar\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 document.body\n );\n}\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nfunction SuggestionsPortal({\n children,\n range,\n container,\n}: {\n children: ReactNode;\n range: Range;\n container: Element;\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 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-suggestions lb-lexical-mention-suggestions\"\n >\n {children}\n </div>,\n container\n );\n}\n"],"names":["MENTION_CHARACTER","$getSelection","$isRangeSelection","offset","$isTextNode","useLexicalComposerContext","useRoom","useState","suggestions","useMentionSuggestions","useCreateTextMention","useDeleteTextMention","useEffect","$getNodeByKey","$isMentionNode","$isGroupMentionNode","MentionNode","GroupMentionNode","match","$isNodeSelection","$createTextNode","$createRangeSelection","$setSelection","$isElementNode","KEY_BACKSPACE_COMMAND","COMMAND_PRIORITY_LOW","useCallback","mentionNode","$createMentionNode","$createGroupMentionNode","assertNever","createPortal","jsx","SuggestionsContext","OnSuggestionSelectCallbackContext","OnResetMatchCallbackContext","Suggestions.List","Suggestions.Item","jsxs","Fragment","Avatar","User","UsersIcon","Group","GroupDescription","useFloating","flip","hide","shift","limitShift","size","autoUpdate","useLayoutEffect"],"mappings":"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"}
1
+ {"version":3,"file":"mention-plugin.cjs","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 Avatar,\n Group,\n GroupDescription,\n Portal,\n User,\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 <Avatar\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 <Avatar\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":["MENTION_CHARACTER","$getSelection","$isRangeSelection","offset","$isTextNode","useLexicalComposerContext","useRoom","useState","suggestions","useMentionSuggestions","useCreateTextMention","useDeleteTextMention","useEffect","$getNodeByKey","$isMentionNode","$isGroupMentionNode","MentionNode","GroupMentionNode","match","$isNodeSelection","$createTextNode","$createRangeSelection","$setSelection","$isElementNode","KEY_BACKSPACE_COMMAND","COMMAND_PRIORITY_LOW","useCallback","mentionNode","$createMentionNode","$createGroupMentionNode","assertNever","jsx","SuggestionsContext","OnSuggestionSelectCallbackContext","OnResetMatchCallbackContext","Suggestions.List","Suggestions.Item","jsxs","Fragment","Avatar","User","UsersIcon","Group","GroupDescription","useFloating","flip","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","Portal"],"mappings":"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"}