@liveblocks/react-lexical 2.18.2 → 2.18.3
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/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/liveblocks-plugin-provider.js +4 -21
- package/dist/liveblocks-plugin-provider.js.map +1 -1
- package/dist/liveblocks-plugin-provider.mjs +6 -23
- package/dist/liveblocks-plugin-provider.mjs.map +1 -1
- package/dist/mentions/mention-node.js +1 -1
- package/dist/mentions/mention-node.js.map +1 -1
- package/dist/mentions/mention-node.mjs +1 -1
- package/dist/mentions/mention-node.mjs.map +1 -1
- package/dist/version-history/history-version-preview.js +1 -0
- package/dist/version-history/history-version-preview.js.map +1 -1
- package/dist/version-history/history-version-preview.mjs +1 -0
- package/dist/version-history/history-version-preview.mjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +12 -12
package/dist/index.d.mts
CHANGED
|
@@ -127,7 +127,6 @@ declare function liveblocksConfig(editorConfig: Omit<InitialConfigType, "editorS
|
|
|
127
127
|
editorState: null;
|
|
128
128
|
html?: lexical.HTMLConfig;
|
|
129
129
|
onError: (error: Error, editor: lexical.LexicalEditor) => void;
|
|
130
|
-
editor__DEPRECATED?: lexical.LexicalEditor | null;
|
|
131
130
|
namespace: string;
|
|
132
131
|
editable?: boolean;
|
|
133
132
|
theme?: lexical.EditorThemeClasses;
|
package/dist/index.d.ts
CHANGED
|
@@ -127,7 +127,6 @@ declare function liveblocksConfig(editorConfig: Omit<InitialConfigType, "editorS
|
|
|
127
127
|
editorState: null;
|
|
128
128
|
html?: lexical.HTMLConfig;
|
|
129
129
|
onError: (error: Error, editor: lexical.LexicalEditor) => void;
|
|
130
|
-
editor__DEPRECATED?: lexical.LexicalEditor | null;
|
|
131
130
|
namespace: string;
|
|
132
131
|
editable?: boolean;
|
|
133
132
|
theme?: lexical.EditorThemeClasses;
|
|
@@ -7,16 +7,14 @@ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
|
7
7
|
var core = require('@liveblocks/core');
|
|
8
8
|
var react$1 = require('@liveblocks/react');
|
|
9
9
|
var _private = require('@liveblocks/react/_private');
|
|
10
|
-
var yjs
|
|
10
|
+
var yjs = require('@liveblocks/yjs');
|
|
11
11
|
var react = require('react');
|
|
12
|
-
var yjs = require('yjs');
|
|
13
12
|
var commentPluginProvider = require('./comments/comment-plugin-provider.js');
|
|
14
13
|
var threadMarkNode = require('./comments/thread-mark-node.js');
|
|
15
14
|
var mentionNode = require('./mentions/mention-node.js');
|
|
16
15
|
var mentionPlugin = require('./mentions/mention-plugin.js');
|
|
17
16
|
var useRootElement = require('./use-root-element.js');
|
|
18
17
|
|
|
19
|
-
const providersMap = /* @__PURE__ */ new Map();
|
|
20
18
|
function useEditorStatus() {
|
|
21
19
|
const provider = _private.useYjsProvider();
|
|
22
20
|
const subscribe = react.useCallback(
|
|
@@ -65,7 +63,6 @@ const LiveblocksPlugin = ({
|
|
|
65
63
|
const isResolveMentionSuggestionsDefined = _private.useResolveMentionSuggestions() !== void 0;
|
|
66
64
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
67
65
|
const room = react$1.useRoom();
|
|
68
|
-
const previousRoomIdRef = react.useRef(null);
|
|
69
66
|
if (!editor.hasNodes([threadMarkNode.ThreadMarkNode, mentionNode.MentionNode])) {
|
|
70
67
|
throw new Error(
|
|
71
68
|
"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig"
|
|
@@ -99,23 +96,9 @@ const LiveblocksPlugin = ({
|
|
|
99
96
|
const self = react$1.useSelf();
|
|
100
97
|
const providerFactory = react.useCallback(
|
|
101
98
|
(id, yjsDocMap) => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
previousProvider.destroy();
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
let doc = yjsDocMap.get(id);
|
|
109
|
-
if (doc === void 0) {
|
|
110
|
-
doc = new yjs.Doc();
|
|
111
|
-
const provider = new yjs$1.LiveblocksYjsProvider(room, doc);
|
|
112
|
-
yjsDocMap.set(id, doc);
|
|
113
|
-
providersMap.set(id, provider);
|
|
114
|
-
}
|
|
115
|
-
return core.nn(
|
|
116
|
-
providersMap.get(id),
|
|
117
|
-
"Internal error. Should never happen"
|
|
118
|
-
);
|
|
99
|
+
const provider = yjs.getYjsProviderForRoom(room);
|
|
100
|
+
yjsDocMap.set(id, provider.getYDoc());
|
|
101
|
+
return provider;
|
|
119
102
|
},
|
|
120
103
|
[room]
|
|
121
104
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { nn, TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => { };\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\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 />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useYjsProvider","useCallback","useSyncExternalStore","useResolveMentionSuggestions","useLexicalComposerContext","useRoom","useRef","ThreadMarkNode","MentionNode","useState","useFloating","autoUpdate","useEffect","useReportTextEditor","TextEditorType","useSelf","Doc","LiveblocksYjsProvider","nn","useRootElement","useLayoutEffect","jsxs","Fragment","jsx","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport {\n useCallback,\n useEffect,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => { };\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\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 />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":["useYjsProvider","useCallback","useSyncExternalStore","useResolveMentionSuggestions","useLexicalComposerContext","useRoom","ThreadMarkNode","MentionNode","useState","useFloating","autoUpdate","useEffect","useReportTextEditor","TextEditorType","useSelf","getYjsProviderForRoom","useRootElement","useLayoutEffect","jsxs","Fragment","jsx","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
|
|
@@ -2,19 +2,17 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useFloating, autoUpdate } from '@floating-ui/react-dom';
|
|
3
3
|
import { CollaborationPlugin } from '@lexical/react/LexicalCollaborationPlugin';
|
|
4
4
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
5
|
-
import { TextEditorType
|
|
5
|
+
import { TextEditorType } from '@liveblocks/core';
|
|
6
6
|
import { useRoom, useSelf } from '@liveblocks/react';
|
|
7
7
|
import { useYjsProvider, useResolveMentionSuggestions, useReportTextEditor, useLayoutEffect } from '@liveblocks/react/_private';
|
|
8
|
-
import {
|
|
9
|
-
import { useCallback, useSyncExternalStore,
|
|
10
|
-
import { Doc } from 'yjs';
|
|
8
|
+
import { getYjsProviderForRoom } from '@liveblocks/yjs';
|
|
9
|
+
import { useCallback, useSyncExternalStore, useState, useEffect } from 'react';
|
|
11
10
|
import { CommentPluginProvider } from './comments/comment-plugin-provider.mjs';
|
|
12
11
|
import { ThreadMarkNode } from './comments/thread-mark-node.mjs';
|
|
13
12
|
import { MentionNode } from './mentions/mention-node.mjs';
|
|
14
13
|
import { MentionPlugin } from './mentions/mention-plugin.mjs';
|
|
15
14
|
import { useRootElement } from './use-root-element.mjs';
|
|
16
15
|
|
|
17
|
-
const providersMap = /* @__PURE__ */ new Map();
|
|
18
16
|
function useEditorStatus() {
|
|
19
17
|
const provider = useYjsProvider();
|
|
20
18
|
const subscribe = useCallback(
|
|
@@ -63,7 +61,6 @@ const LiveblocksPlugin = ({
|
|
|
63
61
|
const isResolveMentionSuggestionsDefined = useResolveMentionSuggestions() !== void 0;
|
|
64
62
|
const [editor] = useLexicalComposerContext();
|
|
65
63
|
const room = useRoom();
|
|
66
|
-
const previousRoomIdRef = useRef(null);
|
|
67
64
|
if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {
|
|
68
65
|
throw new Error(
|
|
69
66
|
"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig"
|
|
@@ -97,23 +94,9 @@ const LiveblocksPlugin = ({
|
|
|
97
94
|
const self = useSelf();
|
|
98
95
|
const providerFactory = useCallback(
|
|
99
96
|
(id, yjsDocMap) => {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
previousProvider.destroy();
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
let doc = yjsDocMap.get(id);
|
|
107
|
-
if (doc === void 0) {
|
|
108
|
-
doc = new Doc();
|
|
109
|
-
const provider = new LiveblocksYjsProvider(room, doc);
|
|
110
|
-
yjsDocMap.set(id, doc);
|
|
111
|
-
providersMap.set(id, provider);
|
|
112
|
-
}
|
|
113
|
-
return nn(
|
|
114
|
-
providersMap.get(id),
|
|
115
|
-
"Internal error. Should never happen"
|
|
116
|
-
);
|
|
97
|
+
const provider = getYjsProviderForRoom(room);
|
|
98
|
+
yjsDocMap.set(id, provider.getYDoc());
|
|
99
|
+
return provider;
|
|
117
100
|
},
|
|
118
101
|
[room]
|
|
119
102
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { nn, TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => { };\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\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 />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { TextEditorType } from \"@liveblocks/core\";\nimport { useRoom, useSelf } from \"@liveblocks/react\";\nimport {\n useLayoutEffect,\n useReportTextEditor,\n useResolveMentionSuggestions,\n useYjsProvider,\n} from \"@liveblocks/react/_private\";\nimport { getYjsProviderForRoom } from \"@liveblocks/yjs\";\nimport type { MutableRefObject, ReactNode } from \"react\";\nimport {\n useCallback,\n useEffect,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport type { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\nimport { useRootElement } from \"./use-root-element\";\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => { };\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const isResolveMentionSuggestionsDefined =\n useResolveMentionSuggestions() !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useReportTextEditor(TextEditorType.Lexical, \"root\");\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n const provider = getYjsProviderForRoom(room);\n yjsDocMap.set(id, provider.getYDoc());\n\n return provider as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\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 />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {isResolveMentionSuggestionsDefined && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ class MentionNode extends lexical.DecoratorNode {
|
|
|
19
19
|
return "lb-mention";
|
|
20
20
|
}
|
|
21
21
|
static clone(node) {
|
|
22
|
-
return new MentionNode(node.__id, node.__userId);
|
|
22
|
+
return new MentionNode(node.__id, node.__userId, node.__key);
|
|
23
23
|
}
|
|
24
24
|
createDOM() {
|
|
25
25
|
const element = document.createElement("span");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mention-node.js","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import { createInboxNotificationId } from \"@liveblocks/core\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const node = new MentionNode(createInboxNotificationId(), userId);\n return $applyNodeReplacement(node);\n}\n"],"names":["DecoratorNode","jsxs","Mention","jsx","User","createInboxNotificationId","$applyNodeReplacement"],"mappings":";;;;;;;;AAeA,MAAM,iBAAoB,GAAA,GAAA,CAAA;AAQnB,MAAM,oBAAoBA,qBAA2B,CAAA;AAAA,EAC1D,IAAA,CAAA;AAAA,EACA,QAAA,CAAA;AAAA,EAEA,WAAA,CAAY,EAAY,EAAA,MAAA,EAAgB,GAAe,EAAA;AACrD,IAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AACT,IAAA,IAAA,CAAK,IAAO,GAAA,EAAA,CAAA;AACZ,IAAA,IAAA,CAAK,QAAW,GAAA,MAAA,CAAA;AAAA,GAClB;AAAA,EAEA,OAAO,OAAkB,GAAA;AACvB,IAAO,OAAA,YAAA,CAAA;AAAA,GACT;AAAA,EAEA,OAAO,MAAM,IAAgC,EAAA;AAC3C,IAAA,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"mention-node.js","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import { createInboxNotificationId } from \"@liveblocks/core\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId, node.__key);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const node = new MentionNode(createInboxNotificationId(), userId);\n return $applyNodeReplacement(node);\n}\n"],"names":["DecoratorNode","jsxs","Mention","jsx","User","createInboxNotificationId","$applyNodeReplacement"],"mappings":"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"}
|
|
@@ -17,7 +17,7 @@ class MentionNode extends DecoratorNode {
|
|
|
17
17
|
return "lb-mention";
|
|
18
18
|
}
|
|
19
19
|
static clone(node) {
|
|
20
|
-
return new MentionNode(node.__id, node.__userId);
|
|
20
|
+
return new MentionNode(node.__id, node.__userId, node.__key);
|
|
21
21
|
}
|
|
22
22
|
createDOM() {
|
|
23
23
|
const element = document.createElement("span");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mention-node.mjs","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import { createInboxNotificationId } from \"@liveblocks/core\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const node = new MentionNode(createInboxNotificationId(), userId);\n return $applyNodeReplacement(node);\n}\n"],"names":[],"mappings":";;;;;;AAeA,MAAM,iBAAoB,GAAA,GAAA,CAAA;AAQnB,MAAM,oBAAoB,aAA2B,CAAA;AAAA,EAC1D,IAAA,CAAA;AAAA,EACA,QAAA,CAAA;AAAA,EAEA,WAAA,CAAY,EAAY,EAAA,MAAA,EAAgB,GAAe,EAAA;AACrD,IAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AACT,IAAA,IAAA,CAAK,IAAO,GAAA,EAAA,CAAA;AACZ,IAAA,IAAA,CAAK,QAAW,GAAA,MAAA,CAAA;AAAA,GAClB;AAAA,EAEA,OAAO,OAAkB,GAAA;AACvB,IAAO,OAAA,YAAA,CAAA;AAAA,GACT;AAAA,EAEA,OAAO,MAAM,IAAgC,EAAA;AAC3C,IAAA,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"mention-node.mjs","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import { createInboxNotificationId } from \"@liveblocks/core\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport type { JSX } from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId, node.__key);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const node = new MentionNode(createInboxNotificationId(), userId);\n return $applyNodeReplacement(node);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-version-preview.js","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n icon={<RestoreIcon />}\n >\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["syncLexicalUpdateToYjs","syncYjsChangesToLexical","forwardRef","useLexicalComposerContext","useRef","useOverrides","useHistoryVersionData","useMemo","liveblocksConfig","useEffect","Doc","createBinding","applyUpdate","useCallback","jsxs","classNames","jsx","SpinnerIcon","LexicalComposer","EditorRefPlugin","RichTextPlugin","ContentEditable","LexicalErrorBoundary","List","User","Button","RestoreIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"history-version-preview.js","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n setLocalStateField: emptyFunction,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n icon={<RestoreIcon />}\n >\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["syncLexicalUpdateToYjs","syncYjsChangesToLexical","forwardRef","useLexicalComposerContext","useRef","useOverrides","useHistoryVersionData","useMemo","liveblocksConfig","useEffect","Doc","createBinding","applyUpdate","useCallback","jsxs","classNames","jsx","SpinnerIcon","LexicalComposer","EditorRefPlugin","RichTextPlugin","ContentEditable","LexicalErrorBoundary","List","User","Button","RestoreIcon"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-version-preview.mjs","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n icon={<RestoreIcon />}\n >\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"history-version-preview.mjs","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport { forwardRef, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n setLocalStateField: emptyFunction,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n icon={<RestoreIcon />}\n >\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
|
package/dist/version.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PKG_NAME = "@liveblocks/react-lexical";
|
|
4
|
-
const PKG_VERSION = typeof "2.18.
|
|
4
|
+
const PKG_VERSION = typeof "2.18.3" === "string" && "2.18.3";
|
|
5
5
|
const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
|
|
6
6
|
|
|
7
7
|
exports.PKG_FORMAT = PKG_FORMAT;
|
package/dist/version.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const PKG_NAME = "@liveblocks/react-lexical";
|
|
2
|
-
const PKG_VERSION = typeof "2.18.
|
|
2
|
+
const PKG_VERSION = typeof "2.18.3" === "string" && "2.18.3";
|
|
3
3
|
const PKG_FORMAT = typeof "esm" === "string" && "esm";
|
|
4
4
|
|
|
5
5
|
export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react-lexical",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.3",
|
|
4
4
|
"description": "A lexical react plugin to enable collaboration, comments, live cursors, and more.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -42,22 +42,22 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@floating-ui/react-dom": "^2.1.1",
|
|
45
|
-
"@liveblocks/client": "2.18.
|
|
46
|
-
"@liveblocks/core": "2.18.
|
|
47
|
-
"@liveblocks/react": "2.18.
|
|
48
|
-
"@liveblocks/react-ui": "2.18.
|
|
49
|
-
"@liveblocks/yjs": "2.18.
|
|
45
|
+
"@liveblocks/client": "2.18.3",
|
|
46
|
+
"@liveblocks/core": "2.18.3",
|
|
47
|
+
"@liveblocks/react": "2.18.3",
|
|
48
|
+
"@liveblocks/react-ui": "2.18.3",
|
|
49
|
+
"@liveblocks/yjs": "2.18.3",
|
|
50
50
|
"@radix-ui/react-select": "^2.1.2",
|
|
51
51
|
"@radix-ui/react-toggle": "^1.1.0",
|
|
52
52
|
"yjs": "^13.6.18"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@lexical/react": "0.
|
|
56
|
-
"@lexical/rich-text": "0.
|
|
57
|
-
"@lexical/selection": "0.
|
|
58
|
-
"@lexical/utils": "0.
|
|
59
|
-
"@lexical/yjs": "0.
|
|
60
|
-
"lexical": "0.
|
|
55
|
+
"@lexical/react": "0.24.0",
|
|
56
|
+
"@lexical/rich-text": "0.24.0",
|
|
57
|
+
"@lexical/selection": "0.24.0",
|
|
58
|
+
"@lexical/utils": "0.24.0",
|
|
59
|
+
"@lexical/yjs": "0.24.0",
|
|
60
|
+
"lexical": "0.24.0",
|
|
61
61
|
"react": "^18 || ^19 || ^19.0.0-rc",
|
|
62
62
|
"react-dom": "^18 || ^19 || ^19.0.0-rc"
|
|
63
63
|
},
|