@lexical/react 0.7.7 → 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 +23 -108
- package/LexicalTypeaheadMenuPlugin.prod.js +18 -18
- 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,212 +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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
parentNode.scrollIntoView(false);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
parentNode.scrollTop = target.offsetTop - target.clientHeight;
|
|
72
|
-
} else {
|
|
73
|
-
target.scrollIntoView(false);
|
|
74
|
-
}
|
|
58
|
+
if (!container) return;
|
|
59
|
+
const typeaheadContainerNode = container.querySelector('.typeahead-popover');
|
|
60
|
+
if (!typeaheadContainerNode) return;
|
|
61
|
+
const typeaheadRect = typeaheadContainerNode.getBoundingClientRect();
|
|
62
|
+
if (typeaheadRect.top + typeaheadRect.height > window.innerHeight) {
|
|
63
|
+
typeaheadContainerNode.scrollIntoView({
|
|
64
|
+
block: 'center'
|
|
65
|
+
});
|
|
75
66
|
}
|
|
67
|
+
if (typeaheadRect.top < 0) {
|
|
68
|
+
typeaheadContainerNode.scrollIntoView({
|
|
69
|
+
block: 'center'
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
target.scrollIntoView({
|
|
73
|
+
block: 'nearest'
|
|
74
|
+
});
|
|
76
75
|
};
|
|
77
|
-
|
|
78
76
|
function getTextUpToAnchor(selection) {
|
|
79
77
|
const anchor = selection.anchor;
|
|
80
|
-
|
|
81
78
|
if (anchor.type !== 'text') {
|
|
82
79
|
return null;
|
|
83
80
|
}
|
|
84
|
-
|
|
85
81
|
const anchorNode = anchor.getNode();
|
|
86
|
-
|
|
87
82
|
if (!anchorNode.isSimpleText()) {
|
|
88
83
|
return null;
|
|
89
84
|
}
|
|
90
|
-
|
|
91
85
|
const anchorOffset = anchor.offset;
|
|
92
86
|
return anchorNode.getTextContent().slice(0, anchorOffset);
|
|
93
87
|
}
|
|
94
|
-
|
|
95
88
|
function tryToPositionRange(leadOffset, range) {
|
|
96
89
|
const domSelection = window.getSelection();
|
|
97
|
-
|
|
98
90
|
if (domSelection === null || !domSelection.isCollapsed) {
|
|
99
91
|
return false;
|
|
100
92
|
}
|
|
101
|
-
|
|
102
93
|
const anchorNode = domSelection.anchorNode;
|
|
103
94
|
const startOffset = leadOffset;
|
|
104
95
|
const endOffset = domSelection.anchorOffset;
|
|
105
|
-
|
|
106
96
|
if (anchorNode == null || endOffset == null) {
|
|
107
97
|
return false;
|
|
108
98
|
}
|
|
109
|
-
|
|
110
99
|
try {
|
|
111
100
|
range.setStart(anchorNode, startOffset);
|
|
112
101
|
range.setEnd(anchorNode, endOffset);
|
|
113
102
|
} catch (error) {
|
|
114
103
|
return false;
|
|
115
104
|
}
|
|
116
|
-
|
|
117
105
|
return true;
|
|
118
106
|
}
|
|
119
|
-
|
|
120
107
|
function getQueryTextForSearch(editor) {
|
|
121
108
|
let text = null;
|
|
122
109
|
editor.getEditorState().read(() => {
|
|
123
110
|
const selection = lexical.$getSelection();
|
|
124
|
-
|
|
125
111
|
if (!lexical.$isRangeSelection(selection)) {
|
|
126
112
|
return;
|
|
127
113
|
}
|
|
128
|
-
|
|
129
114
|
text = getTextUpToAnchor(selection);
|
|
130
115
|
});
|
|
131
116
|
return text;
|
|
132
117
|
}
|
|
118
|
+
|
|
133
119
|
/**
|
|
134
120
|
* Walk backwards along user input and forward through entity title to try
|
|
135
121
|
* and replace more of the user's text with entity.
|
|
136
122
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
123
|
function getFullMatchOffset(documentText, entryText, offset) {
|
|
140
124
|
let triggerOffset = offset;
|
|
141
|
-
|
|
142
125
|
for (let i = triggerOffset; i <= entryText.length; i++) {
|
|
143
126
|
if (documentText.substr(-i) === entryText.substr(0, i)) {
|
|
144
127
|
triggerOffset = i;
|
|
145
128
|
}
|
|
146
129
|
}
|
|
147
|
-
|
|
148
130
|
return triggerOffset;
|
|
149
131
|
}
|
|
132
|
+
|
|
150
133
|
/**
|
|
151
134
|
* Split Lexical TextNode and return a new TextNode only containing matched text.
|
|
152
135
|
* Common use cases include: removing the node, replacing with a new node.
|
|
153
136
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
137
|
function splitNodeContainingQuery(editor, match) {
|
|
157
138
|
const selection = lexical.$getSelection();
|
|
158
|
-
|
|
159
139
|
if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
160
140
|
return null;
|
|
161
141
|
}
|
|
162
|
-
|
|
163
142
|
const anchor = selection.anchor;
|
|
164
|
-
|
|
165
143
|
if (anchor.type !== 'text') {
|
|
166
144
|
return null;
|
|
167
145
|
}
|
|
168
|
-
|
|
169
146
|
const anchorNode = anchor.getNode();
|
|
170
|
-
|
|
171
147
|
if (!anchorNode.isSimpleText()) {
|
|
172
148
|
return null;
|
|
173
149
|
}
|
|
174
|
-
|
|
175
150
|
const selectionOffset = anchor.offset;
|
|
176
151
|
const textContent = anchorNode.getTextContent().slice(0, selectionOffset);
|
|
177
152
|
const characterOffset = match.replaceableString.length;
|
|
178
153
|
const queryOffset = getFullMatchOffset(textContent, match.matchingString, characterOffset);
|
|
179
154
|
const startOffset = selectionOffset - queryOffset;
|
|
180
|
-
|
|
181
155
|
if (startOffset < 0) {
|
|
182
156
|
return null;
|
|
183
157
|
}
|
|
184
|
-
|
|
185
158
|
let newNode;
|
|
186
|
-
|
|
187
159
|
if (startOffset === 0) {
|
|
188
160
|
[newNode] = anchorNode.splitText(selectionOffset);
|
|
189
161
|
} else {
|
|
190
162
|
[, newNode] = anchorNode.splitText(startOffset, selectionOffset);
|
|
191
163
|
}
|
|
192
|
-
|
|
193
164
|
return newNode;
|
|
194
165
|
}
|
|
195
|
-
|
|
196
166
|
function isSelectionOnEntityBoundary(editor, offset) {
|
|
197
167
|
if (offset !== 0) {
|
|
198
168
|
return false;
|
|
199
169
|
}
|
|
200
|
-
|
|
201
170
|
return editor.getEditorState().read(() => {
|
|
202
171
|
const selection = lexical.$getSelection();
|
|
203
|
-
|
|
204
172
|
if (lexical.$isRangeSelection(selection)) {
|
|
205
173
|
const anchor = selection.anchor;
|
|
206
174
|
const anchorNode = anchor.getNode();
|
|
207
175
|
const prevSibling = anchorNode.getPreviousSibling();
|
|
208
176
|
return lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity();
|
|
209
177
|
}
|
|
210
|
-
|
|
211
178
|
return false;
|
|
212
179
|
});
|
|
213
180
|
}
|
|
214
|
-
|
|
215
181
|
function startTransition(callback) {
|
|
216
182
|
if (React.startTransition) {
|
|
217
183
|
React.startTransition(callback);
|
|
218
184
|
} else {
|
|
219
185
|
callback();
|
|
220
186
|
}
|
|
221
|
-
}
|
|
222
|
-
|
|
187
|
+
}
|
|
223
188
|
|
|
189
|
+
// Got from https://stackoverflow.com/a/42543908/2013580
|
|
224
190
|
function getScrollParent(element, includeHidden) {
|
|
225
191
|
let style = getComputedStyle(element);
|
|
226
192
|
const excludeStaticParent = style.position === 'absolute';
|
|
227
193
|
const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
|
|
228
|
-
|
|
229
194
|
if (style.position === 'fixed') {
|
|
230
195
|
return document.body;
|
|
231
196
|
}
|
|
232
|
-
|
|
233
197
|
for (let parent = element; parent = parent.parentElement;) {
|
|
234
198
|
style = getComputedStyle(parent);
|
|
235
|
-
|
|
236
199
|
if (excludeStaticParent && style.position === 'static') {
|
|
237
200
|
continue;
|
|
238
201
|
}
|
|
239
|
-
|
|
240
202
|
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
|
|
241
203
|
return parent;
|
|
242
204
|
}
|
|
243
205
|
}
|
|
244
|
-
|
|
245
206
|
return document.body;
|
|
246
207
|
}
|
|
247
|
-
|
|
248
208
|
function isTriggerVisibleInNearestScrollContainer(targetElement, containerElement) {
|
|
249
209
|
const tRect = targetElement.getBoundingClientRect();
|
|
250
210
|
const cRect = containerElement.getBoundingClientRect();
|
|
251
211
|
return tRect.top > cRect.top && tRect.top < cRect.bottom;
|
|
252
|
-
}
|
|
253
|
-
|
|
212
|
+
}
|
|
254
213
|
|
|
214
|
+
// Reposition the menu on scroll, window resize, and element resize.
|
|
255
215
|
function useDynamicPositioning(resolution, targetElement, onReposition, onVisibilityChange) {
|
|
256
216
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
257
217
|
React.useEffect(() => {
|
|
@@ -260,7 +220,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
260
220
|
const rootScrollParent = rootElement != null ? getScrollParent(rootElement, false) : document.body;
|
|
261
221
|
let ticking = false;
|
|
262
222
|
let previousIsInView = isTriggerVisibleInNearestScrollContainer(targetElement, rootScrollParent);
|
|
263
|
-
|
|
264
223
|
const handleScroll = function () {
|
|
265
224
|
if (!ticking) {
|
|
266
225
|
window.requestAnimationFrame(function () {
|
|
@@ -269,18 +228,14 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
269
228
|
});
|
|
270
229
|
ticking = true;
|
|
271
230
|
}
|
|
272
|
-
|
|
273
231
|
const isInView = isTriggerVisibleInNearestScrollContainer(targetElement, rootScrollParent);
|
|
274
|
-
|
|
275
232
|
if (isInView !== previousIsInView) {
|
|
276
233
|
previousIsInView = isInView;
|
|
277
|
-
|
|
278
234
|
if (onVisibilityChange != null) {
|
|
279
235
|
onVisibilityChange(isInView);
|
|
280
236
|
}
|
|
281
237
|
}
|
|
282
238
|
};
|
|
283
|
-
|
|
284
239
|
const resizeObserver = new ResizeObserver(onReposition);
|
|
285
240
|
window.addEventListener('resize', onReposition);
|
|
286
241
|
document.addEventListener('scroll', handleScroll, {
|
|
@@ -297,7 +252,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
297
252
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
298
253
|
}
|
|
299
254
|
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
300
|
-
|
|
301
255
|
function LexicalPopoverMenu({
|
|
302
256
|
close,
|
|
303
257
|
editor,
|
|
@@ -319,7 +273,6 @@ function LexicalPopoverMenu({
|
|
|
319
273
|
}, [close, editor, resolution.match, onSelectOption]);
|
|
320
274
|
const updateSelectedIndex = React.useCallback(index => {
|
|
321
275
|
const rootElem = editor.getRootElement();
|
|
322
|
-
|
|
323
276
|
if (rootElem !== null) {
|
|
324
277
|
rootElem.setAttribute('aria-activedescendant', 'typeahead-item-' + index);
|
|
325
278
|
setHighlightedIndex(index);
|
|
@@ -328,7 +281,6 @@ function LexicalPopoverMenu({
|
|
|
328
281
|
React.useEffect(() => {
|
|
329
282
|
return () => {
|
|
330
283
|
const rootElem = editor.getRootElement();
|
|
331
|
-
|
|
332
284
|
if (rootElem !== null) {
|
|
333
285
|
rootElem.removeAttribute('aria-activedescendant');
|
|
334
286
|
}
|
|
@@ -349,47 +301,38 @@ function LexicalPopoverMenu({
|
|
|
349
301
|
scrollIntoViewIfNeeded(option.ref.current);
|
|
350
302
|
return true;
|
|
351
303
|
}
|
|
352
|
-
|
|
353
304
|
return false;
|
|
354
305
|
}, lexical.COMMAND_PRIORITY_LOW));
|
|
355
306
|
}, [editor, updateSelectedIndex]);
|
|
356
307
|
React.useEffect(() => {
|
|
357
308
|
return utils.mergeRegister(editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, payload => {
|
|
358
309
|
const event = payload;
|
|
359
|
-
|
|
360
310
|
if (options !== null && options.length && selectedIndex !== null) {
|
|
361
311
|
const newSelectedIndex = selectedIndex !== options.length - 1 ? selectedIndex + 1 : 0;
|
|
362
312
|
updateSelectedIndex(newSelectedIndex);
|
|
363
313
|
const option = options[newSelectedIndex];
|
|
364
|
-
|
|
365
314
|
if (option.ref != null && option.ref.current) {
|
|
366
315
|
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
367
316
|
index: newSelectedIndex,
|
|
368
317
|
option
|
|
369
318
|
});
|
|
370
319
|
}
|
|
371
|
-
|
|
372
320
|
event.preventDefault();
|
|
373
321
|
event.stopImmediatePropagation();
|
|
374
322
|
}
|
|
375
|
-
|
|
376
323
|
return true;
|
|
377
324
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, payload => {
|
|
378
325
|
const event = payload;
|
|
379
|
-
|
|
380
326
|
if (options !== null && options.length && selectedIndex !== null) {
|
|
381
327
|
const newSelectedIndex = selectedIndex !== 0 ? selectedIndex - 1 : options.length - 1;
|
|
382
328
|
updateSelectedIndex(newSelectedIndex);
|
|
383
329
|
const option = options[newSelectedIndex];
|
|
384
|
-
|
|
385
330
|
if (option.ref != null && option.ref.current) {
|
|
386
331
|
scrollIntoViewIfNeeded(option.ref.current);
|
|
387
332
|
}
|
|
388
|
-
|
|
389
333
|
event.preventDefault();
|
|
390
334
|
event.stopImmediatePropagation();
|
|
391
335
|
}
|
|
392
|
-
|
|
393
336
|
return true;
|
|
394
337
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, payload => {
|
|
395
338
|
const event = payload;
|
|
@@ -399,11 +342,9 @@ function LexicalPopoverMenu({
|
|
|
399
342
|
return true;
|
|
400
343
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_TAB_COMMAND, payload => {
|
|
401
344
|
const event = payload;
|
|
402
|
-
|
|
403
345
|
if (options === null || selectedIndex === null || options[selectedIndex] == null) {
|
|
404
346
|
return false;
|
|
405
347
|
}
|
|
406
|
-
|
|
407
348
|
event.preventDefault();
|
|
408
349
|
event.stopImmediatePropagation();
|
|
409
350
|
selectOptionAndCleanUp(options[selectedIndex]);
|
|
@@ -412,12 +353,10 @@ function LexicalPopoverMenu({
|
|
|
412
353
|
if (options === null || selectedIndex === null || options[selectedIndex] == null) {
|
|
413
354
|
return false;
|
|
414
355
|
}
|
|
415
|
-
|
|
416
356
|
if (event !== null) {
|
|
417
357
|
event.preventDefault();
|
|
418
358
|
event.stopImmediatePropagation();
|
|
419
359
|
}
|
|
420
|
-
|
|
421
360
|
selectOptionAndCleanUp(options[selectedIndex]);
|
|
422
361
|
return true;
|
|
423
362
|
}, lexical.COMMAND_PRIORITY_LOW));
|
|
@@ -430,7 +369,6 @@ function LexicalPopoverMenu({
|
|
|
430
369
|
}), [selectOptionAndCleanUp, selectedIndex, options]);
|
|
431
370
|
return menuRenderFn(anchorElementRef, listItemProps, resolution.match.matchingString);
|
|
432
371
|
}
|
|
433
|
-
|
|
434
372
|
function useBasicTypeaheadTriggerMatch(trigger, {
|
|
435
373
|
minLength = 1,
|
|
436
374
|
maxLength = 75
|
|
@@ -439,11 +377,9 @@ function useBasicTypeaheadTriggerMatch(trigger, {
|
|
|
439
377
|
const validChars = '[^' + trigger + PUNCTUATION + '\\s]';
|
|
440
378
|
const TypeaheadTriggerRegex = new RegExp('(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + '){0,' + maxLength + '})' + ')$');
|
|
441
379
|
const match = TypeaheadTriggerRegex.exec(text);
|
|
442
|
-
|
|
443
380
|
if (match !== null) {
|
|
444
381
|
const maybeLeadingWhitespace = match[1];
|
|
445
382
|
const matchingString = match[3];
|
|
446
|
-
|
|
447
383
|
if (matchingString.length >= minLength) {
|
|
448
384
|
return {
|
|
449
385
|
leadOffset: match.index + maybeLeadingWhitespace.length,
|
|
@@ -452,18 +388,15 @@ function useBasicTypeaheadTriggerMatch(trigger, {
|
|
|
452
388
|
};
|
|
453
389
|
}
|
|
454
390
|
}
|
|
455
|
-
|
|
456
391
|
return null;
|
|
457
392
|
}, [maxLength, minLength, trigger]);
|
|
458
393
|
}
|
|
459
|
-
|
|
460
394
|
function useMenuAnchorRef(resolution, setResolution, className) {
|
|
461
395
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
462
396
|
const anchorElementRef = React.useRef(document.createElement('div'));
|
|
463
397
|
const positionMenu = React.useCallback(() => {
|
|
464
398
|
const rootElement = editor.getRootElement();
|
|
465
399
|
const containerDiv = anchorElementRef.current;
|
|
466
|
-
|
|
467
400
|
if (rootElement !== null && resolution !== null) {
|
|
468
401
|
const {
|
|
469
402
|
left,
|
|
@@ -475,12 +408,10 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
475
408
|
containerDiv.style.left = `${left + window.pageXOffset}px`;
|
|
476
409
|
containerDiv.style.height = `${height}px`;
|
|
477
410
|
containerDiv.style.width = `${width}px`;
|
|
478
|
-
|
|
479
411
|
if (!containerDiv.isConnected) {
|
|
480
412
|
if (className != null) {
|
|
481
413
|
containerDiv.className = className;
|
|
482
414
|
}
|
|
483
|
-
|
|
484
415
|
containerDiv.setAttribute('aria-label', 'Typeahead menu');
|
|
485
416
|
containerDiv.setAttribute('id', 'typeahead-menu');
|
|
486
417
|
containerDiv.setAttribute('role', 'listbox');
|
|
@@ -488,23 +419,19 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
488
419
|
containerDiv.style.position = 'absolute';
|
|
489
420
|
document.body.append(containerDiv);
|
|
490
421
|
}
|
|
491
|
-
|
|
492
422
|
anchorElementRef.current = containerDiv;
|
|
493
423
|
rootElement.setAttribute('aria-controls', 'typeahead-menu');
|
|
494
424
|
}
|
|
495
425
|
}, [editor, resolution, className]);
|
|
496
426
|
React.useEffect(() => {
|
|
497
427
|
const rootElement = editor.getRootElement();
|
|
498
|
-
|
|
499
428
|
if (resolution !== null) {
|
|
500
429
|
positionMenu();
|
|
501
430
|
return () => {
|
|
502
431
|
if (rootElement !== null) {
|
|
503
432
|
rootElement.removeAttribute('aria-controls');
|
|
504
433
|
}
|
|
505
|
-
|
|
506
434
|
const containerDiv = anchorElementRef.current;
|
|
507
|
-
|
|
508
435
|
if (containerDiv !== null && containerDiv.isConnected) {
|
|
509
436
|
containerDiv.remove();
|
|
510
437
|
}
|
|
@@ -521,7 +448,6 @@ function useMenuAnchorRef(resolution, setResolution, className) {
|
|
|
521
448
|
useDynamicPositioning(resolution, anchorElementRef.current, positionMenu, onVisibilityChange);
|
|
522
449
|
return anchorElementRef;
|
|
523
450
|
}
|
|
524
|
-
|
|
525
451
|
function LexicalTypeaheadMenuPlugin({
|
|
526
452
|
options,
|
|
527
453
|
onQueryChange,
|
|
@@ -537,14 +463,12 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
537
463
|
const anchorElementRef = useMenuAnchorRef(resolution, setResolution, anchorClassName);
|
|
538
464
|
const closeTypeahead = React.useCallback(() => {
|
|
539
465
|
setResolution(null);
|
|
540
|
-
|
|
541
466
|
if (onClose != null && resolution !== null) {
|
|
542
467
|
onClose();
|
|
543
468
|
}
|
|
544
469
|
}, [onClose, resolution]);
|
|
545
470
|
const openTypeahead = React.useCallback(res => {
|
|
546
471
|
setResolution(res);
|
|
547
|
-
|
|
548
472
|
if (onOpen != null && resolution === null) {
|
|
549
473
|
onOpen(res);
|
|
550
474
|
}
|
|
@@ -555,18 +479,14 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
555
479
|
const range = document.createRange();
|
|
556
480
|
const selection = lexical.$getSelection();
|
|
557
481
|
const text = getQueryTextForSearch(editor);
|
|
558
|
-
|
|
559
482
|
if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed() || text === null || range === null) {
|
|
560
483
|
closeTypeahead();
|
|
561
484
|
return;
|
|
562
485
|
}
|
|
563
|
-
|
|
564
486
|
const match = triggerFn(text, editor);
|
|
565
487
|
onQueryChange(match ? match.matchingString : null);
|
|
566
|
-
|
|
567
488
|
if (match !== null && !isSelectionOnEntityBoundary(editor, match.leadOffset)) {
|
|
568
489
|
const isRangePositioned = tryToPositionRange(match.leadOffset, range);
|
|
569
|
-
|
|
570
490
|
if (isRangePositioned !== null) {
|
|
571
491
|
startTransition(() => openTypeahead({
|
|
572
492
|
getRect: () => range.getBoundingClientRect(),
|
|
@@ -575,11 +495,9 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
575
495
|
return;
|
|
576
496
|
}
|
|
577
497
|
}
|
|
578
|
-
|
|
579
498
|
closeTypeahead();
|
|
580
499
|
});
|
|
581
500
|
};
|
|
582
|
-
|
|
583
501
|
const removeUpdateListener = editor.registerUpdateListener(updateListener);
|
|
584
502
|
return () => {
|
|
585
503
|
removeUpdateListener();
|
|
@@ -609,14 +527,12 @@ function LexicalNodeMenuPlugin({
|
|
|
609
527
|
const anchorElementRef = useMenuAnchorRef(resolution, setResolution, anchorClassName);
|
|
610
528
|
const closeNodeMenu = React.useCallback(() => {
|
|
611
529
|
setResolution(null);
|
|
612
|
-
|
|
613
530
|
if (onClose != null && resolution !== null) {
|
|
614
531
|
onClose();
|
|
615
532
|
}
|
|
616
533
|
}, [onClose, resolution]);
|
|
617
534
|
const openNodeMenu = React.useCallback(res => {
|
|
618
535
|
setResolution(res);
|
|
619
|
-
|
|
620
536
|
if (onOpen != null && resolution === null) {
|
|
621
537
|
onOpen(res);
|
|
622
538
|
}
|
|
@@ -626,7 +542,6 @@ function LexicalNodeMenuPlugin({
|
|
|
626
542
|
editor.update(() => {
|
|
627
543
|
const node = lexical.$getNodeByKey(nodeKey);
|
|
628
544
|
const domElement = editor.getElementByKey(nodeKey);
|
|
629
|
-
|
|
630
545
|
if (node != null && domElement != null) {
|
|
631
546
|
const text = node.getTextContent();
|
|
632
547
|
startTransition(() => openNodeMenu({
|
|
@@ -4,23 +4,23 @@
|
|
|
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 k=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/utils"),w=require("lexical"),x=require("react"),y="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?x.useLayoutEffect:x.useEffect;class z{constructor(
|
|
8
|
-
let A=
|
|
9
|
-
function C(
|
|
10
|
-
function D(
|
|
11
|
-
function E(
|
|
12
|
-
function I(
|
|
13
|
-
function K(
|
|
14
|
-
l)}}},[a,f,e,c
|
|
15
|
-
function M({close:
|
|
7
|
+
'use strict';var k=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/utils"),w=require("lexical"),x=require("react"),y="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?x.useLayoutEffect:x.useEffect;class z{constructor(c){this.key=c;this.ref={current:null};this.setRefElement=this.setRefElement.bind(this)}setRefElement(c){this.ref={current:c}}}
|
|
8
|
+
let A=c=>{var a=document.getElementById("typeahead-menu");if(a&&(a=a.querySelector(".typeahead-popover"))){var b=a.getBoundingClientRect();b.top+b.height>window.innerHeight&&a.scrollIntoView({block:"center"});0>b.top&&a.scrollIntoView({block:"center"});c.scrollIntoView({block:"nearest"})}};function B(c,a){var b=window.getSelection();if(null===b||!b.isCollapsed)return!1;let e=b.anchorNode;b=b.anchorOffset;if(null==e||null==b)return!1;try{a.setStart(e,c),a.setEnd(e,b)}catch(f){return!1}return!0}
|
|
9
|
+
function C(c){let a=null;c.getEditorState().read(()=>{var b=w.$getSelection();if(w.$isRangeSelection(b)){var e=b.anchor;"text"!==e.type?a=null:(b=e.getNode(),b.isSimpleText()?(e=e.offset,a=b.getTextContent().slice(0,e)):a=null)}});return a}
|
|
10
|
+
function D(c,a){c=w.$getSelection();if(!w.$isRangeSelection(c)||!c.isCollapsed())return null;var b=c.anchor;if("text"!==b.type)return null;c=b.getNode();if(!c.isSimpleText())return null;b=b.offset;let e=c.getTextContent().slice(0,b);var f=a.matchingString;a=a.replaceableString.length;for(let p=a;p<=f.length;p++)e.substr(-p)===f.substr(0,p)&&(a=p);a=b-a;if(0>a)return null;let q;0===a?[q]=c.splitText(b):[,q]=c.splitText(a,b);return q}
|
|
11
|
+
function E(c,a){return 0!==a?!1:c.getEditorState().read(()=>{var b=w.$getSelection();return w.$isRangeSelection(b)?(b=b.anchor.getNode().getPreviousSibling(),w.$isTextNode(b)&&b.isTextEntity()):!1})}function F(c){x.startTransition?x.startTransition(c):c()}
|
|
12
|
+
function I(c,a){let b=getComputedStyle(c),e="absolute"===b.position;a=a?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===b.position)return document.body;for(;c=c.parentElement;)if(b=getComputedStyle(c),(!e||"static"!==b.position)&&a.test(b.overflow+b.overflowY+b.overflowX))return c;return document.body}function J(c,a){c=c.getBoundingClientRect();a=a.getBoundingClientRect();return c.top>a.top&&c.top<a.bottom}
|
|
13
|
+
function K(c,a,b,e){let [f]=k.useLexicalComposerContext();x.useEffect(()=>{if(null!=a&&null!=c){let q=f.getRootElement(),p=null!=q?I(q,!1):document.body,g=!1,d=J(a,p),l=function(){g||(window.requestAnimationFrame(function(){b();g=!1}),g=!0);const t=J(a,p);t!==d&&(d=t,null!=e&&e(t))},r=new ResizeObserver(b);window.addEventListener("resize",b);document.addEventListener("scroll",l,{capture:!0,passive:!0});r.observe(a);return()=>{r.unobserve(a);window.removeEventListener("resize",b);document.removeEventListener("scroll",
|
|
14
|
+
l)}}},[a,f,e,b,c])}let L=w.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");
|
|
15
|
+
function M({close:c,editor:a,anchorElementRef:b,resolution:e,options:f,menuRenderFn:q,onSelectOption:p}){let [g,d]=x.useState(null);x.useEffect(()=>{d(0)},[e.match.matchingString]);let l=x.useCallback(h=>{a.update(()=>{const m=D(a,e.match);p(h,m,c,e.match.matchingString)})},[c,a,e.match,p]),r=x.useCallback(h=>{const m=a.getRootElement();null!==m&&(m.setAttribute("aria-activedescendant","typeahead-item-"+h),d(h))},[a]);x.useEffect(()=>()=>{let h=a.getRootElement();null!==h&&h.removeAttribute("aria-activedescendant")},
|
|
16
16
|
[a]);y(()=>{null===f?d(null):null===g&&r(0)},[f,g,r]);x.useEffect(()=>n.mergeRegister(a.registerCommand(L,({option:h})=>h.ref&&null!=h.ref.current?(A(h.ref.current),!0):!1,w.COMMAND_PRIORITY_LOW)),[a,r]);x.useEffect(()=>n.mergeRegister(a.registerCommand(w.KEY_ARROW_DOWN_COMMAND,h=>{if(null!==f&&f.length&&null!==g){let m=g!==f.length-1?g+1:0;r(m);let u=f[m];null!=u.ref&&u.ref.current&&a.dispatchCommand(L,{index:m,option:u});h.preventDefault();h.stopImmediatePropagation()}return!0},w.COMMAND_PRIORITY_LOW),
|
|
17
|
-
a.registerCommand(w.KEY_ARROW_UP_COMMAND,h=>{if(null!==f&&f.length&&null!==g){var m=0!==g?g-1:f.length-1;r(m);m=f[m];null!=m.ref&&m.ref.current&&A(m.ref.current);h.preventDefault();h.stopImmediatePropagation()}return!0},w.COMMAND_PRIORITY_LOW),a.registerCommand(w.KEY_ESCAPE_COMMAND,h=>{h.preventDefault();h.stopImmediatePropagation();
|
|
18
|
-
l(f[g]);return!0},w.COMMAND_PRIORITY_LOW),a.registerCommand(w.KEY_ENTER_COMMAND,h=>{if(null===f||null===g||null==f[g])return!1;null!==h&&(h.preventDefault(),h.stopImmediatePropagation());l(f[g]);return!0},w.COMMAND_PRIORITY_LOW)),[l,
|
|
19
|
-
function N(
|
|
20
|
-
"listbox"),d.style.display="block",d.style.position="absolute",document.body.append(d));f.current=d;g.setAttribute("aria-controls","typeahead-menu")}},[e,b
|
|
21
|
-
exports.LexicalNodeMenuPlugin=function({options:
|
|
22
|
-
match:{leadOffset:u.length,matchingString:u,replaceableString:u}}))}}):null==a&&null!=d&&r()},[r,g,a,t,d]);return null===d||null===g?null:x.createElement(M,{close:r,resolution:d,editor:g,anchorElementRef:p,options:
|
|
23
|
-
exports.LexicalTypeaheadMenuPlugin=function({options:
|
|
24
|
-
G.isCollapsed()&&null!==H&&null!==u){var v=p(H,d);a(v?v.matchingString:null);null===v||E(d,v.leadOffset)||null===B(v.leadOffset,u)?t():F(()=>h({getRect:()=>u.getBoundingClientRect(),match:v}))}else t()})});return()=>{m()}},[d,p,a,l,t,h]);return null===l||null===d?null:x.createElement(M,{close:t,resolution:l,editor:d,anchorElementRef:g,options:
|
|
25
|
-
exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND=L;exports.TypeaheadOption=z;exports.getScrollParent=I;exports.useBasicTypeaheadTriggerMatch=function(
|
|
17
|
+
a.registerCommand(w.KEY_ARROW_UP_COMMAND,h=>{if(null!==f&&f.length&&null!==g){var m=0!==g?g-1:f.length-1;r(m);m=f[m];null!=m.ref&&m.ref.current&&A(m.ref.current);h.preventDefault();h.stopImmediatePropagation()}return!0},w.COMMAND_PRIORITY_LOW),a.registerCommand(w.KEY_ESCAPE_COMMAND,h=>{h.preventDefault();h.stopImmediatePropagation();c();return!0},w.COMMAND_PRIORITY_LOW),a.registerCommand(w.KEY_TAB_COMMAND,h=>{if(null===f||null===g||null==f[g])return!1;h.preventDefault();h.stopImmediatePropagation();
|
|
18
|
+
l(f[g]);return!0},w.COMMAND_PRIORITY_LOW),a.registerCommand(w.KEY_ENTER_COMMAND,h=>{if(null===f||null===g||null==f[g])return!1;null!==h&&(h.preventDefault(),h.stopImmediatePropagation());l(f[g]);return!0},w.COMMAND_PRIORITY_LOW)),[l,c,a,f,g,r]);let t=x.useMemo(()=>({options:f,selectOptionAndCleanUp:l,selectedIndex:g,setHighlightedIndex:d}),[l,g,f]);return q(b,t,e.match.matchingString)}
|
|
19
|
+
function N(c,a,b){let [e]=k.useLexicalComposerContext(),f=x.useRef(document.createElement("div")),q=x.useCallback(()=>{const g=e.getRootElement(),d=f.current;if(null!==g&&null!==c){const {left:l,top:r,width:t,height:h}=c.getRect();d.style.top=`${r+window.pageYOffset}px`;d.style.left=`${l+window.pageXOffset}px`;d.style.height=`${h}px`;d.style.width=`${t}px`;d.isConnected||(null!=b&&(d.className=b),d.setAttribute("aria-label","Typeahead menu"),d.setAttribute("id","typeahead-menu"),d.setAttribute("role",
|
|
20
|
+
"listbox"),d.style.display="block",d.style.position="absolute",document.body.append(d));f.current=d;g.setAttribute("aria-controls","typeahead-menu")}},[e,c,b]);x.useEffect(()=>{let g=e.getRootElement();if(null!==c)return q(),()=>{null!==g&&g.removeAttribute("aria-controls");let d=f.current;null!==d&&d.isConnected&&d.remove()}},[e,q,c]);let p=x.useCallback(g=>{null!==c&&(g||a(null))},[c,a]);K(c,f.current,q,p);return f}
|
|
21
|
+
exports.LexicalNodeMenuPlugin=function({options:c,nodeKey:a,onClose:b,onOpen:e,onSelectOption:f,menuRenderFn:q,anchorClassName:p}){let [g]=k.useLexicalComposerContext(),[d,l]=x.useState(null);p=N(d,l,p);let r=x.useCallback(()=>{l(null);null!=b&&null!==d&&b()},[b,d]),t=x.useCallback(h=>{l(h);null!=e&&null===d&&e(h)},[e,d]);x.useEffect(()=>{a&&null==d?g.update(()=>{let h=w.$getNodeByKey(a),m=g.getElementByKey(a);if(null!=h&&null!=m){let u=h.getTextContent();F(()=>t({getRect:()=>m.getBoundingClientRect(),
|
|
22
|
+
match:{leadOffset:u.length,matchingString:u,replaceableString:u}}))}}):null==a&&null!=d&&r()},[r,g,a,t,d]);return null===d||null===g?null:x.createElement(M,{close:r,resolution:d,editor:g,anchorElementRef:p,options:c,menuRenderFn:q,onSelectOption:f})};
|
|
23
|
+
exports.LexicalTypeaheadMenuPlugin=function({options:c,onQueryChange:a,onSelectOption:b,onOpen:e,onClose:f,menuRenderFn:q,triggerFn:p,anchorClassName:g}){let [d]=k.useLexicalComposerContext(),[l,r]=x.useState(null);g=N(l,r,g);let t=x.useCallback(()=>{r(null);null!=f&&null!==l&&f()},[f,l]),h=x.useCallback(m=>{r(m);null!=e&&null===l&&e(m)},[e,l]);x.useEffect(()=>{let m=d.registerUpdateListener(()=>{d.getEditorState().read(()=>{const u=document.createRange(),G=w.$getSelection(),H=C(d);if(w.$isRangeSelection(G)&&
|
|
24
|
+
G.isCollapsed()&&null!==H&&null!==u){var v=p(H,d);a(v?v.matchingString:null);null===v||E(d,v.leadOffset)||null===B(v.leadOffset,u)?t():F(()=>h({getRect:()=>u.getBoundingClientRect(),match:v}))}else t()})});return()=>{m()}},[d,p,a,l,t,h]);return null===l||null===d?null:x.createElement(M,{close:t,resolution:l,editor:d,anchorElementRef:g,options:c,menuRenderFn:q,onSelectOption:b})};exports.PUNCTUATION="\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";
|
|
25
|
+
exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND=L;exports.TypeaheadOption=z;exports.getScrollParent=I;exports.useBasicTypeaheadTriggerMatch=function(c,{minLength:a=1,maxLength:b=75}){return x.useCallback(e=>{e=(new RegExp("(^|\\s|\\()(["+c+"]((?:[^"+(c+"\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;\\s]){0,")+b+"}))$")).exec(e);if(null!==e){let f=e[1],q=e[3];if(q.length>=a)return{leadOffset:e.index+f.length,matchingString:q,replaceableString:e[2]}}return null},[b,a,c])};
|
|
26
26
|
exports.useDynamicPositioning=K
|
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
|
}
|