@lexical/react 0.38.3-nightly.20251113.0 → 0.38.3-nightly.20251114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalAutoEmbedPlugin.d.ts +2 -3
- package/LexicalAutoEmbedPlugin.dev.js +0 -2
- package/LexicalAutoEmbedPlugin.dev.mjs +0 -2
- package/LexicalAutoEmbedPlugin.js.flow +0 -2
- package/LexicalAutoEmbedPlugin.prod.js +1 -1
- package/LexicalAutoEmbedPlugin.prod.mjs +1 -1
- package/LexicalNodeMenuPlugin.d.ts +3 -4
- package/LexicalNodeMenuPlugin.dev.js +49 -10
- package/LexicalNodeMenuPlugin.dev.mjs +51 -12
- package/LexicalNodeMenuPlugin.js.flow +0 -12
- package/LexicalNodeMenuPlugin.prod.js +1 -1
- package/LexicalNodeMenuPlugin.prod.mjs +1 -1
- package/LexicalTypeaheadMenuPlugin.d.ts +3 -4
- package/LexicalTypeaheadMenuPlugin.dev.js +52 -10
- package/LexicalTypeaheadMenuPlugin.dev.mjs +54 -12
- package/LexicalTypeaheadMenuPlugin.js.flow +0 -12
- package/LexicalTypeaheadMenuPlugin.prod.js +1 -1
- package/LexicalTypeaheadMenuPlugin.prod.mjs +1 -1
- package/package.json +18 -48
- package/shared/LexicalMenu.d.ts +4 -10
- package/LexicalContextMenuPlugin.d.ts +0 -36
- package/LexicalContextMenuPlugin.dev.js +0 -524
- package/LexicalContextMenuPlugin.dev.mjs +0 -509
- package/LexicalContextMenuPlugin.js +0 -11
- package/LexicalContextMenuPlugin.mjs +0 -13
- package/LexicalContextMenuPlugin.node.mjs +0 -11
- package/LexicalContextMenuPlugin.prod.js +0 -9
- package/LexicalContextMenuPlugin.prod.mjs +0 -9
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { CommandListenerPriority, LexicalNode } from 'lexical';
|
|
9
9
|
import type { JSX } from 'react';
|
|
10
|
-
import { MenuOption
|
|
10
|
+
import { MenuOption } from '@lexical/react/LexicalNodeMenuPlugin';
|
|
11
11
|
import { LexicalCommand, LexicalEditor } from 'lexical';
|
|
12
12
|
export type EmbedMatchResult<TEmbedMatchResult = unknown> = {
|
|
13
13
|
url: string;
|
|
@@ -32,8 +32,7 @@ type LexicalAutoEmbedPluginProps<TEmbedConfig extends EmbedConfig> = {
|
|
|
32
32
|
embedConfigs: Array<TEmbedConfig>;
|
|
33
33
|
onOpenEmbedModalForConfig: (embedConfig: TEmbedConfig) => void;
|
|
34
34
|
getMenuOptions: (activeEmbedConfig: TEmbedConfig, embedFn: () => void, dismissFn: () => void) => Array<AutoEmbedOption>;
|
|
35
|
-
menuRenderFn: MenuRenderFn<AutoEmbedOption>;
|
|
36
35
|
menuCommandPriority?: CommandListenerPriority;
|
|
37
36
|
};
|
|
38
|
-
export declare function LexicalAutoEmbedPlugin<TEmbedConfig extends EmbedConfig>({ embedConfigs, onOpenEmbedModalForConfig, getMenuOptions,
|
|
37
|
+
export declare function LexicalAutoEmbedPlugin<TEmbedConfig extends EmbedConfig>({ embedConfigs, onOpenEmbedModalForConfig, getMenuOptions, menuCommandPriority, }: LexicalAutoEmbedPluginProps<TEmbedConfig>): JSX.Element | null;
|
|
39
38
|
export {};
|
|
@@ -39,7 +39,6 @@ function LexicalAutoEmbedPlugin({
|
|
|
39
39
|
embedConfigs,
|
|
40
40
|
onOpenEmbedModalForConfig,
|
|
41
41
|
getMenuOptions,
|
|
42
|
-
menuRenderFn,
|
|
43
42
|
menuCommandPriority = lexical.COMMAND_PRIORITY_LOW
|
|
44
43
|
}) {
|
|
45
44
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
@@ -135,7 +134,6 @@ function LexicalAutoEmbedPlugin({
|
|
|
135
134
|
onClose: reset,
|
|
136
135
|
onSelectOption: onSelectOption,
|
|
137
136
|
options: options,
|
|
138
|
-
menuRenderFn: menuRenderFn,
|
|
139
137
|
commandPriority: menuCommandPriority
|
|
140
138
|
}) : null;
|
|
141
139
|
}
|
|
@@ -37,7 +37,6 @@ function LexicalAutoEmbedPlugin({
|
|
|
37
37
|
embedConfigs,
|
|
38
38
|
onOpenEmbedModalForConfig,
|
|
39
39
|
getMenuOptions,
|
|
40
|
-
menuRenderFn,
|
|
41
40
|
menuCommandPriority = COMMAND_PRIORITY_LOW
|
|
42
41
|
}) {
|
|
43
42
|
const [editor] = useLexicalComposerContext();
|
|
@@ -133,7 +132,6 @@ function LexicalAutoEmbedPlugin({
|
|
|
133
132
|
onClose: reset,
|
|
134
133
|
onSelectOption: onSelectOption,
|
|
135
134
|
options: options,
|
|
136
|
-
menuRenderFn: menuRenderFn,
|
|
137
135
|
commandPriority: menuCommandPriority
|
|
138
136
|
}) : null;
|
|
139
137
|
}
|
|
@@ -13,7 +13,6 @@ import {MenuOption} from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
|
|
13
13
|
import type {LexicalCommand, LexicalEditor, NodeKey, TextNode} from 'lexical';
|
|
14
14
|
import * as React from 'react';
|
|
15
15
|
import {createCommand} from 'lexical';
|
|
16
|
-
import type {MenuRenderFn} from './LexicalTypeaheadMenuPlugin';
|
|
17
16
|
|
|
18
17
|
export type EmbedMatchResult = {
|
|
19
18
|
url: string,
|
|
@@ -43,7 +42,6 @@ type LexicalAutoEmbedPluginProps<TEmbedConfig> = {
|
|
|
43
42
|
embedFn: () => void,
|
|
44
43
|
dismissFn: () => void,
|
|
45
44
|
) => Array<AutoEmbedOption>,
|
|
46
|
-
menuRenderFn: MenuRenderFn<AutoEmbedOption>,
|
|
47
45
|
};
|
|
48
46
|
|
|
49
47
|
declare export class AutoEmbedOption extends MenuOption {
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/react/LexicalNodeMenuPlugin"),o=require("@lexical/utils"),i=require("lexical"),l=require("react"),r=require("react/jsx-runtime");const s=i.createCommand("INSERT_EMBED_COMMAND");class
|
|
9
|
+
"use strict";var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/react/LexicalNodeMenuPlugin"),o=require("@lexical/utils"),i=require("lexical"),l=require("react"),r=require("react/jsx-runtime");const s=i.createCommand("INSERT_EMBED_COMMAND");class a extends n.MenuOption{title;onSelect;constructor(e,t){super(e),this.title=e,this.onSelect=t.onSelect.bind(this)}}exports.AutoEmbedOption=a,exports.INSERT_EMBED_COMMAND=s,exports.LexicalAutoEmbedPlugin=function({embedConfigs:a,onOpenEmbedModalForConfig:u,getMenuOptions:c,menuCommandPriority:d=i.COMMAND_PRIORITY_LOW}){const[m]=t.useLexicalComposerContext(),[p,x]=l.useState(null),[C,f]=l.useState(null),M=l.useCallback(()=>{x(null),f(null)},[]),g=l.useCallback(async t=>{const n=m.getEditorState().read(function(){const n=i.$getNodeByKey(t);if(e.$isLinkNode(n))return n.getURL()});if(void 0!==n)for(const e of a){null!=await Promise.resolve(e.parseUrl(n))&&(f(e),x(t))}},[m,a]);l.useEffect(()=>o.mergeRegister(...[e.LinkNode,e.AutoLinkNode].map(e=>m.registerMutationListener(e,(...e)=>((e,{updateTags:t,dirtyLeaves:n})=>{for(const[o,l]of e)"created"===l&&t.has(i.PASTE_TAG)&&n.size<=3?g(o):o===p&&M()})(...e),{skipInitialization:!0}))),[g,m,a,p,M]),l.useEffect(()=>m.registerCommand(s,e=>{const t=a.find(({type:t})=>t===e);return!!t&&(u(t),!0)},i.COMMAND_PRIORITY_EDITOR),[m,a,u]);const E=l.useCallback(async function(){if(null!=C&&null!=p){const t=m.getEditorState().read(()=>{const t=i.$getNodeByKey(p);return e.$isLinkNode(t)?t:null});if(e.$isLinkNode(t)){const e=await Promise.resolve(C.parseUrl(t.__url));null!=e&&m.update(()=>{i.$getSelection()||t.selectEnd(),C.insertNode(m,e),t.isAttached()&&t.remove()})}}},[C,m,p]),N=l.useMemo(()=>null!=C&&null!=p?c(C,E,M):[],[C,E,c,p,M]),L=l.useCallback((e,t,n)=>{m.update(()=>{e.onSelect(t),n()})},[m]);return null!=p?r.jsx(n.LexicalNodeMenuPlugin,{nodeKey:p,onClose:M,onSelectOption:L,options:N,commandPriority:d}):null},exports.URL_MATCHER=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{$isLinkNode as
|
|
9
|
+
import{$isLinkNode as t,LinkNode as e,AutoLinkNode as o}from"@lexical/link";import{useLexicalComposerContext as n}from"@lexical/react/LexicalComposerContext";import{MenuOption as i,LexicalNodeMenuPlugin as r}from"@lexical/react/LexicalNodeMenuPlugin";import{mergeRegister as l}from"@lexical/utils";import{createCommand as s,$getNodeByKey as a,COMMAND_PRIORITY_EDITOR as c,$getSelection as u,COMMAND_PRIORITY_LOW as m,PASTE_TAG as d}from"lexical";import{useState as p,useCallback as f,useEffect as x,useMemo as g}from"react";import{jsx as w}from"react/jsx-runtime";const C=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/,S=s("INSERT_EMBED_COMMAND");class y extends i{title;onSelect;constructor(t,e){super(t),this.title=t,this.onSelect=e.onSelect.bind(this)}}function E({embedConfigs:i,onOpenEmbedModalForConfig:s,getMenuOptions:C,menuCommandPriority:y=m}){const[E]=n(),[M,h]=p(null),[_,v]=p(null),z=f(()=>{h(null),v(null)},[]),A=f(async e=>{const o=E.getEditorState().read(function(){const o=a(e);if(t(o))return o.getURL()});if(void 0!==o)for(const t of i){null!=await Promise.resolve(t.parseUrl(o))&&(v(t),h(e))}},[E,i]);x(()=>l(...[e,o].map(t=>E.registerMutationListener(t,(...t)=>((t,{updateTags:e,dirtyLeaves:o})=>{for(const[n,i]of t)"created"===i&&e.has(d)&&o.size<=3?A(n):n===M&&z()})(...t),{skipInitialization:!0}))),[A,E,i,M,z]),x(()=>E.registerCommand(S,t=>{const e=i.find(({type:e})=>e===t);return!!e&&(s(e),!0)},c),[E,i,s]);const L=f(async function(){if(null!=_&&null!=M){const e=E.getEditorState().read(()=>{const e=a(M);return t(e)?e:null});if(t(e)){const t=await Promise.resolve(_.parseUrl(e.__url));null!=t&&E.update(()=>{u()||e.selectEnd(),_.insertNode(E,t),e.isAttached()&&e.remove()})}}},[_,E,M]),P=g(()=>null!=_&&null!=M?C(_,L,z):[],[_,L,C,M,z]),b=f((t,e,o)=>{E.update(()=>{t.onSelect(e),o()})},[E]);return null!=M?w(r,{nodeKey:M,onClose:z,onSelectOption:b,options:P,commandPriority:y}):null}export{y as AutoEmbedOption,S as INSERT_EMBED_COMMAND,E as LexicalAutoEmbedPlugin,C as URL_MATCHER};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { MenuResolution } from './shared/LexicalMenu';
|
|
9
9
|
import type { JSX } from 'react';
|
|
10
10
|
import { CommandListenerPriority, NodeKey, TextNode } from 'lexical';
|
|
11
11
|
import { MenuOption } from './shared/LexicalMenu';
|
|
@@ -15,10 +15,9 @@ export type NodeMenuPluginProps<TOption extends MenuOption> = {
|
|
|
15
15
|
nodeKey: NodeKey | null;
|
|
16
16
|
onClose?: () => void;
|
|
17
17
|
onOpen?: (resolution: MenuResolution) => void;
|
|
18
|
-
menuRenderFn: MenuRenderFn<TOption>;
|
|
19
18
|
anchorClassName?: string;
|
|
20
19
|
commandPriority?: CommandListenerPriority;
|
|
21
20
|
parent?: HTMLElement;
|
|
22
21
|
};
|
|
23
|
-
export declare function LexicalNodeMenuPlugin<TOption extends MenuOption>({ options, nodeKey, onClose, onOpen, onSelectOption,
|
|
24
|
-
export { MenuOption,
|
|
22
|
+
export declare function LexicalNodeMenuPlugin<TOption extends MenuOption>({ options, nodeKey, onClose, onOpen, onSelectOption, anchorClassName, commandPriority, parent, }: NodeMenuPluginProps<TOption>): JSX.Element | null;
|
|
23
|
+
export { MenuOption, MenuResolution };
|
|
@@ -12,6 +12,7 @@ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
|
12
12
|
var lexical = require('lexical');
|
|
13
13
|
var React = require('react');
|
|
14
14
|
var utils = require('@lexical/utils');
|
|
15
|
+
var ReactDOM = require('react-dom');
|
|
15
16
|
var jsxRuntime = require('react/jsx-runtime');
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -70,6 +71,8 @@ const useLayoutEffectImpl = CAN_USE_DOM ? React.useLayoutEffect : React.useEffec
|
|
|
70
71
|
class MenuOption {
|
|
71
72
|
key;
|
|
72
73
|
ref;
|
|
74
|
+
icon;
|
|
75
|
+
title;
|
|
73
76
|
constructor(key) {
|
|
74
77
|
this.key = key;
|
|
75
78
|
this.ref = {
|
|
@@ -219,13 +222,38 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
219
222
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
220
223
|
}
|
|
221
224
|
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
225
|
+
function MenuItem({
|
|
226
|
+
index,
|
|
227
|
+
isSelected,
|
|
228
|
+
onClick,
|
|
229
|
+
onMouseEnter,
|
|
230
|
+
option
|
|
231
|
+
}) {
|
|
232
|
+
let className = 'item';
|
|
233
|
+
if (isSelected) {
|
|
234
|
+
className += ' selected';
|
|
235
|
+
}
|
|
236
|
+
return /*#__PURE__*/jsxRuntime.jsxs("li", {
|
|
237
|
+
tabIndex: -1,
|
|
238
|
+
className: className,
|
|
239
|
+
ref: option.setRefElement,
|
|
240
|
+
role: "option",
|
|
241
|
+
"aria-selected": isSelected,
|
|
242
|
+
id: 'typeahead-item-' + index,
|
|
243
|
+
onMouseEnter: onMouseEnter,
|
|
244
|
+
onClick: onClick,
|
|
245
|
+
children: [option.icon, /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
246
|
+
className: "text",
|
|
247
|
+
children: option.title
|
|
248
|
+
})]
|
|
249
|
+
}, option.key);
|
|
250
|
+
}
|
|
222
251
|
function LexicalMenu({
|
|
223
252
|
close,
|
|
224
253
|
editor,
|
|
225
254
|
anchorElementRef,
|
|
226
255
|
resolution,
|
|
227
256
|
options,
|
|
228
|
-
menuRenderFn,
|
|
229
257
|
onSelectOption,
|
|
230
258
|
shouldSplitNodeWithQuery = false,
|
|
231
259
|
commandPriority = lexical.COMMAND_PRIORITY_LOW,
|
|
@@ -253,6 +281,25 @@ function LexicalMenu({
|
|
|
253
281
|
setHighlightedIndex(index);
|
|
254
282
|
}
|
|
255
283
|
}, [editor]);
|
|
284
|
+
const menuRenderFn = React.useCallback(() => {
|
|
285
|
+
return anchorElementRef.current && options.length ? /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
286
|
+
className: "typeahead-popover mentions-menu",
|
|
287
|
+
children: /*#__PURE__*/jsxRuntime.jsx("ul", {
|
|
288
|
+
children: options.map((option, i) => /*#__PURE__*/jsxRuntime.jsx(MenuItem, {
|
|
289
|
+
index: i,
|
|
290
|
+
isSelected: selectedIndex === i,
|
|
291
|
+
onClick: () => {
|
|
292
|
+
setHighlightedIndex(i);
|
|
293
|
+
selectOptionAndCleanUp(option);
|
|
294
|
+
},
|
|
295
|
+
onMouseEnter: () => {
|
|
296
|
+
setHighlightedIndex(i);
|
|
297
|
+
},
|
|
298
|
+
option: option
|
|
299
|
+
}, option.key))
|
|
300
|
+
})
|
|
301
|
+
}), anchorElementRef.current) : null;
|
|
302
|
+
}, [anchorElementRef, options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex]);
|
|
256
303
|
React.useEffect(() => {
|
|
257
304
|
return () => {
|
|
258
305
|
const rootElem = editor.getRootElement();
|
|
@@ -348,13 +395,7 @@ function LexicalMenu({
|
|
|
348
395
|
return true;
|
|
349
396
|
}, commandPriority));
|
|
350
397
|
}, [selectOptionAndCleanUp, close, editor, options, selectedIndex, updateSelectedIndex, commandPriority]);
|
|
351
|
-
|
|
352
|
-
options,
|
|
353
|
-
selectOptionAndCleanUp,
|
|
354
|
-
selectedIndex,
|
|
355
|
-
setHighlightedIndex
|
|
356
|
-
}), [selectOptionAndCleanUp, selectedIndex, options]);
|
|
357
|
-
return menuRenderFn(anchorElementRef, listItemProps, resolution.match ? resolution.match.matchingString : '');
|
|
398
|
+
return menuRenderFn();
|
|
358
399
|
}
|
|
359
400
|
function setContainerDivAttributes(containerDiv, className) {
|
|
360
401
|
if (className != null) {
|
|
@@ -460,7 +501,6 @@ function LexicalNodeMenuPlugin({
|
|
|
460
501
|
onClose,
|
|
461
502
|
onOpen,
|
|
462
503
|
onSelectOption,
|
|
463
|
-
menuRenderFn,
|
|
464
504
|
anchorClassName,
|
|
465
505
|
commandPriority = lexical.COMMAND_PRIORITY_LOW,
|
|
466
506
|
parent
|
|
@@ -517,7 +557,6 @@ function LexicalNodeMenuPlugin({
|
|
|
517
557
|
editor: editor,
|
|
518
558
|
anchorElementRef: anchorElementRef,
|
|
519
559
|
options: options,
|
|
520
|
-
menuRenderFn: menuRenderFn,
|
|
521
560
|
onSelectOption: onSelectOption,
|
|
522
561
|
commandPriority: commandPriority
|
|
523
562
|
});
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
10
10
|
import { createCommand, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $getSelection, $isRangeSelection, $getNodeByKey } from 'lexical';
|
|
11
|
-
import React, { useLayoutEffect, useEffect, useRef, useCallback, useState
|
|
11
|
+
import React, { useLayoutEffect, useEffect, useRef, useCallback, useState } from 'react';
|
|
12
12
|
import { mergeRegister } from '@lexical/utils';
|
|
13
|
-
import
|
|
13
|
+
import ReactDOM from 'react-dom';
|
|
14
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -68,6 +69,8 @@ const useLayoutEffectImpl = CAN_USE_DOM ? useLayoutEffect : useEffect;
|
|
|
68
69
|
class MenuOption {
|
|
69
70
|
key;
|
|
70
71
|
ref;
|
|
72
|
+
icon;
|
|
73
|
+
title;
|
|
71
74
|
constructor(key) {
|
|
72
75
|
this.key = key;
|
|
73
76
|
this.ref = {
|
|
@@ -217,13 +220,38 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
217
220
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
218
221
|
}
|
|
219
222
|
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
223
|
+
function MenuItem({
|
|
224
|
+
index,
|
|
225
|
+
isSelected,
|
|
226
|
+
onClick,
|
|
227
|
+
onMouseEnter,
|
|
228
|
+
option
|
|
229
|
+
}) {
|
|
230
|
+
let className = 'item';
|
|
231
|
+
if (isSelected) {
|
|
232
|
+
className += ' selected';
|
|
233
|
+
}
|
|
234
|
+
return /*#__PURE__*/jsxs("li", {
|
|
235
|
+
tabIndex: -1,
|
|
236
|
+
className: className,
|
|
237
|
+
ref: option.setRefElement,
|
|
238
|
+
role: "option",
|
|
239
|
+
"aria-selected": isSelected,
|
|
240
|
+
id: 'typeahead-item-' + index,
|
|
241
|
+
onMouseEnter: onMouseEnter,
|
|
242
|
+
onClick: onClick,
|
|
243
|
+
children: [option.icon, /*#__PURE__*/jsx("span", {
|
|
244
|
+
className: "text",
|
|
245
|
+
children: option.title
|
|
246
|
+
})]
|
|
247
|
+
}, option.key);
|
|
248
|
+
}
|
|
220
249
|
function LexicalMenu({
|
|
221
250
|
close,
|
|
222
251
|
editor,
|
|
223
252
|
anchorElementRef,
|
|
224
253
|
resolution,
|
|
225
254
|
options,
|
|
226
|
-
menuRenderFn,
|
|
227
255
|
onSelectOption,
|
|
228
256
|
shouldSplitNodeWithQuery = false,
|
|
229
257
|
commandPriority = COMMAND_PRIORITY_LOW,
|
|
@@ -251,6 +279,25 @@ function LexicalMenu({
|
|
|
251
279
|
setHighlightedIndex(index);
|
|
252
280
|
}
|
|
253
281
|
}, [editor]);
|
|
282
|
+
const menuRenderFn = useCallback(() => {
|
|
283
|
+
return anchorElementRef.current && options.length ? /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/jsx("div", {
|
|
284
|
+
className: "typeahead-popover mentions-menu",
|
|
285
|
+
children: /*#__PURE__*/jsx("ul", {
|
|
286
|
+
children: options.map((option, i) => /*#__PURE__*/jsx(MenuItem, {
|
|
287
|
+
index: i,
|
|
288
|
+
isSelected: selectedIndex === i,
|
|
289
|
+
onClick: () => {
|
|
290
|
+
setHighlightedIndex(i);
|
|
291
|
+
selectOptionAndCleanUp(option);
|
|
292
|
+
},
|
|
293
|
+
onMouseEnter: () => {
|
|
294
|
+
setHighlightedIndex(i);
|
|
295
|
+
},
|
|
296
|
+
option: option
|
|
297
|
+
}, option.key))
|
|
298
|
+
})
|
|
299
|
+
}), anchorElementRef.current) : null;
|
|
300
|
+
}, [anchorElementRef, options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex]);
|
|
254
301
|
useEffect(() => {
|
|
255
302
|
return () => {
|
|
256
303
|
const rootElem = editor.getRootElement();
|
|
@@ -346,13 +393,7 @@ function LexicalMenu({
|
|
|
346
393
|
return true;
|
|
347
394
|
}, commandPriority));
|
|
348
395
|
}, [selectOptionAndCleanUp, close, editor, options, selectedIndex, updateSelectedIndex, commandPriority]);
|
|
349
|
-
|
|
350
|
-
options,
|
|
351
|
-
selectOptionAndCleanUp,
|
|
352
|
-
selectedIndex,
|
|
353
|
-
setHighlightedIndex
|
|
354
|
-
}), [selectOptionAndCleanUp, selectedIndex, options]);
|
|
355
|
-
return menuRenderFn(anchorElementRef, listItemProps, resolution.match ? resolution.match.matchingString : '');
|
|
396
|
+
return menuRenderFn();
|
|
356
397
|
}
|
|
357
398
|
function setContainerDivAttributes(containerDiv, className) {
|
|
358
399
|
if (className != null) {
|
|
@@ -458,7 +499,6 @@ function LexicalNodeMenuPlugin({
|
|
|
458
499
|
onClose,
|
|
459
500
|
onOpen,
|
|
460
501
|
onSelectOption,
|
|
461
|
-
menuRenderFn,
|
|
462
502
|
anchorClassName,
|
|
463
503
|
commandPriority = COMMAND_PRIORITY_LOW,
|
|
464
504
|
parent
|
|
@@ -515,7 +555,6 @@ function LexicalNodeMenuPlugin({
|
|
|
515
555
|
editor: editor,
|
|
516
556
|
anchorElementRef: anchorElementRef,
|
|
517
557
|
options: options,
|
|
518
|
-
menuRenderFn: menuRenderFn,
|
|
519
558
|
onSelectOption: onSelectOption,
|
|
520
559
|
commandPriority: commandPriority
|
|
521
560
|
});
|
|
@@ -28,17 +28,6 @@ declare export class MenuOption {
|
|
|
28
28
|
setRefElement(element: HTMLElement | null): void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export type MenuRenderFn<TOption> = (
|
|
32
|
-
anchorElementRef: {current: HTMLElement | null},
|
|
33
|
-
itemProps: {
|
|
34
|
-
selectedIndex: number | null,
|
|
35
|
-
selectOptionAndCleanUp: (option: TOption) => void,
|
|
36
|
-
setHighlightedIndex: (index: number) => void,
|
|
37
|
-
options: Array<TOption>,
|
|
38
|
-
},
|
|
39
|
-
matchingString: string,
|
|
40
|
-
) => React.Portal | React.MixedElement | null;
|
|
41
|
-
|
|
42
31
|
export type TriggerFn = (
|
|
43
32
|
text: string,
|
|
44
33
|
editor: LexicalEditor,
|
|
@@ -55,7 +44,6 @@ type NodeMenuPluginProps<TOption> = {
|
|
|
55
44
|
nodeKey: NodeKey | null,
|
|
56
45
|
onClose?: () => void,
|
|
57
46
|
onOpen?: (resolution: MenuResolution) => void,
|
|
58
|
-
menuRenderFn: MenuRenderFn<TOption>,
|
|
59
47
|
anchorClassName?: string,
|
|
60
48
|
};
|
|
61
49
|
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),n=require("react"),
|
|
9
|
+
"use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),n=require("react"),l=require("@lexical/utils"),o=require("react-dom"),r=require("react/jsx-runtime");const i="startTransition";const s="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,u=s?n.useLayoutEffect:n.useEffect;const c=e=>{const t=document.getElementById("typeahead-menu");if(!t)return;const n=t.getBoundingClientRect();n.top+n.height>window.innerHeight&&t.scrollIntoView({block:"center"}),n.top<0&&t.scrollIntoView({block:"center"}),e.scrollIntoView({block:"nearest"})};function a(e,t){const n=e.getBoundingClientRect(),l=t.getBoundingClientRect();return n.top>=l.top-6&&n.top<=l.bottom+6}function d(t,l,o,r){const[i]=e.useLexicalComposerContext();n.useEffect(()=>{if(null!=l&&null!=t){const e=i.getRootElement(),t=null!=e?function(e){let t=getComputedStyle(e);const n="absolute"===t.position,l=/(auto|scroll)/;if("fixed"===t.position)return document.body;for(let o=e;o=o.parentElement;)if(t=getComputedStyle(o),(!n||"static"!==t.position)&&l.test(t.overflow+t.overflowY+t.overflowX))return o;return document.body}(e):document.body;let n=!1,s=a(l,t);const u=function(){n||(window.requestAnimationFrame(function(){o(),n=!1}),n=!0);const e=a(l,t);e!==s&&(s=e,null!=r&&r(e))},c=new ResizeObserver(o);return window.addEventListener("resize",o),document.addEventListener("scroll",u,{capture:!0,passive:!0}),c.observe(l),()=>{c.unobserve(l),window.removeEventListener("resize",o),document.removeEventListener("scroll",u,!0)}}},[l,i,r,o,t])}const m=t.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function p({index:e,isSelected:t,onClick:n,onMouseEnter:l,option:o}){let i="item";return t&&(i+=" selected"),r.jsxs("li",{tabIndex:-1,className:i,ref:o.setRefElement,role:"option","aria-selected":t,id:"typeahead-item-"+e,onMouseEnter:l,onClick:n,children:[o.icon,r.jsx("span",{className:"text",children:o.title})]},o.key)}function f({close:e,editor:i,anchorElementRef:s,resolution:a,options:d,onSelectOption:f,shouldSplitNodeWithQuery:g=!1,commandPriority:h=t.COMMAND_PRIORITY_LOW,preselectFirstItem:C=!0}){const[E,y]=n.useState(null),x=null!==E?Math.min(d.length-1,E):null,b=a.match&&a.match.matchingString;n.useEffect(()=>{C&&y(0)},[b,C]);const v=n.useCallback(n=>{i.update(()=>{const l=null!=a.match&&g?function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n)||!n.isCollapsed())return null;const l=n.anchor;if("text"!==l.type)return null;const o=l.getNode();if(!o.isSimpleText())return null;const r=l.offset,i=o.getTextContent().slice(0,r),s=e.replaceableString.length,u=r-function(e,t,n){let l=n;for(let n=l;n<=t.length;n++)e.slice(-n)===t.substring(0,n)&&(l=n);return l}(i,e.matchingString,s);if(u<0)return null;let c;return 0===u?[c]=o.splitText(r):[,c]=o.splitText(u,r),c}(a.match):null;f(n,l,e,a.match?a.match.matchingString:"")})},[i,g,a.match,f,e]),w=n.useCallback(e=>{const t=i.getRootElement();null!==t&&(t.setAttribute("aria-activedescendant","typeahead-item-"+e),y(e))},[i]),R=n.useCallback(()=>s.current&&d.length?o.createPortal(r.jsx("div",{className:"typeahead-popover mentions-menu",children:r.jsx("ul",{children:d.map((e,t)=>r.jsx(p,{index:t,isSelected:x===t,onClick:()=>{y(t),v(e)},onMouseEnter:()=>{y(t)},option:e},e.key))})}),s.current):null,[s,d,x,v,y]);return n.useEffect(()=>()=>{const e=i.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[i]),u(()=>{null===d?y(null):null===x&&C&&w(0)},[d,x,w,C]),n.useEffect(()=>l.mergeRegister(i.registerCommand(m,({option:e})=>!(!e.ref||null==e.ref.current)&&(c(e.ref.current),!0),h)),[i,w,h]),n.useEffect(()=>l.mergeRegister(i.registerCommand(t.KEY_ARROW_DOWN_COMMAND,e=>{const t=e;if(null!==d&&d.length){const e=null===x?0:x!==d.length-1?x+1:0;w(e);const n=d[e];if(!n)return w(-1),t.preventDefault(),t.stopImmediatePropagation(),!0;n.ref&&n.ref.current&&i.dispatchCommand(m,{index:e,option:n}),t.preventDefault(),t.stopImmediatePropagation()}return!0},h),i.registerCommand(t.KEY_ARROW_UP_COMMAND,e=>{const t=e;if(null!==d&&d.length){const e=null===x?d.length-1:0!==x?x-1:d.length-1;w(e);const n=d[e];if(!n)return w(-1),t.preventDefault(),t.stopImmediatePropagation(),!0;n.ref&&n.ref.current&&c(n.ref.current),t.preventDefault(),t.stopImmediatePropagation()}return!0},h),i.registerCommand(t.KEY_ESCAPE_COMMAND,t=>{const n=t;return n.preventDefault(),n.stopImmediatePropagation(),e(),!0},h),i.registerCommand(t.KEY_TAB_COMMAND,e=>{const t=e;return null!==d&&null!==x&&null!=d[x]&&(t.preventDefault(),t.stopImmediatePropagation(),v(d[x]),!0)},h),i.registerCommand(t.KEY_ENTER_COMMAND,e=>null!==d&&null!==x&&null!=d[x]&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),v(d[x]),!0),h)),[v,e,i,d,x,w,h]),R()}function g(e,t){null!=t&&(e.className=t),e.setAttribute("aria-label","Typeahead menu"),e.setAttribute("role","listbox"),e.style.display="block",e.style.position="absolute"}exports.LexicalNodeMenuPlugin=function({options:l,nodeKey:o,onClose:u,onOpen:c,onSelectOption:a,anchorClassName:m,commandPriority:p=t.COMMAND_PRIORITY_LOW,parent:h}){const[C]=e.useLexicalComposerContext(),[E,y]=n.useState(null),x=function(t,l,o,r=(s?document.body:void 0),i=!0){const[u]=e.useLexicalComposerContext(),c=s?document.createElement("div"):null,a=n.useRef(c),m=n.useCallback(()=>{if(null===a.current||void 0===r)return;a.current.style.top=a.current.style.bottom;const e=u.getRootElement(),n=a.current,l=n.firstChild;if(null!==e&&null!==t){const{left:s,top:u,width:c,height:d}=t.getRect(),m=a.current.offsetHeight;if(n.style.top=`${u+m+3+(i?window.pageYOffset:0)}px`,n.style.left=`${s+window.pageXOffset}px`,n.style.height=`${d}px`,n.style.width=`${c}px`,null!==l){l.style.top=`${u}`;const t=l.getBoundingClientRect(),o=t.height,r=t.width,c=e.getBoundingClientRect();s+r>c.right&&(n.style.left=`${c.right-r+window.pageXOffset}px`),(u+o>window.innerHeight||u+o>c.bottom)&&u-c.top>o+d&&(n.style.top=`${u-o-d+(i?window.pageYOffset:0)}px`)}n.isConnected||(g(n,o),r.append(n)),n.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[u,t,i,o,r]);n.useEffect(()=>{const e=u.getRootElement();return null!==t&&m(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=a.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}},[u,m,t]);const p=n.useCallback(e=>{null!==t&&(e||l(null))},[t,l]);return d(t,a.current,m,p),null!=c&&c===a.current&&(g(c,o),null!=r&&r.append(c)),a}(E,y,m,h),b=n.useCallback(()=>{y(null),null!=u&&null!==E&&u()},[u,E]),v=n.useCallback(e=>{y(e),null!=c&&null===E&&c(e)},[c,E]),w=n.useCallback(()=>{o?C.update(()=>{const e=t.$getNodeByKey(o),l=C.getElementByKey(o);var r;null!=e&&null!=l&&null==E&&(r=()=>v({getRect:()=>l.getBoundingClientRect()}),i in n?n[i](r):r())}):null==o&&null!=E&&b()},[b,C,o,v,E]);return n.useEffect(()=>{w()},[w,o]),n.useEffect(()=>{if(null!=o)return C.registerUpdateListener(({dirtyElements:e})=>{e.get(o)&&w()})},[C,w,o]),null===x.current||null===E||null===C?null:r.jsx(f,{close:b,resolution:E,editor:C,anchorElementRef:x,options:l,onSelectOption:a,commandPriority:p})},exports.MenuOption=class{key;ref;icon;title;constructor(e){this.key=e,this.ref={current:null},this.setRefElement=this.setRefElement.bind(this)}setRefElement(e){this.ref={current:e}}};
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{useLexicalComposerContext as
|
|
9
|
+
import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{createCommand as t,COMMAND_PRIORITY_LOW as n,KEY_ARROW_DOWN_COMMAND as o,KEY_ARROW_UP_COMMAND as l,KEY_ESCAPE_COMMAND as r,KEY_TAB_COMMAND as i,KEY_ENTER_COMMAND as u,$getSelection as s,$isRangeSelection as c,$getNodeByKey as a}from"lexical";import m,{useLayoutEffect as d,useEffect as p,useRef as f,useCallback as g,useState as h}from"react";import{mergeRegister as y}from"@lexical/utils";import v from"react-dom";import{jsx as w,jsxs as b}from"react/jsx-runtime";const C="startTransition";const E="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,x=E?d:p;class R{key;ref;icon;title;constructor(e){this.key=e,this.ref={current:null},this.setRefElement=this.setRefElement.bind(this)}setRefElement(e){this.ref={current:e}}}const I=e=>{const t=document.getElementById("typeahead-menu");if(!t)return;const n=t.getBoundingClientRect();n.top+n.height>window.innerHeight&&t.scrollIntoView({block:"center"}),n.top<0&&t.scrollIntoView({block:"center"}),e.scrollIntoView({block:"nearest"})};function O(e,t){const n=e.getBoundingClientRect(),o=t.getBoundingClientRect();return n.top>=o.top-6&&n.top<=o.bottom+6}function S(t,n,o,l){const[r]=e();p(()=>{if(null!=n&&null!=t){const e=r.getRootElement(),t=null!=e?function(e){let t=getComputedStyle(e);const n="absolute"===t.position,o=/(auto|scroll)/;if("fixed"===t.position)return document.body;for(let l=e;l=l.parentElement;)if(t=getComputedStyle(l),(!n||"static"!==t.position)&&o.test(t.overflow+t.overflowY+t.overflowX))return l;return document.body}(e):document.body;let i=!1,u=O(n,t);const s=function(){i||(window.requestAnimationFrame(function(){o(),i=!1}),i=!0);const e=O(n,t);e!==u&&(u=e,null!=l&&l(e))},c=new ResizeObserver(o);return window.addEventListener("resize",o),document.addEventListener("scroll",s,{capture:!0,passive:!0}),c.observe(n),()=>{c.unobserve(n),window.removeEventListener("resize",o),document.removeEventListener("scroll",s,!0)}}},[n,r,l,o,t])}const P=t("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function A({index:e,isSelected:t,onClick:n,onMouseEnter:o,option:l}){let r="item";return t&&(r+=" selected"),b("li",{tabIndex:-1,className:r,ref:l.setRefElement,role:"option","aria-selected":t,id:"typeahead-item-"+e,onMouseEnter:o,onClick:n,children:[l.icon,w("span",{className:"text",children:l.title})]},l.key)}function k({close:e,editor:t,anchorElementRef:a,resolution:m,options:d,onSelectOption:f,shouldSplitNodeWithQuery:b=!1,commandPriority:C=n,preselectFirstItem:E=!0}){const[R,O]=h(null),S=null!==R?Math.min(d.length-1,R):null,k=m.match&&m.match.matchingString;p(()=>{E&&O(0)},[k,E]);const N=g(n=>{t.update(()=>{const t=null!=m.match&&b?function(e){const t=s();if(!c(t)||!t.isCollapsed())return null;const n=t.anchor;if("text"!==n.type)return null;const o=n.getNode();if(!o.isSimpleText())return null;const l=n.offset,r=o.getTextContent().slice(0,l),i=e.replaceableString.length,u=l-function(e,t,n){let o=n;for(let n=o;n<=t.length;n++)e.slice(-n)===t.substring(0,n)&&(o=n);return o}(r,e.matchingString,i);if(u<0)return null;let a;return 0===u?[a]=o.splitText(l):[,a]=o.splitText(u,l),a}(m.match):null;f(n,t,e,m.match?m.match.matchingString:"")})},[t,b,m.match,f,e]),D=g(e=>{const n=t.getRootElement();null!==n&&(n.setAttribute("aria-activedescendant","typeahead-item-"+e),O(e))},[t]),T=g(()=>a.current&&d.length?v.createPortal(w("div",{className:"typeahead-popover mentions-menu",children:w("ul",{children:d.map((e,t)=>w(A,{index:t,isSelected:S===t,onClick:()=>{O(t),N(e)},onMouseEnter:()=>{O(t)},option:e},e.key))})}),a.current):null,[a,d,S,N,O]);return p(()=>()=>{const e=t.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[t]),x(()=>{null===d?O(null):null===S&&E&&D(0)},[d,S,D,E]),p(()=>y(t.registerCommand(P,({option:e})=>!(!e.ref||null==e.ref.current)&&(I(e.ref.current),!0),C)),[t,D,C]),p(()=>y(t.registerCommand(o,e=>{const n=e;if(null!==d&&d.length){const e=null===S?0:S!==d.length-1?S+1:0;D(e);const o=d[e];if(!o)return D(-1),n.preventDefault(),n.stopImmediatePropagation(),!0;o.ref&&o.ref.current&&t.dispatchCommand(P,{index:e,option:o}),n.preventDefault(),n.stopImmediatePropagation()}return!0},C),t.registerCommand(l,e=>{const t=e;if(null!==d&&d.length){const e=null===S?d.length-1:0!==S?S-1:d.length-1;D(e);const n=d[e];if(!n)return D(-1),t.preventDefault(),t.stopImmediatePropagation(),!0;n.ref&&n.ref.current&&I(n.ref.current),t.preventDefault(),t.stopImmediatePropagation()}return!0},C),t.registerCommand(r,t=>{const n=t;return n.preventDefault(),n.stopImmediatePropagation(),e(),!0},C),t.registerCommand(i,e=>{const t=e;return null!==d&&null!==S&&null!=d[S]&&(t.preventDefault(),t.stopImmediatePropagation(),N(d[S]),!0)},C),t.registerCommand(u,e=>null!==d&&null!==S&&null!=d[S]&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),N(d[S]),!0),C)),[N,e,t,d,S,D,C]),T()}function N(e,t){null!=t&&(e.className=t),e.setAttribute("aria-label","Typeahead menu"),e.setAttribute("role","listbox"),e.style.display="block",e.style.position="absolute"}function D({options:t,nodeKey:o,onClose:l,onOpen:r,onSelectOption:i,anchorClassName:u,commandPriority:s=n,parent:c}){const[d]=e(),[y,v]=h(null),b=function(t,n,o,l=(E?document.body:void 0),r=!0){const[i]=e(),u=E?document.createElement("div"):null,s=f(u),c=g(()=>{if(null===s.current||void 0===l)return;s.current.style.top=s.current.style.bottom;const e=i.getRootElement(),n=s.current,u=n.firstChild;if(null!==e&&null!==t){const{left:i,top:c,width:a,height:m}=t.getRect(),d=s.current.offsetHeight;if(n.style.top=`${c+d+3+(r?window.pageYOffset:0)}px`,n.style.left=`${i+window.pageXOffset}px`,n.style.height=`${m}px`,n.style.width=`${a}px`,null!==u){u.style.top=`${c}`;const t=u.getBoundingClientRect(),o=t.height,l=t.width,s=e.getBoundingClientRect();i+l>s.right&&(n.style.left=`${s.right-l+window.pageXOffset}px`),(c+o>window.innerHeight||c+o>s.bottom)&&c-s.top>o+m&&(n.style.top=`${c-o-m+(r?window.pageYOffset:0)}px`)}n.isConnected||(N(n,o),l.append(n)),n.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[i,t,r,o,l]);p(()=>{const e=i.getRootElement();return null!==t&&c(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=s.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}},[i,c,t]);const a=g(e=>{null!==t&&(e||n(null))},[t,n]);return S(t,s.current,c,a),null!=u&&u===s.current&&(N(u,o),null!=l&&l.append(u)),s}(y,v,u,c),x=g(()=>{v(null),null!=l&&null!==y&&l()},[l,y]),R=g(e=>{v(e),null!=r&&null===y&&r(e)},[r,y]),I=g(()=>{o?d.update(()=>{const e=a(o),t=d.getElementByKey(o);var n;null!=e&&null!=t&&null==y&&(n=()=>R({getRect:()=>t.getBoundingClientRect()}),C in m?m[C](n):n())}):null==o&&null!=y&&x()},[x,d,o,R,y]);return p(()=>{I()},[I,o]),p(()=>{if(null!=o)return d.registerUpdateListener(({dirtyElements:e})=>{e.get(o)&&I()})},[d,I,o]),null===b.current||null===y||null===d?null:w(k,{close:x,resolution:y,editor:d,anchorElementRef:b,options:t,onSelectOption:i,commandPriority:s})}export{D as LexicalNodeMenuPlugin,R as MenuOption};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { MenuResolution, MenuTextMatch, TriggerFn } from './shared/LexicalMenu';
|
|
9
9
|
import type { JSX } from 'react';
|
|
10
10
|
import { CommandListenerPriority, LexicalCommand, TextNode } from 'lexical';
|
|
11
11
|
import { MenuOption } from './shared/LexicalMenu';
|
|
@@ -26,7 +26,6 @@ export type TypeaheadMenuPluginProps<TOption extends MenuOption> = {
|
|
|
26
26
|
onQueryChange: (matchingString: string | null) => void;
|
|
27
27
|
onSelectOption: (option: TOption, textNodeContainingQuery: TextNode | null, closeMenu: () => void, matchingString: string) => void;
|
|
28
28
|
options: Array<TOption>;
|
|
29
|
-
menuRenderFn: MenuRenderFn<TOption>;
|
|
30
29
|
triggerFn: TriggerFn;
|
|
31
30
|
onOpen?: (resolution: MenuResolution) => void;
|
|
32
31
|
onClose?: () => void;
|
|
@@ -36,5 +35,5 @@ export type TypeaheadMenuPluginProps<TOption extends MenuOption> = {
|
|
|
36
35
|
preselectFirstItem?: boolean;
|
|
37
36
|
ignoreEntityBoundary?: boolean;
|
|
38
37
|
};
|
|
39
|
-
export declare function LexicalTypeaheadMenuPlugin<TOption extends MenuOption>({ options, onQueryChange, onSelectOption, onOpen, onClose,
|
|
40
|
-
export { MenuOption,
|
|
38
|
+
export declare function LexicalTypeaheadMenuPlugin<TOption extends MenuOption>({ options, onQueryChange, onSelectOption, onOpen, onClose, triggerFn, anchorClassName, commandPriority, parent, preselectFirstItem, ignoreEntityBoundary, }: TypeaheadMenuPluginProps<TOption>): JSX.Element | null;
|
|
39
|
+
export { MenuOption, MenuResolution, MenuTextMatch, TriggerFn };
|
|
@@ -12,6 +12,7 @@ var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
|
12
12
|
var lexical = require('lexical');
|
|
13
13
|
var React = require('react');
|
|
14
14
|
var utils = require('@lexical/utils');
|
|
15
|
+
var ReactDOM = require('react-dom');
|
|
15
16
|
var jsxRuntime = require('react/jsx-runtime');
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -70,6 +71,8 @@ const useLayoutEffectImpl = CAN_USE_DOM ? React.useLayoutEffect : React.useEffec
|
|
|
70
71
|
class MenuOption {
|
|
71
72
|
key;
|
|
72
73
|
ref;
|
|
74
|
+
icon;
|
|
75
|
+
title;
|
|
73
76
|
constructor(key) {
|
|
74
77
|
this.key = key;
|
|
75
78
|
this.ref = {
|
|
@@ -219,13 +222,38 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
219
222
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
220
223
|
}
|
|
221
224
|
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND$1 = lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
225
|
+
function MenuItem({
|
|
226
|
+
index,
|
|
227
|
+
isSelected,
|
|
228
|
+
onClick,
|
|
229
|
+
onMouseEnter,
|
|
230
|
+
option
|
|
231
|
+
}) {
|
|
232
|
+
let className = 'item';
|
|
233
|
+
if (isSelected) {
|
|
234
|
+
className += ' selected';
|
|
235
|
+
}
|
|
236
|
+
return /*#__PURE__*/jsxRuntime.jsxs("li", {
|
|
237
|
+
tabIndex: -1,
|
|
238
|
+
className: className,
|
|
239
|
+
ref: option.setRefElement,
|
|
240
|
+
role: "option",
|
|
241
|
+
"aria-selected": isSelected,
|
|
242
|
+
id: 'typeahead-item-' + index,
|
|
243
|
+
onMouseEnter: onMouseEnter,
|
|
244
|
+
onClick: onClick,
|
|
245
|
+
children: [option.icon, /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
246
|
+
className: "text",
|
|
247
|
+
children: option.title
|
|
248
|
+
})]
|
|
249
|
+
}, option.key);
|
|
250
|
+
}
|
|
222
251
|
function LexicalMenu({
|
|
223
252
|
close,
|
|
224
253
|
editor,
|
|
225
254
|
anchorElementRef,
|
|
226
255
|
resolution,
|
|
227
256
|
options,
|
|
228
|
-
menuRenderFn,
|
|
229
257
|
onSelectOption,
|
|
230
258
|
shouldSplitNodeWithQuery = false,
|
|
231
259
|
commandPriority = lexical.COMMAND_PRIORITY_LOW,
|
|
@@ -253,6 +281,25 @@ function LexicalMenu({
|
|
|
253
281
|
setHighlightedIndex(index);
|
|
254
282
|
}
|
|
255
283
|
}, [editor]);
|
|
284
|
+
const menuRenderFn = React.useCallback(() => {
|
|
285
|
+
return anchorElementRef.current && options.length ? /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
286
|
+
className: "typeahead-popover mentions-menu",
|
|
287
|
+
children: /*#__PURE__*/jsxRuntime.jsx("ul", {
|
|
288
|
+
children: options.map((option, i) => /*#__PURE__*/jsxRuntime.jsx(MenuItem, {
|
|
289
|
+
index: i,
|
|
290
|
+
isSelected: selectedIndex === i,
|
|
291
|
+
onClick: () => {
|
|
292
|
+
setHighlightedIndex(i);
|
|
293
|
+
selectOptionAndCleanUp(option);
|
|
294
|
+
},
|
|
295
|
+
onMouseEnter: () => {
|
|
296
|
+
setHighlightedIndex(i);
|
|
297
|
+
},
|
|
298
|
+
option: option
|
|
299
|
+
}, option.key))
|
|
300
|
+
})
|
|
301
|
+
}), anchorElementRef.current) : null;
|
|
302
|
+
}, [anchorElementRef, options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex]);
|
|
256
303
|
React.useEffect(() => {
|
|
257
304
|
return () => {
|
|
258
305
|
const rootElem = editor.getRootElement();
|
|
@@ -348,13 +395,7 @@ function LexicalMenu({
|
|
|
348
395
|
return true;
|
|
349
396
|
}, commandPriority));
|
|
350
397
|
}, [selectOptionAndCleanUp, close, editor, options, selectedIndex, updateSelectedIndex, commandPriority]);
|
|
351
|
-
|
|
352
|
-
options,
|
|
353
|
-
selectOptionAndCleanUp,
|
|
354
|
-
selectedIndex,
|
|
355
|
-
setHighlightedIndex
|
|
356
|
-
}), [selectOptionAndCleanUp, selectedIndex, options]);
|
|
357
|
-
return menuRenderFn(anchorElementRef, listItemProps, resolution.match ? resolution.match.matchingString : '');
|
|
398
|
+
return menuRenderFn();
|
|
358
399
|
}
|
|
359
400
|
function setContainerDivAttributes(containerDiv, className) {
|
|
360
401
|
if (className != null) {
|
|
@@ -564,7 +605,6 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
564
605
|
onSelectOption,
|
|
565
606
|
onOpen,
|
|
566
607
|
onClose,
|
|
567
|
-
menuRenderFn,
|
|
568
608
|
triggerFn,
|
|
569
609
|
anchorClassName,
|
|
570
610
|
commandPriority = lexical.COMMAND_PRIORITY_LOW,
|
|
@@ -595,6 +635,9 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
595
635
|
closeTypeahead();
|
|
596
636
|
return;
|
|
597
637
|
}
|
|
638
|
+
if (editor.isComposing()) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
598
641
|
const editorWindow = editor._window || window;
|
|
599
642
|
const range = editorWindow.document.createRange();
|
|
600
643
|
const selection = lexical.$getSelection();
|
|
@@ -634,7 +677,6 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
634
677
|
editor: editor,
|
|
635
678
|
anchorElementRef: anchorElementRef,
|
|
636
679
|
options: options,
|
|
637
|
-
menuRenderFn: menuRenderFn,
|
|
638
680
|
shouldSplitNodeWithQuery: true,
|
|
639
681
|
onSelectOption: onSelectOption,
|
|
640
682
|
commandPriority: commandPriority,
|