@liveblocks/react-lexical 2.14.0 → 2.15.0-debug1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/comments/anchored-threads.js +52 -50
- package/dist/comments/anchored-threads.js.map +1 -1
- package/dist/comments/anchored-threads.mjs +36 -34
- package/dist/comments/anchored-threads.mjs.map +1 -1
- package/dist/comments/comment-plugin-provider.js +46 -63
- package/dist/comments/comment-plugin-provider.js.map +1 -1
- package/dist/comments/comment-plugin-provider.mjs +29 -28
- package/dist/comments/comment-plugin-provider.mjs.map +1 -1
- package/dist/comments/floating-composer.js +66 -56
- package/dist/comments/floating-composer.js.map +1 -1
- package/dist/comments/floating-composer.mjs +54 -44
- package/dist/comments/floating-composer.mjs.map +1 -1
- package/dist/comments/floating-threads.js +29 -28
- package/dist/comments/floating-threads.js.map +1 -1
- package/dist/comments/floating-threads.mjs +16 -15
- package/dist/comments/floating-threads.mjs.map +1 -1
- package/dist/index.d.mts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/liveblocks-plugin-provider.js +49 -55
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/liveblocks-plugin-provider.mjs +32 -38
- package/dist/liveblocks-plugin-provider.mjs.map +1 -1
- package/dist/mentions/avatar.js +24 -17
- package/dist/mentions/avatar.js.map +1 -1
- package/dist/mentions/avatar.mjs +21 -14
- package/dist/mentions/avatar.mjs.map +1 -1
- package/dist/mentions/mention-component.js +9 -8
- package/dist/mentions/mention-component.js.map +1 -1
- package/dist/mentions/mention-component.mjs +6 -5
- package/dist/mentions/mention-component.mjs.map +1 -1
- package/dist/mentions/mention-node.js +10 -25
- package/dist/mentions/mention-node.js.map +1 -1
- package/dist/mentions/mention-node.mjs +10 -6
- package/dist/mentions/mention-node.mjs.map +1 -1
- package/dist/mentions/mention-plugin.js +47 -41
- package/dist/mentions/mention-plugin.js.map +1 -1
- package/dist/mentions/mention-plugin.mjs +42 -36
- package/dist/mentions/mention-plugin.mjs.map +1 -1
- package/dist/mentions/suggestions.js +34 -30
- package/dist/mentions/suggestions.js.map +1 -1
- package/dist/mentions/suggestions.mjs +16 -12
- package/dist/mentions/suggestions.mjs.map +1 -1
- package/dist/mentions/user.js +9 -7
- package/dist/mentions/user.js.map +1 -1
- package/dist/mentions/user.mjs +6 -4
- package/dist/mentions/user.mjs.map +1 -1
- package/dist/version-history/history-version-preview.js +77 -54
- package/dist/version-history/history-version-preview.js.map +1 -1
- package/dist/version-history/history-version-preview.mjs +70 -47
- package/dist/version-history/history-version-preview.mjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/version.mjs.map +1 -1
- package/package.json +8 -10
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
4
|
var reactDom = require('@floating-ui/react-dom');
|
|
4
5
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
5
6
|
var reactUi = require('@liveblocks/react-ui');
|
|
6
7
|
var lexical = require('lexical');
|
|
7
|
-
var
|
|
8
|
+
var react = require('react');
|
|
8
9
|
var reactDom$1 = require('react-dom');
|
|
9
|
-
var index_js = require('use-sync-external-store/shim/index.js');
|
|
10
10
|
var classnames = require('../classnames.js');
|
|
11
11
|
var anchoredThreads = require('./anchored-threads.js');
|
|
12
12
|
var commentPluginProvider = require('./comment-plugin-provider.js');
|
|
@@ -20,8 +20,8 @@ function FloatingThreads({
|
|
|
20
20
|
const Thread = components?.Thread ?? reactUi.Thread;
|
|
21
21
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
22
22
|
const nodes = useThreadToNodes();
|
|
23
|
-
const [range, setRange] =
|
|
24
|
-
const handleUpdateRange =
|
|
23
|
+
const [range, setRange] = react.useState(null);
|
|
24
|
+
const handleUpdateRange = react.useCallback(() => {
|
|
25
25
|
function getActiveRange() {
|
|
26
26
|
function getActiveElements() {
|
|
27
27
|
const activeElements2 = /* @__PURE__ */ new Set();
|
|
@@ -57,19 +57,19 @@ function FloatingThreads({
|
|
|
57
57
|
}
|
|
58
58
|
setRange({ range: range2, threads: active });
|
|
59
59
|
}, [activeThreads, nodes, editor, threads]);
|
|
60
|
-
|
|
60
|
+
react.useEffect(() => {
|
|
61
61
|
handleUpdateRange();
|
|
62
62
|
}, [handleUpdateRange]);
|
|
63
|
-
|
|
63
|
+
react.useEffect(() => {
|
|
64
64
|
return editor.registerUpdateListener(handleUpdateRange);
|
|
65
65
|
}, [editor, handleUpdateRange]);
|
|
66
|
-
const handleEscapeKeydown =
|
|
66
|
+
const handleEscapeKeydown = react.useCallback(() => {
|
|
67
67
|
if (range === null)
|
|
68
68
|
return false;
|
|
69
69
|
setRange(null);
|
|
70
70
|
return true;
|
|
71
71
|
}, [range]);
|
|
72
|
-
|
|
72
|
+
react.useEffect(() => {
|
|
73
73
|
return editor.registerCommand(
|
|
74
74
|
lexical.KEY_ESCAPE_COMMAND,
|
|
75
75
|
handleEscapeKeydown,
|
|
@@ -79,17 +79,17 @@ function FloatingThreads({
|
|
|
79
79
|
const isCollapsed = useIsSelectionCollapsed();
|
|
80
80
|
if (range === null || isCollapsed === null || !isCollapsed)
|
|
81
81
|
return null;
|
|
82
|
-
return /* @__PURE__ */
|
|
82
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FloatingThreadPortal, {
|
|
83
83
|
range: range.range,
|
|
84
84
|
container: document.body,
|
|
85
|
-
...props
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
})
|
|
85
|
+
...props,
|
|
86
|
+
children: range.threads.map((thread) => /* @__PURE__ */ jsxRuntime.jsx(ThreadWrapper, {
|
|
87
|
+
thread,
|
|
88
|
+
Thread,
|
|
89
|
+
onEscapeKeydown: handleEscapeKeydown,
|
|
90
|
+
className: "lb-lexical-floating-threads-thread"
|
|
91
|
+
}, thread.id))
|
|
92
|
+
});
|
|
93
93
|
}
|
|
94
94
|
const FLOATING_THREAD_COLLISION_PADDING = 10;
|
|
95
95
|
function FloatingThreadPortal({
|
|
@@ -136,13 +136,13 @@ function FloatingThreadPortal({
|
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
|
-
|
|
139
|
+
react.useLayoutEffect(() => {
|
|
140
140
|
setReference({
|
|
141
141
|
getBoundingClientRect: () => range.getBoundingClientRect()
|
|
142
142
|
});
|
|
143
143
|
}, [setReference, range]);
|
|
144
144
|
return reactDom$1.createPortal(
|
|
145
|
-
/* @__PURE__ */
|
|
145
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
146
146
|
ref: setFloating,
|
|
147
147
|
...props,
|
|
148
148
|
style: {
|
|
@@ -156,8 +156,9 @@ function FloatingThreadPortal({
|
|
|
156
156
|
className: classnames.classNames(
|
|
157
157
|
"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
|
|
158
158
|
className
|
|
159
|
-
)
|
|
160
|
-
|
|
159
|
+
),
|
|
160
|
+
children
|
|
161
|
+
}),
|
|
161
162
|
container
|
|
162
163
|
);
|
|
163
164
|
}
|
|
@@ -168,7 +169,7 @@ function ThreadWrapper({
|
|
|
168
169
|
onKeyDown,
|
|
169
170
|
...threadProps
|
|
170
171
|
}) {
|
|
171
|
-
const handleKeyDown =
|
|
172
|
+
const handleKeyDown = react.useCallback(
|
|
172
173
|
(event) => {
|
|
173
174
|
onKeyDown?.(event);
|
|
174
175
|
if (event.key === "Escape") {
|
|
@@ -177,14 +178,14 @@ function ThreadWrapper({
|
|
|
177
178
|
},
|
|
178
179
|
[onEscapeKeydown, onKeyDown]
|
|
179
180
|
);
|
|
180
|
-
return /* @__PURE__ */
|
|
181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Thread, {
|
|
181
182
|
thread,
|
|
182
183
|
onKeyDown: handleKeyDown,
|
|
183
184
|
...threadProps
|
|
184
185
|
});
|
|
185
186
|
}
|
|
186
187
|
function useThreadToNodes() {
|
|
187
|
-
const threadToNodes =
|
|
188
|
+
const threadToNodes = react.useContext(commentPluginProvider.ThreadToNodesContext);
|
|
188
189
|
if (threadToNodes === null) {
|
|
189
190
|
throw new Error(
|
|
190
191
|
"FloatingThreads component must be used within a LiveblocksPlugin component."
|
|
@@ -194,13 +195,13 @@ function useThreadToNodes() {
|
|
|
194
195
|
}
|
|
195
196
|
function useIsSelectionCollapsed() {
|
|
196
197
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
197
|
-
const subscribe =
|
|
198
|
+
const subscribe = react.useCallback(
|
|
198
199
|
(onStoreChange) => {
|
|
199
200
|
return editor.registerUpdateListener(onStoreChange);
|
|
200
201
|
},
|
|
201
202
|
[editor]
|
|
202
203
|
);
|
|
203
|
-
const getSnapshot =
|
|
204
|
+
const getSnapshot = react.useCallback(() => {
|
|
204
205
|
return editor.getEditorState().read(() => {
|
|
205
206
|
const selection = lexical.$getSelection();
|
|
206
207
|
if (selection === null)
|
|
@@ -208,10 +209,10 @@ function useIsSelectionCollapsed() {
|
|
|
208
209
|
return selection.isCollapsed();
|
|
209
210
|
});
|
|
210
211
|
}, [editor]);
|
|
211
|
-
return
|
|
212
|
+
return react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
212
213
|
}
|
|
213
214
|
function useActiveThreads() {
|
|
214
|
-
const activeThreads =
|
|
215
|
+
const activeThreads = react.useContext(commentPluginProvider.ActiveThreadsContext);
|
|
215
216
|
if (activeThreads === null) {
|
|
216
217
|
throw new Error(
|
|
217
218
|
"FloatingThreads component must be used within LiveblocksPlugin."
|
|
@@ -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, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\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={classNames(\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","useFloating","flip","offset","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","createPortal","classNames","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"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, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\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 useLayoutEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\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={classNames(\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","classNames","useContext","ThreadToNodesContext","$getSelection","useSyncExternalStore","ActiveThreadsContext"],"mappings":";;;;;;;;;;;;;AA4DO,SAAS,eAAgB,CAAA;AAAA,EAC9B,OAAA;AAAA,EACA,UAAA;AAAA,EACG,GAAA,KAAA;AACL,CAAyB,EAAA;AACvB,EAAA,MAAM,gBAAgB,gBAAiB,EAAA,CAAA;AAEvC,EAAM,MAAA,MAAA,GAAS,YAAY,MAAU,IAAAA,cAAA,CAAA;AAErC,EAAM,MAAA,CAAC,MAAM,CAAA,GAAIC,gDAA0B,EAAA,CAAA;AAC3C,EAAA,MAAM,QAAQ,gBAAiB,EAAA,CAAA;AAE/B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,eAGhB,IAAI,CAAA,CAAA;AAEd,EAAM,MAAA,iBAAA,GAAoBC,kBAAY,MAAM;AAC1C,IAAA,SAAS,cAA+B,GAAA;AACtC,MAAA,SAAS,iBAAoB,GAAA;AAC3B,QAAMC,MAAAA,eAAAA,uBAAqB,GAAiB,EAAA,CAAA;AAE5C,QAAA,KAAA,MAAW,UAAU,aAAe,EAAA;AAClC,UAAM,MAAA,IAAA,GAAO,KAAM,CAAA,GAAA,CAAI,MAAM,CAAA,CAAA;AAC7B,UAAA,IAAI,IAAS,KAAA,KAAA,CAAA;AAAW,YAAA,SAAA;AAExB,UAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,YAAM,MAAA,OAAA,GAAU,MAAO,CAAA,eAAA,CAAgB,GAAG,CAAA,CAAA;AAC1C,YAAA,IAAI,OAAY,KAAA,IAAA;AAAM,cAAA,SAAA;AACtB,YAAAA,eAAAA,CAAe,IAAI,OAAO,CAAA,CAAA;AAAA,WAC5B;AAAA,SACF;AACA,QAAOA,OAAAA,eAAAA,CAAAA;AAAA,OACT;AAEA,MAAA,MAAM,iBAAiB,iBAAkB,EAAA,CAAA;AAEzC,MAAA,MAAM,iBAAiB,KAAM,CAAA,IAAA,CAAK,cAAc,CAAA,CAAE,KAAKC,4BAAY,CAAA,CAAA;AACnE,MAAA,IAAI,eAAe,MAAW,KAAA,CAAA;AAAG,QAAO,OAAA,IAAA,CAAA;AAExC,MAAMC,MAAAA,MAAAA,GAAQ,SAAS,WAAY,EAAA,CAAA;AACnC,MAAAA,MAAAA,CAAM,cAAe,CAAA,cAAA,CAAe,CAAE,CAAA,CAAA,CAAA;AACtC,MAAAA,MAAM,CAAA,WAAA,CAAY,cAAe,CAAA,cAAA,CAAe,SAAS,CAAE,CAAA,CAAA,CAAA;AAE3D,MAAOA,OAAAA,MAAAA,CAAAA;AAAA,KACT;AAEA,IAAM,MAAA,MAAA,GAAA,CAAU,OAAW,IAAA,EAAI,EAAA,MAAA;AAAA,MAAO,CAAC,MAAA,KACrC,aAAc,CAAA,QAAA,CAAS,OAAO,EAAE,CAAA;AAAA,KAClC,CAAA;AAEA,IAAA,MAAMA,SAAQ,cAAe,EAAA,CAAA;AAC7B,IAAA,IAAIA,WAAU,IAAM,EAAA;AAClB,MAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AACb,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,QAAA,CAAS,EAAE,KAAA,EAAAA,MAAO,EAAA,OAAA,EAAS,QAAQ,CAAA,CAAA;AAAA,KAClC,CAAC,aAAA,EAAe,KAAO,EAAA,MAAA,EAAQ,OAAO,CAAC,CAAA,CAAA;AAE1C,EAAAC,eAAA,CAAU,MAAM;AACd,IAAkB,iBAAA,EAAA,CAAA;AAAA,GACpB,EAAG,CAAC,iBAAiB,CAAC,CAAA,CAAA;AAEtB,EAAAA,eAAA,CAAU,MAAM;AACd,IAAO,OAAA,MAAA,CAAO,uBAAuB,iBAAiB,CAAA,CAAA;AAAA,GACrD,EAAA,CAAC,MAAQ,EAAA,iBAAiB,CAAC,CAAA,CAAA;AAE9B,EAAM,MAAA,mBAAA,GAAsBJ,kBAAY,MAAe;AACrD,IAAA,IAAI,KAAU,KAAA,IAAA;AAAM,MAAO,OAAA,KAAA,CAAA;AAC3B,IAAA,QAAA,CAAS,IAAI,CAAA,CAAA;AACb,IAAO,OAAA,IAAA,CAAA;AAAA,GACT,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAEV,EAAAI,eAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAO,CAAA,eAAA;AAAA,MACZC,0BAAA;AAAA,MACA,mBAAA;AAAA,MACAC,6BAAA;AAAA,KACF,CAAA;AAAA,GACC,EAAA,CAAC,MAAQ,EAAA,mBAAmB,CAAC,CAAA,CAAA;AAEhC,EAAA,MAAM,cAAc,uBAAwB,EAAA,CAAA;AAE5C,EAAA,IAAI,KAAU,KAAA,IAAA,IAAQ,WAAgB,KAAA,IAAA,IAAQ,CAAC,WAAA;AAAa,IAAO,OAAA,IAAA,CAAA;AAEnE,EAAA,uBACGC,cAAA,CAAA,oBAAA,EAAA;AAAA,IACC,OAAO,KAAM,CAAA,KAAA;AAAA,IACb,WAAW,QAAS,CAAA,IAAA;AAAA,IACnB,GAAG,KAAA;AAAA,IAEH,QAAM,EAAA,KAAA,CAAA,OAAA,CAAQ,GAAI,CAAA,CAAC,2BACjBA,cAAA,CAAA,aAAA,EAAA;AAAA,MAEC,MAAA;AAAA,MACA,MAAA;AAAA,MACA,eAAiB,EAAA,mBAAA;AAAA,MACjB,SAAU,EAAA,oCAAA;AAAA,KAJL,EAAA,MAAA,CAAO,EAKd,CACD,CAAA;AAAA,GACH,CAAA,CAAA;AAEJ,CAAA;AASO,MAAM,iCAAoC,GAAA,GAAA;AAEjD,SAAS,oBAAqB,CAAA;AAAA,EAC5B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACG,GAAA,KAAA;AACL,CAA8B,EAAA;AAC5B,EAAM,MAAA;AAAA,IACJ,IAAA,EAAM,EAAE,YAAA,EAAc,WAAY,EAAA;AAAA,IAClC,QAAA;AAAA,IACA,CAAA;AAAA,IACA,CAAA;AAAA,MACEC,oBAAY,CAAA;AAAA,IACd,QAAU,EAAA,UAAA;AAAA,IACV,SAAW,EAAA,QAAA;AAAA,IACX,UAAY,EAAA;AAAA,MACVC,cAAK,EAAE,OAAA,EAAS,iCAAmC,EAAA,SAAA,EAAW,OAAO,CAAA;AAAA,MACrEC,gBAAO,EAAE,CAAA;AAAA,MACTC,aAAK,CAAA,EAAE,OAAS,EAAA,iCAAA,EAAmC,CAAA;AAAA,MACnDC,cAAM,CAAA;AAAA,QACJ,OAAS,EAAA,iCAAA;AAAA,QACT,SAASC,mBAAW,EAAA;AAAA,OACrB,CAAA;AAAA,MACDC,aAAK,CAAA;AAAA,QACH,OAAS,EAAA,iCAAA;AAAA,QACT,KAAM,CAAA,EAAE,cAAgB,EAAA,eAAA,EAAiB,UAAY,EAAA;AACnD,UAAA,QAAA,CAAS,SAAS,KAAM,CAAA,WAAA;AAAA,YACtB,+CAAA;AAAA,YACA,CAAG,EAAA,cAAA,CAAA,EAAA,CAAA;AAAA,WACL,CAAA;AACA,UAAA,QAAA,CAAS,SAAS,KAAM,CAAA,WAAA;AAAA,YACtB,gDAAA;AAAA,YACA,CAAG,EAAA,eAAA,CAAA,EAAA,CAAA;AAAA,WACL,CAAA;AAAA,SACF;AAAA,OACD,CAAA;AAAA,KACH;AAAA,IACA,oBAAA,EAAsB,IAAI,IAAS,KAAA;AACjC,MAAO,OAAAC,mBAAA,CAAW,GAAG,IAAM,EAAA;AAAA,QACzB,cAAgB,EAAA,IAAA;AAAA,OACjB,CAAA,CAAA;AAAA,KACH;AAAA,GACD,CAAA,CAAA;AAED,EAAAC,qBAAA,CAAgB,MAAM;AACpB,IAAa,YAAA,CAAA;AAAA,MACX,qBAAA,EAAuB,MAAM,KAAA,CAAM,qBAAsB,EAAA;AAAA,KAC1D,CAAA,CAAA;AAAA,GACA,EAAA,CAAC,YAAc,EAAA,KAAK,CAAC,CAAA,CAAA;AAExB,EAAO,OAAAC,uBAAA;AAAA,oBACJV,cAAA,CAAA,KAAA,EAAA;AAAA,MACC,GAAK,EAAA,WAAA;AAAA,MACJ,GAAG,KAAA;AAAA,MACJ,KAAO,EAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH,QAAU,EAAA,QAAA;AAAA,QACV,GAAK,EAAA,CAAA;AAAA,QACL,IAAM,EAAA,CAAA;AAAA,QACN,SAAA,EAAW,eAAe,IAAK,CAAA,KAAA,CAAM,CAAC,CAAQ,CAAA,IAAA,EAAA,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,MAAA,CAAA;AAAA,QAC1D,QAAU,EAAA,aAAA;AAAA,OACZ;AAAA,MACA,SAAW,EAAAW,qBAAA;AAAA,QACT,gFAAA;AAAA,QACA,SAAA;AAAA,OACF;AAAA,MAEC,QAAA;AAAA,KACH,CAAA;AAAA,IACA,SAAA;AAAA,GACF,CAAA;AACF,CAAA;AAQA,SAAS,aAAc,CAAA;AAAA,EACrB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACG,GAAA,WAAA;AACL,CAAuB,EAAA;AACrB,EAAA,MAAM,aAAgB,GAAAlB,iBAAA;AAAA,IACpB,CAAC,KAAyC,KAAA;AACxC,MAAA,SAAA,GAAY,KAAK,CAAA,CAAA;AAGjB,MAAI,IAAA,KAAA,CAAM,QAAQ,QAAU,EAAA;AAC1B,QAAgB,eAAA,EAAA,CAAA;AAAA,OAClB;AAAA,KACF;AAAA,IACA,CAAC,iBAAiB,SAAS,CAAA;AAAA,GAC7B,CAAA;AAEA,EAAA,uBAAQO,cAAA,CAAA,MAAA,EAAA;AAAA,IAAO,MAAA;AAAA,IAAgB,SAAW,EAAA,aAAA;AAAA,IAAgB,GAAG,WAAA;AAAA,GAAa,CAAA,CAAA;AAC5E,CAAA;AAEA,SAAS,gBAAqC,GAAA;AAC5C,EAAM,MAAA,aAAA,GAAgBY,iBAAWC,0CAAoB,CAAA,CAAA;AACrD,EAAA,IAAI,kBAAkB,IAAM,EAAA;AAC1B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,6EAAA;AAAA,KACF,CAAA;AAAA,GACF;AACA,EAAO,OAAA,aAAA,CAAA;AACT,CAAA;AAEA,SAAS,uBAA0C,GAAA;AACjD,EAAM,MAAA,CAAC,MAAM,CAAA,GAAItB,gDAA0B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAY,GAAAE,iBAAA;AAAA,IAChB,CAAC,aAA8B,KAAA;AAC7B,MAAO,OAAA,MAAA,CAAO,uBAAuB,aAAa,CAAA,CAAA;AAAA,KACpD;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAM,MAAA,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,OAAO,MAAO,CAAA,cAAA,EAAiB,CAAA,IAAA,CAAK,MAAM;AACxC,MAAA,MAAM,YAAYqB,qBAAc,EAAA,CAAA;AAChC,MAAA,IAAI,SAAc,KAAA,IAAA;AAAM,QAAO,OAAA,IAAA,CAAA;AAC/B,MAAA,OAAO,UAAU,WAAY,EAAA,CAAA;AAAA,KAC9B,CAAA,CAAA;AAAA,GACH,EAAG,CAAC,MAAM,CAAC,CAAA,CAAA;AAEX,EAAO,OAAAC,0BAAA,CAAqB,SAAW,EAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACjE,CAAA;AAEA,SAAS,gBAAmB,GAAA;AAC1B,EAAM,MAAA,aAAA,GAAgBH,iBAAWI,0CAAoB,CAAA,CAAA;AACrD,EAAA,IAAI,kBAAkB,IAAM,EAAA;AAC1B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,iEAAA;AAAA,KACF,CAAA;AAAA,GACF;AAEA,EAAO,OAAA,aAAA,CAAA;AACT;;;;;"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
1
2
|
import { useFloating, flip, offset, hide, shift, limitShift, size, autoUpdate } from '@floating-ui/react-dom';
|
|
2
3
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
4
|
import { Thread } from '@liveblocks/react-ui';
|
|
4
5
|
import { KEY_ESCAPE_COMMAND, COMMAND_PRIORITY_HIGH, $getSelection } from 'lexical';
|
|
5
|
-
import
|
|
6
|
+
import { useState, useCallback, useEffect, useLayoutEffect, useContext, useSyncExternalStore } from 'react';
|
|
6
7
|
import { createPortal } from 'react-dom';
|
|
7
|
-
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
|
|
8
8
|
import { classNames } from '../classnames.mjs';
|
|
9
9
|
import { compareNodes } from './anchored-threads.mjs';
|
|
10
10
|
import { ThreadToNodesContext, ActiveThreadsContext } from './comment-plugin-provider.mjs';
|
|
@@ -77,17 +77,17 @@ function FloatingThreads({
|
|
|
77
77
|
const isCollapsed = useIsSelectionCollapsed();
|
|
78
78
|
if (range === null || isCollapsed === null || !isCollapsed)
|
|
79
79
|
return null;
|
|
80
|
-
return /* @__PURE__ */
|
|
80
|
+
return /* @__PURE__ */ jsx(FloatingThreadPortal, {
|
|
81
81
|
range: range.range,
|
|
82
82
|
container: document.body,
|
|
83
|
-
...props
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
})
|
|
83
|
+
...props,
|
|
84
|
+
children: range.threads.map((thread) => /* @__PURE__ */ jsx(ThreadWrapper, {
|
|
85
|
+
thread,
|
|
86
|
+
Thread: Thread$1,
|
|
87
|
+
onEscapeKeydown: handleEscapeKeydown,
|
|
88
|
+
className: "lb-lexical-floating-threads-thread"
|
|
89
|
+
}, thread.id))
|
|
90
|
+
});
|
|
91
91
|
}
|
|
92
92
|
const FLOATING_THREAD_COLLISION_PADDING = 10;
|
|
93
93
|
function FloatingThreadPortal({
|
|
@@ -140,7 +140,7 @@ function FloatingThreadPortal({
|
|
|
140
140
|
});
|
|
141
141
|
}, [setReference, range]);
|
|
142
142
|
return createPortal(
|
|
143
|
-
/* @__PURE__ */
|
|
143
|
+
/* @__PURE__ */ jsx("div", {
|
|
144
144
|
ref: setFloating,
|
|
145
145
|
...props,
|
|
146
146
|
style: {
|
|
@@ -154,8 +154,9 @@ function FloatingThreadPortal({
|
|
|
154
154
|
className: classNames(
|
|
155
155
|
"lb-root lb-portal lb-elevation lb-lexical-floating lb-lexical-floating-threads",
|
|
156
156
|
className
|
|
157
|
-
)
|
|
158
|
-
|
|
157
|
+
),
|
|
158
|
+
children
|
|
159
|
+
}),
|
|
159
160
|
container
|
|
160
161
|
);
|
|
161
162
|
}
|
|
@@ -175,7 +176,7 @@ function ThreadWrapper({
|
|
|
175
176
|
},
|
|
176
177
|
[onEscapeKeydown, onKeyDown]
|
|
177
178
|
);
|
|
178
|
-
return /* @__PURE__ */
|
|
179
|
+
return /* @__PURE__ */ jsx(Thread, {
|
|
179
180
|
thread,
|
|
180
181
|
onKeyDown: handleKeyDown,
|
|
181
182
|
...threadProps
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-threads.mjs","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, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\nimport {\n $getSelection,\n COMMAND_PRIORITY_HIGH,\n KEY_ESCAPE_COMMAND,\n} from \"lexical\";\nimport React, {\n type ComponentType,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\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={classNames(\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","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating-threads.mjs","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, DM, ThreadData } from \"@liveblocks/core\";\nimport {\n Thread as DefaultThread,\n type ThreadProps,\n} from \"@liveblocks/react-ui\";\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 useLayoutEffect,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { classNames } from \"../classnames\";\nimport { compareNodes } from \"./anchored-threads\";\nimport {\n ActiveThreadsContext,\n type ThreadToNodesMap,\n} from \"./comment-plugin-provider\";\nimport { ThreadToNodesContext } from \"./comment-plugin-provider\";\n\ntype ThreadPanelComponents = {\n Thread: ComponentType<ThreadProps>;\n};\n\nexport interface FloatingThreadsProps<M extends BaseMetadata = DM>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * The threads to display.\n */\n threads: ThreadData<M>[];\n\n /**\n * Override the component's components.\n */\n components?: Partial<ThreadPanelComponents>;\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={classNames(\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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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
2
|
import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
|
|
2
3
|
import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
|
|
3
|
-
import
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes, ReactNode } from 'react';
|
|
4
6
|
import * as lexical from 'lexical';
|
|
5
7
|
import { LexicalCommand } from 'lexical';
|
|
6
8
|
import { InitialConfigType } from '@lexical/react/LexicalComposer';
|
|
@@ -18,7 +20,7 @@ interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<Compone
|
|
|
18
20
|
*/
|
|
19
21
|
components?: Partial<AnchoredThreadsComponents>;
|
|
20
22
|
}
|
|
21
|
-
declare function AnchoredThreads({ threads, components, className, style, ...props }: AnchoredThreadsProps):
|
|
23
|
+
declare function AnchoredThreads({ threads, components, className, style, ...props }: AnchoredThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Returns whether the associated thread annotation for the given thread id is selected or not in the editor.
|
|
@@ -58,7 +60,7 @@ declare type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<ComposerP
|
|
|
58
60
|
* Submitting a comment will attach an annotation thread at the current selection.
|
|
59
61
|
* Should be nested inside `LiveblocksPlugin`.
|
|
60
62
|
*/
|
|
61
|
-
declare const FloatingComposer:
|
|
63
|
+
declare const FloatingComposer: react.ForwardRefExoticComponent<FloatingComposerProps<BaseMetadata> & react.RefAttributes<HTMLFormElement>>;
|
|
62
64
|
|
|
63
65
|
declare type ThreadPanelComponents = {
|
|
64
66
|
Thread: ComponentType<ThreadProps>;
|
|
@@ -73,7 +75,7 @@ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAtt
|
|
|
73
75
|
*/
|
|
74
76
|
components?: Partial<ThreadPanelComponents>;
|
|
75
77
|
}
|
|
76
|
-
declare function FloatingThreads({ threads, components, ...props }: FloatingThreadsProps):
|
|
78
|
+
declare function FloatingThreads({ threads, components, ...props }: FloatingThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Function that takes a Lexical editor config and modifies it to add the necessary
|
|
@@ -140,7 +142,7 @@ declare function useEditorStatus(): EditorStatus;
|
|
|
140
142
|
*/
|
|
141
143
|
declare function useIsEditorReady(): boolean;
|
|
142
144
|
declare type LiveblocksPluginProps = {
|
|
143
|
-
children?:
|
|
145
|
+
children?: ReactNode;
|
|
144
146
|
};
|
|
145
147
|
/**
|
|
146
148
|
* Liveblocks plugin for Lexical that adds collaboration to your editor.
|
|
@@ -187,6 +189,6 @@ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
187
189
|
* @example
|
|
188
190
|
* <HistoryVersionPreview version={version} />
|
|
189
191
|
*/
|
|
190
|
-
declare const HistoryVersionPreview:
|
|
192
|
+
declare const HistoryVersionPreview: react.ForwardRefExoticComponent<HistoryVersionPreviewProps & react.RefAttributes<HTMLDivElement>>;
|
|
191
193
|
|
|
192
194
|
export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsEditorReady, useIsThreadActive };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
2
|
import { BaseMetadata, DM, ThreadData, HistoryVersion } from '@liveblocks/core';
|
|
2
3
|
import { ThreadProps, ComposerProps } from '@liveblocks/react-ui';
|
|
3
|
-
import
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes, ReactNode } from 'react';
|
|
4
6
|
import * as lexical from 'lexical';
|
|
5
7
|
import { LexicalCommand } from 'lexical';
|
|
6
8
|
import { InitialConfigType } from '@lexical/react/LexicalComposer';
|
|
@@ -18,7 +20,7 @@ interface AnchoredThreadsProps<M extends BaseMetadata = DM> extends Omit<Compone
|
|
|
18
20
|
*/
|
|
19
21
|
components?: Partial<AnchoredThreadsComponents>;
|
|
20
22
|
}
|
|
21
|
-
declare function AnchoredThreads({ threads, components, className, style, ...props }: AnchoredThreadsProps):
|
|
23
|
+
declare function AnchoredThreads({ threads, components, className, style, ...props }: AnchoredThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Returns whether the associated thread annotation for the given thread id is selected or not in the editor.
|
|
@@ -58,7 +60,7 @@ declare type FloatingComposerProps<M extends BaseMetadata = DM> = Omit<ComposerP
|
|
|
58
60
|
* Submitting a comment will attach an annotation thread at the current selection.
|
|
59
61
|
* Should be nested inside `LiveblocksPlugin`.
|
|
60
62
|
*/
|
|
61
|
-
declare const FloatingComposer:
|
|
63
|
+
declare const FloatingComposer: react.ForwardRefExoticComponent<FloatingComposerProps<BaseMetadata> & react.RefAttributes<HTMLFormElement>>;
|
|
62
64
|
|
|
63
65
|
declare type ThreadPanelComponents = {
|
|
64
66
|
Thread: ComponentType<ThreadProps>;
|
|
@@ -73,7 +75,7 @@ interface FloatingThreadsProps<M extends BaseMetadata = DM> extends Omit<HTMLAtt
|
|
|
73
75
|
*/
|
|
74
76
|
components?: Partial<ThreadPanelComponents>;
|
|
75
77
|
}
|
|
76
|
-
declare function FloatingThreads({ threads, components, ...props }: FloatingThreadsProps):
|
|
78
|
+
declare function FloatingThreads({ threads, components, ...props }: FloatingThreadsProps): react_jsx_runtime.JSX.Element | null;
|
|
77
79
|
|
|
78
80
|
/**
|
|
79
81
|
* Function that takes a Lexical editor config and modifies it to add the necessary
|
|
@@ -140,7 +142,7 @@ declare function useEditorStatus(): EditorStatus;
|
|
|
140
142
|
*/
|
|
141
143
|
declare function useIsEditorReady(): boolean;
|
|
142
144
|
declare type LiveblocksPluginProps = {
|
|
143
|
-
children?:
|
|
145
|
+
children?: ReactNode;
|
|
144
146
|
};
|
|
145
147
|
/**
|
|
146
148
|
* Liveblocks plugin for Lexical that adds collaboration to your editor.
|
|
@@ -187,6 +189,6 @@ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
187
189
|
* @example
|
|
188
190
|
* <HistoryVersionPreview version={version} />
|
|
189
191
|
*/
|
|
190
|
-
declare const HistoryVersionPreview:
|
|
192
|
+
declare const HistoryVersionPreview: react.ForwardRefExoticComponent<HistoryVersionPreviewProps & react.RefAttributes<HTMLDivElement>>;
|
|
191
193
|
|
|
192
194
|
export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsEditorReady, useIsThreadActive };
|