@lexical/react 0.7.8 → 0.7.9
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.dev.js +3 -4
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +1 -3
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +7 -39
- package/DEPRECATED_useLexicalEditor.dev.js +1 -3
- package/DEPRECATED_useLexicalPlainText.dev.js +4 -1
- package/DEPRECATED_useLexicalRichText.dev.js +4 -1
- package/LexicalAutoEmbedPlugin.dev.js +0 -11
- package/LexicalAutoFocusPlugin.dev.js +0 -1
- package/LexicalAutoLinkPlugin.dev.js +7 -50
- package/LexicalBlockWithAlignableContents.dev.js +0 -11
- package/LexicalCharacterLimitPlugin.dev.js +7 -46
- package/LexicalCheckListPlugin.dev.js +10 -48
- package/LexicalClearEditorPlugin.dev.js +1 -1
- package/LexicalCollaborationContext.dev.js +0 -3
- package/LexicalCollaborationPlugin.dev.js +6 -34
- package/LexicalComposer.dev.js +6 -10
- package/LexicalComposerContext.dev.js +0 -6
- package/LexicalContentEditable.dev.js +3 -1
- package/LexicalDecoratorBlockNode.dev.js +0 -5
- package/LexicalHashtagPlugin.dev.js +73 -43
- package/LexicalHorizontalRuleNode.dev.js +0 -22
- package/LexicalHorizontalRulePlugin.dev.js +0 -4
- package/LexicalLinkPlugin.dev.js +4 -10
- package/LexicalListPlugin.dev.js +0 -2
- package/LexicalMarkdownShortcutPlugin.dev.js +2 -2
- package/LexicalNestedComposer.dev.js +6 -11
- package/LexicalNodeEventPlugin.dev.js +5 -3
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +8 -12
- package/LexicalRichTextPlugin.dev.js +8 -12
- package/LexicalTabIndentationPlugin.dev.js +1 -3
- package/LexicalTableOfContents__EXPERIMENTAL.dev.js +5 -33
- package/LexicalTablePlugin.dev.js +5 -19
- package/LexicalTreeView.dev.js +12 -61
- package/LexicalTypeaheadMenuPlugin.dev.js +7 -96
- package/package.json +19 -19
- package/useLexicalEditable.dev.js +1 -5
- package/useLexicalIsTextContentEmpty.dev.js +1 -0
- package/useLexicalNodeSelection.dev.js +0 -7
- package/useLexicalSubscription.dev.js +1 -3
|
@@ -18,6 +18,7 @@ var React = require('react');
|
|
|
18
18
|
* LICENSE file in the root directory of this source tree.
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
|
+
|
|
21
22
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -46,216 +47,171 @@ class TypeaheadOption {
|
|
|
46
47
|
};
|
|
47
48
|
this.setRefElement = this.setRefElement.bind(this);
|
|
48
49
|
}
|
|
49
|
-
|
|
50
50
|
setRefElement(element) {
|
|
51
51
|
this.ref = {
|
|
52
52
|
current: element
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
|
|
56
55
|
}
|
|
57
|
-
|
|
58
56
|
const scrollIntoViewIfNeeded = target => {
|
|
59
57
|
const container = document.getElementById('typeahead-menu');
|
|
60
58
|
if (!container) return;
|
|
61
59
|
const typeaheadContainerNode = container.querySelector('.typeahead-popover');
|
|
62
60
|
if (!typeaheadContainerNode) return;
|
|
63
61
|
const typeaheadRect = typeaheadContainerNode.getBoundingClientRect();
|
|
64
|
-
|
|
65
62
|
if (typeaheadRect.top + typeaheadRect.height > window.innerHeight) {
|
|
66
63
|
typeaheadContainerNode.scrollIntoView({
|
|
67
64
|
block: 'center'
|
|
68
65
|
});
|
|
69
66
|
}
|
|
70
|
-
|
|
71
67
|
if (typeaheadRect.top < 0) {
|
|
72
68
|
typeaheadContainerNode.scrollIntoView({
|
|
73
69
|
block: 'center'
|
|
74
70
|
});
|
|
75
71
|
}
|
|
76
|
-
|
|
77
72
|
target.scrollIntoView({
|
|
78
73
|
block: 'nearest'
|
|
79
74
|
});
|
|
80
75
|
};
|
|
81
|
-
|
|
82
76
|
function getTextUpToAnchor(selection) {
|
|
83
77
|
const anchor = selection.anchor;
|
|
84
|
-
|
|
85
78
|
if (anchor.type !== 'text') {
|
|
86
79
|
return null;
|
|
87
80
|
}
|
|
88
|
-
|
|
89
81
|
const anchorNode = anchor.getNode();
|
|
90
|
-
|
|
91
82
|
if (!anchorNode.isSimpleText()) {
|
|
92
83
|
return null;
|
|
93
84
|
}
|
|
94
|
-
|
|
95
85
|
const anchorOffset = anchor.offset;
|
|
96
86
|
return anchorNode.getTextContent().slice(0, anchorOffset);
|
|
97
87
|
}
|
|
98
|
-
|
|
99
88
|
function tryToPositionRange(leadOffset, range) {
|
|
100
89
|
const domSelection = window.getSelection();
|
|
101
|
-
|
|
102
90
|
if (domSelection === null || !domSelection.isCollapsed) {
|
|
103
91
|
return false;
|
|
104
92
|
}
|
|
105
|
-
|
|
106
93
|
const anchorNode = domSelection.anchorNode;
|
|
107
94
|
const startOffset = leadOffset;
|
|
108
95
|
const endOffset = domSelection.anchorOffset;
|
|
109
|
-
|
|
110
96
|
if (anchorNode == null || endOffset == null) {
|
|
111
97
|
return false;
|
|
112
98
|
}
|
|
113
|
-
|
|
114
99
|
try {
|
|
115
100
|
range.setStart(anchorNode, startOffset);
|
|
116
101
|
range.setEnd(anchorNode, endOffset);
|
|
117
102
|
} catch (error) {
|
|
118
103
|
return false;
|
|
119
104
|
}
|
|
120
|
-
|
|
121
105
|
return true;
|
|
122
106
|
}
|
|
123
|
-
|
|
124
107
|
function getQueryTextForSearch(editor) {
|
|
125
108
|
let text = null;
|
|
126
109
|
editor.getEditorState().read(() => {
|
|
127
110
|
const selection = lexical.$getSelection();
|
|
128
|
-
|
|
129
111
|
if (!lexical.$isRangeSelection(selection)) {
|
|
130
112
|
return;
|
|
131
113
|
}
|
|
132
|
-
|
|
133
114
|
text = getTextUpToAnchor(selection);
|
|
134
115
|
});
|
|
135
116
|
return text;
|
|
136
117
|
}
|
|
118
|
+
|
|
137
119
|
/**
|
|
138
120
|
* Walk backwards along user input and forward through entity title to try
|
|
139
121
|
* and replace more of the user's text with entity.
|
|
140
122
|
*/
|
|
141
|
-
|
|
142
|
-
|
|
143
123
|
function getFullMatchOffset(documentText, entryText, offset) {
|
|
144
124
|
let triggerOffset = offset;
|
|
145
|
-
|
|
146
125
|
for (let i = triggerOffset; i <= entryText.length; i++) {
|
|
147
126
|
if (documentText.substr(-i) === entryText.substr(0, i)) {
|
|
148
127
|
triggerOffset = i;
|
|
149
128
|
}
|
|
150
129
|
}
|
|
151
|
-
|
|
152
130
|
return triggerOffset;
|
|
153
131
|
}
|
|
132
|
+
|
|
154
133
|
/**
|
|
155
134
|
* Split Lexical TextNode and return a new TextNode only containing matched text.
|
|
156
135
|
* Common use cases include: removing the node, replacing with a new node.
|
|
157
136
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
137
|
function splitNodeContainingQuery(editor, match) {
|
|
161
138
|
const selection = lexical.$getSelection();
|
|
162
|
-
|
|
163
139
|
if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
164
140
|
return null;
|
|
165
141
|
}
|
|
166
|
-
|
|
167
142
|
const anchor = selection.anchor;
|
|
168
|
-
|
|
169
143
|
if (anchor.type !== 'text') {
|
|
170
144
|
return null;
|
|
171
145
|
}
|
|
172
|
-
|
|
173
146
|
const anchorNode = anchor.getNode();
|
|
174
|
-
|
|
175
147
|
if (!anchorNode.isSimpleText()) {
|
|
176
148
|
return null;
|
|
177
149
|
}
|
|
178
|
-
|
|
179
150
|
const selectionOffset = anchor.offset;
|
|
180
151
|
const textContent = anchorNode.getTextContent().slice(0, selectionOffset);
|
|
181
152
|
const characterOffset = match.replaceableString.length;
|
|
182
153
|
const queryOffset = getFullMatchOffset(textContent, match.matchingString, characterOffset);
|
|
183
154
|
const startOffset = selectionOffset - queryOffset;
|
|
184
|
-
|
|
185
155
|
if (startOffset < 0) {
|
|
186
156
|
return null;
|
|
187
157
|
}
|
|
188
|
-
|
|
189
158
|
let newNode;
|
|
190
|
-
|
|
191
159
|
if (startOffset === 0) {
|
|
192
160
|
[newNode] = anchorNode.splitText(selectionOffset);
|
|
193
161
|
} else {
|
|
194
162
|
[, newNode] = anchorNode.splitText(startOffset, selectionOffset);
|
|
195
163
|
}
|
|
196
|
-
|
|
197
164
|
return newNode;
|
|
198
165
|
}
|
|
199
|
-
|
|
200
166
|
function isSelectionOnEntityBoundary(editor, offset) {
|
|
201
167
|
if (offset !== 0) {
|
|
202
168
|
return false;
|
|
203
169
|
}
|
|
204
|
-
|
|
205
170
|
return editor.getEditorState().read(() => {
|
|
206
171
|
const selection = lexical.$getSelection();
|
|
207
|
-
|
|
208
172
|
if (lexical.$isRangeSelection(selection)) {
|
|
209
173
|
const anchor = selection.anchor;
|
|
210
174
|
const anchorNode = anchor.getNode();
|
|
211
175
|
const prevSibling = anchorNode.getPreviousSibling();
|
|
212
176
|
return lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity();
|
|
213
177
|
}
|
|
214
|
-
|
|
215
178
|
return false;
|
|
216
179
|
});
|
|
217
180
|
}
|
|
218
|
-
|
|
219
181
|
function startTransition(callback) {
|
|
220
182
|
if (React.startTransition) {
|
|
221
183
|
React.startTransition(callback);
|
|
222
184
|
} else {
|
|
223
185
|
callback();
|
|
224
186
|
}
|
|
225
|
-
}
|
|
226
|
-
|
|
187
|
+
}
|
|
227
188
|
|
|
189
|
+
// Got from https://stackoverflow.com/a/42543908/2013580
|
|
228
190
|
function getScrollParent(element, includeHidden) {
|
|
229
191
|
let style = getComputedStyle(element);
|
|
230
192
|
const excludeStaticParent = style.position === 'absolute';
|
|
231
193
|
const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
|
|
232
|
-
|
|
233
194
|
if (style.position === 'fixed') {
|
|
234
195
|
return document.body;
|
|
235
196
|
}
|
|
236
|
-
|
|
237
197
|
for (let parent = element; parent = parent.parentElement;) {
|
|
238
198
|
style = getComputedStyle(parent);
|
|
239
|
-
|
|
240
199
|
if (excludeStaticParent && style.position === 'static') {
|
|
241
200
|
continue;
|
|
242
201
|
}
|
|
243
|
-
|
|
244
202
|
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
|
|
245
203
|
return parent;
|
|
246
204
|
}
|
|
247
205
|
}
|
|
248
|
-
|
|
249
206
|
return document.body;
|
|
250
207
|
}
|
|
251
|
-
|
|
252
208
|
function isTriggerVisibleInNearestScrollContainer(targetElement, containerElement) {
|
|
253
209
|
const tRect = targetElement.getBoundingClientRect();
|
|
254
210
|
const cRect = containerElement.getBoundingClientRect();
|
|
255
211
|
return tRect.top > cRect.top && tRect.top < cRect.bottom;
|
|
256
|
-
}
|
|
257
|
-
|
|
212
|
+
}
|
|
258
213
|
|
|
214
|
+
// Reposition the menu on scroll, window resize, and element resize.
|
|
259
215
|
function useDynamicPositioning(resolution, targetElement, onReposition, onVisibilityChange) {
|
|
260
216
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
261
217
|
React.useEffect(() => {
|
|
@@ -264,7 +220,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
264
220
|
const rootScrollParent = rootElement != null ? getScrollParent(rootElement, false) : document.body;
|
|
265
221
|
let ticking = false;
|
|
266
222
|
let previousIsInView = isTriggerVisibleInNearestScrollContainer(targetElement, rootScrollParent);
|
|
267
|
-
|
|
268
223
|
const handleScroll = function () {
|
|
269
224
|
if (!ticking) {
|
|
270
225
|
window.requestAnimationFrame(function () {
|
|
@@ -273,18 +228,14 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
273
228
|
});
|
|
274
229
|
ticking = true;
|
|
275
230
|
}
|
|
276
|
-
|
|
277
231
|
const isInView = isTriggerVisibleInNearestScrollContainer(targetElement, rootScrollParent);
|
|
278
|
-
|
|
279
232
|
if (isInView !== previousIsInView) {
|
|
280
233
|
previousIsInView = isInView;
|
|
281
|
-
|
|
282
234
|
if (onVisibilityChange != null) {
|
|
283
235
|
onVisibilityChange(isInView);
|
|
284
236
|
}
|
|
285
237
|
}
|
|
286
238
|
};
|
|
287
|
-
|
|
288
239
|
const resizeObserver = new ResizeObserver(onReposition);
|
|
289
240
|
window.addEventListener('resize', onReposition);
|
|
290
241
|
document.addEventListener('scroll', handleScroll, {
|
|
@@ -301,7 +252,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
301
252
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
302
253
|
}
|
|
303
254
|
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
304
|
-
|
|
305
255
|
function LexicalPopoverMenu({
|
|
306
256
|
close,
|
|
307
257
|
editor,
|
|
@@ -323,7 +273,6 @@ function LexicalPopoverMenu({
|
|
|
323
273
|
}, [close, editor, resolution.match, onSelectOption]);
|
|
324
274
|
const updateSelectedIndex = React.useCallback(index => {
|
|
325
275
|
const rootElem = editor.getRootElement();
|
|
326
|
-
|
|
327
276
|
if (rootElem !== null) {
|
|
328
277
|
rootElem.setAttribute('aria-activedescendant', 'typeahead-item-' + index);
|
|
329
278
|
setHighlightedIndex(index);
|
|
@@ -332,7 +281,6 @@ function LexicalPopoverMenu({
|
|
|
332
281
|
React.useEffect(() => {
|
|
333
282
|
return () => {
|
|
334
283
|
const rootElem = editor.getRootElement();
|
|
335
|
-
|
|
336
284
|
if (rootElem !== null) {
|
|
337
285
|
rootElem.removeAttribute('aria-activedescendant');
|
|
338
286
|
}
|
|
@@ -353,47 +301,38 @@ function LexicalPopoverMenu({
|
|
|
353
301
|
scrollIntoViewIfNeeded(option.ref.current);
|
|
354
302
|
return true;
|
|
355
303
|
}
|
|
356
|
-
|
|
357
304
|
return false;
|
|
358
305
|
}, lexical.COMMAND_PRIORITY_LOW));
|
|
359
306
|
}, [editor, updateSelectedIndex]);
|
|
360
307
|
React.useEffect(() => {
|
|
361
308
|
return utils.mergeRegister(editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, payload => {
|
|
362
309
|
const event = payload;
|
|
363
|
-
|
|
364
310
|
if (options !== null && options.length && selectedIndex !== null) {
|
|
365
311
|
const newSelectedIndex = selectedIndex !== options.length - 1 ? selectedIndex + 1 : 0;
|
|
366
312
|
updateSelectedIndex(newSelectedIndex);
|
|
367
313
|
const option = options[newSelectedIndex];
|
|
368
|
-
|
|
369
314
|
if (option.ref != null && option.ref.current) {
|
|
370
315
|
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
371
316
|
index: newSelectedIndex,
|
|
372
317
|
option
|
|
373
318
|
});
|
|
374
319
|
}
|
|
375
|
-
|
|
376
320
|
event.preventDefault();
|
|
377
321
|
event.stopImmediatePropagation();
|
|
378
322
|
}
|
|
379
|
-
|
|
380
323
|
return true;
|
|
381
324
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, payload => {
|
|
382
325
|
const event = payload;
|
|
383
|
-
|
|
384
326
|
if (options !== null && options.length && selectedIndex !== null) {
|
|
385
327
|
const newSelectedIndex = selectedIndex !== 0 ? selectedIndex - 1 : options.length - 1;
|
|
386
328
|
updateSelectedIndex(newSelectedIndex);
|
|
387
329
|
const option = options[newSelectedIndex];
|
|
388
|
-
|
|
389
330
|
if (option.ref != null && option.ref.current) {
|
|
390
331
|
scrollIntoViewIfNeeded(option.ref.current);
|
|
391
332
|
}
|
|
392
|
-
|
|
393
333
|
event.preventDefault();
|
|
394
334
|
event.stopImmediatePropagation();
|
|
395
335
|
}
|
|
396
|
-
|
|
397
336
|
return true;
|
|
398
337
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, payload => {
|
|
399
338
|
const event = payload;
|
|
@@ -403,11 +342,9 @@ function LexicalPopoverMenu({
|
|
|
403
342
|
return true;
|
|
404
343
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_TAB_COMMAND, payload => {
|
|
405
344
|
const event = payload;
|
|
406
|
-
|
|
407
345
|
if (options === null || selectedIndex === null || options[selectedIndex] == null) {
|
|
408
346
|
return false;
|
|
409
347
|
}
|
|
410
|
-
|
|
411
348
|
event.preventDefault();
|
|
412
349
|
event.stopImmediatePropagation();
|
|
413
350
|
selectOptionAndCleanUp(options[selectedIndex]);
|
|
@@ -416,12 +353,10 @@ function LexicalPopoverMenu({
|
|
|
416
353
|
if (options === null || selectedIndex === null || options[selectedIndex] == null) {
|
|
417
354
|
return false;
|
|
418
355
|
}
|
|
419
|
-
|
|
420
356
|
if (event !== null) {
|
|
421
357
|
event.preventDefault();
|
|
422
358
|
event.stopImmediatePropagation();
|
|
423
359
|
}
|
|
424
|
-
|
|
425
360
|
selectOptionAndCleanUp(options[selectedIndex]);
|
|
426
361
|
return true;
|
|
427
362
|
}, lexical.COMMAND_PRIORITY_LOW));
|
|
@@ -434,7 +369,6 @@ function LexicalPopoverMenu({
|
|
|
434
369
|
}), [selectOptionAndCleanUp, selectedIndex, options]);
|
|
435
370
|
return menuRenderFn(anchorElementRef, listItemProps, resolution.match.matchingString);
|
|
436
371
|
}
|
|
437
|
-
|
|
438
372
|
function useBasicTypeaheadTriggerMatch(trigger, {
|
|
439
373
|
minLength = 1,
|
|
440
374
|
maxLength = 75
|
|
@@ -443,11 +377,9 @@ function useBasicTypeaheadTriggerMatch(trigger, {
|
|
|
443
377
|
const validChars = '[^' + trigger + PUNCTUATION + '\\s]';
|
|
444
378
|
const TypeaheadTriggerRegex = new RegExp('(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + '){0,' + maxLength + '})' + ')$');
|
|
445
379
|
const match = TypeaheadTriggerRegex.exec(text);
|
|
446
|
-
|
|
447
380
|
if (match !== null) {
|
|
448
381
|
const maybeLeadingWhitespace = match[1];
|
|
449
382
|
const matchingString = match[3];
|
|
450
|
-
|
|
451
383
|
if (matchingString.length >= minLength) {
|
|
452
384
|
return {
|
|
453
385
|
leadOffset: match.index + maybeLeadingWhitespace.length,
|
|
@@ -456,18 +388,15 @@ function useBasicTypeaheadTriggerMatch(trigger, {
|
|
|
456
388
|
};
|
|
457
389
|
}
|
|
458
390
|
}
|
|
459
|
-
|
|
460
391
|
return null;
|
|
461
392
|
}, [maxLength, minLength, trigger]);
|
|
462
393
|
}
|
|
463
|
-
|
|
464
394
|
function useMenuAnchorRef(resolution, setResolution, className) {
|
|
465
395
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
466
396
|
const anchorElementRef = React.useRef(document.createElement('div'));
|
|
467
397
|
const positionMenu = React.useCallback(() => {
|
|
468
398
|
const rootElement = editor.getRootElement();
|
|
469
399
|
const containerDiv = anchorElementRef.current;
|
|
470
|
-
|
|
471
400
|
if (rootElement !== null && resolution !== null) {
|
|
472
401
|
const {
|
|
473
402
|
left,
|
|
@@ -479,12 +408,10 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
479
408
|
containerDiv.style.left = `${left + window.pageXOffset}px`;
|
|
480
409
|
containerDiv.style.height = `${height}px`;
|
|
481
410
|
containerDiv.style.width = `${width}px`;
|
|
482
|
-
|
|
483
411
|
if (!containerDiv.isConnected) {
|
|
484
412
|
if (className != null) {
|
|
485
413
|
containerDiv.className = className;
|
|
486
414
|
}
|
|
487
|
-
|
|
488
415
|
containerDiv.setAttribute('aria-label', 'Typeahead menu');
|
|
489
416
|
containerDiv.setAttribute('id', 'typeahead-menu');
|
|
490
417
|
containerDiv.setAttribute('role', 'listbox');
|
|
@@ -492,23 +419,19 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
492
419
|
containerDiv.style.position = 'absolute';
|
|
493
420
|
document.body.append(containerDiv);
|
|
494
421
|
}
|
|
495
|
-
|
|
496
422
|
anchorElementRef.current = containerDiv;
|
|
497
423
|
rootElement.setAttribute('aria-controls', 'typeahead-menu');
|
|
498
424
|
}
|
|
499
425
|
}, [editor, resolution, className]);
|
|
500
426
|
React.useEffect(() => {
|
|
501
427
|
const rootElement = editor.getRootElement();
|
|
502
|
-
|
|
503
428
|
if (resolution !== null) {
|
|
504
429
|
positionMenu();
|
|
505
430
|
return () => {
|
|
506
431
|
if (rootElement !== null) {
|
|
507
432
|
rootElement.removeAttribute('aria-controls');
|
|
508
433
|
}
|
|
509
|
-
|
|
510
434
|
const containerDiv = anchorElementRef.current;
|
|
511
|
-
|
|
512
435
|
if (containerDiv !== null && containerDiv.isConnected) {
|
|
513
436
|
containerDiv.remove();
|
|
514
437
|
}
|
|
@@ -525,7 +448,6 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
525
448
|
useDynamicPositioning(resolution, anchorElementRef.current, positionMenu, onVisibilityChange);
|
|
526
449
|
return anchorElementRef;
|
|
527
450
|
}
|
|
528
|
-
|
|
529
451
|
function LexicalTypeaheadMenuPlugin({
|
|
530
452
|
options,
|
|
531
453
|
onQueryChange,
|
|
@@ -541,14 +463,12 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
541
463
|
const anchorElementRef = useMenuAnchorRef(resolution, setResolution, anchorClassName);
|
|
542
464
|
const closeTypeahead = React.useCallback(() => {
|
|
543
465
|
setResolution(null);
|
|
544
|
-
|
|
545
466
|
if (onClose != null && resolution !== null) {
|
|
546
467
|
onClose();
|
|
547
468
|
}
|
|
548
469
|
}, [onClose, resolution]);
|
|
549
470
|
const openTypeahead = React.useCallback(res => {
|
|
550
471
|
setResolution(res);
|
|
551
|
-
|
|
552
472
|
if (onOpen != null && resolution === null) {
|
|
553
473
|
onOpen(res);
|
|
554
474
|
}
|
|
@@ -559,18 +479,14 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
559
479
|
const range = document.createRange();
|
|
560
480
|
const selection = lexical.$getSelection();
|
|
561
481
|
const text = getQueryTextForSearch(editor);
|
|
562
|
-
|
|
563
482
|
if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed() || text === null || range === null) {
|
|
564
483
|
closeTypeahead();
|
|
565
484
|
return;
|
|
566
485
|
}
|
|
567
|
-
|
|
568
486
|
const match = triggerFn(text, editor);
|
|
569
487
|
onQueryChange(match ? match.matchingString : null);
|
|
570
|
-
|
|
571
488
|
if (match !== null && !isSelectionOnEntityBoundary(editor, match.leadOffset)) {
|
|
572
489
|
const isRangePositioned = tryToPositionRange(match.leadOffset, range);
|
|
573
|
-
|
|
574
490
|
if (isRangePositioned !== null) {
|
|
575
491
|
startTransition(() => openTypeahead({
|
|
576
492
|
getRect: () => range.getBoundingClientRect(),
|
|
@@ -579,11 +495,9 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
579
495
|
return;
|
|
580
496
|
}
|
|
581
497
|
}
|
|
582
|
-
|
|
583
498
|
closeTypeahead();
|
|
584
499
|
});
|
|
585
500
|
};
|
|
586
|
-
|
|
587
501
|
const removeUpdateListener = editor.registerUpdateListener(updateListener);
|
|
588
502
|
return () => {
|
|
589
503
|
removeUpdateListener();
|
|
@@ -613,14 +527,12 @@ function LexicalNodeMenuPlugin({
|
|
|
613
527
|
const anchorElementRef = useMenuAnchorRef(resolution, setResolution, anchorClassName);
|
|
614
528
|
const closeNodeMenu = React.useCallback(() => {
|
|
615
529
|
setResolution(null);
|
|
616
|
-
|
|
617
530
|
if (onClose != null && resolution !== null) {
|
|
618
531
|
onClose();
|
|
619
532
|
}
|
|
620
533
|
}, [onClose, resolution]);
|
|
621
534
|
const openNodeMenu = React.useCallback(res => {
|
|
622
535
|
setResolution(res);
|
|
623
|
-
|
|
624
536
|
if (onOpen != null && resolution === null) {
|
|
625
537
|
onOpen(res);
|
|
626
538
|
}
|
|
@@ -630,7 +542,6 @@ function LexicalNodeMenuPlugin({
|
|
|
630
542
|
editor.update(() => {
|
|
631
543
|
const node = lexical.$getNodeByKey(nodeKey);
|
|
632
544
|
const domElement = editor.getElementByKey(nodeKey);
|
|
633
|
-
|
|
634
545
|
if (node != null && domElement != null) {
|
|
635
546
|
const text = node.getTextContent();
|
|
636
547
|
startTransition(() => openNodeMenu({
|
package/package.json
CHANGED
|
@@ -8,29 +8,29 @@
|
|
|
8
8
|
"rich-text"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.7.
|
|
11
|
+
"version": "0.7.9",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@lexical/clipboard": "0.7.
|
|
14
|
-
"@lexical/code": "0.7.
|
|
15
|
-
"@lexical/dragon": "0.7.
|
|
16
|
-
"@lexical/hashtag": "0.7.
|
|
17
|
-
"@lexical/history": "0.7.
|
|
18
|
-
"@lexical/link": "0.7.
|
|
19
|
-
"@lexical/list": "0.7.
|
|
20
|
-
"@lexical/mark": "0.7.
|
|
21
|
-
"@lexical/markdown": "0.7.
|
|
22
|
-
"@lexical/overflow": "0.7.
|
|
23
|
-
"@lexical/plain-text": "0.7.
|
|
24
|
-
"@lexical/rich-text": "0.7.
|
|
25
|
-
"@lexical/selection": "0.7.
|
|
26
|
-
"@lexical/table": "0.7.
|
|
27
|
-
"@lexical/text": "0.7.
|
|
28
|
-
"@lexical/utils": "0.7.
|
|
29
|
-
"@lexical/yjs": "0.7.
|
|
13
|
+
"@lexical/clipboard": "0.7.9",
|
|
14
|
+
"@lexical/code": "0.7.9",
|
|
15
|
+
"@lexical/dragon": "0.7.9",
|
|
16
|
+
"@lexical/hashtag": "0.7.9",
|
|
17
|
+
"@lexical/history": "0.7.9",
|
|
18
|
+
"@lexical/link": "0.7.9",
|
|
19
|
+
"@lexical/list": "0.7.9",
|
|
20
|
+
"@lexical/mark": "0.7.9",
|
|
21
|
+
"@lexical/markdown": "0.7.9",
|
|
22
|
+
"@lexical/overflow": "0.7.9",
|
|
23
|
+
"@lexical/plain-text": "0.7.9",
|
|
24
|
+
"@lexical/rich-text": "0.7.9",
|
|
25
|
+
"@lexical/selection": "0.7.9",
|
|
26
|
+
"@lexical/table": "0.7.9",
|
|
27
|
+
"@lexical/text": "0.7.9",
|
|
28
|
+
"@lexical/utils": "0.7.9",
|
|
29
|
+
"@lexical/yjs": "0.7.9",
|
|
30
30
|
"react-error-boundary": "^3.1.4"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"lexical": "0.7.
|
|
33
|
+
"lexical": "0.7.9",
|
|
34
34
|
"react": ">=17.x",
|
|
35
35
|
"react-dom": ">=17.x"
|
|
36
36
|
},
|
|
@@ -16,6 +16,7 @@ var react = require('react');
|
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
19
|
+
|
|
19
20
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -35,7 +36,6 @@ var useLayoutEffect = useLayoutEffectImpl;
|
|
|
35
36
|
* LICENSE file in the root directory of this source tree.
|
|
36
37
|
*
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
39
|
/**
|
|
40
40
|
* Shortcut to Lexical subscriptions when values are used for render.
|
|
41
41
|
*/
|
|
@@ -50,12 +50,10 @@ function useLexicalSubscription(subscription) {
|
|
|
50
50
|
subscribe
|
|
51
51
|
} = initializedSubscription;
|
|
52
52
|
const currentValue = initialValueFn();
|
|
53
|
-
|
|
54
53
|
if (valueRef.current !== currentValue) {
|
|
55
54
|
valueRef.current = currentValue;
|
|
56
55
|
setValue(currentValue);
|
|
57
56
|
}
|
|
58
|
-
|
|
59
57
|
return subscribe(newValue => {
|
|
60
58
|
valueRef.current = newValue;
|
|
61
59
|
setValue(newValue);
|
|
@@ -71,7 +69,6 @@ function useLexicalSubscription(subscription) {
|
|
|
71
69
|
* LICENSE file in the root directory of this source tree.
|
|
72
70
|
*
|
|
73
71
|
*/
|
|
74
|
-
|
|
75
72
|
function subscription(editor) {
|
|
76
73
|
return {
|
|
77
74
|
initialValueFn: () => editor.isEditable(),
|
|
@@ -80,7 +77,6 @@ function subscription(editor) {
|
|
|
80
77
|
}
|
|
81
78
|
};
|
|
82
79
|
}
|
|
83
|
-
|
|
84
80
|
function useLexicalEditable() {
|
|
85
81
|
return useLexicalSubscription(subscription);
|
|
86
82
|
}
|
|
@@ -16,6 +16,7 @@ var react = require('react');
|
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
19
|
+
|
|
19
20
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -17,19 +17,15 @@ var react = require('react');
|
|
|
17
17
|
* LICENSE file in the root directory of this source tree.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
20
|
function isNodeSelected(editor, key) {
|
|
22
21
|
return editor.getEditorState().read(() => {
|
|
23
22
|
const node = lexical.$getNodeByKey(key);
|
|
24
|
-
|
|
25
23
|
if (node === null) {
|
|
26
24
|
return false;
|
|
27
25
|
}
|
|
28
|
-
|
|
29
26
|
return node.isSelected();
|
|
30
27
|
});
|
|
31
28
|
}
|
|
32
|
-
|
|
33
29
|
function useLexicalNodeSelection(key) {
|
|
34
30
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
35
31
|
const [isSelected, setIsSelected] = react.useState(() => isNodeSelected(editor, key));
|
|
@@ -48,12 +44,10 @@ function useLexicalNodeSelection(key) {
|
|
|
48
44
|
const setSelected = react.useCallback(selected => {
|
|
49
45
|
editor.update(() => {
|
|
50
46
|
let selection = lexical.$getSelection();
|
|
51
|
-
|
|
52
47
|
if (!lexical.$isNodeSelection(selection)) {
|
|
53
48
|
selection = lexical.$createNodeSelection();
|
|
54
49
|
lexical.$setSelection(selection);
|
|
55
50
|
}
|
|
56
|
-
|
|
57
51
|
if (selected) {
|
|
58
52
|
selection.add(key);
|
|
59
53
|
} else {
|
|
@@ -64,7 +58,6 @@ function useLexicalNodeSelection(key) {
|
|
|
64
58
|
const clearSelected = react.useCallback(() => {
|
|
65
59
|
editor.update(() => {
|
|
66
60
|
const selection = lexical.$getSelection();
|
|
67
|
-
|
|
68
61
|
if (lexical.$isNodeSelection(selection)) {
|
|
69
62
|
selection.clear();
|
|
70
63
|
}
|
|
@@ -16,6 +16,7 @@ var react = require('react');
|
|
|
16
16
|
* LICENSE file in the root directory of this source tree.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
19
|
+
|
|
19
20
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -35,7 +36,6 @@ var useLayoutEffect = useLayoutEffectImpl;
|
|
|
35
36
|
* LICENSE file in the root directory of this source tree.
|
|
36
37
|
*
|
|
37
38
|
*/
|
|
38
|
-
|
|
39
39
|
/**
|
|
40
40
|
* Shortcut to Lexical subscriptions when values are used for render.
|
|
41
41
|
*/
|
|
@@ -50,12 +50,10 @@ function useLexicalSubscription(subscription) {
|
|
|
50
50
|
subscribe
|
|
51
51
|
} = initializedSubscription;
|
|
52
52
|
const currentValue = initialValueFn();
|
|
53
|
-
|
|
54
53
|
if (valueRef.current !== currentValue) {
|
|
55
54
|
valueRef.current = currentValue;
|
|
56
55
|
setValue(currentValue);
|
|
57
56
|
}
|
|
58
|
-
|
|
59
57
|
return subscribe(newValue => {
|
|
60
58
|
valueRef.current = newValue;
|
|
61
59
|
setValue(newValue);
|