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