@lexical/react
Version:
This package provides Lexical components and hooks for React applications.
10 lines (8 loc) • 7.17 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 e=require("@lexical/react/LexicalComposerContext"),t=require("@lexical/utils"),n=require("lexical"),o=require("react"),l=require("react/jsx-runtime");function r(e){var t=Object.create(null);if(e)for(var n in e)t[n]=e[n];return t.default=e,t}var i=r(o);const u="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,c=u?o.useLayoutEffect:o.useEffect;const s=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(),o=t.getBoundingClientRect();return n.top>o.top&&n.top<o.bottom}function m(t,n,l,r){const[i]=e.useLexicalComposerContext();o.useEffect((()=>{if(null!=n&&null!=t){const e=i.getRootElement(),t=null!=e?function(e,t){let n=getComputedStyle(e);const o="absolute"===n.position,l=/(auto|scroll)/;if("fixed"===n.position)return document.body;for(let t=e;t=t.parentElement;)if(n=getComputedStyle(t),(!o||"static"!==n.position)&&l.test(n.overflow+n.overflowY+n.overflowX))return t;return document.body}(e):document.body;let o=!1,u=a(n,t);const c=function(){o||(window.requestAnimationFrame((function(){l(),o=!1})),o=!0);const e=a(n,t);e!==u&&(u=e,null!=r&&r(e))},s=new ResizeObserver(l);return window.addEventListener("resize",l),document.addEventListener("scroll",c,{capture:!0,passive:!0}),s.observe(n),()=>{s.unobserve(n),window.removeEventListener("resize",l),document.removeEventListener("scroll",c,!0)}}}),[n,i,r,l,t])}const d=n.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function f({close:e,editor:l,anchorElementRef:r,resolution:i,options:u,menuRenderFn:a,onSelectOption:m,shouldSplitNodeWithQuery:f=!1,commandPriority:p=n.COMMAND_PRIORITY_LOW}){const[g,h]=o.useState(null),C=i.match&&i.match.matchingString;o.useEffect((()=>{h(0)}),[C]);const E=o.useCallback((t=>{l.update((()=>{const o=null!=i.match&&f?function(e){const t=n.$getSelection();if(!n.$isRangeSelection(t)||!t.isCollapsed())return null;const o=t.anchor;if("text"!==o.type)return null;const l=o.getNode();if(!l.isSimpleText())return null;const r=o.offset,i=l.getTextContent().slice(0,r),u=e.replaceableString.length,c=r-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}(i,e.matchingString,u);if(c<0)return null;let s;return 0===c?[s]=l.splitText(r):[,s]=l.splitText(c,r),s}(i.match):null;m(t,o,e,i.match?i.match.matchingString:"")}))}),[l,f,i.match,m,e]),v=o.useCallback((e=>{const t=l.getRootElement();null!==t&&(t.setAttribute("aria-activedescendant","typeahead-item-"+e),h(e))}),[l]);o.useEffect((()=>()=>{const e=l.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")}),[l]),c((()=>{null===u?h(null):null===g&&v(0)}),[u,g,v]),o.useEffect((()=>t.mergeRegister(l.registerCommand(d,(({option:e})=>!(!e.ref||null==e.ref.current)&&(s(e.ref.current),!0)),p))),[l,v,p]),o.useEffect((()=>t.mergeRegister(l.registerCommand(n.KEY_ARROW_DOWN_COMMAND,(e=>{const t=e;if(null!==u&&u.length&&null!==g){const e=g!==u.length-1?g+1:0;v(e);const n=u[e];null!=n.ref&&n.ref.current&&l.dispatchCommand(d,{index:e,option:n}),t.preventDefault(),t.stopImmediatePropagation()}return!0}),p),l.registerCommand(n.KEY_ARROW_UP_COMMAND,(e=>{const t=e;if(null!==u&&u.length&&null!==g){const e=0!==g?g-1:u.length-1;v(e);const n=u[e];null!=n.ref&&n.ref.current&&s(n.ref.current),t.preventDefault(),t.stopImmediatePropagation()}return!0}),p),l.registerCommand(n.KEY_ESCAPE_COMMAND,(t=>{const n=t;return n.preventDefault(),n.stopImmediatePropagation(),e(),!0}),p),l.registerCommand(n.KEY_TAB_COMMAND,(e=>{const t=e;return null!==u&&null!==g&&null!=u[g]&&(t.preventDefault(),t.stopImmediatePropagation(),E(u[g]),!0)}),p),l.registerCommand(n.KEY_ENTER_COMMAND,(e=>null!==u&&null!==g&&null!=u[g]&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),E(u[g]),!0)),p))),[E,e,l,u,g,v,p]);return a(r,o.useMemo((()=>({options:u,selectOptionAndCleanUp:E,selectedIndex:g,setHighlightedIndex:h})),[E,g,u]),i.match?i.match.matchingString:"")}function p(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.LexicalContextMenuPlugin=function({options:r,onWillOpen:c,onClose:s,onOpen:a,onSelectOption:d,menuRenderFn:g,anchorClassName:h,commandPriority:C=n.COMMAND_PRIORITY_LOW,parent:E}){const[v]=e.useLexicalComposerContext(),[R,b]=o.useState(null),w=i.useRef(null),x=function(t,n,l,r=(u?document.body:void 0),i=!0){const[c]=e.useLexicalComposerContext(),s=o.useRef(u?document.createElement("div"):null),a=o.useCallback((()=>{if(null===s.current||void 0===r)return;s.current.style.top=s.current.style.bottom;const e=c.getRootElement(),n=s.current,o=n.firstChild;if(null!==e&&null!==t){const{left:u,top:c,width:a,height:m}=t.getRect(),d=s.current.offsetHeight;if(n.style.top=`${c+d+3+(i?window.pageYOffset:0)}px`,n.style.left=`${u+window.pageXOffset}px`,n.style.height=`${m}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();u+r>s.right&&(n.style.left=`${s.right-r+window.pageXOffset}px`),(c+l>window.innerHeight||c+l>s.bottom)&&c-s.top>l+m&&(n.style.top=`${c-l-m+(i?window.pageYOffset:0)}px`)}n.isConnected||(p(n,l),r.append(n)),n.setAttribute("id","typeahead-menu"),s.current=n,e.setAttribute("aria-controls","typeahead-menu")}}),[c,t,i,l,r]);o.useEffect((()=>{const e=c.getRootElement();return null!==t&&a(),()=>{null!==e&&e.removeAttribute("aria-controls");const t=s.current;null!==t&&t.isConnected&&(t.remove(),t.removeAttribute("id"))}}),[c,a,t]);const d=o.useCallback((e=>{null!==t&&(e||n(null))}),[t,n]);m(t,s.current,a,d);const f=s.current;return null!=f&&(p(f,l),null!=r&&r.append(f)),s}(R,b,h,E),O=o.useCallback((()=>{b(null),null!=s&&null!==R&&s()}),[s,R]),y=o.useCallback((e=>{b(e),null!=a&&null===R&&a(e)}),[a,R]),A=o.useCallback((e=>{e.preventDefault(),null!=c&&c(e);const n=t.calculateZoomLevel(e.target);y({getRect:()=>new DOMRect(e.clientX/n,e.clientY/n,1,1)})}),[y,c]),M=o.useCallback((e=>{null!==R&&null!=w.current&&null!=e.target&&n.isDOMNode(e.target)&&!w.current.contains(e.target)&&O()}),[O,R]);return o.useEffect((()=>{const e=v.getRootElement();if(e)return e.addEventListener("contextmenu",A),()=>e.removeEventListener("contextmenu",A)}),[v,A]),o.useEffect((()=>(document.addEventListener("click",M),()=>document.removeEventListener("click",M))),[v,M]),null===x.current||null===R||null===v?null:l.jsx(f,{close:O,resolution:R,editor:v,anchorElementRef:x,options:r,menuRenderFn:(e,t)=>g(e,t,{setMenuRef:e=>{w.current=e}}),onSelectOption:d,commandPriority:C})},exports.MenuOption=class{constructor(e){this.key=e,this.ref={current:null},this.setRefElement=this.setRefElement.bind(this)}setRefElement(e){this.ref={current:e}}};