UNPKG

@lexical/react

Version:

This package provides Lexical components and hooks for React applications.

10 lines (8 loc) 9.76 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. * */ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),n=require("react"),o=require("@lexical/utils"),l=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(),o=t.getBoundingClientRect();return n.top>=o.top-6&&n.top<=o.bottom+6}function d(t,o,l,r){const[i]=e.useLexicalComposerContext();n.useEffect(()=>{if(null!=o&&null!=t){const e=i.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 n=!1,s=a(o,t);const u=function(){n||(window.requestAnimationFrame(function(){l(),n=!1}),n=!0);const e=a(o,t);e!==s&&(s=e,null!=r&&r(e))},c=new ResizeObserver(l);return window.addEventListener("resize",l),document.addEventListener("scroll",u,{capture:!0,passive:!0}),c.observe(o),()=>{c.unobserve(o),window.removeEventListener("resize",l),document.removeEventListener("scroll",u,!0)}}},[o,i,r,l,t])}const m=t.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");function f({index:e,isSelected:t,onClick:n,onMouseEnter:o,option:l}){let i="item";return t&&(i+=" selected"),r.jsxs("li",{tabIndex:-1,className:i,ref:l.setRefElement,role:"option","aria-selected":t,id:"typeahead-item-"+e,onMouseEnter:o,onClick:n,children:[l.icon,r.jsx("span",{className:"text",children:l.title})]},l.key)}function p({close:e,editor:i,anchorElementRef:s,resolution:a,options:d,menuRenderFn:p,onSelectOption:g,shouldSplitNodeWithQuery:h=!1,commandPriority:C=t.COMMAND_PRIORITY_LOW,preselectFirstItem:E=!0}){const[x,y]=n.useState(null),O=null!==x?Math.min(d.length-1,x):null,b=a.match&&a.match.matchingString;n.useEffect(()=>{E&&y(0)},[b,E]);const R=n.useCallback(n=>{i.update(()=>{const o=null!=a.match&&h?function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n)||!n.isCollapsed())return null;const o=n.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),s=e.replaceableString.length,u=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,s);if(u<0)return null;let c;return 0===u?[c]=l.splitText(r):[,c]=l.splitText(u,r),c}(a.match):null;g(n,o,e,a.match?a.match.matchingString:"")})},[i,h,a.match,g,e]),w=n.useCallback(e=>{const t=i.getRootElement();null!==t&&(t.setAttribute("aria-activedescendant","typeahead-item-"+e),y(e))},[i]),v=n.useCallback(()=>s.current&&d.length?l.createPortal(r.jsx("div",{className:"typeahead-popover mentions-menu",children:r.jsx("ul",{children:d.map((e,t)=>r.jsx(f,{index:t,isSelected:O===t,onClick:()=>{y(t),R(e)},onMouseEnter:()=>{y(t)},option:e},e.key))})}),s.current):null,[s,d,O,R,y]);n.useEffect(()=>()=>{const e=i.getRootElement();null!==e&&e.removeAttribute("aria-activedescendant")},[i]),u(()=>{null===d?y(null):null===O&&E&&w(0)},[d,O,w,E]),n.useEffect(()=>o.mergeRegister(i.registerCommand(m,({option:e})=>!(!e.ref||null==e.ref.current)&&(c(e.ref.current),!0),C)),[i,w,C]),n.useEffect(()=>o.mergeRegister(i.registerCommand(t.KEY_ARROW_DOWN_COMMAND,e=>{const t=e;if(null!==d&&d.length){const e=null===O?0:O!==d.length-1?O+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},C),i.registerCommand(t.KEY_ARROW_UP_COMMAND,e=>{const t=e;if(null!==d&&d.length){const e=null===O?d.length-1:0!==O?O-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},C),i.registerCommand(t.KEY_ESCAPE_COMMAND,t=>{const n=t;return n.preventDefault(),n.stopImmediatePropagation(),e(),!0},C),i.registerCommand(t.KEY_TAB_COMMAND,e=>{const t=e;return null!==d&&null!==O&&null!=d[O]&&(t.preventDefault(),t.stopImmediatePropagation(),R(d[O]),!0)},C),i.registerCommand(t.KEY_ENTER_COMMAND,e=>null!==d&&null!==O&&null!=d[O]&&(null!==e&&(e.preventDefault(),e.stopImmediatePropagation()),R(d[O]),!0),C)),[R,e,i,d,O,w,C]);const S=n.useMemo(()=>({options:d,selectOptionAndCleanUp:R,selectedIndex:O,setHighlightedIndex:y}),[R,O,d]);return null!=p?p(s,S,a.match?a.match.matchingString:""):v()}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"}const h="\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";const C=t.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");exports.LexicalTypeaheadMenuPlugin=function({options:o,onQueryChange:l,onSelectOption:u,onOpen:c,onClose:a,menuRenderFn:m,triggerFn:f,anchorClassName:h,commandPriority:C=t.COMMAND_PRIORITY_LOW,parent:E,preselectFirstItem:x=!0,ignoreEntityBoundary:y=!1}){const[O]=e.useLexicalComposerContext(),[b,R]=n.useState(null),w=function(t,o,l,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,o=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!==o){o.style.top=`${u}`;const t=o.getBoundingClientRect(),l=t.height,r=t.width,c=e.getBoundingClientRect();s+r>c.right&&(n.style.left=`${c.right-r+window.pageXOffset}px`),(u+l>window.innerHeight||u+l>c.bottom)&&u-c.top>l+d&&(n.style.top=`${u-l-d+(i?window.pageYOffset:0)}px`)}n.isConnected||(g(n,l),r.append(n)),n.setAttribute("id","typeahead-menu"),e.setAttribute("aria-controls","typeahead-menu")}},[u,t,i,l,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 f=n.useCallback(e=>{null!==t&&(e||o(null))},[t,o]);return d(t,a.current,m,f),null!=c&&c===a.current&&(g(c,l),null!=r&&r.append(c)),a}(b,R,h,E),v=n.useCallback(()=>{R(null),null!=a&&null!==b&&a()},[a,b]),S=n.useCallback(e=>{R(e),null!=c&&null===b&&c(e)},[c,b]);return n.useEffect(()=>{const e=O.registerUpdateListener(()=>{O.getEditorState().read(()=>{if(!O.isEditable())return void v();if(O.isComposing())return;const e=O._window||window,o=e.document.createRange(),r=t.$getSelection(),s=function(e){let n=null;return e.getEditorState().read(()=>{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 o=t.offset;return n.getTextContent().slice(0,o)}(e))}),n}(O);if(!t.$isRangeSelection(r)||!r.isCollapsed()||null===s||null===o)return void v();const u=f(s,O);if(l(u?u.matchingString:null),null!==u&&(y||!function(e,n){return 0===n&&e.getEditorState().read(()=>{const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.anchor.getNode().getPreviousSibling();return t.$isTextNode(n)&&n.isTextEntity()}return!1})}(O,u.leadOffset))){const l=function(e,n,o){const l=t.getDOMSelection(o);if(null===l||!l.isCollapsed)return!1;const r=l.anchorNode,i=e,s=l.anchorOffset;if(null==r||null==s)return!1;try{n.setStart(r,i),n.setEnd(r,s)}catch(e){return!1}return!0}(u.leadOffset,o,e);if(null!==l)return c=()=>S({getRect:()=>o.getBoundingClientRect(),match:u}),void(i in n?n[i](c):c())}var c;v()})});return()=>{e()}},[O,f,l,b,v,S,y]),n.useEffect(()=>O.registerEditableListener(e=>{e||v()}),[O,v]),null===b||null===O||null===w.current?null:r.jsx(p,{close:v,resolution:b,editor:O,anchorElementRef:w,options:o,menuRenderFn:m,shouldSplitNodeWithQuery:!0,onSelectOption:u,commandPriority:C,preselectFirstItem:x})},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=C,exports.getScrollParent=function(e,t){let n=getComputedStyle(e);const o="absolute"===n.position,l=t?/(auto|scroll|hidden)/:/(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},exports.useBasicTypeaheadTriggerMatch=function(e,{minLength:t=1,maxLength:o=75,punctuation:l=h,allowWhitespace:r=!1}){return n.useCallback(n=>{const i=new RegExp("(^|\\s|\\()(["+e+"]((?:"+("[^"+e+l+(r?"":"\\s")+"]")+"){0,"+o+"}))$").exec(n);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,l,o,t])},exports.useDynamicPositioning=d;