@lexical/react
Version:
This package provides Lexical components and hooks for React applications.
25 lines (23 loc) • 6.8 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
;var h=require("@lexical/react/LexicalComposerContext"),w=require("@lexical/utils"),z=require("lexical"),A=require("react"),B=require("react/jsx-runtime"),C=Object.create(null);if(A)for(var D in A)C[D]=A[D];C.default=A;let E="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?A.useLayoutEffect:A.useEffect;
class F{constructor(b){this.key=b;this.ref={current:null};this.setRefElement=this.setRefElement.bind(this)}setRefElement(b){this.ref={current:b}}}let G=b=>{const a=document.getElementById("typeahead-menu");if(a){var g=a.getBoundingClientRect();g.top+g.height>window.innerHeight&&a.scrollIntoView({block:"center"});0>g.top&&a.scrollIntoView({block:"center"});b.scrollIntoView({block:"nearest"})}};
function H(b){var a=z.$getSelection();if(!z.$isRangeSelection(a)||!a.isCollapsed())return null;var g=a.anchor;if("text"!==g.type)return null;a=g.getNode();if(!a.isSimpleText())return null;g=g.offset;let k=a.getTextContent().slice(0,g);var f=b.matchingString;b=b.replaceableString.length;for(let l=b;l<=f.length;l++)k.substr(-l)===f.substr(0,l)&&(b=l);b=g-b;if(0>b)return null;let r;0===b?[r]=a.splitText(g):[,r]=a.splitText(b,g);return r}
function I(b){let a=getComputedStyle(b),g="absolute"===a.position,k=/(auto|scroll)/;if("fixed"===a.position)return document.body;for(;b=b.parentElement;)if(a=getComputedStyle(b),(!g||"static"!==a.position)&&k.test(a.overflow+a.overflowY+a.overflowX))return b;return document.body}function J(b,a){b=b.getBoundingClientRect();a=a.getBoundingClientRect();return b.top>a.top&&b.top<a.bottom}
function K(b,a,g,k){let [f]=h.useLexicalComposerContext();A.useEffect(()=>{if(null!=a&&null!=b){let r=f.getRootElement(),l=null!=r?I(r):document.body,u=!1,t=J(a,l),e=function(){u||(window.requestAnimationFrame(function(){g();u=!1}),u=!0);const m=J(a,l);m!==t&&(t=m,null!=k&&k(m))},c=new ResizeObserver(g);window.addEventListener("resize",g);document.addEventListener("scroll",e,{capture:!0,passive:!0});c.observe(a);return()=>{c.unobserve(a);window.removeEventListener("resize",g);document.removeEventListener("scroll",
e,!0)}}},[a,f,k,g,b])}let L=z.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");
function M({close:b,editor:a,anchorElementRef:g,resolution:k,options:f,menuRenderFn:r,onSelectOption:l,shouldSplitNodeWithQuery:u=!1,commandPriority:t=z.COMMAND_PRIORITY_LOW}){let [e,c]=A.useState(null);A.useEffect(()=>{c(0)},[k.match&&k.match.matchingString]);let m=A.useCallback(d=>{a.update(()=>{const p=null!=k.match&&u?H(k.match):null;l(d,p,b,k.match?k.match.matchingString:"")})},[a,u,k.match,l,b]),q=A.useCallback(d=>{const p=a.getRootElement();null!==p&&(p.setAttribute("aria-activedescendant",
"typeahead-item-"+d),c(d))},[a]);A.useEffect(()=>()=>{let d=a.getRootElement();null!==d&&d.removeAttribute("aria-activedescendant")},[a]);E(()=>{null===f?c(null):null===e&&q(0)},[f,e,q]);A.useEffect(()=>w.mergeRegister(a.registerCommand(L,({option:d})=>d.ref&&null!=d.ref.current?(G(d.ref.current),!0):!1,t)),[a,q,t]);A.useEffect(()=>w.mergeRegister(a.registerCommand(z.KEY_ARROW_DOWN_COMMAND,d=>{if(null!==f&&f.length&&null!==e){let p=e!==f.length-1?e+1:0;q(p);let v=f[p];null!=v.ref&&v.ref.current&&
a.dispatchCommand(L,{index:p,option:v});d.preventDefault();d.stopImmediatePropagation()}return!0},t),a.registerCommand(z.KEY_ARROW_UP_COMMAND,d=>{if(null!==f&&f.length&&null!==e){var p=0!==e?e-1:f.length-1;q(p);p=f[p];null!=p.ref&&p.ref.current&&G(p.ref.current);d.preventDefault();d.stopImmediatePropagation()}return!0},t),a.registerCommand(z.KEY_ESCAPE_COMMAND,d=>{d.preventDefault();d.stopImmediatePropagation();b();return!0},t),a.registerCommand(z.KEY_TAB_COMMAND,d=>{if(null===f||null===e||null==
f[e])return!1;d.preventDefault();d.stopImmediatePropagation();m(f[e]);return!0},t),a.registerCommand(z.KEY_ENTER_COMMAND,d=>{if(null===f||null===e||null==f[e])return!1;null!==d&&(d.preventDefault(),d.stopImmediatePropagation());m(f[e]);return!0},t)),[m,b,a,f,e,q,t]);let x=A.useMemo(()=>({options:f,selectOptionAndCleanUp:m,selectedIndex:e,setHighlightedIndex:c}),[m,e,f]);return r(g,x,k.match?k.match.matchingString:"")}
function N(b,a,g,k=document.body,f=!0){let [r]=h.useLexicalComposerContext(),l=A.useRef(document.createElement("div")),u=A.useCallback(()=>{l.current.style.top=l.current.style.bottom;const e=r.getRootElement(),c=l.current;var m=c.firstChild;if(null!==e&&null!==b){const {left:x,top:d,width:p,height:v}=b.getRect();c.style.top=`${d+l.current.offsetHeight+3+(f?window.pageYOffset:0)}px`;c.style.left=`${x+window.pageXOffset}px`;c.style.height=`${v}px`;c.style.width=`${p}px`;if(null!==m){m.style.top=`${d}`;
var q=m.getBoundingClientRect();m=q.height;q=q.width;const n=e.getBoundingClientRect();x+q>n.right&&(c.style.left=`${n.right-q+window.pageXOffset}px`);(d+m>window.innerHeight||d+m>n.bottom)&&d-n.top>m+v&&(c.style.top=`${d-m-v+(f?window.pageYOffset:0)}px`)}c.isConnected||(null!=g&&(c.className=g),c.setAttribute("aria-label","Typeahead menu"),c.setAttribute("id","typeahead-menu"),c.setAttribute("role","listbox"),c.style.display="block",c.style.position="absolute",k.append(c));l.current=c;e.setAttribute("aria-controls",
"typeahead-menu")}},[r,b,f,g,k]);A.useEffect(()=>{let e=r.getRootElement();if(null!==b)return u(),()=>{null!==e&&e.removeAttribute("aria-controls");let c=l.current;null!==c&&c.isConnected&&c.remove()}},[r,u,b]);let t=A.useCallback(e=>{null!==b&&(e||a(null))},[b,a]);K(b,l.current,u,t);return l}
exports.LexicalContextMenuPlugin=function({options:b,onWillOpen:a,onClose:g,onOpen:k,onSelectOption:f,menuRenderFn:r,anchorClassName:l,commandPriority:u=z.COMMAND_PRIORITY_LOW,parent:t}){let [e]=h.useLexicalComposerContext(),[c,m]=A.useState(null),q=C.useRef(null);l=N(c,m,l,t);let x=A.useCallback(()=>{m(null);null!=g&&null!==c&&g()},[g,c]),d=A.useCallback(n=>{m(n);null!=k&&null===c&&k(n)},[k,c]),p=A.useCallback(n=>{n.preventDefault();null!=a&&a(n);const y=w.calculateZoomLevel(n.target);d({getRect:()=>
new DOMRect(n.clientX/y,n.clientY/y,1,1)})},[d,a]),v=A.useCallback(n=>{null===c||null==q.current||null==n.target||q.current.contains(n.target)||x()},[x,c]);A.useEffect(()=>{let n=e.getRootElement();if(n)return n.addEventListener("contextmenu",p),()=>n.removeEventListener("contextmenu",p)},[e,p]);A.useEffect(()=>{document.addEventListener("click",v);return()=>document.removeEventListener("click",v)},[e,v]);return null===c||null===e?null:B.jsx(M,{close:x,resolution:c,editor:e,anchorElementRef:l,options:b,
menuRenderFn:(n,y)=>r(n,y,{setMenuRef:O=>{q.current=O}}),onSelectOption:f,commandPriority:u})};exports.MenuOption=F