@lexical/react 0.45.1-nightly.20260604.0 → 0.45.1-nightly.20260608.0
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/LexicalCollaborationPlugin.d.ts +10 -2
- package/dist/LexicalCollaborationPlugin.dev.js +35 -21
- package/dist/LexicalCollaborationPlugin.dev.mjs +36 -22
- package/dist/LexicalCollaborationPlugin.prod.js +1 -1
- package/dist/LexicalCollaborationPlugin.prod.mjs +1 -1
- package/dist/shared/useYjsCollaboration.d.ts +2 -1
- package/dist/typescript-too-old.d.ts +18 -0
- package/package.json +236 -20
- package/src/LexicalCollaborationPlugin.tsx +18 -0
- package/src/shared/useYjsCollaboration.tsx +28 -16
|
@@ -22,8 +22,12 @@ type CollaborationPluginProps = {
|
|
|
22
22
|
excludedProperties?: ExcludedProperties;
|
|
23
23
|
awarenessData?: object;
|
|
24
24
|
syncCursorPositionsFn?: SyncCursorPositionsFn;
|
|
25
|
+
/** Opt in to the new CSS Highlights-based selection rendering (if supported by the browser).
|
|
26
|
+
* Fallback to legacy method if not enabled or not supported.
|
|
27
|
+
*/
|
|
28
|
+
selectionHighlight?: boolean;
|
|
25
29
|
};
|
|
26
|
-
export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, syncCursorPositionsFn, }: CollaborationPluginProps): JSX.Element;
|
|
30
|
+
export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, syncCursorPositionsFn, selectionHighlight, }: CollaborationPluginProps): JSX.Element;
|
|
27
31
|
type CollaborationPluginV2Props = {
|
|
28
32
|
id: string;
|
|
29
33
|
doc: Doc;
|
|
@@ -34,6 +38,10 @@ type CollaborationPluginV2Props = {
|
|
|
34
38
|
cursorsContainerRef?: CursorsContainerRef;
|
|
35
39
|
excludedProperties?: ExcludedProperties;
|
|
36
40
|
awarenessData?: object;
|
|
41
|
+
/** Opt in to the new CSS Highlights-based selection rendering (if supported by the browser).
|
|
42
|
+
* Fallback to legacy method if not enabled or not supported.
|
|
43
|
+
*/
|
|
44
|
+
selectionHighlight?: boolean;
|
|
37
45
|
};
|
|
38
|
-
export declare function CollaborationPluginV2__EXPERIMENTAL({ id, doc, provider, __shouldBootstrapUnsafe, username, cursorColor, cursorsContainerRef, excludedProperties, awarenessData, }: CollaborationPluginV2Props): JSX.Element;
|
|
46
|
+
export declare function CollaborationPluginV2__EXPERIMENTAL({ id, doc, provider, __shouldBootstrapUnsafe, username, cursorColor, cursorsContainerRef, excludedProperties, awarenessData, selectionHighlight, }: CollaborationPluginV2Props): JSX.Element;
|
|
39
47
|
export {};
|
|
@@ -48,7 +48,7 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
|
48
48
|
* UndoManager capture timeout.
|
|
49
49
|
*/
|
|
50
50
|
const COLLAB_UNDO_MANAGER = Symbol.for('@lexical/yjs/UndoManager');
|
|
51
|
-
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn = yjs.syncCursorPositions) {
|
|
51
|
+
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn = yjs.syncCursorPositions, selectionHighlight = false) {
|
|
52
52
|
const isReloadingDoc = React.useRef(false);
|
|
53
53
|
const onBootstrap = React.useCallback(() => {
|
|
54
54
|
const {
|
|
@@ -109,7 +109,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
109
109
|
};
|
|
110
110
|
}, [binding, provider, editor, setDoc, docMap, id]);
|
|
111
111
|
useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap);
|
|
112
|
-
useAwareness(binding, provider);
|
|
112
|
+
useAwareness(binding, provider, selectionHighlight);
|
|
113
113
|
return useYjsCursors(binding, cursorsContainerRef);
|
|
114
114
|
}
|
|
115
115
|
function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap, name, color, options = {}) {
|
|
@@ -117,6 +117,7 @@ function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap,
|
|
|
117
117
|
awarenessData,
|
|
118
118
|
excludedProperties,
|
|
119
119
|
rootName,
|
|
120
|
+
selectionHighlight = false,
|
|
120
121
|
__shouldBootstrapUnsafe: shouldBootstrap
|
|
121
122
|
} = options;
|
|
122
123
|
|
|
@@ -195,7 +196,7 @@ function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap,
|
|
|
195
196
|
};
|
|
196
197
|
}, [binding, provider, editor, diffSnapshots]);
|
|
197
198
|
useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap);
|
|
198
|
-
useAwareness(binding, provider);
|
|
199
|
+
useAwareness(binding, provider, selectionHighlight);
|
|
199
200
|
return binding;
|
|
200
201
|
}
|
|
201
202
|
function useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap) {
|
|
@@ -284,19 +285,21 @@ function useProvider(editor, provider, name, color, isReloadingDoc, awarenessDat
|
|
|
284
285
|
};
|
|
285
286
|
}, [provider]);
|
|
286
287
|
}
|
|
287
|
-
function useAwareness(binding, provider) {
|
|
288
|
+
function useAwareness(binding, provider, selectionHighlight) {
|
|
288
289
|
React.useEffect(() => {
|
|
289
290
|
const {
|
|
290
291
|
awareness
|
|
291
292
|
} = provider;
|
|
292
293
|
const onAwarenessUpdate = () => {
|
|
293
|
-
yjs.syncCursorPositions(binding, provider
|
|
294
|
+
yjs.syncCursorPositions(binding, provider, {
|
|
295
|
+
selectionHighlight
|
|
296
|
+
});
|
|
294
297
|
};
|
|
295
298
|
awareness.on('update', onAwarenessUpdate);
|
|
296
299
|
return () => {
|
|
297
300
|
awareness.off('update', onAwarenessUpdate);
|
|
298
301
|
};
|
|
299
|
-
}, [binding, provider]);
|
|
302
|
+
}, [binding, provider, selectionHighlight]);
|
|
300
303
|
}
|
|
301
304
|
function useYjsCursors(binding, cursorsContainerRef) {
|
|
302
305
|
return React.useMemo(() => {
|
|
@@ -446,18 +449,24 @@ function clearEditorSkipCollab(editor, binding) {
|
|
|
446
449
|
if (cursorsContainer == null) {
|
|
447
450
|
return;
|
|
448
451
|
}
|
|
449
|
-
|
|
450
|
-
// reset cursors in dom
|
|
451
|
-
const cursorsArr = Array.from(cursors.values());
|
|
452
|
-
for (let i = 0; i < cursorsArr.length; i++) {
|
|
453
|
-
const cursor = cursorsArr[i];
|
|
452
|
+
for (const cursor of cursors.values()) {
|
|
454
453
|
const selection = cursor.selection;
|
|
455
|
-
if (selection
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
454
|
+
if (selection === null) {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (selection.highlight !== null) {
|
|
458
|
+
CSS.highlights.delete(selection.highlightName);
|
|
459
|
+
yjs.removeCursorHighlightRule(binding, selection.highlightName);
|
|
460
|
+
}
|
|
461
|
+
if (selection.caret.parentNode === cursorsContainer) {
|
|
462
|
+
cursorsContainer.removeChild(selection.caret);
|
|
463
|
+
}
|
|
464
|
+
for (const span of selection.selections) {
|
|
465
|
+
if (span.parentNode === cursorsContainer) {
|
|
466
|
+
cursorsContainer.removeChild(span);
|
|
459
467
|
}
|
|
460
468
|
}
|
|
469
|
+
cursor.selection = null;
|
|
461
470
|
}
|
|
462
471
|
}
|
|
463
472
|
|
|
@@ -479,7 +488,8 @@ function CollaborationPlugin({
|
|
|
479
488
|
initialEditorState,
|
|
480
489
|
excludedProperties,
|
|
481
490
|
awarenessData,
|
|
482
|
-
syncCursorPositionsFn
|
|
491
|
+
syncCursorPositionsFn,
|
|
492
|
+
selectionHighlight
|
|
483
493
|
}) {
|
|
484
494
|
const isBindingInitialized = React.useRef(false);
|
|
485
495
|
const isProviderInitialized = React.useRef(false);
|
|
@@ -537,7 +547,8 @@ function CollaborationPlugin({
|
|
|
537
547
|
setDoc: setDoc,
|
|
538
548
|
shouldBootstrap: shouldBootstrap,
|
|
539
549
|
yjsDocMap: yjsDocMap,
|
|
540
|
-
syncCursorPositionsFn: syncCursorPositionsFn
|
|
550
|
+
syncCursorPositionsFn: syncCursorPositionsFn,
|
|
551
|
+
selectionHighlight: selectionHighlight
|
|
541
552
|
});
|
|
542
553
|
}
|
|
543
554
|
function YjsCollaborationCursors({
|
|
@@ -554,9 +565,10 @@ function YjsCollaborationCursors({
|
|
|
554
565
|
collabContext,
|
|
555
566
|
binding,
|
|
556
567
|
setDoc,
|
|
557
|
-
syncCursorPositionsFn
|
|
568
|
+
syncCursorPositionsFn,
|
|
569
|
+
selectionHighlight
|
|
558
570
|
}) {
|
|
559
|
-
const cursors = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn);
|
|
571
|
+
const cursors = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn, selectionHighlight);
|
|
560
572
|
useYjsHistory(editor, binding);
|
|
561
573
|
useYjsFocusTracking(editor, provider, name, color, awarenessData);
|
|
562
574
|
return cursors;
|
|
@@ -570,7 +582,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
|
|
|
570
582
|
cursorColor,
|
|
571
583
|
cursorsContainerRef,
|
|
572
584
|
excludedProperties,
|
|
573
|
-
awarenessData
|
|
585
|
+
awarenessData,
|
|
586
|
+
selectionHighlight
|
|
574
587
|
}) {
|
|
575
588
|
const collabContext = LexicalCollaborationContext.useCollaborationContext(username, cursorColor);
|
|
576
589
|
const {
|
|
@@ -583,7 +596,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
|
|
|
583
596
|
const binding = useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, yjsDocMap, name, color, {
|
|
584
597
|
__shouldBootstrapUnsafe,
|
|
585
598
|
awarenessData,
|
|
586
|
-
excludedProperties
|
|
599
|
+
excludedProperties,
|
|
600
|
+
selectionHighlight
|
|
587
601
|
});
|
|
588
602
|
useYjsHistoryV2(editor, binding);
|
|
589
603
|
useYjsFocusTracking(editor, provider, name, color, awarenessData);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { useCollaborationContext } from '@lexical/react/LexicalCollaborationContext';
|
|
10
10
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
11
|
-
import { syncCursorPositions, syncLexicalUpdateToYjs, createUndoManager, setLocalStateFocus, createBindingV2__EXPERIMENTAL, CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL, syncYjsStateToLexicalV2__EXPERIMENTAL, DIFF_VERSIONS_COMMAND__EXPERIMENTAL, renderSnapshot__EXPERIMENTAL, syncLexicalUpdateToYjsV2__EXPERIMENTAL, syncYjsChangesToLexical, initLocalState, TOGGLE_CONNECT_COMMAND, syncYjsChangesToLexicalV2__EXPERIMENTAL, CONNECTED_COMMAND, createBinding } from '@lexical/yjs';
|
|
11
|
+
import { syncCursorPositions, syncLexicalUpdateToYjs, createUndoManager, setLocalStateFocus, createBindingV2__EXPERIMENTAL, CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL, syncYjsStateToLexicalV2__EXPERIMENTAL, DIFF_VERSIONS_COMMAND__EXPERIMENTAL, renderSnapshot__EXPERIMENTAL, syncLexicalUpdateToYjsV2__EXPERIMENTAL, syncYjsChangesToLexical, initLocalState, TOGGLE_CONNECT_COMMAND, syncYjsChangesToLexicalV2__EXPERIMENTAL, removeCursorHighlightRule, CONNECTED_COMMAND, createBinding } from '@lexical/yjs';
|
|
12
12
|
import * as React from 'react';
|
|
13
13
|
import { useRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
14
14
|
import { mergeRegister } from '@lexical/utils';
|
|
@@ -34,7 +34,7 @@ import { jsx, Fragment } from 'react/jsx-runtime';
|
|
|
34
34
|
* UndoManager capture timeout.
|
|
35
35
|
*/
|
|
36
36
|
const COLLAB_UNDO_MANAGER = Symbol.for('@lexical/yjs/UndoManager');
|
|
37
|
-
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn = syncCursorPositions) {
|
|
37
|
+
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn = syncCursorPositions, selectionHighlight = false) {
|
|
38
38
|
const isReloadingDoc = useRef(false);
|
|
39
39
|
const onBootstrap = useCallback(() => {
|
|
40
40
|
const {
|
|
@@ -95,7 +95,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
95
95
|
};
|
|
96
96
|
}, [binding, provider, editor, setDoc, docMap, id]);
|
|
97
97
|
useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap);
|
|
98
|
-
useAwareness(binding, provider);
|
|
98
|
+
useAwareness(binding, provider, selectionHighlight);
|
|
99
99
|
return useYjsCursors(binding, cursorsContainerRef);
|
|
100
100
|
}
|
|
101
101
|
function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap, name, color, options = {}) {
|
|
@@ -103,6 +103,7 @@ function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap,
|
|
|
103
103
|
awarenessData,
|
|
104
104
|
excludedProperties,
|
|
105
105
|
rootName,
|
|
106
|
+
selectionHighlight = false,
|
|
106
107
|
__shouldBootstrapUnsafe: shouldBootstrap
|
|
107
108
|
} = options;
|
|
108
109
|
|
|
@@ -181,7 +182,7 @@ function useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, docMap,
|
|
|
181
182
|
};
|
|
182
183
|
}, [binding, provider, editor, diffSnapshots]);
|
|
183
184
|
useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap);
|
|
184
|
-
useAwareness(binding, provider);
|
|
185
|
+
useAwareness(binding, provider, selectionHighlight);
|
|
185
186
|
return binding;
|
|
186
187
|
}
|
|
187
188
|
function useProvider(editor, provider, name, color, isReloadingDoc, awarenessData, onBootstrap) {
|
|
@@ -270,19 +271,21 @@ function useProvider(editor, provider, name, color, isReloadingDoc, awarenessDat
|
|
|
270
271
|
};
|
|
271
272
|
}, [provider]);
|
|
272
273
|
}
|
|
273
|
-
function useAwareness(binding, provider) {
|
|
274
|
+
function useAwareness(binding, provider, selectionHighlight) {
|
|
274
275
|
useEffect(() => {
|
|
275
276
|
const {
|
|
276
277
|
awareness
|
|
277
278
|
} = provider;
|
|
278
279
|
const onAwarenessUpdate = () => {
|
|
279
|
-
syncCursorPositions(binding, provider
|
|
280
|
+
syncCursorPositions(binding, provider, {
|
|
281
|
+
selectionHighlight
|
|
282
|
+
});
|
|
280
283
|
};
|
|
281
284
|
awareness.on('update', onAwarenessUpdate);
|
|
282
285
|
return () => {
|
|
283
286
|
awareness.off('update', onAwarenessUpdate);
|
|
284
287
|
};
|
|
285
|
-
}, [binding, provider]);
|
|
288
|
+
}, [binding, provider, selectionHighlight]);
|
|
286
289
|
}
|
|
287
290
|
function useYjsCursors(binding, cursorsContainerRef) {
|
|
288
291
|
return useMemo(() => {
|
|
@@ -432,18 +435,24 @@ function clearEditorSkipCollab(editor, binding) {
|
|
|
432
435
|
if (cursorsContainer == null) {
|
|
433
436
|
return;
|
|
434
437
|
}
|
|
435
|
-
|
|
436
|
-
// reset cursors in dom
|
|
437
|
-
const cursorsArr = Array.from(cursors.values());
|
|
438
|
-
for (let i = 0; i < cursorsArr.length; i++) {
|
|
439
|
-
const cursor = cursorsArr[i];
|
|
438
|
+
for (const cursor of cursors.values()) {
|
|
440
439
|
const selection = cursor.selection;
|
|
441
|
-
if (selection
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
440
|
+
if (selection === null) {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (selection.highlight !== null) {
|
|
444
|
+
CSS.highlights.delete(selection.highlightName);
|
|
445
|
+
removeCursorHighlightRule(binding, selection.highlightName);
|
|
446
|
+
}
|
|
447
|
+
if (selection.caret.parentNode === cursorsContainer) {
|
|
448
|
+
cursorsContainer.removeChild(selection.caret);
|
|
449
|
+
}
|
|
450
|
+
for (const span of selection.selections) {
|
|
451
|
+
if (span.parentNode === cursorsContainer) {
|
|
452
|
+
cursorsContainer.removeChild(span);
|
|
445
453
|
}
|
|
446
454
|
}
|
|
455
|
+
cursor.selection = null;
|
|
447
456
|
}
|
|
448
457
|
}
|
|
449
458
|
|
|
@@ -465,7 +474,8 @@ function CollaborationPlugin({
|
|
|
465
474
|
initialEditorState,
|
|
466
475
|
excludedProperties,
|
|
467
476
|
awarenessData,
|
|
468
|
-
syncCursorPositionsFn
|
|
477
|
+
syncCursorPositionsFn,
|
|
478
|
+
selectionHighlight
|
|
469
479
|
}) {
|
|
470
480
|
const isBindingInitialized = useRef(false);
|
|
471
481
|
const isProviderInitialized = useRef(false);
|
|
@@ -523,7 +533,8 @@ function CollaborationPlugin({
|
|
|
523
533
|
setDoc: setDoc,
|
|
524
534
|
shouldBootstrap: shouldBootstrap,
|
|
525
535
|
yjsDocMap: yjsDocMap,
|
|
526
|
-
syncCursorPositionsFn: syncCursorPositionsFn
|
|
536
|
+
syncCursorPositionsFn: syncCursorPositionsFn,
|
|
537
|
+
selectionHighlight: selectionHighlight
|
|
527
538
|
});
|
|
528
539
|
}
|
|
529
540
|
function YjsCollaborationCursors({
|
|
@@ -540,9 +551,10 @@ function YjsCollaborationCursors({
|
|
|
540
551
|
collabContext,
|
|
541
552
|
binding,
|
|
542
553
|
setDoc,
|
|
543
|
-
syncCursorPositionsFn
|
|
554
|
+
syncCursorPositionsFn,
|
|
555
|
+
selectionHighlight
|
|
544
556
|
}) {
|
|
545
|
-
const cursors = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn);
|
|
557
|
+
const cursors = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, binding, setDoc, cursorsContainerRef, initialEditorState, awarenessData, syncCursorPositionsFn, selectionHighlight);
|
|
546
558
|
useYjsHistory(editor, binding);
|
|
547
559
|
useYjsFocusTracking(editor, provider, name, color, awarenessData);
|
|
548
560
|
return cursors;
|
|
@@ -556,7 +568,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
|
|
|
556
568
|
cursorColor,
|
|
557
569
|
cursorsContainerRef,
|
|
558
570
|
excludedProperties,
|
|
559
|
-
awarenessData
|
|
571
|
+
awarenessData,
|
|
572
|
+
selectionHighlight
|
|
560
573
|
}) {
|
|
561
574
|
const collabContext = useCollaborationContext(username, cursorColor);
|
|
562
575
|
const {
|
|
@@ -569,7 +582,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
|
|
|
569
582
|
const binding = useYjsCollaborationV2__EXPERIMENTAL(editor, id, doc, provider, yjsDocMap, name, color, {
|
|
570
583
|
__shouldBootstrapUnsafe,
|
|
571
584
|
awarenessData,
|
|
572
|
-
excludedProperties
|
|
585
|
+
excludedProperties,
|
|
586
|
+
selectionHighlight
|
|
573
587
|
});
|
|
574
588
|
useYjsHistoryV2(editor, binding);
|
|
575
589
|
useYjsFocusTracking(editor, provider, name, color, awarenessData);
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/react/LexicalCollaborationContext"),t=require("@lexical/react/LexicalComposerContext"),o=require("@lexical/yjs"),n=require("react"),r=require("@lexical/utils"),s=require("lexical"),a=require("react-dom"),c=require("yjs"),i=require("react/jsx-runtime");function
|
|
9
|
+
"use strict";var e=require("@lexical/react/LexicalCollaborationContext"),t=require("@lexical/react/LexicalComposerContext"),o=require("@lexical/yjs"),n=require("react"),r=require("@lexical/utils"),s=require("lexical"),a=require("react-dom"),c=require("yjs"),i=require("react/jsx-runtime");function l(e){var t=Object.create(null);if(e)for(var o in e)t[o]=e[o];return t.default=e,t}var u=l(n);const d=Symbol.for("@lexical/yjs/UndoManager");function f(e,t,r,a,i,l,u,d,f,p,_,h,M=o.syncCursorPositions,R=!1){const O=n.useRef(!1),D=n.useCallback(()=>{const{root:t}=d;u&&t.isEmpty()&&0===t._xmlText._length&&m(e,_)},[d,e,_,u]);return n.useEffect(()=>{const{root:t}=d,n=(e,t)=>{const n=t.origin;if(n!==d){const t=n instanceof c.UndoManager;o.syncYjsChangesToLexical(d,r,e,t,M)}};t.getSharedType().observeDeep(n);const a=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyLeaves:n,dirtyElements:a,normalizedNodes:c,tags:i})=>{i.has(s.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjs(d,r,e,t,a,n,c,i)});return()=>{t.getSharedType().unobserveDeep(n),a()}},[d,r,e,f,a,t,M]),n.useEffect(()=>{const n=n=>{!function(e,t){if(e.update(()=>{const e=s.$getRoot();e.clear(),e.select()},{tag:s.SKIP_COLLAB_TAG}),null==t.cursors)return;const n=t.cursors;if(null==n)return;const r=t.cursorsContainer;if(null==r)return;for(const e of n.values()){const n=e.selection;if(null!==n){null!==n.highlight&&(CSS.highlights.delete(n.highlightName),o.removeCursorHighlightRule(t,n.highlightName)),n.caret.parentNode===r&&r.removeChild(n.caret);for(const e of n.selections)e.parentNode===r&&r.removeChild(e);e.selection=null}}}(e,d),f(n),a.set(t,n),O.current=!0},c=()=>{O.current=!1};return r.on("reload",n),r.on("sync",c),()=>{r.off("reload",n),r.off("sync",c)}},[d,r,e,f,a,t]),E(e,r,i,l,O,h,D),g(d,r,R),C(d,p)}function E(e,t,r,a,c,i,l){const u=n.useCallback(()=>t.connect(),[t]),d=n.useCallback(()=>{try{t.disconnect()}catch(e){}},[t]);n.useEffect(()=>{const n=({status:t})=>{e.dispatchCommand(o.CONNECTED_COMMAND,"connected"===t)},s=e=>{e&&!1===c.current&&l&&l()};o.initLocalState(t,r,a,document.activeElement===e.getRootElement(),i||{}),t.on("status",n),t.on("sync",s);const f=u();return()=>{!1===c.current&&(f?f.then(d):d()),t.off("sync",s),t.off("status",n)}},[e,t,r,a,c,i,l,u,d]),n.useEffect(()=>e.registerCommand(o.TOGGLE_CONNECT_COMMAND,e=>(e?(console.log("Collaboration connected!"),u()):(console.log("Collaboration disconnected!"),d()),!0),s.COMMAND_PRIORITY_EDITOR),[u,d,e]),n.useEffect(()=>{const e=()=>{try{t.awareness.setLocalState(null)}catch(e){}};return window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),()=>{window.removeEventListener("beforeunload",e),window.removeEventListener("pagehide",e)}},[t])}function g(e,t,r){n.useEffect(()=>{const{awareness:n}=t,s=()=>{o.syncCursorPositions(e,t,{selectionHighlight:r})};return n.on("update",s),()=>{n.off("update",s)}},[e,t,r])}function C(e,t){return n.useMemo(()=>a.createPortal(i.jsx("div",{ref:t=>{e.cursorsContainer=t}}),t&&t.current||document.body),[e,t])}function p(e,t,a,c,i){n.useEffect(()=>r.mergeRegister(e.registerCommand(s.FOCUS_COMMAND,()=>(o.setLocalStateFocus(t,a,c,!0,i||{}),!1),s.COMMAND_PRIORITY_EDITOR),e.registerCommand(s.BLUR_COMMAND,()=>(o.setLocalStateFocus(t,a,c,!1,i||{}),!1),s.COMMAND_PRIORITY_EDITOR)),[c,e,a,t,i])}function _(e,t){n.useEffect(()=>r.mergeRegister(e.registerCommand(s.UNDO_COMMAND,()=>(t.undo(),!0),s.COMMAND_PRIORITY_EDITOR),e.registerCommand(s.REDO_COMMAND,()=>(t.redo(),!0),s.COMMAND_PRIORITY_EDITOR))),n.useEffect(()=>{const o=e;return o[d]=t,()=>{o[d]===t&&delete o[d]}},[e,t]);const o=n.useCallback(()=>{t.clear()},[t]);return u.useEffect(()=>{const o=()=>{e.dispatchCommand(s.CAN_UNDO_COMMAND,t.undoStack.length>0),e.dispatchCommand(s.CAN_REDO_COMMAND,t.redoStack.length>0)};return t.on("stack-item-added",o),t.on("stack-item-popped",o),t.on("stack-cleared",o),()=>{t.off("stack-item-added",o),t.off("stack-item-popped",o),t.off("stack-cleared",o)}},[e,t]),o}function m(e,t){e.update(()=>{const o=s.$getRoot();if(o.isEmpty())if(t)switch(typeof t){case"string":{const o=e.parseEditorState(t);e.setEditorState(o,{tag:s.HISTORY_MERGE_TAG});break}case"object":e.setEditorState(t,{tag:s.HISTORY_MERGE_TAG});break;case"function":e.update(()=>{s.$getRoot().isEmpty()&&t(e)},{tag:s.HISTORY_MERGE_TAG})}else{const t=s.$createParagraphNode();o.append(t);const{activeElement:n}=document;(null!==s.$getSelection()||null!==n&&n===e.getRootElement())&&t.select()}},{tag:s.HISTORY_MERGE_TAG})}function h({editor:e,id:t,provider:r,yjsDocMap:s,name:a,color:c,shouldBootstrap:i,cursorsContainerRef:l,initialEditorState:u,awarenessData:d,collabContext:E,binding:g,setDoc:C,syncCursorPositionsFn:m,selectionHighlight:h}){const M=f(e,t,r,s,a,c,i,g,C,l,u,d,m,h);return function(e,t){_(e,n.useMemo(()=>o.createUndoManager(t,t.root.getSharedType()),[t]))}(e,g),p(e,r,a,c,d),M}const M=(e,t)=>{n.useEffect(()=>(e.isCollabActive=!0,()=>{null==t._parentEditor&&(e.isCollabActive=!1)}),[e,t])};exports.CollaborationPlugin=function({id:r,providerFactory:s,shouldBootstrap:a,username:c,cursorColor:l,cursorsContainerRef:u,initialEditorState:d,excludedProperties:f,awarenessData:E,syncCursorPositionsFn:g,selectionHighlight:C}){const p=n.useRef(!1),_=n.useRef(!1),m=e.useCollaborationContext(c,l),{yjsDocMap:R,name:O,color:D}=m,[T]=t.useLexicalComposerContext();M(m,T);const[N,S]=n.useState(),[A,I]=n.useState();n.useEffect(()=>{if(_.current)return;_.current=!0;const e=s(r,R);return S(e),I(R.get(r)),()=>{e.disconnect()}},[r,s,R]);const[y,L]=n.useState();return n.useEffect(()=>{if(!N)return;if(p.current)return;p.current=!0;const e=o.createBinding(T,N,r,A||R.get(r),R,f);return L(e),()=>{e.root.destroy(e)}},[T,N,r,R,A,f]),N&&y?i.jsx(h,{awarenessData:E,binding:y,collabContext:m,color:D,cursorsContainerRef:u,editor:T,id:r,initialEditorState:d,name:O,provider:N,setDoc:I,shouldBootstrap:a,yjsDocMap:R,syncCursorPositionsFn:g,selectionHighlight:C}):i.jsx(i.Fragment,{})},exports.CollaborationPluginV2__EXPERIMENTAL=function({id:a,doc:i,provider:l,__shouldBootstrapUnsafe:u,username:d,cursorColor:f,cursorsContainerRef:h,excludedProperties:R,awarenessData:O,selectionHighlight:D}){const T=e.useCollaborationContext(d,f),{yjsDocMap:N,name:S,color:A}=T,[I]=t.useLexicalComposerContext();M(T,I);const y=function(e,t,a,i,l,u,d,f={}){const{awarenessData:C,excludedProperties:p,rootName:_,selectionHighlight:h=!1,__shouldBootstrapUnsafe:M}=f,R=n.useMemo(()=>({current:!1}),[]),O=n.useMemo(()=>o.createBindingV2__EXPERIMENTAL(e,t,a,l,{excludedProperties:p,rootName:_}),[e,t,a,l,p,_]);n.useEffect(()=>(l.set(t,a),()=>{l.delete(t)}),[a,l,t]);const D=n.useCallback(()=>{const{root:t}=O;M&&0===t._length&&m(e)},[O,e,M]),[T,N]=n.useState();return n.useEffect(()=>{r.mergeRegister(e.registerCommand(o.CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL,()=>(N(null),o.syncYjsStateToLexicalV2__EXPERIMENTAL(O,i),!0),s.COMMAND_PRIORITY_EDITOR),e.registerCommand(o.DIFF_VERSIONS_COMMAND__EXPERIMENTAL,({prevSnapshot:e,snapshot:t})=>(N({prevSnapshot:e,snapshot:t}),!0),s.COMMAND_PRIORITY_EDITOR))},[e,O,i]),n.useEffect(()=>{const{root:t}=O;if(T)return void o.renderSnapshot__EXPERIMENTAL(O,T.snapshot,T.prevSnapshot);const n=(e,t)=>{const n=t.origin;if(n!==O){const r=n instanceof c.UndoManager;o.syncYjsChangesToLexicalV2__EXPERIMENTAL(O,i,e,t,r)}};t.observeDeep(n);const r=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyElements:n,normalizedNodes:r,tags:a})=>{a.has(s.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjsV2__EXPERIMENTAL(O,i,e,t,n,r,a)});return()=>{t.unobserveDeep(n),r()}},[O,i,e,T]),E(e,i,u,d,R,C,D),g(O,i,h),O}(I,a,i,l,N,S,A,{__shouldBootstrapUnsafe:u,awarenessData:O,excludedProperties:R,selectionHighlight:D});return function(e,t){_(e,n.useMemo(()=>o.createUndoManager(t,t.root),[t]))}(I,y),p(I,l,S,A,O),C(y,h)};
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{useCollaborationContext as
|
|
9
|
+
import{useCollaborationContext as e}from"@lexical/react/LexicalCollaborationContext";import{useLexicalComposerContext as t}from"@lexical/react/LexicalComposerContext";import{syncCursorPositions as o,syncLexicalUpdateToYjs as n,createUndoManager as r,setLocalStateFocus as s,createBindingV2__EXPERIMENTAL as i,CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL as a,syncYjsStateToLexicalV2__EXPERIMENTAL as c,DIFF_VERSIONS_COMMAND__EXPERIMENTAL as l,renderSnapshot__EXPERIMENTAL as d,syncLexicalUpdateToYjsV2__EXPERIMENTAL as u,syncYjsChangesToLexical as m,initLocalState as p,TOGGLE_CONNECT_COMMAND as f,syncYjsChangesToLexicalV2__EXPERIMENTAL as g,removeCursorHighlightRule as h,CONNECTED_COMMAND as C,createBinding as y}from"@lexical/yjs";import*as v from"react";import{useRef as E,useCallback as S,useEffect as x,useMemo as b,useState as w}from"react";import{mergeRegister as D}from"@lexical/utils";import{SKIP_COLLAB_TAG as k,FOCUS_COMMAND as L,COMMAND_PRIORITY_EDITOR as _,BLUR_COMMAND as j,$getRoot as N,HISTORY_MERGE_TAG as P,$createParagraphNode as H,$getSelection as B,UNDO_COMMAND as R,REDO_COMMAND as U,CAN_UNDO_COMMAND as M,CAN_REDO_COMMAND as F}from"lexical";import{createPortal as T}from"react-dom";import{UndoManager as z}from"yjs";import{jsx as A,Fragment as q}from"react/jsx-runtime";const G=Symbol.for("@lexical/yjs/UndoManager");function I(e,t,r,s,i,a,c,l,d,u,p,f,g=o,C=!1){const y=E(!1),v=S(()=>{const{root:t}=l;c&&t.isEmpty()&&0===t._xmlText._length&&W(e,p)},[l,e,p,c]);return x(()=>{const{root:t}=l,o=(e,t)=>{const o=t.origin;if(o!==l){m(l,r,e,o instanceof z,g)}};t.getSharedType().observeDeep(o);const s=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyLeaves:o,dirtyElements:s,normalizedNodes:i,tags:a})=>{a.has(k)||n(l,r,e,t,s,o,i,a)});return()=>{t.getSharedType().unobserveDeep(o),s()}},[l,r,e,d,s,t,g]),x(()=>{const o=o=>{!function(e,t){if(e.update(()=>{const e=N();e.clear(),e.select()},{tag:k}),null==t.cursors)return;const o=t.cursors;if(null==o)return;const n=t.cursorsContainer;if(null==n)return;for(const e of o.values()){const o=e.selection;if(null!==o){null!==o.highlight&&(CSS.highlights.delete(o.highlightName),h(t,o.highlightName)),o.caret.parentNode===n&&n.removeChild(o.caret);for(const e of o.selections)e.parentNode===n&&n.removeChild(e);e.selection=null}}}(e,l),d(o),s.set(t,o),y.current=!0},n=()=>{y.current=!1};return r.on("reload",o),r.on("sync",n),()=>{r.off("reload",o),r.off("sync",n)}},[l,r,e,d,s,t]),J(e,r,i,a,y,f,v),K(l,r,C),O(l,u)}function J(e,t,o,n,r,s,i){const a=S(()=>t.connect(),[t]),c=S(()=>{try{t.disconnect()}catch(e){}},[t]);x(()=>{const l=({status:t})=>{e.dispatchCommand(C,"connected"===t)},d=e=>{e&&!1===r.current&&i&&i()};p(t,o,n,document.activeElement===e.getRootElement(),s||{}),t.on("status",l),t.on("sync",d);const u=a();return()=>{!1===r.current&&(u?u.then(c):c()),t.off("sync",d),t.off("status",l)}},[e,t,o,n,r,s,i,a,c]),x(()=>e.registerCommand(f,e=>(e?(console.log("Collaboration connected!"),a()):(console.log("Collaboration disconnected!"),c()),!0),_),[a,c,e]),x(()=>{const e=()=>{try{t.awareness.setLocalState(null)}catch(e){}};return window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),()=>{window.removeEventListener("beforeunload",e),window.removeEventListener("pagehide",e)}},[t])}function K(e,t,n){x(()=>{const{awareness:r}=t,s=()=>{o(e,t,{selectionHighlight:n})};return r.on("update",s),()=>{r.off("update",s)}},[e,t,n])}function O(e,t){return b(()=>T(A("div",{ref:t=>{e.cursorsContainer=t}}),t&&t.current||document.body),[e,t])}function Q(e,t,o,n,r){x(()=>D(e.registerCommand(L,()=>(s(t,o,n,!0,r||{}),!1),_),e.registerCommand(j,()=>(s(t,o,n,!1,r||{}),!1),_)),[n,e,o,t,r])}function V(e,t){x(()=>D(e.registerCommand(R,()=>(t.undo(),!0),_),e.registerCommand(U,()=>(t.redo(),!0),_))),x(()=>{const o=e;return o[G]=t,()=>{o[G]===t&&delete o[G]}},[e,t]);const o=S(()=>{t.clear()},[t]);return v.useEffect(()=>{const o=()=>{e.dispatchCommand(M,t.undoStack.length>0),e.dispatchCommand(F,t.redoStack.length>0)};return t.on("stack-item-added",o),t.on("stack-item-popped",o),t.on("stack-cleared",o),()=>{t.off("stack-item-added",o),t.off("stack-item-popped",o),t.off("stack-cleared",o)}},[e,t]),o}function W(e,t){e.update(()=>{const o=N();if(o.isEmpty())if(t)switch(typeof t){case"string":{const o=e.parseEditorState(t);e.setEditorState(o,{tag:P});break}case"object":e.setEditorState(t,{tag:P});break;case"function":e.update(()=>{N().isEmpty()&&t(e)},{tag:P})}else{const t=H();o.append(t);const{activeElement:n}=document;(null!==B()||null!==n&&n===e.getRootElement())&&t.select()}},{tag:P})}function X({id:o,providerFactory:n,shouldBootstrap:r,username:s,cursorColor:i,cursorsContainerRef:a,initialEditorState:c,excludedProperties:l,awarenessData:d,syncCursorPositionsFn:u,selectionHighlight:m}){const p=E(!1),f=E(!1),g=e(s,i),{yjsDocMap:h,name:C,color:v}=g,[S]=t();$(g,S);const[b,D]=w(),[k,L]=w();x(()=>{if(f.current)return;f.current=!0;const e=n(o,h);return D(e),L(h.get(o)),()=>{e.disconnect()}},[o,n,h]);const[_,j]=w();return x(()=>{if(!b)return;if(p.current)return;p.current=!0;const e=y(S,b,o,k||h.get(o),h,l);return j(e),()=>{e.root.destroy(e)}},[S,b,o,h,k,l]),b&&_?A(Y,{awarenessData:d,binding:_,collabContext:g,color:v,cursorsContainerRef:a,editor:S,id:o,initialEditorState:c,name:C,provider:b,setDoc:L,shouldBootstrap:r,yjsDocMap:h,syncCursorPositionsFn:u,selectionHighlight:m}):A(q,{})}function Y({editor:e,id:t,provider:o,yjsDocMap:n,name:s,color:i,shouldBootstrap:a,cursorsContainerRef:c,initialEditorState:l,awarenessData:d,collabContext:u,binding:m,setDoc:p,syncCursorPositionsFn:f,selectionHighlight:g}){const h=I(e,t,o,n,s,i,a,m,p,c,l,d,f,g);return function(e,t){V(e,b(()=>r(t,t.root.getSharedType()),[t]))}(e,m),Q(e,o,s,i,d),h}function Z({id:o,doc:n,provider:s,__shouldBootstrapUnsafe:m,username:p,cursorColor:f,cursorsContainerRef:h,excludedProperties:C,awarenessData:y,selectionHighlight:v}){const E=e(p,f),{yjsDocMap:L,name:j,color:N}=E,[P]=t();$(E,P);const H=function(e,t,o,n,r,s,m,p={}){const{awarenessData:f,excludedProperties:h,rootName:C,selectionHighlight:y=!1,__shouldBootstrapUnsafe:v}=p,E=b(()=>({current:!1}),[]),L=b(()=>i(e,t,o,r,{excludedProperties:h,rootName:C}),[e,t,o,r,h,C]);x(()=>(r.set(t,o),()=>{r.delete(t)}),[o,r,t]);const j=S(()=>{const{root:t}=L;v&&0===t._length&&W(e)},[L,e,v]),[N,P]=w();return x(()=>{D(e.registerCommand(a,()=>(P(null),c(L,n),!0),_),e.registerCommand(l,({prevSnapshot:e,snapshot:t})=>(P({prevSnapshot:e,snapshot:t}),!0),_))},[e,L,n]),x(()=>{const{root:t}=L;if(N)return void d(L,N.snapshot,N.prevSnapshot);const o=(e,t)=>{const o=t.origin;o!==L&&g(L,n,e,t,o instanceof z)};t.observeDeep(o);const r=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyElements:o,normalizedNodes:r,tags:s})=>{s.has(k)||u(L,n,e,t,o,r,s)});return()=>{t.unobserveDeep(o),r()}},[L,n,e,N]),J(e,n,s,m,E,f,j),K(L,n,y),L}(P,o,n,s,L,j,N,{__shouldBootstrapUnsafe:m,awarenessData:y,excludedProperties:C,selectionHighlight:v});return function(e,t){V(e,b(()=>r(t,t.root),[t]))}(P,H),Q(P,s,j,N,y),O(H,h)}const $=(e,t)=>{x(()=>(e.isCollabActive=!0,()=>{null==t._parentEditor&&(e.isCollabActive=!1)}),[e,t])};export{X as CollaborationPlugin,Z as CollaborationPluginV2__EXPERIMENTAL};
|
|
@@ -12,11 +12,12 @@ import * as React from 'react';
|
|
|
12
12
|
import { Doc } from 'yjs';
|
|
13
13
|
import { InitialEditorStateType } from '../LexicalComposer';
|
|
14
14
|
export type CursorsContainerRef = React.RefObject<HTMLElement | null>;
|
|
15
|
-
export declare function useYjsCollaboration(editor: LexicalEditor, id: string, provider: Provider, docMap: Map<string, Doc>, name: string, color: string, shouldBootstrap: boolean, binding: Binding, setDoc: React.Dispatch<React.SetStateAction<Doc | undefined>>, cursorsContainerRef?: CursorsContainerRef, initialEditorState?: InitialEditorStateType, awarenessData?: object, syncCursorPositionsFn?: SyncCursorPositionsFn): JSX.Element;
|
|
15
|
+
export declare function useYjsCollaboration(editor: LexicalEditor, id: string, provider: Provider, docMap: Map<string, Doc>, name: string, color: string, shouldBootstrap: boolean, binding: Binding, setDoc: React.Dispatch<React.SetStateAction<Doc | undefined>>, cursorsContainerRef?: CursorsContainerRef, initialEditorState?: InitialEditorStateType, awarenessData?: object, syncCursorPositionsFn?: SyncCursorPositionsFn, selectionHighlight?: boolean): JSX.Element;
|
|
16
16
|
export declare function useYjsCollaborationV2__EXPERIMENTAL(editor: LexicalEditor, id: string, doc: Doc, provider: Provider, docMap: Map<string, Doc>, name: string, color: string, options?: {
|
|
17
17
|
awarenessData?: object;
|
|
18
18
|
excludedProperties?: ExcludedProperties;
|
|
19
19
|
rootName?: string;
|
|
20
|
+
selectionHighlight?: boolean;
|
|
20
21
|
__shouldBootstrapUnsafe?: boolean;
|
|
21
22
|
}): BindingV2;
|
|
22
23
|
export declare function useYjsCursors(binding: BaseBinding, cursorsContainerRef?: CursorsContainerRef): JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// You are seeing this declaration file because your TypeScript cannot read
|
|
10
|
+
// Lexical's types through the package.json "exports" field.
|
|
11
|
+
//
|
|
12
|
+
// Lexical requires TypeScript >= 5.2 with "moduleResolution" set to
|
|
13
|
+
// "bundler", "node16", or "nodenext". To fix this:
|
|
14
|
+
// 1. Upgrade TypeScript to >= 5.2.
|
|
15
|
+
// 2. In tsconfig.json set "moduleResolution" to "bundler" (recommended for
|
|
16
|
+
// apps/bundlers) or "node16" / "nodenext", and a matching "module".
|
|
17
|
+
import 'Lexical requires TypeScript >=5.2 with moduleResolution bundler, node16, or nodenext';
|
|
18
|
+
export {};
|