@lexical/react 0.1.10 → 0.1.11
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/DEPRECATED_useLexicalAutoFormatter.dev.js +69 -28
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +19 -18
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +20 -17
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +8 -8
- package/DEPRECATED_useLexicalList.dev.js +6 -0
- package/DEPRECATED_useLexicalList.prod.js +1 -1
- package/DEPRECATED_useLexicalPlainText.dev.js +61 -58
- package/DEPRECATED_useLexicalPlainText.prod.js +15 -15
- package/DEPRECATED_useLexicalRichText.dev.js +64 -61
- package/DEPRECATED_useLexicalRichText.prod.js +24 -25
- package/LexicalAutoFormatterPlugin.dev.js +69 -28
- package/LexicalAutoFormatterPlugin.js.flow +10 -0
- package/LexicalAutoFormatterPlugin.prod.js +20 -19
- package/LexicalAutoLinkPlugin.js.flow +23 -0
- package/LexicalCharacterLimitPlugin.dev.js +20 -17
- package/LexicalCharacterLimitPlugin.js.flow +12 -0
- package/LexicalCharacterLimitPlugin.prod.js +9 -8
- package/LexicalClearEditorPlugin.dev.js +52 -0
- package/LexicalClearEditorPlugin.js +9 -0
- package/LexicalClearEditorPlugin.js.flow +14 -0
- package/LexicalClearEditorPlugin.prod.js +7 -0
- package/LexicalCollaborationPlugin.dev.js +21 -11
- package/LexicalCollaborationPlugin.js.flow +55 -0
- package/LexicalCollaborationPlugin.prod.js +7 -7
- package/LexicalComposer.dev.js +7 -0
- package/LexicalComposer.js.flow +23 -0
- package/LexicalComposer.prod.js +3 -2
- package/LexicalComposerContext.js.flow +27 -0
- package/LexicalContentEditable.dev.js +14 -8
- package/LexicalContentEditable.js.flow +35 -0
- package/LexicalContentEditable.prod.js +3 -3
- package/LexicalHashtagPlugin.js.flow +20 -0
- package/LexicalHistoryPlugin.js.flow +34 -0
- package/LexicalHorizontalRuleNode.js.flow +25 -0
- package/LexicalLinkPlugin.js.flow +10 -0
- package/LexicalListPlugin.dev.js +6 -0
- package/LexicalListPlugin.js.flow +10 -0
- package/LexicalListPlugin.prod.js +2 -2
- package/LexicalNestedComposer.js.flow +21 -0
- package/LexicalOnChangePlugin.js.flow +14 -0
- package/LexicalPlainTextPlugin.dev.js +64 -60
- package/LexicalPlainTextPlugin.js.flow +18 -0
- package/LexicalPlainTextPlugin.prod.js +12 -12
- package/LexicalRichTextPlugin.dev.js +65 -61
- package/LexicalRichTextPlugin.js.flow +18 -0
- package/LexicalRichTextPlugin.prod.js +19 -20
- package/LexicalTablePlugin.dev.js +22 -0
- package/LexicalTablePlugin.js.flow +10 -0
- package/LexicalTablePlugin.prod.js +4 -3
- package/LexicalTreeView.js.flow +19 -0
- package/README.md +0 -1
- package/package.json +5 -5
- package/useLexicalDecoratorMap.js.flow +16 -0
- package/useLexicalIsTextContentEmpty.js.flow +15 -0
- package/useLexicalNodeSelection.js.flow +14 -0
- package/withSubscriptions.js.flow +13 -0
- package/LexicalBootstrapPlugin.dev.js +0 -122
- package/LexicalBootstrapPlugin.js +0 -9
- package/LexicalBootstrapPlugin.prod.js +0 -8
|
@@ -20,11 +20,15 @@ var OverflowNode = require('lexical/OverflowNode');
|
|
|
20
20
|
*
|
|
21
21
|
*
|
|
22
22
|
*/
|
|
23
|
-
function $
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
function $dfs(startingNode, endingNode) {
|
|
24
|
+
const nodes = [];
|
|
25
|
+
const start = (startingNode || lexical.$getRoot()).getLatest();
|
|
26
|
+
const end = endingNode || (lexical.$isElementNode(start) ? start.getLastDescendant() : start);
|
|
27
|
+
let node = start;
|
|
28
|
+
|
|
29
|
+
while (node !== null && !node.is(end)) {
|
|
30
|
+
nodes.push(node);
|
|
26
31
|
|
|
27
|
-
while (node !== null) {
|
|
28
32
|
if (lexical.$isElementNode(node) && node.getChildrenSize() > 0) {
|
|
29
33
|
node = node.getFirstChild();
|
|
30
34
|
} else {
|
|
@@ -41,11 +45,13 @@ function $dfs__DEPRECATED(startingNode, nextNode) {
|
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
}
|
|
48
|
+
}
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
50
|
+
if (node !== null && node.is(end)) {
|
|
51
|
+
nodes.push(node);
|
|
48
52
|
}
|
|
53
|
+
|
|
54
|
+
return nodes;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
/**
|
|
@@ -159,10 +165,13 @@ function findOffset(text, maxCharacters, strlen) {
|
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
function $wrapOverflowedNodes(offset) {
|
|
162
|
-
const
|
|
168
|
+
const dfsNodes = $dfs();
|
|
169
|
+
const dfsNodesLength = dfsNodes.length;
|
|
163
170
|
let accumulatedLength = 0;
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < dfsNodesLength; i += 1) {
|
|
173
|
+
const node = dfsNodes[i];
|
|
174
|
+
|
|
166
175
|
if (OverflowNode.$isOverflowNode(node)) {
|
|
167
176
|
const previousLength = accumulatedLength;
|
|
168
177
|
const nextLength = accumulatedLength + node.getTextContentSize();
|
|
@@ -183,8 +192,6 @@ function $wrapOverflowedNodes(offset) {
|
|
|
183
192
|
parent.select();
|
|
184
193
|
}
|
|
185
194
|
}
|
|
186
|
-
|
|
187
|
-
return previousNode;
|
|
188
195
|
} else if (previousLength < offset) {
|
|
189
196
|
const descendant = node.getFirstDescendant();
|
|
190
197
|
const descendantLength = descendant !== null ? descendant.getTextContentSize() : 0;
|
|
@@ -196,7 +203,6 @@ function $wrapOverflowedNodes(offset) {
|
|
|
196
203
|
|
|
197
204
|
if (firstDescendantIsSimpleText || firstDescendantDoesNotOverflow) {
|
|
198
205
|
$unwrapNode(node);
|
|
199
|
-
return previousNode;
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
} else if (lexical.$isLeafNode(node)) {
|
|
@@ -222,10 +228,7 @@ function $wrapOverflowedNodes(offset) {
|
|
|
222
228
|
mergePrevious(overflowNode);
|
|
223
229
|
}
|
|
224
230
|
}
|
|
225
|
-
|
|
226
|
-
previousNode = node;
|
|
227
|
-
return node;
|
|
228
|
-
});
|
|
231
|
+
}
|
|
229
232
|
}
|
|
230
233
|
|
|
231
234
|
function $wrapNode(node) {
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare export default function LexicalCharacterLimitPlugin(props: {
|
|
11
|
+
charset: 'UTF-8' | 'UTF-16',
|
|
12
|
+
}): React$Node;
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var l=require("@lexical/react/LexicalComposerContext"),
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
var l=require("@lexical/react/LexicalComposerContext"),w=require("react"),x=require("lexical"),B=require("@lexical/react/withSubscriptions"),C=require("lexical/OverflowNode");function D(){return x.$getRoot().getTextContent()}
|
|
8
|
+
function F(b,d,p=Object.freeze({})){const {strlen:h=e=>e.length,remainingCharacters:r=()=>{}}=p;w.useEffect(()=>{if(!b.hasNodes([C.OverflowNode]))throw Error("Minified Lexical error #58; see codes.json for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");},[b]);w.useEffect(()=>{let e=b.getEditorState().read(D),f=0;return B(b.addListener("textcontent",q=>{e=q}),b.addListener("update",({dirtyLeaves:q})=>{var y=b.isComposing();q=0<q.size;if(!y&&
|
|
9
|
+
q){y=h(e);q=y>d||null!==f&&f>d;r(d-y);if(null===f||q){const u=G(e,d,h);b.update(()=>{const z=[];for(var c=x.$getRoot().getLatest(),A=x.$isElementNode(c)?c.getLastDescendant():c;null!==c&&!c.is(A);)if(z.push(c),x.$isElementNode(c)&&0<c.getChildrenSize())c=c.getFirstChild();else for(var t=null;null===t&&null!==c;)t=c.getNextSibling(),c=null===t?c.getParent():t;null!==c&&c.is(A)&&z.push(c);A=z.length;c=0;for(t=0;t<A;t+=1){var a=z[t];if(C.$isOverflowNode(a)){var g=c;if(c+a.getTextContentSize()<=u){var k=
|
|
10
|
+
a.getParent();g=a.getPreviousSibling();var m=a.getNextSibling();H(a);a=x.$getSelection();!x.$isRangeSelection(a)||a.anchor.getNode().isAttached()&&a.focus.getNode().isAttached()||(x.$isTextNode(g)?g.select():x.$isTextNode(m)?m.select():null!==k&&k.select())}else g<u&&(k=a.getFirstDescendant(),m=null!==k?k.getTextContentSize():0,g+=m,k=x.$isTextNode(k)&&k.isSimpleText(),g=g<=u,(k||g)&&H(a))}else if(x.$isLeafNode(a)&&(g=c,c+=a.getTextContentSize(),c>u&&!C.$isOverflowNode(a.getParent())&&(k=x.$getSelection(),
|
|
11
|
+
g<u&&x.$isTextNode(a)&&a.isSimpleText()?([,a]=a.splitText(u-g),a=I(a)):a=I(a),null!==k&&x.$setSelection(k),g=a.getPreviousSibling(),C.$isOverflowNode(g)))){m=a.getFirstChild();var v=g.getChildren();k=v.length;if(null===m)a.append(...v);else for(var n=0;n<k;n++)m.insertBefore(v[n]);n=x.$getSelection();if(x.$isRangeSelection(n)){m=n.anchor;v=m.getNode();n=n.focus;const E=m.getNode();v.is(g)?m.set(a.getKey(),m.offset,"element"):v.is(a)&&m.set(a.getKey(),k+m.offset,"element");E.is(g)?n.set(a.getKey(),
|
|
12
|
+
n.offset,"element"):E.is(a)&&n.set(a.getKey(),k+n.offset,"element")}g.remove()}}},{tag:"history-merge"})}f=y}}))},[b,d,r,h])}function G(b,d,p){var h=Intl.Segmenter;let r=0;var e=0;if("function"===typeof h){b=(new h).segment(b);for(var {segment:f}of b){e+=p(f);if(e>d)break;r+=f.length}}else for(f=Array.from(b),b=f.length,h=0;h<b;h++){const q=f[h];e+=p(q);if(e>d)break;r+=q.length}return r}function I(b){const d=C.$createOverflowNode();b.insertBefore(d);d.append(b);return d}
|
|
13
|
+
function H(b){const d=b.getChildren(),p=d.length;for(let h=0;h<p;h++)b.insertBefore(d[h]);b.remove();return 0<p?d[p-1]:null}let J=null;
|
|
14
|
+
module.exports=function({charset:b="UTF-16"}){const [d]=l.useLexicalComposerContext(),[p,h]=w.useState(0),r=w.useMemo(()=>({remainingCharacters:h,strlen:e=>{if("UTF-8"===b){if(void 0===window.TextEncoder)var f=null;else null===J&&(J=new window.TextEncoder),f=J;null===f?(f=encodeURIComponent(e).match(/%[89ABab]/g),e=e.length+(f?f.length:0)):e=f.encode(e).length;return e}if("UTF-16"===b)return e.length;throw Error("Unrecognized charset");}}),[b]);F(d,5,r);return w.createElement("span",{className:`characters-limit ${0>
|
|
15
|
+
p?"characters-limit-exceeded":""}`},p)};
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
|
+
var lexical = require('lexical');
|
|
11
|
+
var react = require('react');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
function LexicalClearEditorPlugin({
|
|
22
|
+
onClear
|
|
23
|
+
}) {
|
|
24
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
25
|
+
react.useLayoutEffect(() => {
|
|
26
|
+
return editor.addListener('command', (type, payload) => {
|
|
27
|
+
if (type === 'clearEditor') {
|
|
28
|
+
editor.update(() => {
|
|
29
|
+
if (onClear == null) {
|
|
30
|
+
const root = lexical.$getRoot();
|
|
31
|
+
const selection = lexical.$getSelection();
|
|
32
|
+
const paragraph = lexical.$createParagraphNode();
|
|
33
|
+
root.clear();
|
|
34
|
+
root.append(paragraph);
|
|
35
|
+
|
|
36
|
+
if (selection !== null) {
|
|
37
|
+
paragraph.select();
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
onClear();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return false;
|
|
47
|
+
}, 0);
|
|
48
|
+
}, [editor, onClear]);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = LexicalClearEditorPlugin;
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
'use strict'
|
|
8
|
+
const LexicalClearEditorPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalClearEditorPlugin.dev.js') : require('./LexicalClearEditorPlugin.prod.js')
|
|
9
|
+
module.exports = LexicalClearEditorPlugin;
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
type Props = $ReadOnly<{
|
|
11
|
+
onClear?: () => void,
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
declare export default function LexicalClearEditorPlugin(Props): React$Node;
|
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
var a=require("@lexical/react/LexicalComposerContext"),f=require("lexical"),g=require("react");module.exports=function({onClear:b}){const [c]=a.useLexicalComposerContext();g.useLayoutEffect(()=>c.addListener("command",h=>"clearEditor"===h?(c.update(()=>{if(null==b){const d=f.$getRoot(),k=f.$getSelection(),e=f.$createParagraphNode();d.clear();d.append(e);null!==k&&e.select()}else b()}),!0):!1,0),[c,b]);return null};
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
10
|
var React = require('react');
|
|
11
11
|
var yjs = require('@lexical/yjs');
|
|
12
|
+
var lexical = require('lexical');
|
|
12
13
|
var reactDom = require('react-dom');
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -20,7 +21,6 @@ var reactDom = require('react-dom');
|
|
|
20
21
|
*
|
|
21
22
|
*/
|
|
22
23
|
const EditorPriority = 0;
|
|
23
|
-
const BootstrapPriority = 1;
|
|
24
24
|
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap) {
|
|
25
25
|
const binding = React.useMemo(() => yjs.createBinding(editor, provider, id, docMap), [editor, provider, id, docMap]);
|
|
26
26
|
const connect = React.useCallback(() => {
|
|
@@ -33,15 +33,6 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
33
33
|
}
|
|
34
34
|
}, [provider]);
|
|
35
35
|
const bootstrapPropagationRef = React.useRef(true);
|
|
36
|
-
React.useLayoutEffect(() => {
|
|
37
|
-
return editor.addListener('command', type => {
|
|
38
|
-
if (type === 'bootstrapEditor') {
|
|
39
|
-
return bootstrapPropagationRef.current;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return false;
|
|
43
|
-
}, BootstrapPriority);
|
|
44
|
-
}, [editor]);
|
|
45
36
|
React.useEffect(() => {
|
|
46
37
|
const {
|
|
47
38
|
root
|
|
@@ -59,7 +50,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
59
50
|
const onSync = isSynced => {
|
|
60
51
|
if (shouldBootstrap && isSynced && root.isEmpty() && root._xmlText._length === 0) {
|
|
61
52
|
bootstrapPropagationRef.current = false;
|
|
62
|
-
editor
|
|
53
|
+
initializeEditor(editor);
|
|
63
54
|
}
|
|
64
55
|
};
|
|
65
56
|
|
|
@@ -176,6 +167,25 @@ function useYjsHistory(editor, binding) {
|
|
|
176
167
|
return clearHistory;
|
|
177
168
|
}
|
|
178
169
|
|
|
170
|
+
function initializeEditor(editor) {
|
|
171
|
+
editor.update(() => {
|
|
172
|
+
const root = lexical.$getRoot();
|
|
173
|
+
const firstChild = root.getFirstChild();
|
|
174
|
+
|
|
175
|
+
if (firstChild === null) {
|
|
176
|
+
const paragraph = lexical.$createParagraphNode();
|
|
177
|
+
root.append(paragraph);
|
|
178
|
+
const activeElement = document.activeElement;
|
|
179
|
+
|
|
180
|
+
if (lexical.$getSelection() !== null || activeElement !== null && activeElement === editor.getRootElement()) {
|
|
181
|
+
paragraph.select();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}, {
|
|
185
|
+
tag: 'history-merge'
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
179
189
|
/**
|
|
180
190
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
181
191
|
*
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {Doc, RelativePosition} from 'yjs';
|
|
11
|
+
|
|
12
|
+
export type UserState = {
|
|
13
|
+
anchorPos: null | RelativePosition,
|
|
14
|
+
focusPos: null | RelativePosition,
|
|
15
|
+
name: string,
|
|
16
|
+
color: string,
|
|
17
|
+
focusing: boolean,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ProviderAwareness = {
|
|
21
|
+
getLocalState: () => UserState,
|
|
22
|
+
setLocalState: (UserState) => void,
|
|
23
|
+
getStates: () => Array<UserState>,
|
|
24
|
+
on: (type: 'update', cb: () => void) => void,
|
|
25
|
+
off: (type: 'update', cb: () => void) => void,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export interface Provider {
|
|
29
|
+
connect(): void | Promise<void>;
|
|
30
|
+
disconnect(): void;
|
|
31
|
+
awareness: ProviderAwareness;
|
|
32
|
+
on(type: 'sync', cb: (isSynced: boolean) => void): void;
|
|
33
|
+
on(type: 'status', cb: ({status: string}) => void): void;
|
|
34
|
+
// $FlowFixMe: temp
|
|
35
|
+
on(type: 'update', cb: (any) => void): void;
|
|
36
|
+
off(type: 'sync', cb: (isSynced: boolean) => void): void;
|
|
37
|
+
// $FlowFixMe: temp
|
|
38
|
+
off(type: 'update', cb: (any) => void): void;
|
|
39
|
+
off(type: 'status', cb: ({status: string}) => void): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type CollaborationContextType = {
|
|
43
|
+
clientID: number,
|
|
44
|
+
color: string,
|
|
45
|
+
name: string,
|
|
46
|
+
yjsDocMap: Map<string, Doc>,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
declare export function CollaborationPlugin(arg0: {
|
|
50
|
+
id: string,
|
|
51
|
+
providerFactory: (id: string, yjsDocMap: Map<string, Doc>) => Provider,
|
|
52
|
+
shouldBootstrap: boolean,
|
|
53
|
+
}): React$Node;
|
|
54
|
+
declare export var CollaborationContext: React$Context<CollaborationContextType>;
|
|
55
|
+
declare export function useCollaborationContext(): CollaborationContextType;
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
function
|
|
7
|
+
var d=require("@lexical/react/LexicalComposerContext"),g=require("react"),u=require("@lexical/yjs"),A=require("lexical"),B=require("react-dom");
|
|
8
|
+
function C(b,c,a,h,n,p,q){const e=g.useMemo(()=>u.createBinding(b,a,c,h),[b,a,c,h]),k=g.useCallback(()=>{a.connect()},[a]),l=g.useCallback(()=>{try{a.disconnect()}catch(f){}},[a]),r=g.useRef(!0);g.useEffect(()=>{const {root:f}=e,{awareness:t}=a,w=({status:m})=>{b.execCommand("connected","connected"===m)},x=m=>{q&&m&&f.isEmpty()&&0===f._xmlText._length&&(r.current=!1,D(b))},y=()=>{u.syncCursorPositions(e,a)},z=(m,v)=>{v.origin!==e&&u.syncYjsChangesToLexical(e,a,m)};u.initLocalState(a,n,p,document.activeElement===
|
|
9
|
+
b.getRootElement());a.on("status",w);a.on("sync",x);t.on("update",y);f.getSharedType().observeDeep(z);const M=b.addListener("update",({prevEditorState:m,editorState:v,dirtyLeaves:I,dirtyElements:J,normalizedNodes:K,tags:L})=>{u.syncLexicalUpdateToYjs(e,a,m,v,J,I,K,L)});k();return()=>{l();a.off("sync",x);a.off("status",w);t.off("update",y);f.getSharedType().unobserveDeep(z);M()}},[e,p,k,l,b,n,a,q]);const N=g.useMemo(()=>B.createPortal(g.createElement("div",{ref:f=>{e.cursorsContainer=f}}),document.body),
|
|
10
|
+
[e]);g.useEffect(()=>b.addListener("command",(f,t)=>{"toggleConnect"===f&&void 0!==k&&void 0!==l&&(t?(console.log("Collaboration connected!"),k()):(console.log("Collaboration disconnected!"),l()));return!1},0),[k,l,b]);return[N,e]}function E(b,c){g.useEffect(()=>b.addListener("command",a=>{"focus"===a?u.setLocalStateFocus(c,!0):"blur"===a&&u.setLocalStateFocus(c,!1);return!1},0),[b,c])}
|
|
11
|
+
function F(b,c){const a=g.useMemo(()=>u.createUndoManager(c,c.root.getSharedType()),[c]);g.useEffect(()=>b.addListener("command",h=>"undo"===h?(a.undo(),!0):"redo"===h?(a.redo(),!0):!1,0));return g.useCallback(()=>{a.clear()},[a])}function D(b){b.update(()=>{var c=A.$getRoot();if(null===c.getFirstChild()){const a=A.$createParagraphNode();c.append(a);c=document.activeElement;(null!==A.$getSelection()||null!==c&&c===b.getRootElement())&&a.select()}},{tag:"history-merge"})}
|
|
12
|
+
const G=[["Cat","255,165,0"],["Dog","0,200,55"],["Rabbit","160,0,200"],["Frog","0,172,200"],["Fox","197,200,0"],["Hedgehog","31,200,0"],["Pigeon","200,0,0"],["Squirrel","200,0,148"],["Bear","255,235,0"],["Tiger","86,255,0"],["Leopard","0,255,208"],["Zebra","0,243,255"],["Wolf","0,102,255"],["Owl","147,0,255"],["Gull","255,0,153"],["Squid","0,220,255"]],H=G[Math.floor(Math.random()*(G.length-1+1))],O=g.createContext({clientID:0,color:H[1],name:H[0],yjsDocMap:new Map});
|
|
13
|
+
function P(){return g.useContext(O)}exports.CollaborationContext=O;exports.CollaborationPlugin=function({id:b,providerFactory:c,shouldBootstrap:a}){const h=P(),{yjsDocMap:n,name:p,color:q}=h,[e]=d.useLexicalComposerContext(),k=g.useMemo(()=>c(b,n),[b,c,n]),[l,r]=C(e,b,k,n,p,q,a);h.clientID=r.clientID;F(e,r);E(e,k);return l};exports.useCollaborationContext=P;
|
package/LexicalComposer.dev.js
CHANGED
|
@@ -57,12 +57,19 @@ function LexicalComposer({
|
|
|
57
57
|
parentEditor,
|
|
58
58
|
theme: composerTheme
|
|
59
59
|
});
|
|
60
|
+
editor.setReadOnly(true);
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
return [editor, context];
|
|
63
64
|
}, // We only do this for init
|
|
64
65
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
66
|
[]);
|
|
67
|
+
React.useLayoutEffect(() => {
|
|
68
|
+
const isReadOnly = initialConfig.isReadOnly;
|
|
69
|
+
const [editor] = composerContext;
|
|
70
|
+
editor.setReadOnly(isReadOnly || false); // We only do this for init
|
|
71
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
72
|
+
}, []);
|
|
66
73
|
return /*#__PURE__*/React.createElement(LexicalComposerContext.LexicalComposerContext.Provider, {
|
|
67
74
|
value: composerContext
|
|
68
75
|
}, children);
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {EditorThemeClasses, LexicalEditor, LexicalNode} from 'lexical';
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
initialConfig?: {
|
|
14
|
+
editor?: LexicalEditor | null,
|
|
15
|
+
namespace?: string,
|
|
16
|
+
nodes?: Array<Class<LexicalNode>>,
|
|
17
|
+
theme?: EditorThemeClasses,
|
|
18
|
+
onError?: (Error) => void,
|
|
19
|
+
},
|
|
20
|
+
children: React$Node,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
declare export default function LexicalComposer(Props): React$MixedElement;
|
package/LexicalComposer.prod.js
CHANGED
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
module.exports=function({initialConfig:
|
|
7
|
+
var c=require("@lexical/react/LexicalComposerContext"),g=require("lexical"),m=require("react");
|
|
8
|
+
module.exports=function({initialConfig:h={},children:n}){const d=m.useContext(c.LexicalComposerContext),l=m.useMemo(()=>{let a,e;const {theme:k,namespace:p,editor:q,nodes:r,onError:t}=h;if(null!=k)a=k;else if(null!=d){e=d[0];var b=d[1].getTheme();null!=b&&(a=b)}b=c.createLexicalComposerContext(d,a);let f=q||null;null===f&&(f=g.createEditor({context:b,namespace:p,nodes:r,onError:t,parentEditor:e,theme:a}),f.setReadOnly(!0));return[f,b]},[]);m.useLayoutEffect(()=>{const a=h.isReadOnly,[e]=l;e.setReadOnly(a||
|
|
9
|
+
!1)},[]);return m.createElement(c.LexicalComposerContext.Provider,{value:l},n)};
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {EditorThemeClasses, LexicalEditor} from 'lexical';
|
|
11
|
+
|
|
12
|
+
export type LexicalComposerContextType = {
|
|
13
|
+
getTheme: () => ?EditorThemeClasses,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type LexicalComposerContextWithEditor = [
|
|
17
|
+
LexicalEditor,
|
|
18
|
+
LexicalComposerContextType,
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export let LexicalComposerContext: React$Context<?LexicalComposerContextWithEditor>;
|
|
22
|
+
|
|
23
|
+
declare export function createLexicalComposerContext(
|
|
24
|
+
parent: ?LexicalComposerContextWithEditor,
|
|
25
|
+
theme: ?EditorThemeClasses,
|
|
26
|
+
): LexicalComposerContextType;
|
|
27
|
+
declare export function useLexicalComposerContext(): LexicalComposerContextWithEditor;
|
|
@@ -32,7 +32,6 @@ function LexicalContentEditable({
|
|
|
32
32
|
autoComplete,
|
|
33
33
|
autoCorrect,
|
|
34
34
|
className,
|
|
35
|
-
readOnly = false,
|
|
36
35
|
role = 'textbox',
|
|
37
36
|
spellCheck = true,
|
|
38
37
|
style,
|
|
@@ -40,28 +39,35 @@ function LexicalContentEditable({
|
|
|
40
39
|
testid
|
|
41
40
|
}) {
|
|
42
41
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
42
|
+
const [isReadOnly, setReadOnly] = React.useState(true);
|
|
43
43
|
const ref = React.useCallback(rootElement => {
|
|
44
44
|
editor.setRootElement(rootElement);
|
|
45
45
|
}, [editor]);
|
|
46
|
+
React.useLayoutEffect(() => {
|
|
47
|
+
setReadOnly(editor.isReadOnly());
|
|
48
|
+
return editor.addListener('readonly', currentIsReadOnly => {
|
|
49
|
+
setReadOnly(currentIsReadOnly);
|
|
50
|
+
});
|
|
51
|
+
}, [editor]);
|
|
46
52
|
return /*#__PURE__*/React.createElement("div", {
|
|
47
|
-
"aria-activedescendant":
|
|
48
|
-
"aria-autocomplete":
|
|
49
|
-
"aria-controls":
|
|
53
|
+
"aria-activedescendant": isReadOnly ? null : ariaActiveDescendantID,
|
|
54
|
+
"aria-autocomplete": isReadOnly ? null : ariaAutoComplete,
|
|
55
|
+
"aria-controls": isReadOnly ? null : ariaControls,
|
|
50
56
|
"aria-describedby": ariaDescribedBy,
|
|
51
|
-
"aria-expanded":
|
|
57
|
+
"aria-expanded": isReadOnly ? null : role === 'combobox' ? !!ariaExpanded : null,
|
|
52
58
|
"aria-label": ariaLabel,
|
|
53
59
|
"aria-labelledby": ariaLabelledBy,
|
|
54
60
|
"aria-multiline": ariaMultiline,
|
|
55
|
-
"aria-owns":
|
|
61
|
+
"aria-owns": isReadOnly ? null : ariaOwneeID,
|
|
56
62
|
"aria-required": ariaRequired,
|
|
57
63
|
autoCapitalize: autoCapitalize,
|
|
58
64
|
autoComplete: autoComplete,
|
|
59
65
|
autoCorrect: autoCorrect,
|
|
60
66
|
className: className,
|
|
61
|
-
contentEditable: !
|
|
67
|
+
contentEditable: !isReadOnly,
|
|
62
68
|
"data-testid": testid,
|
|
63
69
|
ref: ref,
|
|
64
|
-
role:
|
|
70
|
+
role: isReadOnly ? null : role,
|
|
65
71
|
spellCheck: spellCheck,
|
|
66
72
|
style: style,
|
|
67
73
|
tabIndex: tabIndex
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type Props = $ReadOnly<{
|
|
11
|
+
ariaActiveDescendantID?: string,
|
|
12
|
+
ariaAutoComplete?: string,
|
|
13
|
+
ariaControls?: string,
|
|
14
|
+
ariaDescribedBy?: string,
|
|
15
|
+
ariaExpanded?: boolean,
|
|
16
|
+
ariaLabel?: string,
|
|
17
|
+
ariaLabelledBy?: string,
|
|
18
|
+
ariaMultiline?: boolean,
|
|
19
|
+
ariaOwneeID?: string,
|
|
20
|
+
ariaRequired?: string,
|
|
21
|
+
autoCapitalize?: boolean,
|
|
22
|
+
autoComplete?: boolean,
|
|
23
|
+
autoCorrect?: boolean,
|
|
24
|
+
className?: string,
|
|
25
|
+
readOnly?: boolean,
|
|
26
|
+
role?: string,
|
|
27
|
+
style?: StyleSheetList,
|
|
28
|
+
spellCheck?: boolean,
|
|
29
|
+
tabIndex?: number,
|
|
30
|
+
testid?: string,
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
declare export default function LexicalContentEditable(
|
|
34
|
+
props: Props,
|
|
35
|
+
): React$Node;
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
module.exports=function({ariaActiveDescendantID:
|
|
9
|
-
g,"aria-
|
|
7
|
+
var c=require("@lexical/react/LexicalComposerContext"),g=require("react");
|
|
8
|
+
module.exports=function({ariaActiveDescendantID:h,ariaAutoComplete:k,ariaControls:l,ariaDescribedBy:m,ariaExpanded:n,ariaLabel:p,ariaLabelledBy:q,ariaMultiline:r,ariaOwneeID:t,ariaRequired:u,autoCapitalize:v,autoComplete:w,autoCorrect:x,className:y,role:e="textbox",spellCheck:z=!0,style:A,tabIndex:B,testid:C}){const [b]=c.useLexicalComposerContext(),[a,f]=g.useState(!0),D=g.useCallback(d=>{b.setRootElement(d)},[b]);g.useLayoutEffect(()=>{f(b.isReadOnly());return b.addListener("readonly",d=>{f(d)})},
|
|
9
|
+
[b]);return g.createElement("div",{"aria-activedescendant":a?null:h,"aria-autocomplete":a?null:k,"aria-controls":a?null:l,"aria-describedby":m,"aria-expanded":a?null:"combobox"===e?!!n:null,"aria-label":p,"aria-labelledby":q,"aria-multiline":r,"aria-owns":a?null:t,"aria-required":u,autoCapitalize:v,autoComplete:w,autoCorrect:x,className:y,contentEditable:!a,"data-testid":C,ref:D,role:a?null:e,spellCheck:z,style:A,tabIndex:B})};
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
import type {LexicalEditor, TextNode} from 'lexical';
|
|
10
|
+
|
|
11
|
+
declare function getHashtagRegexStringChars(): $ReadOnly<{
|
|
12
|
+
alpha: string,
|
|
13
|
+
alphanumeric: string,
|
|
14
|
+
hashChars: string,
|
|
15
|
+
}>;
|
|
16
|
+
|
|
17
|
+
declare function getHashtagRegexString(): string;
|
|
18
|
+
declare function textNodeTransform(node: TextNode): void;
|
|
19
|
+
declare function useHashtags(editor: LexicalEditor): void;
|
|
20
|
+
declare export default function LexicalHashtagPlugin(): React$Node;
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
EditorState,
|
|
12
|
+
GridSelection,
|
|
13
|
+
LexicalEditor,
|
|
14
|
+
NodeSelection,
|
|
15
|
+
RangeSelection,
|
|
16
|
+
} from 'lexical';
|
|
17
|
+
|
|
18
|
+
export type HistoryStateEntry = {
|
|
19
|
+
editor: LexicalEditor,
|
|
20
|
+
editorState: EditorState,
|
|
21
|
+
undoSelection?: RangeSelection | NodeSelection | GridSelection | null,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type HistoryState = {
|
|
25
|
+
current: null | HistoryStateEntry,
|
|
26
|
+
redoStack: Array<HistoryStateEntry>,
|
|
27
|
+
undoStack: Array<HistoryStateEntry>,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
declare export function HistoryPlugin({
|
|
31
|
+
externalHistoryState?: HistoryState,
|
|
32
|
+
}): React$Node;
|
|
33
|
+
|
|
34
|
+
declare export function createEmptyHistoryState(): HistoryState;
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
* @flow strict
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {LexicalNode} from 'lexical';
|
|
11
|
+
|
|
12
|
+
import {DecoratorNode} from 'lexical';
|
|
13
|
+
|
|
14
|
+
declare export class HorizontalRuleNode extends DecoratorNode<React$Node> {
|
|
15
|
+
static getType(): string;
|
|
16
|
+
static clone(node: HorizontalRuleNode): HorizontalRuleNode;
|
|
17
|
+
createDOM(): HTMLElement;
|
|
18
|
+
getTextContent(): '\n';
|
|
19
|
+
isTopLevel(): true;
|
|
20
|
+
updateDOM(): false;
|
|
21
|
+
decorate(): React$Node;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare export function $createHorizontalRuleNode(): HorizontalRuleNode;
|
|
25
|
+
declare export function $isHorizontalRuleNode(node: ?LexicalNode): boolean;
|