UNPKG

@lexical/react

Version:

This package provides Lexical components and hooks for React applications.

10 lines (8 loc) • 9.35 kB
/** * 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. * */ import{useLexicalComposerContext as t}from"@lexical/react/LexicalComposerContext";import{CAN_USE_DOM as e,getDOMShadowRoots as n,mergeRegister as l,registerEventListener as o,getRootOwnerDocument as r,COMMAND_PRIORITY_LOW as i,KEY_ARROW_DOWN_COMMAND as c,KEY_ARROW_UP_COMMAND as u,KEY_ESCAPE_COMMAND as s,KEY_TAB_COMMAND as a,KEY_ENTER_COMMAND as d,isDOMShadowRoot as p,isHTMLElement as m,getParentElement as f,$getSelection as g,$isRangeSelection as h,$isTextNode as y,getDOMSelection as x,getDOMSelectionPoints as C}from"lexical";import{useLayoutEffect as b,useEffect as v,useRef as w,useCallback as R,useState as E,useMemo as I,startTransition as S}from"react";import{SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND as O}from"@lexical/react/LexicalTypeaheadMenuPluginUtils";export{PUNCTUATION,SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND,getScrollParent,useBasicTypeaheadTriggerMatch}from"@lexical/react/LexicalTypeaheadMenuPluginUtils";import{getScrollParent as T}from"@lexical/utils";import P from"react-dom";import{jsx as N,jsxs as A}from"react/jsx-runtime";export{MenuOption}from"@lexical/react/LexicalMenuOption";const k=e?b:v,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 M(t,e){const n=t.getBoundingClientRect(),l=e.getBoundingClientRect();return n.top>=l.top-6&&n.top<=l.bottom+6}function L(e,r,i,c){const[u]=t();v(()=>{if(null!=r&&null!=e){const t=u.getRootElement(),e=null!=t?T(t,!1):document.body;let s=!1,a=M(r,e);const d=function(){s||(window.requestAnimationFrame(function(){i(),s=!1}),s=!0);const t=M(r,e);t!==a&&(a=t,null!=c&&c(t))},p=new ResizeObserver(i),m=n(t??r);return p.observe(r),l(o(window,"resize",i),o(document,"scroll",d,{capture:!0,passive:!0}),...m.map(t=>o(t,"scroll",d,{capture:!0,passive:!0})),()=>p.unobserve(r))}},[r,u,c,i,e])}function B({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__*/N("span",{className:"text",children:o.title})]},o.key)}function F({close:t,editor:e,anchorElementRef:n,resolution:o,options:r,menuRenderFn:p,onSelectOption:m,shouldSplitNodeWithQuery:f=!1,commandPriority:y=i,preselectFirstItem:x=!0}){const[C,b]=E(null),w=null!==C?Math.min(r.length-1,C):null,S=o.match&&o.match.matchingString;v(()=>{x&&b(0)},[S,x]);const T=R(n=>{e.update(()=>{const e=null!=o.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}(o.match):null;m(n,e,t,o.match?o.match.matchingString:"")})},[e,f,o.match,m,t]),A=R(t=>{const n=e.getRootElement();null!==n&&(n.setAttribute("aria-activedescendant","typeahead-item-"+t),b(t))},[e]),M=R(()=>n.current&&r.length?/*#__PURE__*/P.createPortal(/*#__PURE__*/N("div",{className:"typeahead-popover mentions-menu",children:/*#__PURE__*/N("ul",{children:r.map((t,e)=>/*#__PURE__*/N(B,{index:e,isSelected:w===e,onClick:()=>{b(e),T(t)},onMouseEnter:()=>{b(e)},option:t},t.key))})}),n.current):null,[n,r,w,T,b]);v(()=>()=>{const t=e.getRootElement();null!==t&&t.removeAttribute("aria-activedescendant")},[e]),k(()=>{null===r?b(null):null===w&&x&&A(0)},[r,w,A,x]);const L=null==p&&(null===r||!r.length);v(()=>l(e.registerCommand(O,({option:t})=>!(!t.ref||null==t.ref.current)&&(D(t.ref.current),!0),y)),[e,A,y]),v(()=>l(e.registerCommand(c,t=>{const n=t;if(L)return!1;const l=null===w?0:w!==r.length-1?w+1:0;A(l);const o=r[l];return o?(o.ref&&o.ref.current&&e.dispatchCommand(O,{index:l,option:o}),n.preventDefault(),n.stopImmediatePropagation(),!0):(A(-1),n.preventDefault(),n.stopImmediatePropagation(),!0)},y),e.registerCommand(u,t=>{const e=t;if(L)return!1;const n=null===w?r.length-1:0!==w?w-1:r.length-1;A(n);const l=r[n];return l?(l.ref&&l.ref.current&&D(l.ref.current),e.preventDefault(),e.stopImmediatePropagation(),!0):(A(-1),e.preventDefault(),e.stopImmediatePropagation(),!0)},y),e.registerCommand(s,e=>{const n=e;return!L&&(n.preventDefault(),n.stopImmediatePropagation(),t(),!0)},y),e.registerCommand(a,t=>{const e=t;return null!==r&&null!==w&&null!=r[w]&&(e.preventDefault(),e.stopImmediatePropagation(),T(r[w]),!0)},y),e.registerCommand(d,t=>!(null===r||null===w||null==r[w]||t&&t.shiftKey)&&(null!==t&&(t.preventDefault(),t.stopImmediatePropagation()),T(r[w]),!0),y)),[T,t,e,r,L,w,A,y]);const F=I(()=>({options:r,selectOptionAndCleanUp:T,selectedIndex:w,setHighlightedIndex:b}),[T,w,r]);return null!=p?p(n,F,o.match?o.match.matchingString:""):M()}function $(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 U(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 _(n,l,o,i,c=!0){const[u]=t(),s=i??function(t){if(!e)return;const n=t.getRootElement();if(null!==n){const t=n.getRootNode();return p(t)?t:n.ownerDocument.body}return document.body}(u),a=e?r(u.getRootElement()).createElement("div"):null,d=w(a),g=R(()=>{if(null===d.current||void 0===s)return;d.current.style.top=d.current.style.bottom;const t=u.getRootElement(),e=d.current,l=e.firstChild;if(null!==t&&null!==n){const{left:r,top:i,width:u,height:a}=n.getRect(),g=d.current.offsetHeight,h=function(t){const e=p(t)?t.host:t;for(let t=m(e)?e:null;null!==t;t=f(t)){const e=t.ownerDocument.defaultView;if(null===e)break;if(U(e.getComputedStyle(t))){const e=t.getBoundingClientRect();return{left:e.left+t.clientLeft-t.scrollLeft,top:e.top+t.clientTop-t.scrollTop}}}return null}(s),y=t=>null!==h?t-h.left:t+window.pageXOffset,x=t=>null!==h?t-h.top:t+(c?window.pageYOffset:0);if(e.style.top=`${x(i+g+3)}px`,e.style.left=`${y(r)}px`,e.style.height=`${a}px`,e.style.width=`${u}px`,null!==l){l.style.top=`${i}`;const n=l.getBoundingClientRect(),o=n.height,c=n.width,u=t.getBoundingClientRect();r+c>u.right&&(e.style.left=`${y(u.right-c)}px`),(i+o>window.innerHeight||i+o>u.bottom)&&i-u.top>o+a&&(e.style.top=`${x(i-o-a)}px`)}e.isConnected||($(e,o),s.append(e)),e.setAttribute("id","typeahead-menu"),t.setAttribute("aria-controls","typeahead-menu")}},[u,n,c,o,s]);v(()=>{const t=u.getRootElement();return null!==n&&g(),()=>{null!==t&&t.removeAttribute("aria-controls");const e=d.current;null!==e&&e.isConnected&&(e.remove(),e.removeAttribute("id"))}},[u,g,n]);const h=R(t=>{null!==n&&(t||l(null))},[n,l]);return L(n,d.current,g,h),null!=a&&a===d.current&&($(a,o),null!=s&&s.append(a)),d}function H({options:e,onQueryChange:n,onSelectOption:l,onOpen:o,onClose:r,menuRenderFn:c,triggerFn:u,anchorClassName:s,commandPriority:a=i,parent:d,preselectFirstItem:p=!0,ignoreEntityBoundary:m=!1}){const[f]=t(),[b,w]=E(null),I=_(b,w,s,d),O=R(()=>{if(null===b)return;const t=()=>{w(null)};let e;try{e=r&&r()}finally{e?e.then(t,t):t()}},[r,b]),T=R(t=>{w(t),null!=o&&null===b&&o(t)},[o,b]);return v(()=>{const t=f.registerUpdateListener(()=>{f.read("latest",()=>{if(!f.isEditable())return void O();const t=()=>{f.isComposing()||O()},e=f._window||window,l=e.document.createRange(),o=g(),r=function(t){let e=null;return t.read("latest",()=>{const t=g();h(t)&&(e=function(t){const e=t.anchor;if("text"!==e.type)return null;const n=e.getNode();if(!n.isSimpleText())return null;const l=e.offset;return n.getTextContent().slice(0,l)}(t))}),e}(f);if(!h(o)||!o.isCollapsed()||null===r||null===l)return void t();const i=u(r,f);if(n(i?i.matchingString:null),null!==i&&(m||!function(t,e){return 0===e&&t.read("latest",()=>{const t=g();if(h(t)){const e=t.anchor.getNode().getPreviousSibling();return y(e)&&e.isTextEntity()}return!1})}(f,i.leadOffset))){const t=function(t,e,n,l){const o=x(n);if(null===o||!o.isCollapsed)return!1;const r=C(o,l),i=r.anchorNode,c=t,u=r.anchorOffset;if(null==i||null==u)return!1;try{e.setStart(i,c),e.setEnd(i,u)}catch(t){return!1}return!0}(i.leadOffset,l,e,f.getRootElement());if(null!==t)return void S(()=>T({getRect:()=>l.getBoundingClientRect(),match:i}))}t()})});return()=>{t()}},[f,u,n,b,O,T,m]),v(()=>f.registerEditableListener(t=>{t||O()}),[f,O]),null===b||null===f||null===I.current?null:/*#__PURE__*/N(F,{close:O,resolution:b,editor:f,anchorElementRef:I,options:e,menuRenderFn:c,shouldSplitNodeWithQuery:!0,onSelectOption:l,commandPriority:a,preselectFirstItem:p})}export{H as LexicalTypeaheadMenuPlugin,L as useDynamicPositioning};