text-editor-drcsystems
Version:
Text Editor Made with Love by DRC Systems
8 lines (7 loc) • 13 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"),r=require("react"),i=require("@lexical/react/useLexicalNodeSelection"),a=require("@excalidraw/excalidraw"),l=require("react-dom");function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o.apply(this,arguments)}const c=r.lazy((()=>Promise.resolve().then((function(){return L}))));function u(e){const t=e.getAttribute("data-lexical-excalidraw-json"),n=window.getComputedStyle(e),r=n.getPropertyValue("height"),i=n.getPropertyValue("width"),a=r&&"inherit"!==r?parseInt(r,10):"inherit",l=i&&"inherit"!==i?parseInt(i,10):"inherit";if(t){return{node:m(t,l,a)}}return null}class d extends n.DecoratorNode{static getType(){return"excalidraw"}static clone(e){return new d(e.__data,e.__width,e.__height,e.__key)}static importJSON(e){return new d(e.data,e.width??"inherit",e.height??"inherit")}exportJSON(){return{...super.exportJSON(),data:this.__data,height:"inherit"===this.__height?void 0:this.__height,type:"excalidraw",version:1,width:"inherit"===this.__width?void 0:this.__width}}constructor(e="[]",t="inherit",n="inherit",r){super(r),s(this,"__data",void 0),s(this,"__width",void 0),s(this,"__height",void 0),this.__data=e,this.__width=t,this.__height=n}createDOM(e){const t=document.createElement("span"),n=e.theme.image;return void 0!==n&&(t.className=n),t}updateDOM(){return!1}static importDOM(){return{span:e=>e.hasAttribute("data-lexical-excalidraw-json")?{conversion:u,priority:1}:null}}exportDOM(e){const t=document.createElement("span");t.style.display="inline-block";const n=e.getElementByKey(this.getKey());if(null!==n){const e=n.querySelector("svg");null!==e&&(t.innerHTML=e.outerHTML)}return t.style.width="inherit"===this.__width?"inherit":`${this.__width}px`,t.style.height="inherit"===this.__height?"inherit":`${this.__height}px`,t.setAttribute("data-lexical-excalidraw-json",this.__data),{element:t}}setData(e){this.getWritable().__data=e}getWidth(){return this.getLatest().__width}setWidth(e){this.getWritable().__width=e}getHeight(){return this.getLatest().__height}setHeight(e){this.getWritable().__height=e}decorate(e,t){return r.createElement(r.Suspense,{fallback:null},r.createElement(c,{nodeKey:this.getKey(),data:this.__data}))}}function m(e="[]",t="inherit",n="inherit"){return new d(e,t,n)}function h(e){return e instanceof d}const g=n.createCommand("INSERT_EXCALIDRAW_COMMAND");function E(){const[i]=e.useLexicalComposerContext();return r.useEffect((()=>{if(!i.hasNodes([d]))throw new Error("ExcalidrawPlugin: ExcalidrawNode not registered on editor");return i.registerCommand(g,(()=>{const e=m();return n.$insertNodes([e]),n.$isRootOrShadowRoot(e.getParentOrThrow())&&t.$wrapNodeInElement(e,n.$createParagraphNode).selectEnd(),!0}),n.COMMAND_PRIORITY_EDITOR)}),[i]),null}const f=r.createContext(null);function p({children:e,className:t,onClick:n,title:i}){const a=r.useRef(null),l=r.useContext(f);if(null===l)throw new Error("DropDownItem must be used within a DropDown");const{registerItem:s}=l;return r.useEffect((()=>{a&&a.current&&s(a)}),[a,s]),r.createElement("button",{className:t,onClick:n,ref:a,title:i,type:"button"},e)}const _={name:"excalidraw",node:d,plugin:E,toolbarInsertAfter:function({activeEditor:e}){return r.createElement(p,{onClick:()=>{e.dispatchCommand(g,void 0)},className:"item"},r.createElement("i",{className:"icon diagram-2"}),r.createElement("span",{className:"text"},"Excalidraw"))}};function w(e,t,n){return Math.min(Math.max(e,t),n)}const y=1,b=8,v=2,C=4;function x({onResizeStart:e,onResizeEnd:t,buttonRef:n,imageRef:i,maxWidth:a,editor:l,showCaption:s,setShowCaption:o,captionsEnabled:c}){const u=r.useRef(null),d=r.useRef({priority:"",value:"default"}),m=r.useRef({currentHeight:0,currentWidth:0,direction:0,isResizing:!1,ratio:0,startHeight:0,startWidth:0,startX:0,startY:0}),h=l.getRootElement(),g=a||(null!==h?h.getBoundingClientRect().width-20:100),E=null!==h?h.getBoundingClientRect().height-20:100,f=(t,n)=>{if(!l.isEditable())return;const r=i.current,a=u.current;if(null!==r&&null!==a){const{width:i,height:l}=r.getBoundingClientRect(),s=m.current;s.startWidth=i,s.startHeight=l,s.ratio=i/l,s.currentWidth=i,s.currentHeight=l,s.startX=t.clientX,s.startY=t.clientY,s.isResizing=!0,s.direction=n,(e=>{const t=e===y||e===C?"ew":e===b||e===v?"ns":e&b&&e&C||e&v&&e&y?"nwse":"nesw";null!==h&&h.style.setProperty("cursor",`${t}-resize`,"important"),null!==document.body&&(document.body.style.setProperty("cursor",`${t}-resize`,"important"),d.current.value=document.body.style.getPropertyValue("-webkit-user-select"),d.current.priority=document.body.style.getPropertyPriority("-webkit-user-select"),document.body.style.setProperty("-webkit-user-select","none","important"))})(n),e(),a.classList.add("image-control-wrapper--resizing"),r.style.height=`${l}px`,r.style.width=`${i}px`,document.addEventListener("pointermove",p),document.addEventListener("pointerup",_)}},p=e=>{const t=i.current,n=m.current,r=n.direction&(y|C),a=n.direction&(v|b);if(null!==t&&n.isResizing)if(r&&a){let r=Math.floor(n.startX-e.clientX);r=n.direction&y?-r:r;const i=w(n.startWidth+r,100,g),a=i/n.ratio;t.style.width=`${i}px`,t.style.height=`${a}px`,n.currentHeight=a,n.currentWidth=i}else if(a){let r=Math.floor(n.startY-e.clientY);r=n.direction&v?-r:r;const i=w(n.startHeight+r,100,E);t.style.height=`${i}px`,n.currentHeight=i}else{let r=Math.floor(n.startX-e.clientX);r=n.direction&y?-r:r;const i=w(n.startWidth+r,100,g);t.style.width=`${i}px`,n.currentWidth=i}},_=()=>{const e=i.current,n=m.current,r=u.current;if(null!==e&&null!==r&&n.isResizing){const e=n.currentWidth,i=n.currentHeight;n.startWidth=0,n.startHeight=0,n.ratio=0,n.startX=0,n.startY=0,n.currentWidth=0,n.currentHeight=0,n.isResizing=!1,r.classList.remove("image-control-wrapper--resizing"),null!==h&&h.style.setProperty("cursor","default"),null!==document.body&&(document.body.style.setProperty("cursor","default"),document.body.style.setProperty("-webkit-user-select",d.current.value,d.current.priority)),t(e,i),document.removeEventListener("pointermove",p),document.removeEventListener("pointerup",_)}};return r.createElement("div",{ref:u},!s&&c&&r.createElement("button",{className:"image-caption-button",ref:n,onClick:()=>{o(!s)}},"Add Caption"),r.createElement("div",{className:"image-resizer image-resizer-n",onPointerDown:e=>{f(e,b)}}),r.createElement("div",{className:"image-resizer image-resizer-ne",onPointerDown:e=>{f(e,b|y)}}),r.createElement("div",{className:"image-resizer image-resizer-e",onPointerDown:e=>{f(e,y)}}),r.createElement("div",{className:"image-resizer image-resizer-se",onPointerDown:e=>{f(e,v|y)}}),r.createElement("div",{className:"image-resizer image-resizer-s",onPointerDown:e=>{f(e,v)}}),r.createElement("div",{className:"image-resizer image-resizer-sw",onPointerDown:e=>{f(e,v|C)}}),r.createElement("div",{className:"image-resizer image-resizer-w",onPointerDown:e=>{f(e,C)}}),r.createElement("div",{className:"image-resizer image-resizer-nw",onPointerDown:e=>{f(e,b|C)}}))}function N({elements:e,imageContainerRef:t,appState:n=null,rootClassName:i=null}){const[l,s]=r.useState(null);return r.useEffect((()=>{(async()=>{const t=await a.exportToSvg({elements:e,files:null});(e=>{const t=e?.firstElementChild?.firstElementChild,n=e.getAttribute("viewBox");if(null!=n){const t=n.split(" ");e.setAttribute("width",t[2]),e.setAttribute("height",t[3])}t&&"style"===t.tagName&&t.remove()})(t),t.setAttribute("width","100%"),t.setAttribute("height","100%"),t.setAttribute("display","block"),s(t)})()}),[e,n]),r.createElement("div",{ref:t,className:i??"",dangerouslySetInnerHTML:{__html:l?.outerHTML??""}})}function O(...e){return e.filter(Boolean).join(" ")}function R({"data-test-id":e,children:t,className:n,onClick:i,disabled:a,small:l,title:s}){return r.createElement("button",o({type:"button",disabled:a,className:O("Button__root",a&&"Button__disabled",l&&"Button__small",n),onClick:i,title:s,"aria-label":s},e&&{"data-test-id":e}),t)}function M({onClose:e,children:t,title:n,closeOnClickOutside:i}){const a=r.useRef(null);return r.useEffect((()=>{null!==a.current&&a.current.focus()}),[]),r.useEffect((()=>{let t=null;const n=t=>{27===t.keyCode&&e()},r=t=>{const n=t.target;null!==a.current&&!a.current.contains(n)&&i&&e()},l=a.current;return null!==l&&(t=l.parentElement,null!==t&&t.addEventListener("click",r)),window.addEventListener("keydown",n),()=>{window.removeEventListener("keydown",n),null!==t&&t?.removeEventListener("click",r)}}),[i,e]),r.createElement("div",{className:"Modal__overlay",role:"dialog"},r.createElement("div",{className:"Modal__modal",tabIndex:-1,ref:a},r.createElement("h2",{className:"Modal__title"},n),r.createElement("button",{className:"Modal__closeButton","aria-label":"Close modal",type:"button",onClick:e},"X"),r.createElement("div",{className:"Modal__content"},t)))}function D({onClose:e,children:t,title:n,closeOnClickOutside:i=!1}){return l.createPortal(r.createElement(M,{onClose:e,title:n,closeOnClickOutside:i},t),document.body)}function k({closeOnClickOutside:e=!1,onSave:t,initialElements:n,isShown:i=!1,onDelete:s}){const o=r.useRef(null),[c,u]=r.useState(!1),[d,m]=r.useState(n);r.useEffect((()=>{null!==o.current&&o.current.focus()}),[]),r.useEffect((()=>{let t=null;const n=t=>{const n=t.target;null!==o.current&&!o.current.contains(n)&&e&&s()};return null!==o.current&&(t=o.current?.parentElement,null!==t&&t?.addEventListener("click",n)),()=>{null!==t&&t?.removeEventListener("click",n)}}),[e,s]),r.useLayoutEffect((()=>{const e=o.current,t=e=>{"Escape"===e.key&&s()};return null!==e&&e.addEventListener("keydown",t),()=>{null!==e&&e.removeEventListener("keydown",t)}}),[d,s]);function h(){return r.createElement(D,{title:"Discard",onClose:()=>{u(!1)},closeOnClickOutside:!0},"Are you sure you want to discard the changes?",r.createElement("div",{className:"ExcalidrawModal__discardModal"},r.createElement(R,{onClick:()=>{u(!1),s()}},"Discard")," ",r.createElement(R,{onClick:()=>{u(!1)}},"Cancel")))}if(!1===i)return null;const g=null!=a.$$typeof?a:a.default;return l.createPortal(r.createElement("div",{className:"ExcalidrawModal__overlay",role:"dialog"},r.createElement("div",{className:"ExcalidrawModal__modal",ref:o,tabIndex:-1},r.createElement("div",{className:"ExcalidrawModal__row"},c&&r.createElement(h,null),r.createElement(g,{onChange:e=>{m(e)},initialData:{appState:{isLoading:!1},elements:n}}),r.createElement("div",{className:"ExcalidrawModal__actions"},r.createElement("button",{className:"action-button",onClick:()=>{0===d.filter((e=>!e.isDeleted)).length?s():u(!0)}},"Discard"),r.createElement("button",{className:"action-button",onClick:()=>{d.filter((e=>!e.isDeleted)).length>0?t(d):s()}},"Save"))))),document.body)}var L={__proto__:null,default:function({nodeKey:a,data:l}){const[s]=e.useLexicalComposerContext(),[o,c]=r.useState("[]"===l&&s.isEditable()),u=r.useRef(null),d=r.useRef(null),m=r.useRef(null),[g,E,f]=i.useLexicalNodeSelection(a),[p,_]=r.useState(!1),w=r.useCallback((e=>(g&&n.$isNodeSelection(n.$getSelection())&&(e.preventDefault(),s.update((()=>{const e=n.$getNodeByKey(a);h(e)&&e.remove(),E(!1)}))),!1)),[s,g,a,E]);r.useEffect((()=>{o?s.setEditable(!1):s.setEditable(!0)}),[o,s]),r.useEffect((()=>t.mergeRegister(s.registerCommand(n.CLICK_COMMAND,(e=>{const t=d.current,n=e.target;return!!p||!(null===t||!t.contains(n))&&(e.shiftKey||f(),E(!g),e.detail>1&&c(!0),!0)}),n.COMMAND_PRIORITY_LOW),s.registerCommand(n.KEY_DELETE_COMMAND,w,n.COMMAND_PRIORITY_LOW),s.registerCommand(n.KEY_BACKSPACE_COMMAND,w,n.COMMAND_PRIORITY_LOW))),[f,s,g,p,w,E]);const y=r.useCallback((()=>(c(!1),s.update((()=>{const e=n.$getNodeByKey(a);h(e)&&e.remove()})))),[s,a]),b=r.useMemo((()=>JSON.parse(l)),[l]);return r.createElement(r.Fragment,null,r.createElement(k,{initialElements:b,isShown:o,onDelete:y,onSave:e=>{s.setEditable(!0),(e=>{if(s.isEditable())s.update((()=>{const t=n.$getNodeByKey(a);h(t)&&(e.length>0?t.setData(JSON.stringify(e)):t.remove())}))})(e),c(!1)},closeOnClickOutside:!0}),b.length>0&&r.createElement("button",{ref:d,className:"excalidraw-button "+(g?"selected":"")},r.createElement(N,{imageContainerRef:u,className:"image",elements:b}),(g||p)&&r.createElement(x,{buttonRef:m,showCaption:!0,setShowCaption:()=>null,imageRef:u,editor:s,onResizeStart:()=>{_(!0)},onResizeEnd:()=>{setTimeout((()=>{_(!1)}),200)},captionsEnabled:!0})))}};exports.$createExcalidrawNode=m,exports.$isExcalidrawNode=h,exports.ExcalidrawNode=d,exports.ExcalidrawPlugin=E,exports.excalidrawExt=_;