@lexical/react 0.8.1 → 0.9.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/LexicalAutoEmbedPlugin.d.ts +1 -0
- package/LexicalAutoEmbedPlugin.dev.js +11 -0
- package/LexicalAutoFocusPlugin.dev.js +1 -0
- package/LexicalAutoLinkPlugin.d.ts +1 -0
- package/LexicalAutoLinkPlugin.dev.js +50 -7
- package/LexicalBlockWithAlignableContents.dev.js +13 -2
- package/LexicalBlockWithAlignableContents.prod.js +4 -4
- package/LexicalCharacterLimitPlugin.d.ts +1 -0
- package/LexicalCharacterLimitPlugin.dev.js +46 -7
- package/LexicalCheckListPlugin.dev.js +48 -10
- package/LexicalClearEditorPlugin.d.ts +1 -0
- package/LexicalClearEditorPlugin.dev.js +1 -1
- package/LexicalCollaborationContext.dev.js +3 -0
- package/LexicalCollaborationPlugin.d.ts +3 -2
- package/LexicalCollaborationPlugin.dev.js +35 -6
- package/LexicalComposer.d.ts +1 -0
- package/LexicalComposer.dev.js +10 -6
- package/LexicalComposerContext.dev.js +6 -0
- package/LexicalContentEditable.dev.js +0 -1
- package/LexicalDecoratorBlockNode.d.ts +1 -0
- package/LexicalDecoratorBlockNode.dev.js +5 -0
- package/LexicalErrorBoundary.d.ts +1 -0
- package/LexicalHashtagPlugin.d.ts +1 -0
- package/LexicalHashtagPlugin.dev.js +43 -73
- package/LexicalHorizontalRuleNode.d.ts +1 -0
- package/LexicalHorizontalRuleNode.dev.js +22 -0
- package/LexicalHorizontalRulePlugin.dev.js +4 -0
- package/LexicalLinkPlugin.dev.js +10 -4
- package/LexicalListPlugin.dev.js +2 -0
- package/LexicalMarkdownShortcutPlugin.dev.js +2 -2
- package/LexicalNestedComposer.dev.js +12 -6
- package/LexicalNestedComposer.prod.js +2 -2
- package/LexicalNodeEventPlugin.dev.js +3 -5
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.d.ts +1 -0
- package/LexicalPlainTextPlugin.dev.js +12 -8
- package/LexicalRichTextPlugin.d.ts +1 -0
- package/LexicalRichTextPlugin.dev.js +12 -8
- package/LexicalTabIndentationPlugin.dev.js +3 -1
- package/{LexicalTableOfContents__EXPERIMENTAL.d.ts → LexicalTableOfContents.d.ts} +1 -0
- package/{LexicalTableOfContents__EXPERIMENTAL.dev.js → LexicalTableOfContents.dev.js} +33 -5
- package/{DEPRECATED_useLexical.js → LexicalTableOfContents.js} +2 -2
- package/LexicalTablePlugin.d.ts +1 -0
- package/LexicalTablePlugin.dev.js +19 -5
- package/LexicalTreeView.d.ts +1 -0
- package/LexicalTreeView.dev.js +113 -21
- package/LexicalTreeView.prod.js +16 -15
- package/LexicalTypeaheadMenuPlugin.dev.js +123 -17
- package/LexicalTypeaheadMenuPlugin.prod.js +18 -18
- package/package.json +19 -19
- package/shared/useYjsCollaboration.d.ts +3 -4
- package/useLexicalEditable.dev.js +5 -1
- package/useLexicalIsTextContentEmpty.dev.js +0 -1
- package/useLexicalNodeSelection.dev.js +7 -0
- package/useLexicalSubscription.dev.js +3 -1
- package/DEPRECATED_useLexical.d.ts +0 -18
- package/DEPRECATED_useLexical.dev.js +0 -104
- package/DEPRECATED_useLexical.js.flow +0 -25
- package/DEPRECATED_useLexical.prod.js +0 -8
- package/DEPRECATED_useLexicalCanShowPlaceholder.d.ts +0 -9
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +0 -72
- package/DEPRECATED_useLexicalCanShowPlaceholder.js +0 -9
- package/DEPRECATED_useLexicalCanShowPlaceholder.js.flow +0 -15
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +0 -8
- package/DEPRECATED_useLexicalCharacterLimit.d.ts +0 -8
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +0 -213
- package/DEPRECATED_useLexicalCharacterLimit.js +0 -9
- package/DEPRECATED_useLexicalCharacterLimit.js.flow +0 -31
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +0 -13
- package/DEPRECATED_useLexicalEditor.d.ts +0 -9
- package/DEPRECATED_useLexicalEditor.dev.js +0 -87
- package/DEPRECATED_useLexicalEditor.js +0 -9
- package/DEPRECATED_useLexicalEditor.prod.js +0 -8
- package/DEPRECATED_useLexicalHistory.d.ts +0 -12
- package/DEPRECATED_useLexicalHistory.dev.js +0 -38
- package/DEPRECATED_useLexicalHistory.js +0 -9
- package/DEPRECATED_useLexicalHistory.js.flow +0 -34
- package/DEPRECATED_useLexicalHistory.prod.js +0 -7
- package/DEPRECATED_useLexicalPlainText.d.ts +0 -10
- package/DEPRECATED_useLexicalPlainText.dev.js +0 -88
- package/DEPRECATED_useLexicalPlainText.js +0 -9
- package/DEPRECATED_useLexicalPlainText.js.flow +0 -17
- package/DEPRECATED_useLexicalPlainText.prod.js +0 -8
- package/DEPRECATED_useLexicalRichText.d.ts +0 -10
- package/DEPRECATED_useLexicalRichText.dev.js +0 -88
- package/DEPRECATED_useLexicalRichText.js +0 -9
- package/DEPRECATED_useLexicalRichText.js.flow +0 -17
- package/DEPRECATED_useLexicalRichText.prod.js +0 -8
- package/LexicalTableOfContents__EXPERIMENTAL.js +0 -9
- /package/{LexicalTableOfContents__EXPERIMENTAL.js.flow → LexicalTableOfContents.js.flow} +0 -0
- /package/{LexicalTableOfContents__EXPERIMENTAL.prod.js → LexicalTableOfContents.prod.js} +0 -0
|
@@ -31,19 +31,25 @@ function CheckListPlugin() {
|
|
|
31
31
|
return handleArrownUpOrDown(event, editor, true);
|
|
32
32
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, event => {
|
|
33
33
|
const activeItem = getActiveCheckListItem();
|
|
34
|
+
|
|
34
35
|
if (activeItem != null) {
|
|
35
36
|
const rootElement = editor.getRootElement();
|
|
37
|
+
|
|
36
38
|
if (rootElement != null) {
|
|
37
39
|
rootElement.focus();
|
|
38
40
|
}
|
|
41
|
+
|
|
39
42
|
return true;
|
|
40
43
|
}
|
|
44
|
+
|
|
41
45
|
return false;
|
|
42
46
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_SPACE_COMMAND, event => {
|
|
43
47
|
const activeItem = getActiveCheckListItem();
|
|
48
|
+
|
|
44
49
|
if (activeItem != null && editor.isEditable()) {
|
|
45
50
|
editor.update(() => {
|
|
46
51
|
const listItemNode = lexical.$getNearestNodeFromDOMNode(activeItem);
|
|
52
|
+
|
|
47
53
|
if (list.$isListItemNode(listItemNode)) {
|
|
48
54
|
event.preventDefault();
|
|
49
55
|
listItemNode.toggleChecked();
|
|
@@ -51,22 +57,28 @@ function CheckListPlugin() {
|
|
|
51
57
|
});
|
|
52
58
|
return true;
|
|
53
59
|
}
|
|
60
|
+
|
|
54
61
|
return false;
|
|
55
62
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_LEFT_COMMAND, event => {
|
|
56
63
|
return editor.getEditorState().read(() => {
|
|
57
64
|
const selection = lexical.$getSelection();
|
|
65
|
+
|
|
58
66
|
if (lexical.$isRangeSelection(selection) && selection.isCollapsed()) {
|
|
59
67
|
const {
|
|
60
68
|
anchor
|
|
61
69
|
} = selection;
|
|
62
70
|
const isElement = anchor.type === 'element';
|
|
71
|
+
|
|
63
72
|
if (isElement || anchor.offset === 0) {
|
|
64
73
|
const anchorNode = anchor.getNode();
|
|
65
74
|
const elementNode = utils.$findMatchingParent(anchorNode, node => lexical.$isElementNode(node) && !node.isInline());
|
|
75
|
+
|
|
66
76
|
if (list.$isListItemNode(elementNode)) {
|
|
67
77
|
const parent = elementNode.getParent();
|
|
78
|
+
|
|
68
79
|
if (list.$isListNode(parent) && parent.getListType() === 'check' && (isElement || elementNode.getFirstDescendant() === anchorNode)) {
|
|
69
80
|
const domNode = editor.getElementByKey(elementNode.__key);
|
|
81
|
+
|
|
70
82
|
if (domNode != null && document.activeElement !== domNode) {
|
|
71
83
|
domNode.focus();
|
|
72
84
|
event.preventDefault();
|
|
@@ -76,6 +88,7 @@ function CheckListPlugin() {
|
|
|
76
88
|
}
|
|
77
89
|
}
|
|
78
90
|
}
|
|
91
|
+
|
|
79
92
|
return false;
|
|
80
93
|
});
|
|
81
94
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerRootListener((rootElement, prevElement) => {
|
|
@@ -83,6 +96,7 @@ function CheckListPlugin() {
|
|
|
83
96
|
rootElement.addEventListener('click', handleClick);
|
|
84
97
|
rootElement.addEventListener('pointerdown', handlePointerDown);
|
|
85
98
|
}
|
|
99
|
+
|
|
86
100
|
if (prevElement !== null) {
|
|
87
101
|
prevElement.removeEventListener('click', handleClick);
|
|
88
102
|
prevElement.removeEventListener('pointerdown', handlePointerDown);
|
|
@@ -91,37 +105,45 @@ function CheckListPlugin() {
|
|
|
91
105
|
});
|
|
92
106
|
return null;
|
|
93
107
|
}
|
|
108
|
+
|
|
94
109
|
function handleCheckItemEvent(event, callback) {
|
|
95
110
|
const target = event.target;
|
|
111
|
+
|
|
96
112
|
if (target === null || !utils.isHTMLElement(target)) {
|
|
97
113
|
return;
|
|
98
|
-
}
|
|
114
|
+
} // Ignore clicks on LI that have nested lists
|
|
115
|
+
|
|
99
116
|
|
|
100
|
-
// Ignore clicks on LI that have nested lists
|
|
101
117
|
const firstChild = target.firstChild;
|
|
118
|
+
|
|
102
119
|
if (firstChild != null && utils.isHTMLElement(firstChild) && (firstChild.tagName === 'UL' || firstChild.tagName === 'OL')) {
|
|
103
120
|
return;
|
|
104
121
|
}
|
|
105
|
-
const parentNode = target.parentNode;
|
|
106
122
|
|
|
107
|
-
// @ts-ignore internal field
|
|
123
|
+
const parentNode = target.parentNode; // @ts-ignore internal field
|
|
124
|
+
|
|
108
125
|
if (!parentNode || parentNode.__lexicalListType !== 'check') {
|
|
109
126
|
return;
|
|
110
127
|
}
|
|
128
|
+
|
|
111
129
|
const pageX = event.pageX;
|
|
112
130
|
const rect = target.getBoundingClientRect();
|
|
131
|
+
|
|
113
132
|
if (target.dir === 'rtl' ? pageX < rect.right && pageX > rect.right - 20 : pageX > rect.left && pageX < rect.left + 20) {
|
|
114
133
|
callback();
|
|
115
134
|
}
|
|
116
135
|
}
|
|
136
|
+
|
|
117
137
|
function handleClick(event) {
|
|
118
138
|
handleCheckItemEvent(event, () => {
|
|
119
139
|
const domNode = event.target;
|
|
120
140
|
const editor = findEditor(domNode);
|
|
141
|
+
|
|
121
142
|
if (editor != null && editor.isEditable()) {
|
|
122
143
|
editor.update(() => {
|
|
123
144
|
if (event.target) {
|
|
124
145
|
const node = lexical.$getNearestNodeFromDOMNode(domNode);
|
|
146
|
+
|
|
125
147
|
if (list.$isListItemNode(node)) {
|
|
126
148
|
domNode.focus();
|
|
127
149
|
node.toggleChecked();
|
|
@@ -131,65 +153,80 @@ function handleClick(event) {
|
|
|
131
153
|
}
|
|
132
154
|
});
|
|
133
155
|
}
|
|
156
|
+
|
|
134
157
|
function handlePointerDown(event) {
|
|
135
158
|
handleCheckItemEvent(event, () => {
|
|
136
159
|
// Prevents caret moving when clicking on check mark
|
|
137
160
|
event.preventDefault();
|
|
138
161
|
});
|
|
139
162
|
}
|
|
163
|
+
|
|
140
164
|
function findEditor(target) {
|
|
141
165
|
let node = target;
|
|
166
|
+
|
|
142
167
|
while (node) {
|
|
143
168
|
// @ts-ignore internal field
|
|
144
169
|
if (node.__lexicalEditor) {
|
|
145
170
|
// @ts-ignore internal field
|
|
146
171
|
return node.__lexicalEditor;
|
|
147
172
|
}
|
|
173
|
+
|
|
148
174
|
node = node.parentNode;
|
|
149
175
|
}
|
|
176
|
+
|
|
150
177
|
return null;
|
|
151
178
|
}
|
|
179
|
+
|
|
152
180
|
function getActiveCheckListItem() {
|
|
153
181
|
const activeElement = document.activeElement;
|
|
154
|
-
return activeElement != null && activeElement.tagName === 'LI' && activeElement.parentNode != null &&
|
|
155
|
-
// @ts-ignore internal field
|
|
182
|
+
return activeElement != null && activeElement.tagName === 'LI' && activeElement.parentNode != null && // @ts-ignore internal field
|
|
156
183
|
activeElement.parentNode.__lexicalListType === 'check' ? activeElement : null;
|
|
157
184
|
}
|
|
185
|
+
|
|
158
186
|
function findCheckListItemSibling(node, backward) {
|
|
159
187
|
let sibling = backward ? node.getPreviousSibling() : node.getNextSibling();
|
|
160
|
-
let parent = node;
|
|
188
|
+
let parent = node; // Going up in a tree to get non-null sibling
|
|
161
189
|
|
|
162
|
-
// Going up in a tree to get non-null sibling
|
|
163
190
|
while (sibling == null && list.$isListItemNode(parent)) {
|
|
164
191
|
// Get li -> parent ul/ol -> parent li
|
|
165
192
|
parent = parent.getParentOrThrow().getParent();
|
|
193
|
+
|
|
166
194
|
if (parent != null) {
|
|
167
195
|
sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling();
|
|
168
196
|
}
|
|
169
|
-
}
|
|
197
|
+
} // Going down in a tree to get first non-nested list item
|
|
198
|
+
|
|
170
199
|
|
|
171
|
-
// Going down in a tree to get first non-nested list item
|
|
172
200
|
while (list.$isListItemNode(sibling)) {
|
|
173
201
|
const firstChild = backward ? sibling.getLastChild() : sibling.getFirstChild();
|
|
202
|
+
|
|
174
203
|
if (!list.$isListNode(firstChild)) {
|
|
175
204
|
return sibling;
|
|
176
205
|
}
|
|
206
|
+
|
|
177
207
|
sibling = backward ? firstChild.getLastChild() : firstChild.getFirstChild();
|
|
178
208
|
}
|
|
209
|
+
|
|
179
210
|
return null;
|
|
180
211
|
}
|
|
212
|
+
|
|
181
213
|
function handleArrownUpOrDown(event, editor, backward) {
|
|
182
214
|
const activeItem = getActiveCheckListItem();
|
|
215
|
+
|
|
183
216
|
if (activeItem != null) {
|
|
184
217
|
editor.update(() => {
|
|
185
218
|
const listItem = lexical.$getNearestNodeFromDOMNode(activeItem);
|
|
219
|
+
|
|
186
220
|
if (!list.$isListItemNode(listItem)) {
|
|
187
221
|
return;
|
|
188
222
|
}
|
|
223
|
+
|
|
189
224
|
const nextListItem = findCheckListItemSibling(listItem, backward);
|
|
225
|
+
|
|
190
226
|
if (nextListItem != null) {
|
|
191
227
|
nextListItem.selectStart();
|
|
192
228
|
const dom = editor.getElementByKey(nextListItem.__key);
|
|
229
|
+
|
|
193
230
|
if (dom != null) {
|
|
194
231
|
event.preventDefault();
|
|
195
232
|
setTimeout(() => {
|
|
@@ -199,6 +236,7 @@ function handleArrownUpOrDown(event, editor, backward) {
|
|
|
199
236
|
}
|
|
200
237
|
});
|
|
201
238
|
}
|
|
239
|
+
|
|
202
240
|
return false;
|
|
203
241
|
}
|
|
204
242
|
|
|
@@ -17,7 +17,6 @@ var react = require('react');
|
|
|
17
17
|
* LICENSE file in the root directory of this source tree.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
20
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
22
21
|
|
|
23
22
|
/**
|
|
@@ -50,6 +49,7 @@ function ClearEditorPlugin({
|
|
|
50
49
|
const paragraph = lexical.$createParagraphNode();
|
|
51
50
|
root.clear();
|
|
52
51
|
root.append(paragraph);
|
|
52
|
+
|
|
53
53
|
if (selection !== null) {
|
|
54
54
|
paragraph.select();
|
|
55
55
|
}
|
|
@@ -26,12 +26,15 @@ const CollaborationContext = /*#__PURE__*/react.createContext({
|
|
|
26
26
|
});
|
|
27
27
|
function useCollaborationContext(username, color) {
|
|
28
28
|
const collabContext = react.useContext(CollaborationContext);
|
|
29
|
+
|
|
29
30
|
if (username != null) {
|
|
30
31
|
collabContext.name = username;
|
|
31
32
|
}
|
|
33
|
+
|
|
32
34
|
if (color != null) {
|
|
33
35
|
collabContext.color = color;
|
|
34
36
|
}
|
|
37
|
+
|
|
35
38
|
return collabContext;
|
|
36
39
|
}
|
|
37
40
|
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
/// <reference types="react" />
|
|
8
9
|
import type { Doc } from 'yjs';
|
|
9
|
-
import {
|
|
10
|
+
import { Provider } from '@lexical/yjs';
|
|
10
11
|
import { InitialEditorStateType } from './LexicalComposer';
|
|
11
12
|
import { CursorsContainerRef } from './shared/useYjsCollaboration';
|
|
12
13
|
export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, }: {
|
|
13
14
|
id: string;
|
|
14
|
-
providerFactory: (id: string, yjsDocMap: Map<string, Doc>) =>
|
|
15
|
+
providerFactory: (id: string, yjsDocMap: Map<string, Doc>) => Provider;
|
|
15
16
|
shouldBootstrap: boolean;
|
|
16
17
|
username?: string;
|
|
17
18
|
cursorColor?: string;
|
|
@@ -32,8 +32,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
32
32
|
const disconnect = React.useCallback(() => {
|
|
33
33
|
try {
|
|
34
34
|
provider.disconnect();
|
|
35
|
-
} catch (e) {
|
|
36
|
-
// Do nothing
|
|
35
|
+
} catch (e) {// Do nothing
|
|
37
36
|
}
|
|
38
37
|
}, [provider]);
|
|
39
38
|
React.useEffect(() => {
|
|
@@ -43,39 +42,48 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
43
42
|
const {
|
|
44
43
|
awareness
|
|
45
44
|
} = provider;
|
|
45
|
+
|
|
46
46
|
const onStatus = ({
|
|
47
47
|
status
|
|
48
48
|
}) => {
|
|
49
49
|
editor.dispatchCommand(yjs.CONNECTED_COMMAND, status === 'connected');
|
|
50
50
|
};
|
|
51
|
+
|
|
51
52
|
const onSync = isSynced => {
|
|
52
53
|
if (shouldBootstrap && isSynced && root.isEmpty() && root._xmlText._length === 0 && isReloadingDoc.current === false) {
|
|
53
54
|
initializeEditor(editor, initialEditorState);
|
|
54
55
|
}
|
|
56
|
+
|
|
55
57
|
isReloadingDoc.current = false;
|
|
56
58
|
};
|
|
59
|
+
|
|
57
60
|
const onAwarenessUpdate = () => {
|
|
58
61
|
yjs.syncCursorPositions(binding, provider);
|
|
59
62
|
};
|
|
63
|
+
|
|
60
64
|
const onYjsTreeChanges = (events, transaction) => {
|
|
61
65
|
const origin = transaction.origin;
|
|
66
|
+
|
|
62
67
|
if (origin !== binding) {
|
|
63
68
|
const isFromUndoManger = origin instanceof yjs$1.UndoManager;
|
|
64
69
|
yjs.syncYjsChangesToLexical(binding, provider, events, isFromUndoManger);
|
|
65
70
|
}
|
|
66
71
|
};
|
|
72
|
+
|
|
67
73
|
yjs.initLocalState(provider, name, color, document.activeElement === editor.getRootElement());
|
|
74
|
+
|
|
68
75
|
const onProviderDocReload = ydoc => {
|
|
69
76
|
clearEditorSkipCollab(editor, binding);
|
|
70
77
|
setDoc(ydoc);
|
|
71
78
|
docMap.set(id, ydoc);
|
|
72
79
|
isReloadingDoc.current = true;
|
|
73
80
|
};
|
|
81
|
+
|
|
74
82
|
provider.on('reload', onProviderDocReload);
|
|
75
83
|
provider.on('status', onStatus);
|
|
76
84
|
provider.on('sync', onSync);
|
|
77
|
-
awareness.on('update', onAwarenessUpdate);
|
|
78
|
-
|
|
85
|
+
awareness.on('update', onAwarenessUpdate); // This updates the local editor state when we recieve updates from other clients
|
|
86
|
+
|
|
79
87
|
root.getSharedType().observeDeep(onYjsTreeChanges);
|
|
80
88
|
const removeListener = editor.registerUpdateListener(({
|
|
81
89
|
prevEditorState,
|
|
@@ -94,6 +102,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
94
102
|
if (isReloadingDoc.current === false) {
|
|
95
103
|
disconnect();
|
|
96
104
|
}
|
|
105
|
+
|
|
97
106
|
provider.off('sync', onSync);
|
|
98
107
|
provider.off('status', onStatus);
|
|
99
108
|
provider.off('reload', onProviderDocReload);
|
|
@@ -107,6 +116,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
107
116
|
const ref = element => {
|
|
108
117
|
binding.cursorsContainer = element;
|
|
109
118
|
};
|
|
119
|
+
|
|
110
120
|
return /*#__PURE__*/reactDom.createPortal( /*#__PURE__*/React.createElement("div", {
|
|
111
121
|
ref: ref
|
|
112
122
|
}), cursorsContainerRef && cursorsContainerRef.current || document.body);
|
|
@@ -115,6 +125,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
115
125
|
return editor.registerCommand(yjs.TOGGLE_CONNECT_COMMAND, payload => {
|
|
116
126
|
if (connect !== undefined && disconnect !== undefined) {
|
|
117
127
|
const shouldConnect = payload;
|
|
128
|
+
|
|
118
129
|
if (shouldConnect) {
|
|
119
130
|
// eslint-disable-next-line no-console
|
|
120
131
|
console.log('Collaboration connected!');
|
|
@@ -125,6 +136,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
125
136
|
disconnect();
|
|
126
137
|
}
|
|
127
138
|
}
|
|
139
|
+
|
|
128
140
|
return true;
|
|
129
141
|
}, lexical.COMMAND_PRIORITY_EDITOR);
|
|
130
142
|
}, [connect, disconnect, editor]);
|
|
@@ -147,9 +159,11 @@ function useYjsHistory(editor, binding) {
|
|
|
147
159
|
const undo = () => {
|
|
148
160
|
undoManager.undo();
|
|
149
161
|
};
|
|
162
|
+
|
|
150
163
|
const redo = () => {
|
|
151
164
|
undoManager.redo();
|
|
152
165
|
};
|
|
166
|
+
|
|
153
167
|
return utils.mergeRegister(editor.registerCommand(lexical.UNDO_COMMAND, () => {
|
|
154
168
|
undo();
|
|
155
169
|
return true;
|
|
@@ -163,9 +177,11 @@ function useYjsHistory(editor, binding) {
|
|
|
163
177
|
}, [undoManager]);
|
|
164
178
|
return clearHistory;
|
|
165
179
|
}
|
|
180
|
+
|
|
166
181
|
function initializeEditor(editor, initialEditorState) {
|
|
167
182
|
editor.update(() => {
|
|
168
183
|
const root = lexical.$getRoot();
|
|
184
|
+
|
|
169
185
|
if (root.isEmpty()) {
|
|
170
186
|
if (initialEditorState) {
|
|
171
187
|
switch (typeof initialEditorState) {
|
|
@@ -177,6 +193,7 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
177
193
|
});
|
|
178
194
|
break;
|
|
179
195
|
}
|
|
196
|
+
|
|
180
197
|
case 'object':
|
|
181
198
|
{
|
|
182
199
|
editor.setEditorState(initialEditorState, {
|
|
@@ -184,10 +201,12 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
184
201
|
});
|
|
185
202
|
break;
|
|
186
203
|
}
|
|
204
|
+
|
|
187
205
|
case 'function':
|
|
188
206
|
{
|
|
189
207
|
editor.update(() => {
|
|
190
208
|
const root1 = lexical.$getRoot();
|
|
209
|
+
|
|
191
210
|
if (root1.isEmpty()) {
|
|
192
211
|
initialEditorState(editor);
|
|
193
212
|
}
|
|
@@ -203,6 +222,7 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
203
222
|
const {
|
|
204
223
|
activeElement
|
|
205
224
|
} = document;
|
|
225
|
+
|
|
206
226
|
if (lexical.$getSelection() !== null || activeElement !== null && activeElement === editor.getRootElement()) {
|
|
207
227
|
paragraph.select();
|
|
208
228
|
}
|
|
@@ -212,6 +232,7 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
212
232
|
tag: 'history-merge'
|
|
213
233
|
});
|
|
214
234
|
}
|
|
235
|
+
|
|
215
236
|
function clearEditorSkipCollab(editor, binding) {
|
|
216
237
|
// reset editor state
|
|
217
238
|
editor.update(() => {
|
|
@@ -221,25 +242,33 @@ function clearEditorSkipCollab(editor, binding) {
|
|
|
221
242
|
}, {
|
|
222
243
|
tag: 'skip-collab'
|
|
223
244
|
});
|
|
245
|
+
|
|
224
246
|
if (binding.cursors == null) {
|
|
225
247
|
return;
|
|
226
248
|
}
|
|
249
|
+
|
|
227
250
|
const cursors = binding.cursors;
|
|
251
|
+
|
|
228
252
|
if (cursors == null) {
|
|
229
253
|
return;
|
|
230
254
|
}
|
|
255
|
+
|
|
231
256
|
const cursorsContainer = binding.cursorsContainer;
|
|
257
|
+
|
|
232
258
|
if (cursorsContainer == null) {
|
|
233
259
|
return;
|
|
234
|
-
}
|
|
260
|
+
} // reset cursors in dom
|
|
261
|
+
|
|
235
262
|
|
|
236
|
-
// reset cursors in dom
|
|
237
263
|
const cursorsArr = Array.from(cursors.values());
|
|
264
|
+
|
|
238
265
|
for (let i = 0; i < cursorsArr.length; i++) {
|
|
239
266
|
const cursor = cursorsArr[i];
|
|
240
267
|
const selection = cursor.selection;
|
|
268
|
+
|
|
241
269
|
if (selection && selection.selections != null) {
|
|
242
270
|
const selections = selection.selections;
|
|
271
|
+
|
|
243
272
|
for (let j = 0; j < selections.length; j++) {
|
|
244
273
|
cursorsContainer.removeChild(selections[i]);
|
|
245
274
|
}
|
package/LexicalComposer.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
/// <reference types="react" />
|
|
8
9
|
import { EditorState, EditorThemeClasses, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
9
10
|
export declare type InitialEditorStateType = null | string | EditorState | ((editor: LexicalEditor) => void);
|
|
10
11
|
export declare type InitialConfigType = Readonly<{
|
package/LexicalComposer.dev.js
CHANGED
|
@@ -17,7 +17,6 @@ var React = require('react');
|
|
|
17
17
|
* LICENSE file in the root directory of this source tree.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
20
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
22
21
|
|
|
23
22
|
/**
|
|
@@ -55,6 +54,7 @@ function LexicalComposer({
|
|
|
55
54
|
} = initialConfig;
|
|
56
55
|
const context = LexicalComposerContext.createLexicalComposerContext(null, theme);
|
|
57
56
|
let editor = initialEditor || null;
|
|
57
|
+
|
|
58
58
|
if (editor === null) {
|
|
59
59
|
const newEditor = lexical.createEditor({
|
|
60
60
|
editable: false,
|
|
@@ -66,33 +66,34 @@ function LexicalComposer({
|
|
|
66
66
|
initializeEditor(newEditor, initialEditorState);
|
|
67
67
|
editor = newEditor;
|
|
68
68
|
}
|
|
69
|
+
|
|
69
70
|
return [editor, context];
|
|
70
|
-
},
|
|
71
|
-
// We only do this for init
|
|
71
|
+
}, // We only do this for init
|
|
72
72
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
73
|
[]);
|
|
74
74
|
useLayoutEffect(() => {
|
|
75
75
|
const isEditable = initialConfig.editable;
|
|
76
76
|
const [editor] = composerContext;
|
|
77
|
-
editor.setEditable(isEditable !== undefined ? isEditable : true);
|
|
78
|
-
|
|
79
|
-
// We only do this for init
|
|
77
|
+
editor.setEditable(isEditable !== undefined ? isEditable : true); // We only do this for init
|
|
80
78
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
79
|
}, []);
|
|
82
80
|
return /*#__PURE__*/React.createElement(LexicalComposerContext.LexicalComposerContext.Provider, {
|
|
83
81
|
value: composerContext
|
|
84
82
|
}, children);
|
|
85
83
|
}
|
|
84
|
+
|
|
86
85
|
function initializeEditor(editor, initialEditorState) {
|
|
87
86
|
if (initialEditorState === null) {
|
|
88
87
|
return;
|
|
89
88
|
} else if (initialEditorState === undefined) {
|
|
90
89
|
editor.update(() => {
|
|
91
90
|
const root = lexical.$getRoot();
|
|
91
|
+
|
|
92
92
|
if (root.isEmpty()) {
|
|
93
93
|
const paragraph = lexical.$createParagraphNode();
|
|
94
94
|
root.append(paragraph);
|
|
95
95
|
const activeElement = CAN_USE_DOM ? document.activeElement : null;
|
|
96
|
+
|
|
96
97
|
if (lexical.$getSelection() !== null || activeElement !== null && activeElement === editor.getRootElement()) {
|
|
97
98
|
paragraph.select();
|
|
98
99
|
}
|
|
@@ -106,15 +107,18 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
106
107
|
editor.setEditorState(parsedEditorState, HISTORY_MERGE_OPTIONS);
|
|
107
108
|
break;
|
|
108
109
|
}
|
|
110
|
+
|
|
109
111
|
case 'object':
|
|
110
112
|
{
|
|
111
113
|
editor.setEditorState(initialEditorState, HISTORY_MERGE_OPTIONS);
|
|
112
114
|
break;
|
|
113
115
|
}
|
|
116
|
+
|
|
114
117
|
case 'function':
|
|
115
118
|
{
|
|
116
119
|
editor.update(() => {
|
|
117
120
|
const root = lexical.$getRoot();
|
|
121
|
+
|
|
118
122
|
if (root.isEmpty()) {
|
|
119
123
|
initialEditorState(editor);
|
|
120
124
|
}
|
|
@@ -18,26 +18,32 @@ var react = require('react');
|
|
|
18
18
|
const LexicalComposerContext = /*#__PURE__*/react.createContext(null);
|
|
19
19
|
function createLexicalComposerContext(parent, theme) {
|
|
20
20
|
let parentContext = null;
|
|
21
|
+
|
|
21
22
|
if (parent != null) {
|
|
22
23
|
parentContext = parent[1];
|
|
23
24
|
}
|
|
25
|
+
|
|
24
26
|
function getTheme() {
|
|
25
27
|
if (theme != null) {
|
|
26
28
|
return theme;
|
|
27
29
|
}
|
|
30
|
+
|
|
28
31
|
return parentContext != null ? parentContext.getTheme() : null;
|
|
29
32
|
}
|
|
33
|
+
|
|
30
34
|
return {
|
|
31
35
|
getTheme
|
|
32
36
|
};
|
|
33
37
|
}
|
|
34
38
|
function useLexicalComposerContext() {
|
|
35
39
|
const composerContext = react.useContext(LexicalComposerContext);
|
|
40
|
+
|
|
36
41
|
if (composerContext == null) {
|
|
37
42
|
{
|
|
38
43
|
throw Error(`LexicalComposerContext.useLexicalComposerContext: cannot find a LexicalComposerContext`);
|
|
39
44
|
}
|
|
40
45
|
}
|
|
46
|
+
|
|
41
47
|
return composerContext;
|
|
42
48
|
}
|
|
43
49
|
|
|
@@ -16,7 +16,6 @@ var React = require('react');
|
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
19
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
21
20
|
|
|
22
21
|
/**
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
+
/// <reference types="react" />
|
|
8
9
|
import type { ElementFormatType, LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';
|
|
9
10
|
import { DecoratorNode } from 'lexical';
|
|
10
11
|
export declare type SerializedDecoratorBlockNode = Spread<{
|
|
@@ -20,6 +20,7 @@ class DecoratorBlockNode extends lexical.DecoratorNode {
|
|
|
20
20
|
super(key);
|
|
21
21
|
this.__format = format || '';
|
|
22
22
|
}
|
|
23
|
+
|
|
23
24
|
exportJSON() {
|
|
24
25
|
return {
|
|
25
26
|
format: this.__format || '',
|
|
@@ -27,16 +28,20 @@ class DecoratorBlockNode extends lexical.DecoratorNode {
|
|
|
27
28
|
version: 1
|
|
28
29
|
};
|
|
29
30
|
}
|
|
31
|
+
|
|
30
32
|
createDOM() {
|
|
31
33
|
return document.createElement('div');
|
|
32
34
|
}
|
|
35
|
+
|
|
33
36
|
updateDOM() {
|
|
34
37
|
return false;
|
|
35
38
|
}
|
|
39
|
+
|
|
36
40
|
setFormat(format) {
|
|
37
41
|
const self = this.getWritable();
|
|
38
42
|
self.__format = format;
|
|
39
43
|
}
|
|
44
|
+
|
|
40
45
|
}
|
|
41
46
|
function $isDecoratorBlockNode(node) {
|
|
42
47
|
return node instanceof DecoratorBlockNode;
|