@lexical/react
Version:
This package provides Lexical components and hooks for React applications.
10 lines (8 loc) • 7.93 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.
*
*/
import{useCollaborationContext as t}from"@lexical/react/LexicalCollaborationContext";import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{syncCursorPositions as o,syncLexicalUpdateToYjs as r,createUndoManager as n,setLocalStateFocus as s,createBindingV2__EXPERIMENTAL as i,CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL as a,syncYjsStateToLexicalV2__EXPERIMENTAL as c,DIFF_VERSIONS_COMMAND__EXPERIMENTAL as l,renderSnapshot__EXPERIMENTAL as d,syncLexicalUpdateToYjsV2__EXPERIMENTAL as u,syncYjsChangesToLexical as p,initLocalState as m,TOGGLE_CONNECT_COMMAND as f,syncYjsChangesToLexicalV2__EXPERIMENTAL as g,removeCursorHighlightRule as h,CONNECTED_COMMAND as y,createYjsBinding as C}from"@lexical/yjs";import*as v from"react";import{useRef as x,useCallback as S,useEffect as E,useMemo as b,useState as D}from"react";import{SKIP_COLLAB_TAG as N,mergeRegister as j,FOCUS_COMMAND as k,COMMAND_PRIORITY_EDITOR as w,BLUR_COMMAND as _,getActiveElement as B,registerEventListeners as M,UNDO_COMMAND as P,REDO_COMMAND as H,$getRoot as L,HISTORY_MERGE_TAG as U,$createParagraphNode as F,$getSelection as R,CAN_UNDO_COMMAND as T,CAN_REDO_COMMAND as X}from"lexical";import{createPortal as z}from"react-dom";import{UndoManager as A}from"yjs";import{jsx as q,Fragment as G}from"react/jsx-runtime";const I=Symbol.for("@lexical/yjs/UndoManager");function J(t,e,n,s,i,a,c,l,d,u,m,f,g=o,y=!1){const C=x(!1),v=S(()=>{const{root:e}=l;c&&e.isEmpty()&&0===e._xmlText._length&&Y(l,t,m)},[l,t,m,c]);return E(()=>{const{root:e}=l,o=(t,e)=>{const o=e.origin;if(o!==l){p(l,n,t,o instanceof A,g)}};e.getSharedType().observeDeep(o);const s=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyLeaves:o,dirtyElements:s,normalizedNodes:i,tags:a})=>{a.has(N)||r(l,n,t,e,s,o,i,a)});return()=>{e.getSharedType().unobserveDeep(o),s()}},[l,n,t,d,s,e,g]),E(()=>{const o=o=>{!function(t,e){if(t.update(()=>{const t=L();t.clear(),t.select()},{tag:N}),null==e.cursors)return;const o=e.cursors;if(null==o)return;const r=e.cursorsContainer;if(null==r)return;for(const t of o.values()){const o=t.selection;if(null!==o){null!==o.highlight&&(CSS.highlights.delete(o.highlightName),h(e,o.highlightName)),o.caret.parentNode===r&&r.removeChild(o.caret);for(const t of o.selections)t.parentNode===r&&r.removeChild(t);t.selection=null}}}(t,l),d(o),s.set(e,o),C.current=!0},r=()=>{C.current=!1};return n.on("reload",o),n.on("sync",r),()=>{n.off("reload",o),n.off("sync",r)}},[l,n,t,d,s,e]),K(t,n,i,a,C,f,v),O(l,n,y),Q(l,u)}function K(t,e,o,r,n,s,i){const a=S(()=>e.connect(),[e]),c=S(()=>{try{e.disconnect()}catch(t){}},[e]);E(()=>{const l=({status:e})=>{t.dispatchCommand(y,"connected"===e)},d=t=>{t&&!1===n.current&&i&&i()},u=t.getRootElement();m(e,o,r,null!==u&&B(u)===u,s||{}),e.on("status",l),e.on("sync",d);const p=a();return()=>{!1===n.current&&(p?p.then(c):c()),e.off("sync",d),e.off("status",l)}},[t,e,o,r,n,s,i,a,c]),E(()=>t.registerCommand(f,t=>(t?(console.log("Collaboration connected!"),a()):(console.log("Collaboration disconnected!"),c()),!0),w),[a,c,t]),E(()=>{const t=()=>{try{e.awareness.setLocalState(null)}catch(t){}};return M(window,{beforeunload:t,pagehide:t})},[e])}function O(t,e,r){E(()=>{const{awareness:n}=e,s=()=>{o(t,e,{selectionHighlight:r})};return n.on("update",s),()=>{n.off("update",s)}},[t,e,r])}function Q(t,e){return b(()=>/*#__PURE__*/z(/*#__PURE__*/q("div",{ref:e=>{t.cursorsContainer=e}}),e&&e.current||document.body),[t,e])}function V(t,e,o,r,n){E(()=>j(t.registerCommand(k,()=>(s(e,o,r,!0,n||{}),!1),w),t.registerCommand(_,()=>(s(e,o,r,!1,n||{}),!1),w)),[r,t,o,e,n])}function W(t,e){E(()=>j(t.registerCommand(P,()=>(e.undo(),!0),w),t.registerCommand(H,()=>(e.redo(),!0),w))),E(()=>{const o=t;return o[I]=e,()=>{o[I]===e&&delete o[I]}},[t,e]);const o=S(()=>{e.clear()},[e]);return v.useEffect(()=>{const o=()=>{t.dispatchCommand(T,e.undoStack.length>0),t.dispatchCommand(X,e.redoStack.length>0)};return e.on("stack-item-added",o),e.on("stack-item-popped",o),e.on("stack-cleared",o),()=>{e.off("stack-item-added",o),e.off("stack-item-popped",o),e.off("stack-cleared",o)}},[t,e]),o}function Y(t,e,o){t.isBootstrapping=!0;try{!function(t,e,o){t.update(()=>{const o=L();if(o.isEmpty())if(e)switch(typeof e){case"string":{const o=t.parseEditorState(e);t.setEditorState(o,{tag:U});break}case"object":t.setEditorState(e,{tag:U});break;case"function":t.update(()=>{L().isEmpty()&&e(t)},{tag:U})}else{const e=F();o.append(e);const r=t.getRootElement();(null!==R()||null!==r&&B(r)===r)&&e.select()}},{onUpdate:o,tag:U})}(e,o,()=>{t.isBootstrapping=!1})}finally{queueMicrotask(()=>{t.isBootstrapping=!1})}}function Z({id:o,providerFactory:r,shouldBootstrap:n,username:s,cursorColor:i,cursorsContainerRef:a,initialEditorState:c,excludedProperties:l,awarenessData:d,syncCursorPositionsFn:u,selectionHighlight:p,rootName:m,getXmlText:f}){const g=x(!1),h=x(null),y=x(null),v=t(s,i),{yjsDocMap:S,name:b,color:N}=v,[j]=e();et(v,j);const[k,w]=D(),[_,B]=D();E(()=>{const t=h.current;if(null!==t&&t.id===o&&t.providerFactory===r&&t.yjsDocMap===S)return;h.current={id:o,providerFactory:r,yjsDocMap:S};const e=r(o,S),n=y.current;null!==n&&n!==e&&n.disconnect(),y.current=e,w(e),B(S.get(o))},[o,r,S]),E(()=>()=>{const t=y.current;null!==t&&(y.current=null,t.disconnect())},[]);const[M,P]=D();return E(()=>{if(!k)return;if(g.current)return;const t=_||S.get(o);if(!t)return;g.current=!0;const e=C({doc:t,docMap:S,editor:j,excludedProperties:l,getXmlText:f,id:o,rootName:m});P(e)},[j,k,o,S,_]),E(()=>{if(void 0!==M)return()=>{M.root.destroy(M)}},[M]),k&&M?/*#__PURE__*/q($,{awarenessData:d,binding:M,collabContext:v,color:N,cursorsContainerRef:a,editor:j,id:o,initialEditorState:c,name:b,provider:k,setDoc:B,shouldBootstrap:n,yjsDocMap:S,syncCursorPositionsFn:u,selectionHighlight:p}):/*#__PURE__*/q(G,{})}function $({editor:t,id:e,provider:o,yjsDocMap:r,name:s,color:i,shouldBootstrap:a,cursorsContainerRef:c,initialEditorState:l,awarenessData:d,collabContext:u,binding:p,setDoc:m,syncCursorPositionsFn:f,selectionHighlight:g}){const h=J(t,e,o,r,s,i,a,p,m,c,l,d,f,g);return function(t,e){W(t,b(()=>n(e,e.root.getSharedType()),[e]))}(t,p),V(t,o,s,i,d),h}function tt({id:o,doc:r,provider:s,__shouldBootstrapUnsafe:p,username:m,cursorColor:f,cursorsContainerRef:h,excludedProperties:y,awarenessData:C,selectionHighlight:v,rootName:x,getXmlElement:k}){const _=t(m,f),{yjsDocMap:B,name:M,color:P}=_,[H]=e();et(_,H);const L=function(t,e,o,r,n,s,p,m={}){const{awarenessData:f,excludedProperties:h,rootName:y,getXmlElement:C,selectionHighlight:v=!1,__shouldBootstrapUnsafe:x}=m,k=b(()=>({current:!1}),[]),[_]=D(()=>i(t,e,o,n,{excludedProperties:h,getXmlElement:C,rootName:y}));E(()=>(n.set(e,o),()=>{n.delete(e)}),[o,n,e]);const B=S(()=>{const{root:e}=_;x&&0===e._length&&Y(_,t)},[_,t,x]),[M,P]=D();return E(()=>{j(t.registerCommand(a,()=>(P(null),c(_,r),!0),w),t.registerCommand(l,({prevSnapshot:t,snapshot:e})=>(P({prevSnapshot:t,snapshot:e}),!0),w))},[t,_,r]),E(()=>{const{root:e}=_;if(M)return void d(_,M.snapshot,M.prevSnapshot);const o=(t,e)=>{const o=e.origin;o!==_&&g(_,r,t,e,o instanceof A)};e.observeDeep(o);const n=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyElements:o,dirtyLeaves:n,normalizedNodes:s,tags:i})=>{i.has(N)||u(_,r,t,e,o,n,s,i)});return()=>{e.unobserveDeep(o),n()}},[_,r,t,M]),K(t,r,s,p,k,f,B),O(_,r,v),_}(H,o,r,s,B,M,P,{__shouldBootstrapUnsafe:p,awarenessData:C,excludedProperties:y,getXmlElement:k,rootName:x,selectionHighlight:v});return function(t,e){W(t,b(()=>n(e,e.root),[e]))}(H,L),V(H,s,M,P,C),Q(L,h)}const et=(t,e)=>{E(()=>(t.isCollabActive=!0,()=>{null==e._parentEditor&&(t.isCollabActive=!1)}),[t,e])};export{Z as CollaborationPlugin,tt as CollaborationPluginV2__EXPERIMENTAL};