@lexical/react 0.4.1 → 0.5.1-next.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/DEPRECATED_useLexical.js.flow +0 -1
- package/DEPRECATED_useLexicalDecorators.d.ts +2 -1
- package/DEPRECATED_useLexicalDecorators.dev.js +125 -10
- package/DEPRECATED_useLexicalDecorators.js.flow +8 -0
- package/DEPRECATED_useLexicalDecorators.prod.js +6 -2
- package/DEPRECATED_useLexicalPlainText.d.ts +2 -2
- package/DEPRECATED_useLexicalPlainText.dev.js +4 -4
- package/DEPRECATED_useLexicalPlainText.js.flow +0 -1
- package/DEPRECATED_useLexicalPlainText.prod.js +2 -2
- package/DEPRECATED_useLexicalRichText.d.ts +2 -2
- package/DEPRECATED_useLexicalRichText.dev.js +4 -4
- package/DEPRECATED_useLexicalRichText.js.flow +0 -1
- package/DEPRECATED_useLexicalRichText.prod.js +2 -2
- package/LexicalAutoEmbedPlugin.d.ts +3 -13
- package/LexicalAutoEmbedPlugin.dev.js +3 -19
- package/LexicalAutoEmbedPlugin.js.flow +3 -11
- package/LexicalAutoEmbedPlugin.prod.js +4 -5
- package/LexicalAutoLinkPlugin.dev.js +49 -45
- package/LexicalAutoLinkPlugin.prod.js +6 -6
- package/LexicalBlockWithAlignableContents.dev.js +1 -1
- package/LexicalBlockWithAlignableContents.prod.js +1 -1
- package/LexicalCollaborationPlugin.d.ts +5 -1
- package/LexicalCollaborationPlugin.dev.js +54 -16
- package/LexicalCollaborationPlugin.js.flow +1 -0
- package/LexicalCollaborationPlugin.prod.js +9 -9
- package/LexicalComposer.d.ts +1 -2
- package/LexicalComposer.dev.js +15 -1
- package/LexicalComposer.js.flow +14 -7
- package/LexicalComposer.prod.js +3 -3
- package/LexicalContentEditable.dev.js +1 -1
- package/LexicalContentEditable.prod.js +1 -1
- package/LexicalHorizontalRuleNode.d.ts +4 -2
- package/LexicalHorizontalRuleNode.dev.js +25 -3
- package/LexicalHorizontalRuleNode.js.flow +0 -1
- package/LexicalHorizontalRuleNode.prod.js +5 -5
- package/LexicalNestedComposer.d.ts +4 -2
- package/LexicalNestedComposer.dev.js +25 -3
- package/LexicalNestedComposer.js.flow +1 -0
- package/LexicalNestedComposer.prod.js +3 -3
- package/LexicalOnChangePlugin.d.ts +1 -2
- package/LexicalOnChangePlugin.dev.js +3 -9
- package/LexicalOnChangePlugin.js.flow +0 -2
- package/LexicalOnChangePlugin.prod.js +2 -2
- package/LexicalPlainTextPlugin.d.ts +3 -3
- package/LexicalPlainTextPlugin.dev.js +111 -20
- package/LexicalPlainTextPlugin.js.flow +3 -1
- package/LexicalPlainTextPlugin.prod.js +6 -4
- package/LexicalRichTextPlugin.d.ts +3 -3
- package/LexicalRichTextPlugin.dev.js +111 -20
- package/LexicalRichTextPlugin.js.flow +3 -1
- package/LexicalRichTextPlugin.prod.js +6 -4
- package/LexicalTableOfContents__EXPERIMENTAL.js.flow +1 -1
- package/LexicalTablePlugin.dev.js +1 -1
- package/LexicalTablePlugin.prod.js +1 -1
- package/LexicalTreeView.dev.js +28 -13
- package/LexicalTreeView.prod.js +14 -13
- package/LexicalTypeaheadMenuPlugin.d.ts +20 -8
- package/LexicalTypeaheadMenuPlugin.dev.js +200 -57
- package/LexicalTypeaheadMenuPlugin.js.flow +19 -21
- package/LexicalTypeaheadMenuPlugin.prod.js +18 -14
- package/package.json +19 -19
- package/shared/ReactErrorBoundary.d.ts +63 -0
- package/shared/useDecorators.d.ts +8 -1
- package/shared/usePlainTextSetup.d.ts +1 -2
- package/shared/useRichTextSetup.d.ts +1 -2
- package/shared/useYjsCollaboration.d.ts +4 -1
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
export declare function PlainTextPlugin({ contentEditable, placeholder,
|
|
8
|
+
import { ErrorBoundaryType } from './shared/useDecorators';
|
|
9
|
+
export declare function PlainTextPlugin({ contentEditable, placeholder, ErrorBoundary, }: {
|
|
10
10
|
contentEditable: JSX.Element;
|
|
11
|
-
initialEditorState?: InitialEditorStateType;
|
|
12
11
|
placeholder: JSX.Element | string;
|
|
12
|
+
ErrorBoundary?: ErrorBoundaryType;
|
|
13
13
|
}): JSX.Element;
|
|
@@ -21,16 +21,94 @@ var plainText = require('@lexical/plain-text');
|
|
|
21
21
|
* LICENSE file in the root directory of this source tree.
|
|
22
22
|
*
|
|
23
23
|
*/
|
|
24
|
-
function warnOnlyOnce(message) {
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const changedArray = (a = [], b = []) => a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
|
|
26
|
+
|
|
27
|
+
const initialState = {
|
|
28
|
+
error: null
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class ErrorBoundary extends React.Component {
|
|
32
|
+
constructor(props) {
|
|
33
|
+
super(props);
|
|
34
|
+
this.state = initialState;
|
|
35
|
+
this.resetErrorBoundary = this.resetErrorBoundary.bind(this);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static getDerivedStateFromError(error) {
|
|
39
|
+
return {
|
|
40
|
+
error
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
resetErrorBoundary(...args) {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
// eslint-disable-next-line no-unused-expressions
|
|
47
|
+
this.props.onReset && this.props.onReset(...args);
|
|
48
|
+
this.reset();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
reset() {
|
|
52
|
+
this.setState(initialState);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
componentDidCatch(error, info) {
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
// eslint-disable-next-line no-unused-expressions
|
|
58
|
+
this.props.onError && this.props.onError(error, info);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
componentDidUpdate(prevProps, prevState) {
|
|
62
|
+
const {
|
|
63
|
+
error
|
|
64
|
+
} = this.state;
|
|
65
|
+
const {
|
|
66
|
+
resetKeys
|
|
67
|
+
} = this.props; // There's an edge case where if the thing that triggered the error
|
|
68
|
+
// happens to *also* be in the resetKeys array, we'd end up resetting
|
|
69
|
+
// the error boundary immediately. This would likely trigger a second
|
|
70
|
+
// error to be thrown.
|
|
71
|
+
// So we make sure that we don't check the resetKeys on the first call
|
|
72
|
+
// of cDU after the error is set
|
|
73
|
+
|
|
74
|
+
if (error !== null && prevState.error !== null && changedArray(prevProps.resetKeys, resetKeys)) {
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
// eslint-disable-next-line no-unused-expressions
|
|
77
|
+
this.props.onResetKeysChange && this.props.onResetKeysChange(prevProps.resetKeys, resetKeys);
|
|
78
|
+
this.reset();
|
|
30
79
|
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
render() {
|
|
83
|
+
const {
|
|
84
|
+
error
|
|
85
|
+
} = this.state;
|
|
86
|
+
const {
|
|
87
|
+
fallbackRender,
|
|
88
|
+
FallbackComponent,
|
|
89
|
+
fallback
|
|
90
|
+
} = this.props;
|
|
91
|
+
|
|
92
|
+
if (error !== null) {
|
|
93
|
+
const props = {
|
|
94
|
+
error,
|
|
95
|
+
resetErrorBoundary: this.resetErrorBoundary
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if ( /*#__PURE__*/React.isValidElement(fallback)) {
|
|
99
|
+
return fallback;
|
|
100
|
+
} else if (typeof fallbackRender === 'function') {
|
|
101
|
+
return fallbackRender(props);
|
|
102
|
+
} else if (FallbackComponent) {
|
|
103
|
+
return /*#__PURE__*/React.createElement(FallbackComponent, props);
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error('react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return this.props.children;
|
|
110
|
+
}
|
|
31
111
|
|
|
32
|
-
run = true;
|
|
33
|
-
};
|
|
34
112
|
}
|
|
35
113
|
|
|
36
114
|
/**
|
|
@@ -90,7 +168,14 @@ function useCanShowPlaceholder(editor) {
|
|
|
90
168
|
* LICENSE file in the root directory of this source tree.
|
|
91
169
|
*
|
|
92
170
|
*/
|
|
93
|
-
function useDecorators(editor
|
|
171
|
+
function useDecorators(editor, // TODO 0.6 Make non-optional non-default
|
|
172
|
+
ErrorBoundary$1 = ({
|
|
173
|
+
children,
|
|
174
|
+
onError
|
|
175
|
+
}) => /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
176
|
+
fallback: null,
|
|
177
|
+
onError: onError
|
|
178
|
+
}, children)) {
|
|
94
179
|
const [decorators, setDecorators] = React.useState(() => editor.getDecorators()); // Subscribe to changes
|
|
95
180
|
|
|
96
181
|
useLayoutEffect(() => {
|
|
@@ -113,7 +198,11 @@ function useDecorators(editor) {
|
|
|
113
198
|
|
|
114
199
|
for (let i = 0; i < decoratorKeys.length; i++) {
|
|
115
200
|
const nodeKey = decoratorKeys[i];
|
|
116
|
-
const reactDecorator =
|
|
201
|
+
const reactDecorator = /*#__PURE__*/React.createElement(ErrorBoundary$1, {
|
|
202
|
+
onError: e => editor._onError(e)
|
|
203
|
+
}, /*#__PURE__*/React.createElement(React.Suspense, {
|
|
204
|
+
fallback: null
|
|
205
|
+
}, decorators[nodeKey]));
|
|
117
206
|
const element = editor.getElementByKey(nodeKey);
|
|
118
207
|
|
|
119
208
|
if (element !== null) {
|
|
@@ -122,7 +211,7 @@ function useDecorators(editor) {
|
|
|
122
211
|
}
|
|
123
212
|
|
|
124
213
|
return decoratedPortals;
|
|
125
|
-
}, [decorators, editor]);
|
|
214
|
+
}, [ErrorBoundary$1, decorators, editor]);
|
|
126
215
|
}
|
|
127
216
|
|
|
128
217
|
/**
|
|
@@ -132,9 +221,9 @@ function useDecorators(editor) {
|
|
|
132
221
|
* LICENSE file in the root directory of this source tree.
|
|
133
222
|
*
|
|
134
223
|
*/
|
|
135
|
-
function usePlainTextSetup(editor
|
|
224
|
+
function usePlainTextSetup(editor) {
|
|
136
225
|
useLayoutEffect(() => {
|
|
137
|
-
return utils.mergeRegister(plainText.registerPlainText(editor
|
|
226
|
+
return utils.mergeRegister(plainText.registerPlainText(editor), dragon.registerDragonSupport(editor)); // We only do this for init
|
|
138
227
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
139
228
|
}, [editor]);
|
|
140
229
|
}
|
|
@@ -146,20 +235,22 @@ function usePlainTextSetup(editor, initialEditorState) {
|
|
|
146
235
|
* LICENSE file in the root directory of this source tree.
|
|
147
236
|
*
|
|
148
237
|
*/
|
|
149
|
-
const deprecatedInitialEditorStateWarning = warnOnlyOnce('`initialEditorState` on `PlainTextPlugin` is deprecated and will be removed soon. Use the `initialConfig.editorState` prop on the `LexicalComposer` instead.');
|
|
150
238
|
function PlainTextPlugin({
|
|
151
239
|
contentEditable,
|
|
152
240
|
placeholder,
|
|
153
|
-
|
|
241
|
+
// TODO 0.6 Make non-optional non-default
|
|
242
|
+
ErrorBoundary: ErrorBoundary$1 = ({
|
|
243
|
+
children,
|
|
244
|
+
onError
|
|
245
|
+
}) => /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
246
|
+
fallback: null,
|
|
247
|
+
onError: onError
|
|
248
|
+
}, children)
|
|
154
249
|
}) {
|
|
155
|
-
if (deprecatedInitialEditorStateWarning && initialEditorState !== undefined) {
|
|
156
|
-
deprecatedInitialEditorStateWarning();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
250
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
160
251
|
const showPlaceholder = useCanShowPlaceholder(editor);
|
|
161
|
-
const decorators = useDecorators(editor);
|
|
162
|
-
usePlainTextSetup(editor
|
|
252
|
+
const decorators = useDecorators(editor, ErrorBoundary$1);
|
|
253
|
+
usePlainTextSetup(editor);
|
|
163
254
|
return /*#__PURE__*/React.createElement(React.Fragment, null, contentEditable, showPlaceholder && placeholder, decorators);
|
|
164
255
|
}
|
|
165
256
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type {ErrorBoundaryType} from './DEPRECATED_useLexicalDecorators';
|
|
10
11
|
import type {EditorState, LexicalEditor} from 'lexical';
|
|
11
12
|
|
|
12
13
|
type InitialEditorStateType =
|
|
@@ -17,6 +18,7 @@ type InitialEditorStateType =
|
|
|
17
18
|
|
|
18
19
|
declare export function PlainTextPlugin({
|
|
19
20
|
contentEditable: React$Node,
|
|
20
|
-
initialEditorState?: InitialEditorStateType,
|
|
21
21
|
placeholder: React$Node,
|
|
22
|
+
// TODO 0.6 Make non-optional non-default
|
|
23
|
+
ErrorBoundary?: ErrorBoundaryType,
|
|
22
24
|
}): React$Node;
|
|
@@ -4,7 +4,9 @@
|
|
|
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
|
-
'use strict';var d=require("@lexical/react/LexicalComposerContext"),h=require("react"),l=require("@lexical/text"),m=require("@lexical/utils"),n=require("react-dom"),p=require("@lexical/dragon"),q=require("@lexical/plain-text")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
'use strict';var d=require("@lexical/react/LexicalComposerContext"),h=require("react"),l=require("@lexical/text"),m=require("@lexical/utils"),n=require("react-dom"),p=require("@lexical/dragon"),q=require("@lexical/plain-text");let t=(a=[],e=[])=>a.length!==e.length||a.some((c,b)=>!Object.is(c,e[b])),u={error:null};
|
|
8
|
+
class v extends h.Component{constructor(a){super(a);this.state=u;this.resetErrorBoundary=this.resetErrorBoundary.bind(this)}static getDerivedStateFromError(a){return{error:a}}resetErrorBoundary(...a){this.props.onReset&&this.props.onReset(...a);this.reset()}reset(){this.setState(u)}componentDidCatch(a,e){this.props.onError&&this.props.onError(a,e)}componentDidUpdate(a,e){let {error:c}=this.state,{resetKeys:b}=this.props;null!==c&&null!==e.error&&t(a.resetKeys,b)&&(this.props.onResetKeysChange&&this.props.onResetKeysChange(a.resetKeys,
|
|
9
|
+
b),this.reset())}render(){var {error:a}=this.state;let {fallbackRender:e,FallbackComponent:c,fallback:b}=this.props;if(null!==a){a={error:a,resetErrorBoundary:this.resetErrorBoundary};if(h.isValidElement(b))return b;if("function"===typeof e)return e(a);if(c)return h.createElement(c,a);throw Error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop");}return this.props.children}}
|
|
10
|
+
var w="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?h.useLayoutEffect:h.useEffect;function x(a){return a.getEditorState().read(l.$canShowPlaceholderCurry(a.isComposing(),a.isEditable()))}function y(a){let [e,c]=h.useState(()=>x(a));w(()=>{function b(){let f=x(a);c(f)}b();return m.mergeRegister(a.registerUpdateListener(()=>{b()}),a.registerEditableListener(()=>{b()}))},[a]);return e}
|
|
11
|
+
function z(a,e=({children:c,onError:b})=>h.createElement(v,{fallback:null,onError:b},c)){let [c,b]=h.useState(()=>a.getDecorators());w(()=>a.registerDecoratorListener(f=>{n.flushSync(()=>{b(f)})}),[a]);h.useEffect(()=>{b(a.getDecorators())},[a]);return h.useMemo(()=>{let f=[],r=Object.keys(c);for(let k=0;k<r.length;k++){var g=r[k];let B=h.createElement(e,{onError:A=>a._onError(A)},h.createElement(h.Suspense,{fallback:null},c[g]));g=a.getElementByKey(g);null!==g&&f.push(n.createPortal(B,g))}return f},
|
|
12
|
+
[e,c,a])}function C(a){w(()=>m.mergeRegister(q.registerPlainText(a),p.registerDragonSupport(a)),[a])}exports.PlainTextPlugin=function({contentEditable:a,placeholder:e,ErrorBoundary:c=({children:b,onError:f})=>h.createElement(v,{fallback:null,onError:f},b)}){let [b]=d.useLexicalComposerContext(),f=y(b);c=z(b,c);C(b);return h.createElement(h.Fragment,null,a,f&&e,c)}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
export declare function RichTextPlugin({ contentEditable, placeholder,
|
|
8
|
+
import { ErrorBoundaryType } from './shared/useDecorators';
|
|
9
|
+
export declare function RichTextPlugin({ contentEditable, placeholder, ErrorBoundary, }: Readonly<{
|
|
10
10
|
contentEditable: JSX.Element;
|
|
11
|
-
initialEditorState?: InitialEditorStateType;
|
|
12
11
|
placeholder: JSX.Element | string;
|
|
12
|
+
ErrorBoundary?: ErrorBoundaryType;
|
|
13
13
|
}>): JSX.Element;
|
|
@@ -21,16 +21,94 @@ var richText = require('@lexical/rich-text');
|
|
|
21
21
|
* LICENSE file in the root directory of this source tree.
|
|
22
22
|
*
|
|
23
23
|
*/
|
|
24
|
-
function warnOnlyOnce(message) {
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const changedArray = (a = [], b = []) => a.length !== b.length || a.some((item, index) => !Object.is(item, b[index]));
|
|
26
|
+
|
|
27
|
+
const initialState = {
|
|
28
|
+
error: null
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class ErrorBoundary extends React.Component {
|
|
32
|
+
constructor(props) {
|
|
33
|
+
super(props);
|
|
34
|
+
this.state = initialState;
|
|
35
|
+
this.resetErrorBoundary = this.resetErrorBoundary.bind(this);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static getDerivedStateFromError(error) {
|
|
39
|
+
return {
|
|
40
|
+
error
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
resetErrorBoundary(...args) {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
// eslint-disable-next-line no-unused-expressions
|
|
47
|
+
this.props.onReset && this.props.onReset(...args);
|
|
48
|
+
this.reset();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
reset() {
|
|
52
|
+
this.setState(initialState);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
componentDidCatch(error, info) {
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
// eslint-disable-next-line no-unused-expressions
|
|
58
|
+
this.props.onError && this.props.onError(error, info);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
componentDidUpdate(prevProps, prevState) {
|
|
62
|
+
const {
|
|
63
|
+
error
|
|
64
|
+
} = this.state;
|
|
65
|
+
const {
|
|
66
|
+
resetKeys
|
|
67
|
+
} = this.props; // There's an edge case where if the thing that triggered the error
|
|
68
|
+
// happens to *also* be in the resetKeys array, we'd end up resetting
|
|
69
|
+
// the error boundary immediately. This would likely trigger a second
|
|
70
|
+
// error to be thrown.
|
|
71
|
+
// So we make sure that we don't check the resetKeys on the first call
|
|
72
|
+
// of cDU after the error is set
|
|
73
|
+
|
|
74
|
+
if (error !== null && prevState.error !== null && changedArray(prevProps.resetKeys, resetKeys)) {
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
// eslint-disable-next-line no-unused-expressions
|
|
77
|
+
this.props.onResetKeysChange && this.props.onResetKeysChange(prevProps.resetKeys, resetKeys);
|
|
78
|
+
this.reset();
|
|
30
79
|
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
render() {
|
|
83
|
+
const {
|
|
84
|
+
error
|
|
85
|
+
} = this.state;
|
|
86
|
+
const {
|
|
87
|
+
fallbackRender,
|
|
88
|
+
FallbackComponent,
|
|
89
|
+
fallback
|
|
90
|
+
} = this.props;
|
|
91
|
+
|
|
92
|
+
if (error !== null) {
|
|
93
|
+
const props = {
|
|
94
|
+
error,
|
|
95
|
+
resetErrorBoundary: this.resetErrorBoundary
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if ( /*#__PURE__*/React.isValidElement(fallback)) {
|
|
99
|
+
return fallback;
|
|
100
|
+
} else if (typeof fallbackRender === 'function') {
|
|
101
|
+
return fallbackRender(props);
|
|
102
|
+
} else if (FallbackComponent) {
|
|
103
|
+
return /*#__PURE__*/React.createElement(FallbackComponent, props);
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error('react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return this.props.children;
|
|
110
|
+
}
|
|
31
111
|
|
|
32
|
-
run = true;
|
|
33
|
-
};
|
|
34
112
|
}
|
|
35
113
|
|
|
36
114
|
/**
|
|
@@ -90,7 +168,14 @@ function useCanShowPlaceholder(editor) {
|
|
|
90
168
|
* LICENSE file in the root directory of this source tree.
|
|
91
169
|
*
|
|
92
170
|
*/
|
|
93
|
-
function useDecorators(editor
|
|
171
|
+
function useDecorators(editor, // TODO 0.6 Make non-optional non-default
|
|
172
|
+
ErrorBoundary$1 = ({
|
|
173
|
+
children,
|
|
174
|
+
onError
|
|
175
|
+
}) => /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
176
|
+
fallback: null,
|
|
177
|
+
onError: onError
|
|
178
|
+
}, children)) {
|
|
94
179
|
const [decorators, setDecorators] = React.useState(() => editor.getDecorators()); // Subscribe to changes
|
|
95
180
|
|
|
96
181
|
useLayoutEffect(() => {
|
|
@@ -113,7 +198,11 @@ function useDecorators(editor) {
|
|
|
113
198
|
|
|
114
199
|
for (let i = 0; i < decoratorKeys.length; i++) {
|
|
115
200
|
const nodeKey = decoratorKeys[i];
|
|
116
|
-
const reactDecorator =
|
|
201
|
+
const reactDecorator = /*#__PURE__*/React.createElement(ErrorBoundary$1, {
|
|
202
|
+
onError: e => editor._onError(e)
|
|
203
|
+
}, /*#__PURE__*/React.createElement(React.Suspense, {
|
|
204
|
+
fallback: null
|
|
205
|
+
}, decorators[nodeKey]));
|
|
117
206
|
const element = editor.getElementByKey(nodeKey);
|
|
118
207
|
|
|
119
208
|
if (element !== null) {
|
|
@@ -122,7 +211,7 @@ function useDecorators(editor) {
|
|
|
122
211
|
}
|
|
123
212
|
|
|
124
213
|
return decoratedPortals;
|
|
125
|
-
}, [decorators, editor]);
|
|
214
|
+
}, [ErrorBoundary$1, decorators, editor]);
|
|
126
215
|
}
|
|
127
216
|
|
|
128
217
|
/**
|
|
@@ -132,9 +221,9 @@ function useDecorators(editor) {
|
|
|
132
221
|
* LICENSE file in the root directory of this source tree.
|
|
133
222
|
*
|
|
134
223
|
*/
|
|
135
|
-
function useRichTextSetup(editor
|
|
224
|
+
function useRichTextSetup(editor) {
|
|
136
225
|
useLayoutEffect(() => {
|
|
137
|
-
return utils.mergeRegister(richText.registerRichText(editor
|
|
226
|
+
return utils.mergeRegister(richText.registerRichText(editor), dragon.registerDragonSupport(editor)); // We only do this for init
|
|
138
227
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
139
228
|
}, [editor]);
|
|
140
229
|
}
|
|
@@ -146,20 +235,22 @@ function useRichTextSetup(editor, initialEditorState) {
|
|
|
146
235
|
* LICENSE file in the root directory of this source tree.
|
|
147
236
|
*
|
|
148
237
|
*/
|
|
149
|
-
const deprecatedInitialEditorStateWarning = warnOnlyOnce('`initialEditorState` on `RichTextPlugin` is deprecated and will be removed soon. Use the `initialConfig.editorState` prop on the `LexicalComposer` instead.');
|
|
150
238
|
function RichTextPlugin({
|
|
151
239
|
contentEditable,
|
|
152
240
|
placeholder,
|
|
153
|
-
|
|
241
|
+
// TODO 0.6 Make non-optional non-default
|
|
242
|
+
ErrorBoundary: ErrorBoundary$1 = ({
|
|
243
|
+
children,
|
|
244
|
+
onError
|
|
245
|
+
}) => /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
246
|
+
fallback: null,
|
|
247
|
+
onError: onError
|
|
248
|
+
}, children)
|
|
154
249
|
}) {
|
|
155
|
-
if (deprecatedInitialEditorStateWarning && initialEditorState !== undefined) {
|
|
156
|
-
deprecatedInitialEditorStateWarning();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
250
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
160
251
|
const showPlaceholder = useCanShowPlaceholder(editor);
|
|
161
|
-
const decorators = useDecorators(editor);
|
|
162
|
-
useRichTextSetup(editor
|
|
252
|
+
const decorators = useDecorators(editor, ErrorBoundary$1);
|
|
253
|
+
useRichTextSetup(editor);
|
|
163
254
|
return /*#__PURE__*/React.createElement(React.Fragment, null, contentEditable, showPlaceholder && placeholder, decorators);
|
|
164
255
|
}
|
|
165
256
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type {ErrorBoundaryType} from './DEPRECATED_useLexicalDecorators';
|
|
10
11
|
import type {EditorState, LexicalEditor} from 'lexical';
|
|
11
12
|
|
|
12
13
|
type InitialEditorStateType =
|
|
@@ -17,6 +18,7 @@ type InitialEditorStateType =
|
|
|
17
18
|
|
|
18
19
|
declare export function RichTextPlugin({
|
|
19
20
|
contentEditable: React$Node,
|
|
20
|
-
initialEditorState?: InitialEditorStateType,
|
|
21
21
|
placeholder: React$Node,
|
|
22
|
+
// TODO 0.6 Make non-optional non-default
|
|
23
|
+
ErrorBoundary?: ErrorBoundaryType,
|
|
22
24
|
}): React$Node;
|
|
@@ -4,7 +4,9 @@
|
|
|
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
|
-
'use strict';var d=require("@lexical/react/LexicalComposerContext"),h=require("react"),l=require("@lexical/text"),m=require("@lexical/utils"),n=require("react-dom"),p=require("@lexical/dragon"),q=require("@lexical/rich-text")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
'use strict';var d=require("@lexical/react/LexicalComposerContext"),h=require("react"),l=require("@lexical/text"),m=require("@lexical/utils"),n=require("react-dom"),p=require("@lexical/dragon"),q=require("@lexical/rich-text");let t=(a=[],e=[])=>a.length!==e.length||a.some((c,b)=>!Object.is(c,e[b])),u={error:null};
|
|
8
|
+
class v extends h.Component{constructor(a){super(a);this.state=u;this.resetErrorBoundary=this.resetErrorBoundary.bind(this)}static getDerivedStateFromError(a){return{error:a}}resetErrorBoundary(...a){this.props.onReset&&this.props.onReset(...a);this.reset()}reset(){this.setState(u)}componentDidCatch(a,e){this.props.onError&&this.props.onError(a,e)}componentDidUpdate(a,e){let {error:c}=this.state,{resetKeys:b}=this.props;null!==c&&null!==e.error&&t(a.resetKeys,b)&&(this.props.onResetKeysChange&&this.props.onResetKeysChange(a.resetKeys,
|
|
9
|
+
b),this.reset())}render(){var {error:a}=this.state;let {fallbackRender:e,FallbackComponent:c,fallback:b}=this.props;if(null!==a){a={error:a,resetErrorBoundary:this.resetErrorBoundary};if(h.isValidElement(b))return b;if("function"===typeof e)return e(a);if(c)return h.createElement(c,a);throw Error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop");}return this.props.children}}
|
|
10
|
+
var w="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?h.useLayoutEffect:h.useEffect;function x(a){return a.getEditorState().read(l.$canShowPlaceholderCurry(a.isComposing(),a.isEditable()))}function y(a){let [e,c]=h.useState(()=>x(a));w(()=>{function b(){let f=x(a);c(f)}b();return m.mergeRegister(a.registerUpdateListener(()=>{b()}),a.registerEditableListener(()=>{b()}))},[a]);return e}
|
|
11
|
+
function z(a,e=({children:c,onError:b})=>h.createElement(v,{fallback:null,onError:b},c)){let [c,b]=h.useState(()=>a.getDecorators());w(()=>a.registerDecoratorListener(f=>{n.flushSync(()=>{b(f)})}),[a]);h.useEffect(()=>{b(a.getDecorators())},[a]);return h.useMemo(()=>{let f=[],r=Object.keys(c);for(let k=0;k<r.length;k++){var g=r[k];let B=h.createElement(e,{onError:A=>a._onError(A)},h.createElement(h.Suspense,{fallback:null},c[g]));g=a.getElementByKey(g);null!==g&&f.push(n.createPortal(B,g))}return f},
|
|
12
|
+
[e,c,a])}function C(a){w(()=>m.mergeRegister(q.registerRichText(a),p.registerDragonSupport(a)),[a])}exports.RichTextPlugin=function({contentEditable:a,placeholder:e,ErrorBoundary:c=({children:b,onError:f})=>h.createElement(v,{fallback:null,onError:f},b)}){let [b]=d.useLexicalComposerContext(),f=y(b);c=z(b,c);C(b);return h.createElement(h.Fragment,null,a,f&&e,c)}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import type {HeadingTagType} from '@lexical/rich-text';
|
|
11
11
|
import type {NodeKey} from 'lexical';
|
|
12
12
|
|
|
13
|
-
declare export function LexicalTableOfContentsPlugin({
|
|
13
|
+
declare export default function LexicalTableOfContentsPlugin({
|
|
14
14
|
children: (
|
|
15
15
|
tableOfContents: Array<[NodeKey, string, HeadingTagType]>,
|
|
16
16
|
) => React$Node,
|
|
@@ -44,7 +44,7 @@ function TablePlugin() {
|
|
|
44
44
|
if (focusNode !== null) {
|
|
45
45
|
const tableNode = table.$createTableNodeWithDimensions(Number(rows), Number(columns), includeHeaders);
|
|
46
46
|
|
|
47
|
-
if (lexical.$
|
|
47
|
+
if (lexical.$isRootOrShadowRoot(focusNode)) {
|
|
48
48
|
const target = focusNode.getChildAtIndex(focus.offset);
|
|
49
49
|
|
|
50
50
|
if (target !== null) {
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
*/
|
|
7
7
|
'use strict';var e=require("@lexical/react/LexicalComposerContext"),f=require("@lexical/table"),k=require("lexical"),m=require("react");
|
|
8
8
|
exports.TablePlugin=function(){let [d]=e.useLexicalComposerContext();m.useEffect(()=>{if(!d.hasNodes([f.TableNode,f.TableCellNode,f.TableRowNode]))throw Error("Minified Lexical error #10; visit https://lexical.dev/docs/error?code=10 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");return d.registerCommand(f.INSERT_TABLE_COMMAND,({columns:a,rows:c,includeHeaders:g})=>{var b=k.$getSelection();if(!k.$isRangeSelection(b))return!0;let h=b.focus;
|
|
9
|
-
b=h.getNode();null!==b&&(a=f.$createTableNodeWithDimensions(Number(c),Number(a),g),k.$
|
|
9
|
+
b=h.getNode();null!==b&&(a=f.$createTableNodeWithDimensions(Number(c),Number(a),g),k.$isRootOrShadowRoot(b)?(c=b.getChildAtIndex(h.offset),null!==c?c.insertBefore(a):b.append(a),a.insertBefore(k.$createParagraphNode())):b.getTopLevelElementOrThrow().insertAfter(a),a.insertAfter(k.$createParagraphNode()),a.getFirstChildOrThrow().getFirstChildOrThrow().select());return!0},k.COMMAND_PRIORITY_EDITOR)},[d]);m.useEffect(()=>{let a=new Map;return d.registerMutationListener(f.TableNode,c=>{for(let [g,b]of c)"created"===
|
|
10
10
|
b?d.update(()=>{var h=d.getElementByKey(g);let l=k.$getNodeByKey(g);h&&l&&(h=f.applyTableHandlers(l,h,d),a.set(g,h))}):"destroyed"===b&&(c=a.get(g),void 0!==c&&(c.removeListeners(),a.delete(g)))})},[d]);return null}
|
package/LexicalTreeView.dev.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
var link = require('@lexical/link');
|
|
10
10
|
var mark = require('@lexical/mark');
|
|
11
|
+
var utils = require('@lexical/utils');
|
|
11
12
|
var lexical = require('lexical');
|
|
12
13
|
var React = require('react');
|
|
13
14
|
|
|
@@ -47,19 +48,20 @@ function TreeView({
|
|
|
47
48
|
const inputRef = React.useRef(null);
|
|
48
49
|
const [isPlaying, setIsPlaying] = React.useState(false);
|
|
49
50
|
React.useEffect(() => {
|
|
50
|
-
setContent(generateContent(editor.getEditorState()));
|
|
51
|
-
return editor.registerUpdateListener(({
|
|
51
|
+
setContent(generateContent(editor.getEditorState(), editor._config, editor._compositionKey, editor._editable));
|
|
52
|
+
return utils.mergeRegister(editor.registerUpdateListener(({
|
|
52
53
|
editorState
|
|
53
54
|
}) => {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const compositionText = compositionKey !== null && `Composition key: ${compositionKey}`;
|
|
57
|
-
setContent([treeText, compositionText].filter(Boolean).join('\n\n'));
|
|
55
|
+
const treeText = generateContent(editor.getEditorState(), editor._config, editor._compositionKey, editor._editable);
|
|
56
|
+
setContent(treeText);
|
|
58
57
|
|
|
59
58
|
if (!timeTravelEnabled) {
|
|
60
59
|
setTimeStampedEditorStates(currentEditorStates => [...currentEditorStates, [Date.now(), editorState]]);
|
|
61
60
|
}
|
|
62
|
-
})
|
|
61
|
+
}), editor.registerEditableListener(() => {
|
|
62
|
+
const treeText = generateContent(editor.getEditorState(), editor._config, editor._compositionKey, editor._editable);
|
|
63
|
+
setContent(treeText);
|
|
64
|
+
}));
|
|
63
65
|
}, [timeTravelEnabled, editor]);
|
|
64
66
|
const totalEditorStates = timeStampedEditorStates.length;
|
|
65
67
|
React.useEffect(() => {
|
|
@@ -130,6 +132,10 @@ function TreeView({
|
|
|
130
132
|
}, /*#__PURE__*/React.createElement("button", {
|
|
131
133
|
className: timeTravelPanelButtonClassName,
|
|
132
134
|
onClick: () => {
|
|
135
|
+
if (playingIndexRef.current === totalEditorStates - 1) {
|
|
136
|
+
playingIndexRef.current = 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
133
139
|
setIsPlaying(!isPlaying);
|
|
134
140
|
},
|
|
135
141
|
type: "button"
|
|
@@ -193,7 +199,7 @@ function printGridSelection(selection) {
|
|
|
193
199
|
return `: grid\n └ { grid: ${selection.gridKey}, anchorCell: ${selection.anchor.key}, focusCell: ${selection.focus.key} }`;
|
|
194
200
|
}
|
|
195
201
|
|
|
196
|
-
function generateContent(editorState) {
|
|
202
|
+
function generateContent(editorState, editorConfig, compositionKey, editable) {
|
|
197
203
|
let res = ' root\n';
|
|
198
204
|
const selectionString = editorState.read(() => {
|
|
199
205
|
const selection = lexical.$getSelection();
|
|
@@ -213,9 +219,18 @@ function generateContent(editorState) {
|
|
|
213
219
|
typeDisplay
|
|
214
220
|
});
|
|
215
221
|
});
|
|
216
|
-
return selection === null ? ': null' : lexical.$isRangeSelection(selection) ? printRangeSelection(selection) : lexical
|
|
222
|
+
return selection === null ? ': null' : lexical.$isRangeSelection(selection) ? printRangeSelection(selection) : lexical.DEPRECATED_$isGridSelection(selection) ? printGridSelection(selection) : printObjectSelection(selection);
|
|
217
223
|
});
|
|
218
|
-
|
|
224
|
+
res += '\n selection' + selectionString;
|
|
225
|
+
res += '\n\n editor:';
|
|
226
|
+
res += `\n └ namespace ${editorConfig.namespace}`;
|
|
227
|
+
|
|
228
|
+
if (compositionKey !== null) {
|
|
229
|
+
res += `\n └ compositionKey ${compositionKey}`;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
res += `\n └ editable ${String(editable)}`;
|
|
233
|
+
return res;
|
|
219
234
|
}
|
|
220
235
|
|
|
221
236
|
function visitTree(currentNode, visitor, indent = []) {
|
|
@@ -237,7 +252,7 @@ function normalize(text) {
|
|
|
237
252
|
|
|
238
253
|
function printNode(node) {
|
|
239
254
|
if (lexical.$isTextNode(node)) {
|
|
240
|
-
const text = node.getTextContent(
|
|
255
|
+
const text = node.getTextContent();
|
|
241
256
|
const title = text.length === 0 ? '(empty)' : `"${normalize(text)}"`;
|
|
242
257
|
const properties = printAllTextNodeProperties(node);
|
|
243
258
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
@@ -253,7 +268,7 @@ function printNode(node) {
|
|
|
253
268
|
|
|
254
269
|
const FORMAT_PREDICATES = [node => node.hasFormat('bold') && 'Bold', node => node.hasFormat('code') && 'Code', node => node.hasFormat('italic') && 'Italic', node => node.hasFormat('strikethrough') && 'Strikethrough', node => node.hasFormat('subscript') && 'Subscript', node => node.hasFormat('superscript') && 'Superscript', node => node.hasFormat('underline') && 'Underline'];
|
|
255
270
|
const DETAIL_PREDICATES = [node => node.isDirectionless() && 'Directionless', node => node.isUnmergeable() && 'Unmergeable'];
|
|
256
|
-
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'
|
|
271
|
+
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'];
|
|
257
272
|
|
|
258
273
|
function printAllTextNodeProperties(node) {
|
|
259
274
|
return [printFormatProperties(node), printDetailProperties(node), printModeProperties(node)].filter(Boolean).join(', ');
|
|
@@ -353,7 +368,7 @@ function printSelectedCharsLine({
|
|
|
353
368
|
function $getSelectionStartEnd(node, selection) {
|
|
354
369
|
const anchor = selection.anchor;
|
|
355
370
|
const focus = selection.focus;
|
|
356
|
-
const textContent = node.getTextContent(
|
|
371
|
+
const textContent = node.getTextContent();
|
|
357
372
|
const textLength = textContent.length;
|
|
358
373
|
let start = -1;
|
|
359
374
|
let end = -1; // Only one node is being selected.
|