@lexical/react 0.49.1-nightly.20260901.0 → 0.50.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/dist/LexicalAutoEmbedPlugin.d.ts +4 -47
- package/dist/LexicalAutoEmbedPlugin.dev.js +5 -31
- package/dist/LexicalAutoEmbedPlugin.dev.mjs +5 -30
- package/dist/LexicalAutoEmbedPlugin.prod.js +1 -1
- package/dist/LexicalAutoEmbedPlugin.prod.mjs +1 -1
- package/dist/LexicalAutoEmbedPluginUtils.d.ts +53 -0
- package/dist/LexicalAutoEmbedPluginUtils.dev.js +66 -0
- package/dist/LexicalAutoEmbedPluginUtils.dev.mjs +62 -0
- package/dist/LexicalAutoEmbedPluginUtils.js +11 -0
- package/dist/LexicalAutoEmbedPluginUtils.js.flow +40 -0
- package/dist/LexicalAutoEmbedPluginUtils.mjs +14 -0
- package/dist/LexicalAutoEmbedPluginUtils.node.mjs +12 -0
- package/dist/LexicalAutoEmbedPluginUtils.prod.js +9 -0
- package/dist/LexicalAutoEmbedPluginUtils.prod.mjs +9 -0
- package/dist/LexicalCollaborationContext.d.ts +1 -26
- package/dist/LexicalCollaborationContext.dev.js +5 -55
- package/dist/LexicalCollaborationContext.dev.mjs +4 -53
- package/dist/LexicalCollaborationContext.prod.js +2 -2
- package/dist/LexicalCollaborationContext.prod.mjs +2 -2
- package/dist/LexicalCollaborationContextUtils.d.ts +35 -0
- package/dist/LexicalCollaborationContextUtils.dev.js +83 -0
- package/dist/LexicalCollaborationContextUtils.dev.mjs +79 -0
- package/dist/LexicalCollaborationContextUtils.js +11 -0
- package/dist/LexicalCollaborationContextUtils.js.flow +25 -0
- package/dist/LexicalCollaborationContextUtils.mjs +14 -0
- package/dist/LexicalCollaborationContextUtils.node.mjs +12 -0
- package/dist/LexicalCollaborationContextUtils.prod.js +9 -0
- package/dist/LexicalCollaborationContextUtils.prod.mjs +9 -0
- package/dist/LexicalMenuOption.d.ts +29 -0
- package/dist/LexicalMenuOption.dev.js +51 -0
- package/dist/LexicalMenuOption.dev.mjs +49 -0
- package/dist/LexicalMenuOption.js +11 -0
- package/dist/LexicalMenuOption.js.flow +20 -0
- package/dist/LexicalMenuOption.mjs +12 -0
- package/dist/LexicalMenuOption.node.mjs +10 -0
- package/dist/LexicalMenuOption.prod.js +9 -0
- package/dist/LexicalMenuOption.prod.mjs +9 -0
- package/dist/LexicalNodeMenuPlugin.dev.js +5 -28
- package/dist/LexicalNodeMenuPlugin.dev.mjs +4 -27
- package/dist/LexicalNodeMenuPlugin.prod.js +1 -1
- package/dist/LexicalNodeMenuPlugin.prod.mjs +1 -1
- package/dist/LexicalTypeaheadMenuPlugin.d.ts +2 -34
- package/dist/LexicalTypeaheadMenuPlugin.dev.js +10 -78
- package/dist/LexicalTypeaheadMenuPlugin.dev.mjs +9 -76
- package/dist/LexicalTypeaheadMenuPlugin.prod.js +1 -1
- package/dist/LexicalTypeaheadMenuPlugin.prod.mjs +1 -1
- package/dist/LexicalTypeaheadMenuPluginUtils.d.ts +44 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.dev.js +81 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.dev.mjs +76 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.js +11 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.js.flow +34 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.mjs +15 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.node.mjs +13 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.prod.js +9 -0
- package/dist/LexicalTypeaheadMenuPluginUtils.prod.mjs +9 -0
- package/dist/shared/LexicalMenu.d.ts +5 -19
- package/package.json +164 -20
- package/src/LexicalAutoEmbedPlugin.tsx +12 -70
- package/src/LexicalAutoEmbedPluginUtils.ts +80 -0
- package/src/LexicalCollaborationContext.tsx +11 -90
- package/src/LexicalCollaborationContextUtils.ts +99 -0
- package/src/LexicalMenuOption.ts +39 -0
- package/src/LexicalTypeaheadMenuPlugin.tsx +6 -80
- package/src/LexicalTypeaheadMenuPluginUtils.ts +93 -0
- package/src/shared/LexicalMenu.tsx +12 -28
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
12
12
|
var lexical = require('lexical');
|
|
13
13
|
var react = require('react');
|
|
14
|
+
var LexicalTypeaheadMenuPluginUtils = require('@lexical/react/LexicalTypeaheadMenuPluginUtils');
|
|
14
15
|
var utils = require('@lexical/utils');
|
|
15
16
|
var ReactDOM = require('react-dom');
|
|
16
17
|
var jsxRuntime = require('react/jsx-runtime');
|
|
18
|
+
var LexicalMenuOption = require('@lexical/react/LexicalMenuOption');
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -37,30 +39,6 @@ const useLayoutEffectImpl = lexical.CAN_USE_DOM ? react.useLayoutEffect : react.
|
|
|
37
39
|
*
|
|
38
40
|
*/
|
|
39
41
|
|
|
40
|
-
/**
|
|
41
|
-
* The base class for an item shown in a {@link LexicalTypeaheadMenuPlugin} or
|
|
42
|
-
* {@link LexicalNodeMenuPlugin} menu. Each option has a unique `key` and a `ref`
|
|
43
|
-
* to its rendered element (used for scrolling and keyboard navigation).
|
|
44
|
-
* Subclass it to attach your own data such as a label or callback.
|
|
45
|
-
*/
|
|
46
|
-
class MenuOption {
|
|
47
|
-
key;
|
|
48
|
-
ref;
|
|
49
|
-
icon;
|
|
50
|
-
title;
|
|
51
|
-
constructor(key) {
|
|
52
|
-
this.key = key;
|
|
53
|
-
this.ref = {
|
|
54
|
-
current: null
|
|
55
|
-
};
|
|
56
|
-
this.setRefElement = this.setRefElement.bind(this);
|
|
57
|
-
}
|
|
58
|
-
setRefElement(element) {
|
|
59
|
-
this.ref = {
|
|
60
|
-
current: element
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
42
|
|
|
65
43
|
/**
|
|
66
44
|
* A render function for a menu's contents. It receives the anchor element ref,
|
|
@@ -202,7 +180,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
202
180
|
}
|
|
203
181
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
204
182
|
}
|
|
205
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = /* @__PURE__ */lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
206
183
|
function MenuItem({
|
|
207
184
|
index,
|
|
208
185
|
isSelected,
|
|
@@ -306,7 +283,7 @@ function LexicalMenu({
|
|
|
306
283
|
// has to be able to arrow through and dismiss.
|
|
307
284
|
const rendersNothing = menuRenderFnProp == null && (options === null || !options.length);
|
|
308
285
|
react.useEffect(() => {
|
|
309
|
-
return lexical.mergeRegister(editor.registerCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, ({
|
|
286
|
+
return lexical.mergeRegister(editor.registerCommand(LexicalTypeaheadMenuPluginUtils.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, ({
|
|
310
287
|
option
|
|
311
288
|
}) => {
|
|
312
289
|
if (option.ref && option.ref.current != null) {
|
|
@@ -335,7 +312,7 @@ function LexicalMenu({
|
|
|
335
312
|
return true;
|
|
336
313
|
}
|
|
337
314
|
if (option.ref && option.ref.current) {
|
|
338
|
-
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
315
|
+
editor.dispatchCommand(LexicalTypeaheadMenuPluginUtils.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
339
316
|
index: newSelectedIndex,
|
|
340
317
|
option
|
|
341
318
|
});
|
|
@@ -677,5 +654,5 @@ function LexicalNodeMenuPlugin({
|
|
|
677
654
|
});
|
|
678
655
|
}
|
|
679
656
|
|
|
657
|
+
exports.MenuOption = LexicalMenuOption.MenuOption;
|
|
680
658
|
exports.LexicalNodeMenuPlugin = LexicalNodeMenuPlugin;
|
|
681
|
-
exports.MenuOption = MenuOption;
|
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
10
|
-
import { CAN_USE_DOM, getRootOwnerDocument, mergeRegister, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, isDOMShadowRoot, isHTMLElement, getParentElement, getDOMShadowRoots, registerEventListener, $getSelection, $isRangeSelection,
|
|
10
|
+
import { CAN_USE_DOM, getRootOwnerDocument, mergeRegister, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, isDOMShadowRoot, isHTMLElement, getParentElement, getDOMShadowRoots, registerEventListener, $getSelection, $isRangeSelection, $getNodeByKey } from 'lexical';
|
|
11
11
|
import { useLayoutEffect, useEffect, useRef, useCallback, useState, useMemo, startTransition } from 'react';
|
|
12
|
+
import { SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND } from '@lexical/react/LexicalTypeaheadMenuPluginUtils';
|
|
12
13
|
import { getScrollParent } from '@lexical/utils';
|
|
13
14
|
import ReactDOM from 'react-dom';
|
|
14
15
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
16
|
+
export { MenuOption } from '@lexical/react/LexicalMenuOption';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -35,30 +37,6 @@ const useLayoutEffectImpl = CAN_USE_DOM ? useLayoutEffect : useEffect;
|
|
|
35
37
|
*
|
|
36
38
|
*/
|
|
37
39
|
|
|
38
|
-
/**
|
|
39
|
-
* The base class for an item shown in a {@link LexicalTypeaheadMenuPlugin} or
|
|
40
|
-
* {@link LexicalNodeMenuPlugin} menu. Each option has a unique `key` and a `ref`
|
|
41
|
-
* to its rendered element (used for scrolling and keyboard navigation).
|
|
42
|
-
* Subclass it to attach your own data such as a label or callback.
|
|
43
|
-
*/
|
|
44
|
-
class MenuOption {
|
|
45
|
-
key;
|
|
46
|
-
ref;
|
|
47
|
-
icon;
|
|
48
|
-
title;
|
|
49
|
-
constructor(key) {
|
|
50
|
-
this.key = key;
|
|
51
|
-
this.ref = {
|
|
52
|
-
current: null
|
|
53
|
-
};
|
|
54
|
-
this.setRefElement = this.setRefElement.bind(this);
|
|
55
|
-
}
|
|
56
|
-
setRefElement(element) {
|
|
57
|
-
this.ref = {
|
|
58
|
-
current: element
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
40
|
|
|
63
41
|
/**
|
|
64
42
|
* A render function for a menu's contents. It receives the anchor element ref,
|
|
@@ -200,7 +178,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
200
178
|
}
|
|
201
179
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
202
180
|
}
|
|
203
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = /* @__PURE__ */createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
204
181
|
function MenuItem({
|
|
205
182
|
index,
|
|
206
183
|
isSelected,
|
|
@@ -675,4 +652,4 @@ function LexicalNodeMenuPlugin({
|
|
|
675
652
|
});
|
|
676
653
|
}
|
|
677
654
|
|
|
678
|
-
export { LexicalNodeMenuPlugin
|
|
655
|
+
export { LexicalNodeMenuPlugin };
|
|
@@ -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"),l=require("@lexical/
|
|
9
|
+
"use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),n=require("react"),l=require("@lexical/react/LexicalTypeaheadMenuPluginUtils"),o=require("@lexical/utils"),r=require("react-dom"),i=require("react/jsx-runtime"),u=require("@lexical/react/LexicalMenuOption");const s=t.CAN_USE_DOM?n.useLayoutEffect:n.useEffect,c=e=>{const t=e.closest("#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({index:e,isSelected:t,onClick:n,onMouseEnter:l,option:o}){let r="item";return t&&(r+=" selected"),/*#__PURE__*/i.jsxs("li",{tabIndex:-1,className:r,ref:o.setRefElement,role:"option","aria-selected":t,id:"typeahead-item-"+e,onMouseEnter:l,onClick:n,children:[o.icon,/*#__PURE__*/i.jsx("span",{className:"text",children:o.title})]},o.key)}function p({close:e,editor:o,anchorElementRef:u,resolution:a,options:p,menuRenderFn:m,onSelectOption:f,shouldSplitNodeWithQuery:g=!1,commandPriority:h=t.COMMAND_PRIORITY_LOW,preselectFirstItem:C=!0}){const[E,x]=n.useState(null),R=null!==E?Math.min(p.length-1,E):null,O=a.match&&a.match.matchingString;n.useEffect(()=>{C&&x(0)},[O,C]);const y=n.useCallback(n=>{o.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),u=e.replaceableString.length,s=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,u);if(s<0)return null;let c;return 0===s?[c]=o.splitText(r):[,c]=o.splitText(s,r),c}(a.match):null;f(n,l,e,a.match?a.match.matchingString:"")})},[o,g,a.match,f,e]),b=n.useCallback(e=>{const t=o.getRootElement();null!==t&&(t.setAttribute("aria-activedescendant","typeahead-item-"+e),x(e))},[o]),M=n.useCallback(()=>u.current&&p.length?/*#__PURE__*/r.createPortal(/*#__PURE__*/i.jsx("div",{className:"typeahead-popover mentions-menu",children:/*#__PURE__*/i.jsx("ul",{children:p.map((e,t)=>/*#__PURE__*/i.jsx(d,{index:t,isSelected:R===t,onClick:()=>{x(t),y(e)},onMouseEnter:()=>{x(t)},option:e},e.key))})}),u.current):null,[u,p,R,y,x]);n.useEffect(()=>()=>{const e=o.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[o]),s(()=>{null===p?x(null):null===R&&C&&b(0)},[p,R,b,C]);const _=null==m&&(null===p||!p.length);n.useEffect(()=>t.mergeRegister(o.registerCommand(l.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,({option:e})=>!(!e.ref||null==e.ref.current)&&(c(e.ref.current),!0),h)),[o,b,h]),n.useEffect(()=>t.mergeRegister(o.registerCommand(t.KEY_ARROW_DOWN_COMMAND,e=>{const t=e;if(_)return!1;const n=null===R?0:R!==p.length-1?R+1:0;b(n);const r=p[n];return r?(r.ref&&r.ref.current&&o.dispatchCommand(l.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,{index:n,option:r}),t.preventDefault(),t.stopImmediatePropagation(),!0):(b(-1),t.preventDefault(),t.stopImmediatePropagation(),!0)},h),o.registerCommand(t.KEY_ARROW_UP_COMMAND,e=>{const t=e;if(_)return!1;const n=null===R?p.length-1:0!==R?R-1:p.length-1;b(n);const l=p[n];return l?(l.ref&&l.ref.current&&c(l.ref.current),t.preventDefault(),t.stopImmediatePropagation(),!0):(b(-1),t.preventDefault(),t.stopImmediatePropagation(),!0)},h),o.registerCommand(t.KEY_ESCAPE_COMMAND,t=>{const n=t;return!_&&(n.preventDefault(),n.stopImmediatePropagation(),e(),!0)},h),o.registerCommand(t.KEY_TAB_COMMAND,e=>{const t=e;return null!==p&&null!==R&&null!=p[R]&&(t.preventDefault(),t.stopImmediatePropagation(),y(p[R]),!0)},h),o.registerCommand(t.KEY_ENTER_COMMAND,e=>!(null===p||null===R||null==p[R]||e&&e.shiftKey)&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),y(p[R]),!0),h)),[y,e,o,p,_,R,b,h]);const A=n.useMemo(()=>({options:p,selectOptionAndCleanUp:y,selectedIndex:R,setHighlightedIndex:x}),[y,R,p]);return null!=m?m(u,A,a.match?a.match.matchingString:""):M()}function m(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 f(e){if("static"!==e.position)return!0;const t=e.willChange;return"none"!==e.transform||"none"!==e.perspective||"none"!==e.filter||"none"!==e.backdropFilter||e.contain.includes("paint")||e.contain.includes("layout")||e.contain.includes("strict")||e.contain.includes("content")||t.includes("transform")||t.includes("perspective")||t.includes("filter")||t.includes("contain")}function g(l,r,i,u,s=!0){const[c]=e.useLexicalComposerContext(),d=u??function(e){if(!t.CAN_USE_DOM)return;const n=e.getRootElement();if(null!==n){const e=n.getRootNode();return t.isDOMShadowRoot(e)?e:n.ownerDocument.body}return document.body}(c),p=t.CAN_USE_DOM?t.getRootOwnerDocument(c.getRootElement()).createElement("div"):null,g=n.useRef(p),h=n.useCallback(()=>{if(null===g.current||void 0===d)return;g.current.style.top=g.current.style.bottom;const e=c.getRootElement(),n=g.current,o=n.firstChild;if(null!==e&&null!==l){const{left:r,top:u,width:c,height:a}=l.getRect(),p=g.current.offsetHeight,h=function(e){const n=t.isDOMShadowRoot(e)?e.host:e;for(let e=t.isHTMLElement(n)?n:null;null!==e;e=t.getParentElement(e)){const t=e.ownerDocument.defaultView;if(null===t)break;if(f(t.getComputedStyle(e))){const t=e.getBoundingClientRect();return{left:t.left+e.clientLeft-e.scrollLeft,top:t.top+e.clientTop-e.scrollTop}}}return null}(d),C=e=>null!==h?e-h.left:e+window.pageXOffset,E=e=>null!==h?e-h.top:e+(s?window.pageYOffset:0);if(n.style.top=`${E(u+p+3)}px`,n.style.left=`${C(r)}px`,n.style.height=`${a}px`,n.style.width=`${c}px`,null!==o){o.style.top=`${u}`;const t=o.getBoundingClientRect(),l=t.height,i=t.width,s=e.getBoundingClientRect();r+i>s.right&&(n.style.left=`${C(s.right-i)}px`),(u+l>window.innerHeight||u+l>s.bottom)&&u-s.top>l+a&&(n.style.top=`${E(u-l-a)}px`)}n.isConnected||(m(n,i),d.append(n)),n.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[c,l,s,i,d]);n.useEffect(()=>{const e=c.getRootElement();return null!==l&&h(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=g.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}},[c,h,l]);const C=n.useCallback(e=>{null!==l&&(e||r(null))},[l,r]);return function(l,r,i,u){const[s]=e.useLexicalComposerContext();n.useEffect(()=>{if(null!=r&&null!=l){const e=s.getRootElement(),n=null!=e?o.getScrollParent(e,!1):document.body;let l=!1,c=a(r,n);const d=function(){l||(window.requestAnimationFrame(function(){i(),l=!1}),l=!0);const e=a(r,n);e!==c&&(c=e,null!=u&&u(e))},p=new ResizeObserver(i),m=t.getDOMShadowRoots(e??r);return p.observe(r),t.mergeRegister(t.registerEventListener(window,"resize",i),t.registerEventListener(document,"scroll",d,{capture:!0,passive:!0}),...m.map(e=>t.registerEventListener(e,"scroll",d,{capture:!0,passive:!0})),()=>p.unobserve(r))}},[r,s,u,i,l])}(l,g.current,h,C),null!=p&&p===g.current&&(m(p,i),null!=d&&d.append(p)),g}exports.MenuOption=u.MenuOption,exports.LexicalNodeMenuPlugin=function({options:l,nodeKey:o,onClose:r,onOpen:u,onSelectOption:s,menuRenderFn:c,anchorClassName:a,commandPriority:d=t.COMMAND_PRIORITY_LOW,parent:m}){const[f]=e.useLexicalComposerContext(),[h,C]=n.useState(null),E=g(h,C,a,m),x=n.useCallback(()=>{C(null),null!=r&&null!==h&&r()},[r,h]),R=n.useCallback(e=>{C(e),null!=u&&null===h&&u(e)},[u,h]),O=n.useCallback(()=>{o?f.update(()=>{const e=t.$getNodeByKey(o),l=f.getElementByKey(o);null!=e&&null!=l&&null==h&&n.startTransition(()=>R({getRect:()=>l.getBoundingClientRect()}))}):null==o&&null!=h&&x()},[x,f,o,R,h]);return n.useEffect(()=>{O()},[O,o]),n.useEffect(()=>{if(null!=o)return f.registerUpdateListener(({dirtyElements:e})=>{e.get(o)&&O()})},[f,O,o]),null===E.current||null===h||null===f?null:/*#__PURE__*/i.jsx(p,{close:x,resolution:h,editor:f,anchorElementRef:E,options:l,menuRenderFn:c,onSelectOption:s,commandPriority:d})};
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{useLexicalComposerContext as t}from"@lexical/react/LexicalComposerContext";import{CAN_USE_DOM as e,getRootOwnerDocument as n,mergeRegister as l,COMMAND_PRIORITY_LOW as o,KEY_ARROW_DOWN_COMMAND as r,KEY_ARROW_UP_COMMAND as i,KEY_ESCAPE_COMMAND as c,KEY_TAB_COMMAND as u,KEY_ENTER_COMMAND as s,isDOMShadowRoot as a,isHTMLElement as m,getParentElement as p,getDOMShadowRoots as d,registerEventListener as f,$getSelection as g,$isRangeSelection as h
|
|
9
|
+
import{useLexicalComposerContext as t}from"@lexical/react/LexicalComposerContext";import{CAN_USE_DOM as e,getRootOwnerDocument as n,mergeRegister as l,COMMAND_PRIORITY_LOW as o,KEY_ARROW_DOWN_COMMAND as r,KEY_ARROW_UP_COMMAND as i,KEY_ESCAPE_COMMAND as c,KEY_TAB_COMMAND as u,KEY_ENTER_COMMAND as s,isDOMShadowRoot as a,isHTMLElement as m,getParentElement as p,getDOMShadowRoots as d,registerEventListener as f,$getSelection as g,$isRangeSelection as h,$getNodeByKey as y}from"lexical";import{useLayoutEffect as x,useEffect as b,useRef as C,useCallback as v,useState as R,useMemo as w,startTransition as E}from"react";import{SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND as I}from"@lexical/react/LexicalTypeaheadMenuPluginUtils";import{getScrollParent as S}from"@lexical/utils";import P from"react-dom";import{jsx as k,jsxs as A}from"react/jsx-runtime";export{MenuOption}from"@lexical/react/LexicalMenuOption";const O=e?x:b,D=t=>{const e=t.closest("#typeahead-menu");if(!e)return;const n=e.getBoundingClientRect();n.top+n.height>window.innerHeight&&e.scrollIntoView({block:"center"}),n.top<0&&e.scrollIntoView({block:"center"}),t.scrollIntoView({block:"nearest"})};function B(t,e){const n=t.getBoundingClientRect(),l=e.getBoundingClientRect();return n.top>=l.top-6&&n.top<=l.bottom+6}function N({index:t,isSelected:e,onClick:n,onMouseEnter:l,option:o}){let r="item";return e&&(r+=" selected"),/*#__PURE__*/A("li",{tabIndex:-1,className:r,ref:o.setRefElement,role:"option","aria-selected":e,id:"typeahead-item-"+t,onMouseEnter:l,onClick:n,children:[o.icon,/*#__PURE__*/k("span",{className:"text",children:o.title})]},o.key)}function T({close:t,editor:e,anchorElementRef:n,resolution:a,options:m,menuRenderFn:p,onSelectOption:d,shouldSplitNodeWithQuery:f=!1,commandPriority:y=o,preselectFirstItem:x=!0}){const[C,E]=R(null),S=null!==C?Math.min(m.length-1,C):null,A=a.match&&a.match.matchingString;b(()=>{x&&E(0)},[A,x]);const B=v(n=>{e.update(()=>{const e=null!=a.match&&f?function(t){const e=g();if(!h(e)||!e.isCollapsed())return null;const n=e.anchor;if("text"!==n.type)return null;const l=n.getNode();if(!l.isSimpleText())return null;const o=n.offset,r=l.getTextContent().slice(0,o),i=t.replaceableString.length,c=o-function(t,e,n){let l=n;for(let n=l;n<=e.length;n++)t.slice(-n)===e.substring(0,n)&&(l=n);return l}(r,t.matchingString,i);if(c<0)return null;let u;return 0===c?[u]=l.splitText(o):[,u]=l.splitText(c,o),u}(a.match):null;d(n,e,t,a.match?a.match.matchingString:"")})},[e,f,a.match,d,t]),T=v(t=>{const n=e.getRootElement();null!==n&&(n.setAttribute("aria-activedescendant","typeahead-item-"+t),E(t))},[e]),M=v(()=>n.current&&m.length?/*#__PURE__*/P.createPortal(/*#__PURE__*/k("div",{className:"typeahead-popover mentions-menu",children:/*#__PURE__*/k("ul",{children:m.map((t,e)=>/*#__PURE__*/k(N,{index:e,isSelected:S===e,onClick:()=>{E(e),B(t)},onMouseEnter:()=>{E(e)},option:t},t.key))})}),n.current):null,[n,m,S,B,E]);b(()=>()=>{const t=e.getRootElement();null!==t&&t.removeAttribute("aria-activedescendant")},[e]),O(()=>{null===m?E(null):null===S&&x&&T(0)},[m,S,T,x]);const $=null==p&&(null===m||!m.length);b(()=>l(e.registerCommand(I,({option:t})=>!(!t.ref||null==t.ref.current)&&(D(t.ref.current),!0),y)),[e,T,y]),b(()=>l(e.registerCommand(r,t=>{const n=t;if($)return!1;const l=null===S?0:S!==m.length-1?S+1:0;T(l);const o=m[l];return o?(o.ref&&o.ref.current&&e.dispatchCommand(I,{index:l,option:o}),n.preventDefault(),n.stopImmediatePropagation(),!0):(T(-1),n.preventDefault(),n.stopImmediatePropagation(),!0)},y),e.registerCommand(i,t=>{const e=t;if($)return!1;const n=null===S?m.length-1:0!==S?S-1:m.length-1;T(n);const l=m[n];return l?(l.ref&&l.ref.current&&D(l.ref.current),e.preventDefault(),e.stopImmediatePropagation(),!0):(T(-1),e.preventDefault(),e.stopImmediatePropagation(),!0)},y),e.registerCommand(c,e=>{const n=e;return!$&&(n.preventDefault(),n.stopImmediatePropagation(),t(),!0)},y),e.registerCommand(u,t=>{const e=t;return null!==m&&null!==S&&null!=m[S]&&(e.preventDefault(),e.stopImmediatePropagation(),B(m[S]),!0)},y),e.registerCommand(s,t=>!(null===m||null===S||null==m[S]||t&&t.shiftKey)&&(null!==t&&(t.preventDefault(),t.stopImmediatePropagation()),B(m[S]),!0),y)),[B,t,e,m,$,S,T,y]);const F=w(()=>({options:m,selectOptionAndCleanUp:B,selectedIndex:S,setHighlightedIndex:E}),[B,S,m]);return null!=p?p(n,F,a.match?a.match.matchingString:""):M()}function M(t,e){null!=e&&(t.className=e),t.setAttribute("aria-label","Typeahead menu"),t.setAttribute("role","listbox"),t.style.display="block",t.style.position="absolute"}function $(t){if("static"!==t.position)return!0;const e=t.willChange;return"none"!==t.transform||"none"!==t.perspective||"none"!==t.filter||"none"!==t.backdropFilter||t.contain.includes("paint")||t.contain.includes("layout")||t.contain.includes("strict")||t.contain.includes("content")||e.includes("transform")||e.includes("perspective")||e.includes("filter")||e.includes("contain")}function F(o,r,i,c,u=!0){const[s]=t(),g=c??function(t){if(!e)return;const n=t.getRootElement();if(null!==n){const t=n.getRootNode();return a(t)?t:n.ownerDocument.body}return document.body}(s),h=e?n(s.getRootElement()).createElement("div"):null,y=C(h),x=v(()=>{if(null===y.current||void 0===g)return;y.current.style.top=y.current.style.bottom;const t=s.getRootElement(),e=y.current,n=e.firstChild;if(null!==t&&null!==o){const{left:l,top:r,width:c,height:s}=o.getRect(),d=y.current.offsetHeight,f=function(t){const e=a(t)?t.host:t;for(let t=m(e)?e:null;null!==t;t=p(t)){const e=t.ownerDocument.defaultView;if(null===e)break;if($(e.getComputedStyle(t))){const e=t.getBoundingClientRect();return{left:e.left+t.clientLeft-t.scrollLeft,top:e.top+t.clientTop-t.scrollTop}}}return null}(g),h=t=>null!==f?t-f.left:t+window.pageXOffset,x=t=>null!==f?t-f.top:t+(u?window.pageYOffset:0);if(e.style.top=`${x(r+d+3)}px`,e.style.left=`${h(l)}px`,e.style.height=`${s}px`,e.style.width=`${c}px`,null!==n){n.style.top=`${r}`;const o=n.getBoundingClientRect(),i=o.height,c=o.width,u=t.getBoundingClientRect();l+c>u.right&&(e.style.left=`${h(u.right-c)}px`),(r+i>window.innerHeight||r+i>u.bottom)&&r-u.top>i+s&&(e.style.top=`${x(r-i-s)}px`)}e.isConnected||(M(e,i),g.append(e)),e.setAttribute("id","typeahead-menu"),t.setAttribute("aria-controls","typeahead-menu")}},[s,o,u,i,g]);b(()=>{const t=s.getRootElement();return null!==o&&x(),()=>{null!==t&&t.removeAttribute("aria-controls");const e=y.current;null!==e&&e.isConnected&&(e.remove(),e.removeAttribute("id"))}},[s,x,o]);const R=v(t=>{null!==o&&(t||r(null))},[o,r]);return function(e,n,o,r){const[i]=t();b(()=>{if(null!=n&&null!=e){const t=i.getRootElement(),e=null!=t?S(t,!1):document.body;let c=!1,u=B(n,e);const s=function(){c||(window.requestAnimationFrame(function(){o(),c=!1}),c=!0);const t=B(n,e);t!==u&&(u=t,null!=r&&r(t))},a=new ResizeObserver(o),m=d(t??n);return a.observe(n),l(f(window,"resize",o),f(document,"scroll",s,{capture:!0,passive:!0}),...m.map(t=>f(t,"scroll",s,{capture:!0,passive:!0})),()=>a.unobserve(n))}},[n,i,r,o,e])}(o,y.current,x,R),null!=h&&h===y.current&&(M(h,i),null!=g&&g.append(h)),y}function L({options:e,nodeKey:n,onClose:l,onOpen:r,onSelectOption:i,menuRenderFn:c,anchorClassName:u,commandPriority:s=o,parent:a}){const[m]=t(),[p,d]=R(null),f=F(p,d,u,a),g=v(()=>{d(null),null!=l&&null!==p&&l()},[l,p]),h=v(t=>{d(t),null!=r&&null===p&&r(t)},[r,p]),x=v(()=>{n?m.update(()=>{const t=y(n),e=m.getElementByKey(n);null!=t&&null!=e&&null==p&&E(()=>h({getRect:()=>e.getBoundingClientRect()}))}):null==n&&null!=p&&g()},[g,m,n,h,p]);return b(()=>{x()},[x,n]),b(()=>{if(null!=n)return m.registerUpdateListener(({dirtyElements:t})=>{t.get(n)&&x()})},[m,x,n]),null===f.current||null===p||null===m?null:/*#__PURE__*/k(T,{close:g,resolution:p,editor:m,anchorElementRef:f,options:e,menuRenderFn:c,onSelectOption:i,commandPriority:s})}export{L as LexicalNodeMenuPlugin};
|
|
@@ -5,43 +5,11 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import { type CommandListenerPriority, type LexicalCommand, type TextNode } from 'lexical';
|
|
8
|
+
import { type CommandListenerPriority, type TextNode } from 'lexical';
|
|
10
9
|
import { type JSX } from 'react';
|
|
11
10
|
import { MenuOption, type MenuRenderFn, type MenuResolution, type MenuTextMatch, type TriggerFn } from './shared/LexicalMenu';
|
|
12
|
-
/**
|
|
13
|
-
* The default set of punctuation characters (as a character-class fragment)
|
|
14
|
-
* that terminate a typeahead query. Used as the default `punctuation` option of
|
|
15
|
-
* {@link useBasicTypeaheadTriggerMatch}.
|
|
16
|
-
*/
|
|
17
|
-
export declare const PUNCTUATION = "\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";
|
|
18
11
|
export { useDynamicPositioning } from './shared/LexicalMenu';
|
|
19
|
-
|
|
20
|
-
export declare const getScrollParent: typeof getScrollParent_;
|
|
21
|
-
/**
|
|
22
|
-
* Command dispatched while the typeahead menu is open to scroll the option at
|
|
23
|
-
* the given `index` into view. The default menu renderer listens for it; custom
|
|
24
|
-
* {@link MenuRenderFn}s can handle it to implement their own scrolling.
|
|
25
|
-
*/
|
|
26
|
-
export declare const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND: LexicalCommand<{
|
|
27
|
-
index: number;
|
|
28
|
-
option: MenuOption;
|
|
29
|
-
}>;
|
|
30
|
-
/**
|
|
31
|
-
* Builds a {@link TriggerFn} for the common case of a single-character
|
|
32
|
-
* `trigger` (such as `@` or `#`) followed by a query. The returned function
|
|
33
|
-
* matches when the trigger is preceded by whitespace or the start of the line
|
|
34
|
-
* and is followed by between `minLength` and `maxLength` non-`punctuation`
|
|
35
|
-
* characters (optionally allowing whitespace).
|
|
36
|
-
*
|
|
37
|
-
* @returns A memoized trigger function for {@link LexicalTypeaheadMenuPlugin}.
|
|
38
|
-
*/
|
|
39
|
-
export declare function useBasicTypeaheadTriggerMatch(trigger: string, { minLength, maxLength, punctuation, allowWhitespace, }: {
|
|
40
|
-
minLength?: number;
|
|
41
|
-
maxLength?: number;
|
|
42
|
-
punctuation?: string;
|
|
43
|
-
allowWhitespace?: boolean;
|
|
44
|
-
}): TriggerFn;
|
|
12
|
+
export { getScrollParent, PUNCTUATION, SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, useBasicTypeaheadTriggerMatch, } from '@lexical/react/LexicalTypeaheadMenuPluginUtils';
|
|
45
13
|
/**
|
|
46
14
|
* Props for the {@link LexicalTypeaheadMenuPlugin} component.
|
|
47
15
|
*/
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
11
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
12
|
-
var utils = require('@lexical/utils');
|
|
13
12
|
var lexical = require('lexical');
|
|
14
13
|
var react = require('react');
|
|
14
|
+
var LexicalTypeaheadMenuPluginUtils = require('@lexical/react/LexicalTypeaheadMenuPluginUtils');
|
|
15
|
+
var utils = require('@lexical/utils');
|
|
15
16
|
var ReactDOM = require('react-dom');
|
|
16
17
|
var jsxRuntime = require('react/jsx-runtime');
|
|
18
|
+
var LexicalMenuOption = require('@lexical/react/LexicalMenuOption');
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -37,30 +39,6 @@ const useLayoutEffectImpl = lexical.CAN_USE_DOM ? react.useLayoutEffect : react.
|
|
|
37
39
|
*
|
|
38
40
|
*/
|
|
39
41
|
|
|
40
|
-
/**
|
|
41
|
-
* The base class for an item shown in a {@link LexicalTypeaheadMenuPlugin} or
|
|
42
|
-
* {@link LexicalNodeMenuPlugin} menu. Each option has a unique `key` and a `ref`
|
|
43
|
-
* to its rendered element (used for scrolling and keyboard navigation).
|
|
44
|
-
* Subclass it to attach your own data such as a label or callback.
|
|
45
|
-
*/
|
|
46
|
-
class MenuOption {
|
|
47
|
-
key;
|
|
48
|
-
ref;
|
|
49
|
-
icon;
|
|
50
|
-
title;
|
|
51
|
-
constructor(key) {
|
|
52
|
-
this.key = key;
|
|
53
|
-
this.ref = {
|
|
54
|
-
current: null
|
|
55
|
-
};
|
|
56
|
-
this.setRefElement = this.setRefElement.bind(this);
|
|
57
|
-
}
|
|
58
|
-
setRefElement(element) {
|
|
59
|
-
this.ref = {
|
|
60
|
-
current: element
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
42
|
|
|
65
43
|
/**
|
|
66
44
|
* A render function for a menu's contents. It receives the anchor element ref,
|
|
@@ -202,7 +180,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
202
180
|
}
|
|
203
181
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
204
182
|
}
|
|
205
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND$1 = /* @__PURE__ */lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
206
183
|
function MenuItem({
|
|
207
184
|
index,
|
|
208
185
|
isSelected,
|
|
@@ -306,7 +283,7 @@ function LexicalMenu({
|
|
|
306
283
|
// has to be able to arrow through and dismiss.
|
|
307
284
|
const rendersNothing = menuRenderFnProp == null && (options === null || !options.length);
|
|
308
285
|
react.useEffect(() => {
|
|
309
|
-
return lexical.mergeRegister(editor.registerCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND
|
|
286
|
+
return lexical.mergeRegister(editor.registerCommand(LexicalTypeaheadMenuPluginUtils.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, ({
|
|
310
287
|
option
|
|
311
288
|
}) => {
|
|
312
289
|
if (option.ref && option.ref.current != null) {
|
|
@@ -335,7 +312,7 @@ function LexicalMenu({
|
|
|
335
312
|
return true;
|
|
336
313
|
}
|
|
337
314
|
if (option.ref && option.ref.current) {
|
|
338
|
-
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND
|
|
315
|
+
editor.dispatchCommand(LexicalTypeaheadMenuPluginUtils.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
339
316
|
index: newSelectedIndex,
|
|
340
317
|
option
|
|
341
318
|
});
|
|
@@ -598,7 +575,6 @@ function useMenuAnchorRef(resolution, setResolution, className, parent, shouldIn
|
|
|
598
575
|
*
|
|
599
576
|
*/
|
|
600
577
|
|
|
601
|
-
const PUNCTUATION = '\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%\'"~=<>_:;';
|
|
602
578
|
function getTextUpToAnchor(selection) {
|
|
603
579
|
const anchor = selection.anchor;
|
|
604
580
|
if (anchor.type !== 'text') {
|
|
@@ -657,50 +633,6 @@ function isSelectionOnEntityBoundary(editor, offset) {
|
|
|
657
633
|
return false;
|
|
658
634
|
});
|
|
659
635
|
}
|
|
660
|
-
/** @deprecated Moved to `@lexical/utils`. Import `getScrollParent` from there. */
|
|
661
|
-
const getScrollParent = utils.getScrollParent;
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* Command dispatched while the typeahead menu is open to scroll the option at
|
|
665
|
-
* the given `index` into view. The default menu renderer listens for it; custom
|
|
666
|
-
* {@link MenuRenderFn}s can handle it to implement their own scrolling.
|
|
667
|
-
*/
|
|
668
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = /* @__PURE__ */lexical.createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* Builds a {@link TriggerFn} for the common case of a single-character
|
|
672
|
-
* `trigger` (such as `@` or `#`) followed by a query. The returned function
|
|
673
|
-
* matches when the trigger is preceded by whitespace or the start of the line
|
|
674
|
-
* and is followed by between `minLength` and `maxLength` non-`punctuation`
|
|
675
|
-
* characters (optionally allowing whitespace).
|
|
676
|
-
*
|
|
677
|
-
* @returns A memoized trigger function for {@link LexicalTypeaheadMenuPlugin}.
|
|
678
|
-
*/
|
|
679
|
-
function useBasicTypeaheadTriggerMatch(trigger, {
|
|
680
|
-
minLength = 1,
|
|
681
|
-
maxLength = 75,
|
|
682
|
-
punctuation = PUNCTUATION,
|
|
683
|
-
allowWhitespace = false
|
|
684
|
-
}) {
|
|
685
|
-
return react.useCallback(text => {
|
|
686
|
-
const validCharsSuffix = allowWhitespace ? '' : '\\s';
|
|
687
|
-
const validChars = '[^' + trigger + punctuation + validCharsSuffix + ']';
|
|
688
|
-
const TypeaheadTriggerRegex = new RegExp('(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + '){0,' + maxLength + '})' + ')$');
|
|
689
|
-
const match = TypeaheadTriggerRegex.exec(text);
|
|
690
|
-
if (match !== null) {
|
|
691
|
-
const maybeLeadingWhitespace = match[1];
|
|
692
|
-
const matchingString = match[3];
|
|
693
|
-
if (matchingString.length >= minLength) {
|
|
694
|
-
return {
|
|
695
|
-
leadOffset: match.index + maybeLeadingWhitespace.length,
|
|
696
|
-
matchingString,
|
|
697
|
-
replaceableString: match[2]
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
return null;
|
|
702
|
-
}, [allowWhitespace, trigger, punctuation, maxLength, minLength]);
|
|
703
|
-
}
|
|
704
636
|
|
|
705
637
|
/**
|
|
706
638
|
* Props for the {@link LexicalTypeaheadMenuPlugin} component.
|
|
@@ -816,10 +748,10 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
816
748
|
});
|
|
817
749
|
}
|
|
818
750
|
|
|
751
|
+
exports.PUNCTUATION = LexicalTypeaheadMenuPluginUtils.PUNCTUATION;
|
|
752
|
+
exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = LexicalTypeaheadMenuPluginUtils.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND;
|
|
753
|
+
exports.getScrollParent = LexicalTypeaheadMenuPluginUtils.getScrollParent;
|
|
754
|
+
exports.useBasicTypeaheadTriggerMatch = LexicalTypeaheadMenuPluginUtils.useBasicTypeaheadTriggerMatch;
|
|
755
|
+
exports.MenuOption = LexicalMenuOption.MenuOption;
|
|
819
756
|
exports.LexicalTypeaheadMenuPlugin = LexicalTypeaheadMenuPlugin;
|
|
820
|
-
exports.MenuOption = MenuOption;
|
|
821
|
-
exports.PUNCTUATION = PUNCTUATION;
|
|
822
|
-
exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND;
|
|
823
|
-
exports.getScrollParent = getScrollParent;
|
|
824
|
-
exports.useBasicTypeaheadTriggerMatch = useBasicTypeaheadTriggerMatch;
|
|
825
757
|
exports.useDynamicPositioning = useDynamicPositioning;
|
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
10
|
-
import {
|
|
11
|
-
import { CAN_USE_DOM, getDOMShadowRoots, mergeRegister, registerEventListener, getRootOwnerDocument, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, isDOMShadowRoot, isHTMLElement, getParentElement, $getSelection, $isRangeSelection, createCommand, $isTextNode, getDOMSelection, getDOMSelectionPoints } from 'lexical';
|
|
10
|
+
import { CAN_USE_DOM, getDOMShadowRoots, mergeRegister, registerEventListener, getRootOwnerDocument, COMMAND_PRIORITY_LOW, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, isDOMShadowRoot, isHTMLElement, getParentElement, $getSelection, $isRangeSelection, $isTextNode, getDOMSelection, getDOMSelectionPoints } from 'lexical';
|
|
12
11
|
import { useLayoutEffect, useEffect, useRef, useCallback, useState, useMemo, startTransition } from 'react';
|
|
12
|
+
import { SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND } from '@lexical/react/LexicalTypeaheadMenuPluginUtils';
|
|
13
|
+
export { PUNCTUATION, SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, getScrollParent, useBasicTypeaheadTriggerMatch } from '@lexical/react/LexicalTypeaheadMenuPluginUtils';
|
|
14
|
+
import { getScrollParent } from '@lexical/utils';
|
|
13
15
|
import ReactDOM from 'react-dom';
|
|
14
16
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
17
|
+
export { MenuOption } from '@lexical/react/LexicalMenuOption';
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -35,30 +38,6 @@ const useLayoutEffectImpl = CAN_USE_DOM ? useLayoutEffect : useEffect;
|
|
|
35
38
|
*
|
|
36
39
|
*/
|
|
37
40
|
|
|
38
|
-
/**
|
|
39
|
-
* The base class for an item shown in a {@link LexicalTypeaheadMenuPlugin} or
|
|
40
|
-
* {@link LexicalNodeMenuPlugin} menu. Each option has a unique `key` and a `ref`
|
|
41
|
-
* to its rendered element (used for scrolling and keyboard navigation).
|
|
42
|
-
* Subclass it to attach your own data such as a label or callback.
|
|
43
|
-
*/
|
|
44
|
-
class MenuOption {
|
|
45
|
-
key;
|
|
46
|
-
ref;
|
|
47
|
-
icon;
|
|
48
|
-
title;
|
|
49
|
-
constructor(key) {
|
|
50
|
-
this.key = key;
|
|
51
|
-
this.ref = {
|
|
52
|
-
current: null
|
|
53
|
-
};
|
|
54
|
-
this.setRefElement = this.setRefElement.bind(this);
|
|
55
|
-
}
|
|
56
|
-
setRefElement(element) {
|
|
57
|
-
this.ref = {
|
|
58
|
-
current: element
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
41
|
|
|
63
42
|
/**
|
|
64
43
|
* A render function for a menu's contents. It receives the anchor element ref,
|
|
@@ -157,7 +136,7 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
157
136
|
useEffect(() => {
|
|
158
137
|
if (targetElement != null && resolution != null) {
|
|
159
138
|
const rootElement = editor.getRootElement();
|
|
160
|
-
const rootScrollParent = rootElement != null ? getScrollParent
|
|
139
|
+
const rootScrollParent = rootElement != null ? getScrollParent(rootElement, false) :
|
|
161
140
|
// eslint-disable-next-line no-restricted-syntax
|
|
162
141
|
document.body;
|
|
163
142
|
let ticking = false;
|
|
@@ -200,7 +179,6 @@ function useDynamicPositioning(resolution, targetElement, onReposition, onVisibi
|
|
|
200
179
|
}
|
|
201
180
|
}, [targetElement, editor, onVisibilityChange, onReposition, resolution]);
|
|
202
181
|
}
|
|
203
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND$1 = /* @__PURE__ */createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
204
182
|
function MenuItem({
|
|
205
183
|
index,
|
|
206
184
|
isSelected,
|
|
@@ -304,7 +282,7 @@ function LexicalMenu({
|
|
|
304
282
|
// has to be able to arrow through and dismiss.
|
|
305
283
|
const rendersNothing = menuRenderFnProp == null && (options === null || !options.length);
|
|
306
284
|
useEffect(() => {
|
|
307
|
-
return mergeRegister(editor.registerCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND
|
|
285
|
+
return mergeRegister(editor.registerCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, ({
|
|
308
286
|
option
|
|
309
287
|
}) => {
|
|
310
288
|
if (option.ref && option.ref.current != null) {
|
|
@@ -333,7 +311,7 @@ function LexicalMenu({
|
|
|
333
311
|
return true;
|
|
334
312
|
}
|
|
335
313
|
if (option.ref && option.ref.current) {
|
|
336
|
-
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND
|
|
314
|
+
editor.dispatchCommand(SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND, {
|
|
337
315
|
index: newSelectedIndex,
|
|
338
316
|
option
|
|
339
317
|
});
|
|
@@ -596,7 +574,6 @@ function useMenuAnchorRef(resolution, setResolution, className, parent, shouldIn
|
|
|
596
574
|
*
|
|
597
575
|
*/
|
|
598
576
|
|
|
599
|
-
const PUNCTUATION = '\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%\'"~=<>_:;';
|
|
600
577
|
function getTextUpToAnchor(selection) {
|
|
601
578
|
const anchor = selection.anchor;
|
|
602
579
|
if (anchor.type !== 'text') {
|
|
@@ -655,50 +632,6 @@ function isSelectionOnEntityBoundary(editor, offset) {
|
|
|
655
632
|
return false;
|
|
656
633
|
});
|
|
657
634
|
}
|
|
658
|
-
/** @deprecated Moved to `@lexical/utils`. Import `getScrollParent` from there. */
|
|
659
|
-
const getScrollParent = getScrollParent$1;
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* Command dispatched while the typeahead menu is open to scroll the option at
|
|
663
|
-
* the given `index` into view. The default menu renderer listens for it; custom
|
|
664
|
-
* {@link MenuRenderFn}s can handle it to implement their own scrolling.
|
|
665
|
-
*/
|
|
666
|
-
const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND = /* @__PURE__ */createCommand('SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND');
|
|
667
|
-
|
|
668
|
-
/**
|
|
669
|
-
* Builds a {@link TriggerFn} for the common case of a single-character
|
|
670
|
-
* `trigger` (such as `@` or `#`) followed by a query. The returned function
|
|
671
|
-
* matches when the trigger is preceded by whitespace or the start of the line
|
|
672
|
-
* and is followed by between `minLength` and `maxLength` non-`punctuation`
|
|
673
|
-
* characters (optionally allowing whitespace).
|
|
674
|
-
*
|
|
675
|
-
* @returns A memoized trigger function for {@link LexicalTypeaheadMenuPlugin}.
|
|
676
|
-
*/
|
|
677
|
-
function useBasicTypeaheadTriggerMatch(trigger, {
|
|
678
|
-
minLength = 1,
|
|
679
|
-
maxLength = 75,
|
|
680
|
-
punctuation = PUNCTUATION,
|
|
681
|
-
allowWhitespace = false
|
|
682
|
-
}) {
|
|
683
|
-
return useCallback(text => {
|
|
684
|
-
const validCharsSuffix = allowWhitespace ? '' : '\\s';
|
|
685
|
-
const validChars = '[^' + trigger + punctuation + validCharsSuffix + ']';
|
|
686
|
-
const TypeaheadTriggerRegex = new RegExp('(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + '){0,' + maxLength + '})' + ')$');
|
|
687
|
-
const match = TypeaheadTriggerRegex.exec(text);
|
|
688
|
-
if (match !== null) {
|
|
689
|
-
const maybeLeadingWhitespace = match[1];
|
|
690
|
-
const matchingString = match[3];
|
|
691
|
-
if (matchingString.length >= minLength) {
|
|
692
|
-
return {
|
|
693
|
-
leadOffset: match.index + maybeLeadingWhitespace.length,
|
|
694
|
-
matchingString,
|
|
695
|
-
replaceableString: match[2]
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
return null;
|
|
700
|
-
}, [allowWhitespace, trigger, punctuation, maxLength, minLength]);
|
|
701
|
-
}
|
|
702
635
|
|
|
703
636
|
/**
|
|
704
637
|
* Props for the {@link LexicalTypeaheadMenuPlugin} component.
|
|
@@ -814,4 +747,4 @@ function LexicalTypeaheadMenuPlugin({
|
|
|
814
747
|
});
|
|
815
748
|
}
|
|
816
749
|
|
|
817
|
-
export { LexicalTypeaheadMenuPlugin,
|
|
750
|
+
export { LexicalTypeaheadMenuPlugin, useDynamicPositioning };
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("@lexical/utils"),n=require("lexical"),l=require("react"),o=require("react-dom"),r=require("react/jsx-runtime");const i=n.CAN_USE_DOM?l.useLayoutEffect:l.useEffect;const s=e=>{const t=e.closest("#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 c(e,t){const n=e.getBoundingClientRect(),l=t.getBoundingClientRect();return n.top>=l.top-6&&n.top<=l.bottom+6}function u(o,r,i,s){const[u]=e.useLexicalComposerContext();l.useEffect(()=>{if(null!=r&&null!=o){const e=u.getRootElement(),l=null!=e?t.getScrollParent(e,!1):document.body;let o=!1,a=c(r,l);const d=function(){o||(window.requestAnimationFrame(function(){i(),o=!1}),o=!0);const e=c(r,l);e!==a&&(a=e,null!=s&&s(e))},f=new ResizeObserver(i),m=n.getDOMShadowRoots(e??r);return f.observe(r),n.mergeRegister(n.registerEventListener(window,"resize",i),n.registerEventListener(document,"scroll",d,{capture:!0,passive:!0}),...m.map(e=>n.registerEventListener(e,"scroll",d,{capture:!0,passive:!0})),()=>f.unobserve(r))}},[r,u,s,i,o])}const a=/* @__PURE__ */n.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function d({index:e,isSelected:t,onClick:n,onMouseEnter:l,option:o}){let i="item";return t&&(i+=" selected"),/*#__PURE__*/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,/*#__PURE__*/r.jsx("span",{className:"text",children:o.title})]},o.key)}function f({close:e,editor:t,anchorElementRef:c,resolution:u,options:f,menuRenderFn:m,onSelectOption:p,shouldSplitNodeWithQuery:g=!1,commandPriority:h=n.COMMAND_PRIORITY_LOW,preselectFirstItem:C=!0}){const[E,x]=l.useState(null),R=null!==E?Math.min(f.length-1,E):null,O=u.match&&u.match.matchingString;l.useEffect(()=>{C&&x(0)},[O,C]);const y=l.useCallback(l=>{t.update(()=>{const t=null!=u.match&&g?function(e){const t=n.$getSelection();if(!n.$isRangeSelection(t)||!t.isCollapsed())return null;const l=t.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,c=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(c<0)return null;let u;return 0===c?[u]=o.splitText(r):[,u]=o.splitText(c,r),u}(u.match):null;p(l,t,e,u.match?u.match.matchingString:"")})},[t,g,u.match,p,e]),S=l.useCallback(e=>{const n=t.getRootElement();null!==n&&(n.setAttribute("aria-activedescendant","typeahead-item-"+e),x(e))},[t]),b=l.useCallback(()=>c.current&&f.length?/*#__PURE__*/o.createPortal(/*#__PURE__*/r.jsx("div",{className:"typeahead-popover mentions-menu",children:/*#__PURE__*/r.jsx("ul",{children:f.map((e,t)=>/*#__PURE__*/r.jsx(d,{index:t,isSelected:R===t,onClick:()=>{x(t),y(e)},onMouseEnter:()=>{x(t)},option:e},e.key))})}),c.current):null,[c,f,R,y,x]);l.useEffect(()=>()=>{const e=t.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[t]),i(()=>{null===f?x(null):null===R&&C&&S(0)},[f,R,S,C]);const _=null==m&&(null===f||!f.length);l.useEffect(()=>n.mergeRegister(t.registerCommand(a,({option:e})=>!(!e.ref||null==e.ref.current)&&(s(e.ref.current),!0),h)),[t,S,h]),l.useEffect(()=>n.mergeRegister(t.registerCommand(n.KEY_ARROW_DOWN_COMMAND,e=>{const n=e;if(_)return!1;const l=null===R?0:R!==f.length-1?R+1:0;S(l);const o=f[l];return o?(o.ref&&o.ref.current&&t.dispatchCommand(a,{index:l,option:o}),n.preventDefault(),n.stopImmediatePropagation(),!0):(S(-1),n.preventDefault(),n.stopImmediatePropagation(),!0)},h),t.registerCommand(n.KEY_ARROW_UP_COMMAND,e=>{const t=e;if(_)return!1;const n=null===R?f.length-1:0!==R?R-1:f.length-1;S(n);const l=f[n];return l?(l.ref&&l.ref.current&&s(l.ref.current),t.preventDefault(),t.stopImmediatePropagation(),!0):(S(-1),t.preventDefault(),t.stopImmediatePropagation(),!0)},h),t.registerCommand(n.KEY_ESCAPE_COMMAND,t=>{const n=t;return!_&&(n.preventDefault(),n.stopImmediatePropagation(),e(),!0)},h),t.registerCommand(n.KEY_TAB_COMMAND,e=>{const t=e;return null!==f&&null!==R&&null!=f[R]&&(t.preventDefault(),t.stopImmediatePropagation(),y(f[R]),!0)},h),t.registerCommand(n.KEY_ENTER_COMMAND,e=>!(null===f||null===R||null==f[R]||e&&e.shiftKey)&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),y(f[R]),!0),h)),[y,e,t,f,_,R,S,h]);const M=l.useMemo(()=>({options:f,selectOptionAndCleanUp:y,selectedIndex:R,setHighlightedIndex:x}),[y,R,f]);return null!=m?m(c,M,u.match?u.match.matchingString:""):b()}function m(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 p(e){if("static"!==e.position)return!0;const t=e.willChange;return"none"!==e.transform||"none"!==e.perspective||"none"!==e.filter||"none"!==e.backdropFilter||e.contain.includes("paint")||e.contain.includes("layout")||e.contain.includes("strict")||e.contain.includes("content")||t.includes("transform")||t.includes("perspective")||t.includes("filter")||t.includes("contain")}function g(t,o,r,i,s=!0){const[c]=e.useLexicalComposerContext(),a=i??function(e){if(!n.CAN_USE_DOM)return;const t=e.getRootElement();if(null!==t){const e=t.getRootNode();return n.isDOMShadowRoot(e)?e:t.ownerDocument.body}return document.body}(c),d=n.CAN_USE_DOM?n.getRootOwnerDocument(c.getRootElement()).createElement("div"):null,f=l.useRef(d),g=l.useCallback(()=>{if(null===f.current||void 0===a)return;f.current.style.top=f.current.style.bottom;const e=c.getRootElement(),l=f.current,o=l.firstChild;if(null!==e&&null!==t){const{left:i,top:c,width:u,height:d}=t.getRect(),g=f.current.offsetHeight,h=function(e){const t=n.isDOMShadowRoot(e)?e.host:e;for(let e=n.isHTMLElement(t)?t:null;null!==e;e=n.getParentElement(e)){const t=e.ownerDocument.defaultView;if(null===t)break;if(p(t.getComputedStyle(e))){const t=e.getBoundingClientRect();return{left:t.left+e.clientLeft-e.scrollLeft,top:t.top+e.clientTop-e.scrollTop}}}return null}(a),C=e=>null!==h?e-h.left:e+window.pageXOffset,E=e=>null!==h?e-h.top:e+(s?window.pageYOffset:0);if(l.style.top=`${E(c+g+3)}px`,l.style.left=`${C(i)}px`,l.style.height=`${d}px`,l.style.width=`${u}px`,null!==o){o.style.top=`${c}`;const t=o.getBoundingClientRect(),n=t.height,r=t.width,s=e.getBoundingClientRect();i+r>s.right&&(l.style.left=`${C(s.right-r)}px`),(c+n>window.innerHeight||c+n>s.bottom)&&c-s.top>n+d&&(l.style.top=`${E(c-n-d)}px`)}l.isConnected||(m(l,r),a.append(l)),l.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[c,t,s,r,a]);l.useEffect(()=>{const e=c.getRootElement();return null!==t&&g(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=f.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}},[c,g,t]);const h=l.useCallback(e=>{null!==t&&(e||o(null))},[t,o]);return u(t,f.current,g,h),null!=d&&d===f.current&&(m(d,r),null!=a&&a.append(d)),f}const h="\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";const C=t.getScrollParent,E=/* @__PURE__ */n.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");exports.LexicalTypeaheadMenuPlugin=function({options:t,onQueryChange:o,onSelectOption:i,onOpen:s,onClose:c,menuRenderFn:u,triggerFn:a,anchorClassName:d,commandPriority:m=n.COMMAND_PRIORITY_LOW,parent:p,preselectFirstItem:h=!0,ignoreEntityBoundary:C=!1}){const[E]=e.useLexicalComposerContext(),[x,R]=l.useState(null),O=g(x,R,d,p),y=l.useCallback(()=>{if(null===x)return;const e=()=>{R(null)};let t;try{t=c&&c()}finally{t?t.then(e,e):e()}},[c,x]),S=l.useCallback(e=>{R(e),null!=s&&null===x&&s(e)},[s,x]);return l.useEffect(()=>{const e=E.registerUpdateListener(()=>{E.read("latest",()=>{if(!E.isEditable())return void y();const e=()=>{E.isComposing()||y()},t=E._window||window,r=t.document.createRange(),i=n.$getSelection(),s=function(e){let t=null;return e.read("latest",()=>{const e=n.$getSelection();n.$isRangeSelection(e)&&(t=function(e){const t=e.anchor;if("text"!==t.type)return null;const n=t.getNode();if(!n.isSimpleText())return null;const l=t.offset;return n.getTextContent().slice(0,l)}(e))}),t}(E);if(!n.$isRangeSelection(i)||!i.isCollapsed()||null===s||null===r)return void e();const c=a(s,E);if(o(c?c.matchingString:null),null!==c&&(C||!function(e,t){return 0===t&&e.read("latest",()=>{const e=n.$getSelection();if(n.$isRangeSelection(e)){const t=e.anchor.getNode().getPreviousSibling();return n.$isTextNode(t)&&t.isTextEntity()}return!1})}(E,c.leadOffset))){const e=function(e,t,l,o){const r=n.getDOMSelection(l);if(null===r||!r.isCollapsed)return!1;const i=n.getDOMSelectionPoints(r,o),s=i.anchorNode,c=e,u=i.anchorOffset;if(null==s||null==u)return!1;try{t.setStart(s,c),t.setEnd(s,u)}catch(e){return!1}return!0}(c.leadOffset,r,t,E.getRootElement());if(null!==e)return void l.startTransition(()=>S({getRect:()=>r.getBoundingClientRect(),match:c}))}e()})});return()=>{e()}},[E,a,o,x,y,S,C]),l.useEffect(()=>E.registerEditableListener(e=>{e||y()}),[E,y]),null===x||null===E||null===O.current?null:/*#__PURE__*/r.jsx(f,{close:y,resolution:x,editor:E,anchorElementRef:O,options:t,menuRenderFn:u,shouldSplitNodeWithQuery:!0,onSelectOption:i,commandPriority:m,preselectFirstItem:h})},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}}},exports.PUNCTUATION=h,exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND=E,exports.getScrollParent=C,exports.useBasicTypeaheadTriggerMatch=function(e,{minLength:t=1,maxLength:n=75,punctuation:o=h,allowWhitespace:r=!1}){return l.useCallback(l=>{const i=new RegExp("(^|\\s|\\()(["+e+"]((?:"+("[^"+e+o+(r?"":"\\s")+"]")+"){0,"+n+"}))$").exec(l);if(null!==i){const e=i[1],n=i[3];if(n.length>=t)return{leadOffset:i.index+e.length,matchingString:n,replaceableString:i[2]}}return null},[r,e,o,n,t])},exports.useDynamicPositioning=u;
|
|
9
|
+
"use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),n=require("react"),l=require("@lexical/react/LexicalTypeaheadMenuPluginUtils"),o=require("@lexical/utils"),r=require("react-dom"),i=require("react/jsx-runtime"),s=require("@lexical/react/LexicalMenuOption");const c=t.CAN_USE_DOM?n.useLayoutEffect:n.useEffect,u=e=>{const t=e.closest("#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(l,r,i,s){const[c]=e.useLexicalComposerContext();n.useEffect(()=>{if(null!=r&&null!=l){const e=c.getRootElement(),n=null!=e?o.getScrollParent(e,!1):document.body;let l=!1,u=a(r,n);const d=function(){l||(window.requestAnimationFrame(function(){i(),l=!1}),l=!0);const e=a(r,n);e!==u&&(u=e,null!=s&&s(e))},p=new ResizeObserver(i),g=t.getDOMShadowRoots(e??r);return p.observe(r),t.mergeRegister(t.registerEventListener(window,"resize",i),t.registerEventListener(document,"scroll",d,{capture:!0,passive:!0}),...g.map(e=>t.registerEventListener(e,"scroll",d,{capture:!0,passive:!0})),()=>p.unobserve(r))}},[r,c,s,i,l])}function p({index:e,isSelected:t,onClick:n,onMouseEnter:l,option:o}){let r="item";return t&&(r+=" selected"),/*#__PURE__*/i.jsxs("li",{tabIndex:-1,className:r,ref:o.setRefElement,role:"option","aria-selected":t,id:"typeahead-item-"+e,onMouseEnter:l,onClick:n,children:[o.icon,/*#__PURE__*/i.jsx("span",{className:"text",children:o.title})]},o.key)}function g({close:e,editor:o,anchorElementRef:s,resolution:a,options:d,menuRenderFn:g,onSelectOption:m,shouldSplitNodeWithQuery:f=!1,commandPriority:h=t.COMMAND_PRIORITY_LOW,preselectFirstItem:C=!0}){const[E,O]=n.useState(null),x=null!==E?Math.min(d.length-1,E):null,R=a.match&&a.match.matchingString;n.useEffect(()=>{C&&O(0)},[R,C]);const y=n.useCallback(n=>{o.update(()=>{const l=null!=a.match&&f?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,c=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(c<0)return null;let u;return 0===c?[u]=o.splitText(r):[,u]=o.splitText(c,r),u}(a.match):null;m(n,l,e,a.match?a.match.matchingString:"")})},[o,f,a.match,m,e]),S=n.useCallback(e=>{const t=o.getRootElement();null!==t&&(t.setAttribute("aria-activedescendant","typeahead-item-"+e),O(e))},[o]),M=n.useCallback(()=>s.current&&d.length?/*#__PURE__*/r.createPortal(/*#__PURE__*/i.jsx("div",{className:"typeahead-popover mentions-menu",children:/*#__PURE__*/i.jsx("ul",{children:d.map((e,t)=>/*#__PURE__*/i.jsx(p,{index:t,isSelected:x===t,onClick:()=>{O(t),y(e)},onMouseEnter:()=>{O(t)},option:e},e.key))})}),s.current):null,[s,d,x,y,O]);n.useEffect(()=>()=>{const e=o.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[o]),c(()=>{null===d?O(null):null===x&&C&&S(0)},[d,x,S,C]);const _=null==g&&(null===d||!d.length);n.useEffect(()=>t.mergeRegister(o.registerCommand(l.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,({option:e})=>!(!e.ref||null==e.ref.current)&&(u(e.ref.current),!0),h)),[o,S,h]),n.useEffect(()=>t.mergeRegister(o.registerCommand(t.KEY_ARROW_DOWN_COMMAND,e=>{const t=e;if(_)return!1;const n=null===x?0:x!==d.length-1?x+1:0;S(n);const r=d[n];return r?(r.ref&&r.ref.current&&o.dispatchCommand(l.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,{index:n,option:r}),t.preventDefault(),t.stopImmediatePropagation(),!0):(S(-1),t.preventDefault(),t.stopImmediatePropagation(),!0)},h),o.registerCommand(t.KEY_ARROW_UP_COMMAND,e=>{const t=e;if(_)return!1;const n=null===x?d.length-1:0!==x?x-1:d.length-1;S(n);const l=d[n];return l?(l.ref&&l.ref.current&&u(l.ref.current),t.preventDefault(),t.stopImmediatePropagation(),!0):(S(-1),t.preventDefault(),t.stopImmediatePropagation(),!0)},h),o.registerCommand(t.KEY_ESCAPE_COMMAND,t=>{const n=t;return!_&&(n.preventDefault(),n.stopImmediatePropagation(),e(),!0)},h),o.registerCommand(t.KEY_TAB_COMMAND,e=>{const t=e;return null!==d&&null!==x&&null!=d[x]&&(t.preventDefault(),t.stopImmediatePropagation(),y(d[x]),!0)},h),o.registerCommand(t.KEY_ENTER_COMMAND,e=>!(null===d||null===x||null==d[x]||e&&e.shiftKey)&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),y(d[x]),!0),h)),[y,e,o,d,_,x,S,h]);const N=n.useMemo(()=>({options:d,selectOptionAndCleanUp:y,selectedIndex:x,setHighlightedIndex:O}),[y,x,d]);return null!=g?g(s,N,a.match?a.match.matchingString:""):M()}function m(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 f(e){if("static"!==e.position)return!0;const t=e.willChange;return"none"!==e.transform||"none"!==e.perspective||"none"!==e.filter||"none"!==e.backdropFilter||e.contain.includes("paint")||e.contain.includes("layout")||e.contain.includes("strict")||e.contain.includes("content")||t.includes("transform")||t.includes("perspective")||t.includes("filter")||t.includes("contain")}function h(l,o,r,i,s=!0){const[c]=e.useLexicalComposerContext(),u=i??function(e){if(!t.CAN_USE_DOM)return;const n=e.getRootElement();if(null!==n){const e=n.getRootNode();return t.isDOMShadowRoot(e)?e:n.ownerDocument.body}return document.body}(c),a=t.CAN_USE_DOM?t.getRootOwnerDocument(c.getRootElement()).createElement("div"):null,p=n.useRef(a),g=n.useCallback(()=>{if(null===p.current||void 0===u)return;p.current.style.top=p.current.style.bottom;const e=c.getRootElement(),n=p.current,o=n.firstChild;if(null!==e&&null!==l){const{left:i,top:c,width:a,height:d}=l.getRect(),g=p.current.offsetHeight,h=function(e){const n=t.isDOMShadowRoot(e)?e.host:e;for(let e=t.isHTMLElement(n)?n:null;null!==e;e=t.getParentElement(e)){const t=e.ownerDocument.defaultView;if(null===t)break;if(f(t.getComputedStyle(e))){const t=e.getBoundingClientRect();return{left:t.left+e.clientLeft-e.scrollLeft,top:t.top+e.clientTop-e.scrollTop}}}return null}(u),C=e=>null!==h?e-h.left:e+window.pageXOffset,E=e=>null!==h?e-h.top:e+(s?window.pageYOffset:0);if(n.style.top=`${E(c+g+3)}px`,n.style.left=`${C(i)}px`,n.style.height=`${d}px`,n.style.width=`${a}px`,null!==o){o.style.top=`${c}`;const t=o.getBoundingClientRect(),l=t.height,r=t.width,s=e.getBoundingClientRect();i+r>s.right&&(n.style.left=`${C(s.right-r)}px`),(c+l>window.innerHeight||c+l>s.bottom)&&c-s.top>l+d&&(n.style.top=`${E(c-l-d)}px`)}n.isConnected||(m(n,r),u.append(n)),n.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[c,l,s,r,u]);n.useEffect(()=>{const e=c.getRootElement();return null!==l&&g(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=p.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}},[c,g,l]);const h=n.useCallback(e=>{null!==l&&(e||o(null))},[l,o]);return d(l,p.current,g,h),null!=a&&a===p.current&&(m(a,r),null!=u&&u.append(a)),p}exports.PUNCTUATION=l.PUNCTUATION,exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND=l.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,exports.getScrollParent=l.getScrollParent,exports.useBasicTypeaheadTriggerMatch=l.useBasicTypeaheadTriggerMatch,exports.MenuOption=s.MenuOption,exports.LexicalTypeaheadMenuPlugin=function({options:l,onQueryChange:o,onSelectOption:r,onOpen:s,onClose:c,menuRenderFn:u,triggerFn:a,anchorClassName:d,commandPriority:p=t.COMMAND_PRIORITY_LOW,parent:m,preselectFirstItem:f=!0,ignoreEntityBoundary:C=!1}){const[E]=e.useLexicalComposerContext(),[O,x]=n.useState(null),R=h(O,x,d,m),y=n.useCallback(()=>{if(null===O)return;const e=()=>{x(null)};let t;try{t=c&&c()}finally{t?t.then(e,e):e()}},[c,O]),S=n.useCallback(e=>{x(e),null!=s&&null===O&&s(e)},[s,O]);return n.useEffect(()=>{const e=E.registerUpdateListener(()=>{E.read("latest",()=>{if(!E.isEditable())return void y();const e=()=>{E.isComposing()||y()},l=E._window||window,r=l.document.createRange(),i=t.$getSelection(),s=function(e){let n=null;return e.read("latest",()=>{const e=t.$getSelection();t.$isRangeSelection(e)&&(n=function(e){const t=e.anchor;if("text"!==t.type)return null;const n=t.getNode();if(!n.isSimpleText())return null;const l=t.offset;return n.getTextContent().slice(0,l)}(e))}),n}(E);if(!t.$isRangeSelection(i)||!i.isCollapsed()||null===s||null===r)return void e();const c=a(s,E);if(o(c?c.matchingString:null),null!==c&&(C||!function(e,n){return 0===n&&e.read("latest",()=>{const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.anchor.getNode().getPreviousSibling();return t.$isTextNode(n)&&n.isTextEntity()}return!1})}(E,c.leadOffset))){const e=function(e,n,l,o){const r=t.getDOMSelection(l);if(null===r||!r.isCollapsed)return!1;const i=t.getDOMSelectionPoints(r,o),s=i.anchorNode,c=e,u=i.anchorOffset;if(null==s||null==u)return!1;try{n.setStart(s,c),n.setEnd(s,u)}catch(e){return!1}return!0}(c.leadOffset,r,l,E.getRootElement());if(null!==e)return void n.startTransition(()=>S({getRect:()=>r.getBoundingClientRect(),match:c}))}e()})});return()=>{e()}},[E,a,o,O,y,S,C]),n.useEffect(()=>E.registerEditableListener(e=>{e||y()}),[E,y]),null===O||null===E||null===R.current?null:/*#__PURE__*/i.jsx(g,{close:y,resolution:O,editor:E,anchorElementRef:R,options:l,menuRenderFn:u,shouldSplitNodeWithQuery:!0,onSelectOption:r,commandPriority:p,preselectFirstItem:f})},exports.useDynamicPositioning=d;
|