UNPKG

@lexical/react

Version:

This package provides Lexical components and hooks for React applications.

10 lines (8 loc) • 6.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. * */ 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 u,syncLexicalUpdateToYjsV2__EXPERIMENTAL as l,syncYjsChangesToLexical as p,initLocalState as m,TOGGLE_CONNECT_COMMAND as f,syncYjsChangesToLexicalV2__EXPERIMENTAL as g,CONNECTED_COMMAND as C,createBinding as h}from"@lexical/yjs";import*as y from"react";import{useRef as v,useCallback as x,useEffect as E,useMemo as S,useState as b}from"react";import{mergeRegister as D}from"@lexical/utils";import{SKIP_COLLAB_TAG as k,FOCUS_COMMAND as _,COMMAND_PRIORITY_EDITOR as j,BLUR_COMMAND as w,$getRoot as P,HISTORY_MERGE_TAG as B,$createParagraphNode as R,$getSelection as L,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,u,l,m,f,g=o){const C=v(!1),h=x(()=>{const{root:e}=d;i&&e.isEmpty()&&0===e._xmlText._length&&Q(t,m)},[d,t,m,i]);return E(()=>{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(k)||r(d,n,t,e,s,o,a,c)});return()=>{e.getSharedType().unobserveDeep(o),s()}},[d,n,t,u,s,e,g]),E(()=>{const o=o=>{!function(t,e){if(t.update(()=>{const t=P();t.clear(),t.select()},{tag:k}),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),u(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)}},[d,n,t,u,s,e]),H(t,n,a,c,C,f,h),I(d,n),J(d,l)}function H(t,e,o,r,n,s,a){const c=x(()=>e.connect(),[e]),i=x(()=>{try{e.disconnect()}catch(t){}},[e]);E(()=>{const d=({status:e})=>{t.dispatchCommand(C,"connected"===e)},u=t=>{t&&!1===n.current&&a&&a()};m(e,o,r,document.activeElement===t.getRootElement(),s||{}),e.on("status",d),e.on("sync",u);const l=c();return()=>{!1===n.current&&(l?l.then(i):i()),e.off("sync",u),e.off("status",d)}},[t,e,o,r,n,s,a,c,i]),E(()=>t.registerCommand(f,t=>(t?(console.log("Collaboration connected!"),c()):(console.log("Collaboration disconnected!"),i()),!0),j),[c,i,t])}function I(t,e){E(()=>{const{awareness:r}=e,n=()=>{o(t,e)};return r.on("update",n),()=>{r.off("update",n)}},[t,e])}function J(t,e){return S(()=>T(z("div",{ref:e=>{t.cursorsContainer=e}}),e&&e.current||document.body),[t,e])}function K(t,e,o,r,n){E(()=>D(t.registerCommand(_,()=>(s(e,o,r,!0,n||{}),!1),j),t.registerCommand(w,()=>(s(e,o,r,!1,n||{}),!1),j)),[r,t,o,e,n])}function O(t,e){E(()=>D(t.registerCommand(U,()=>(e.undo(),!0),j),t.registerCommand(F,()=>(e.redo(),!0),j)));const o=x(()=>{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=P();if(o.isEmpty())if(e)switch(typeof e){case"string":{const o=t.parseEditorState(e);t.setEditorState(o,{tag:B});break}case"object":t.setEditorState(e,{tag:B});break;case"function":t.update(()=>{P().isEmpty()&&e(t)},{tag:B})}else{const e=R();o.append(e);const{activeElement:r}=document;(null!==L()||null!==r&&r===t.getRootElement())&&e.select()}},{tag:B})}function V({id:o,providerFactory:r,shouldBootstrap:n,username:s,cursorColor:a,cursorsContainerRef:c,initialEditorState:i,excludedProperties:d,awarenessData:u,syncCursorPositionsFn:l}){const p=v(!1),m=v(!1),f=t(s,a),{yjsDocMap:g,name:C,color:y}=f,[x]=e();Y(f,x);const[S,D]=b(),[k,_]=b();E(()=>{if(m.current)return;m.current=!0;const t=r(o,g);return D(t),_(g.get(o)),()=>{t.disconnect()}},[o,r,g]);const[j,w]=b();return E(()=>{if(!S)return;if(p.current)return;p.current=!0;const t=h(x,S,o,k||g.get(o),g,d);return w(t),()=>{t.root.destroy(t)}},[x,S,o,g,k,d]),S&&j?z(W,{awarenessData:u,binding:j,collabContext:f,color:y,cursorsContainerRef:c,editor:x,id:o,initialEditorState:i,name:C,provider:S,setDoc:_,shouldBootstrap:n,yjsDocMap:g,syncCursorPositionsFn:l}):z(q,{})}function W({editor:t,id:e,provider:o,yjsDocMap:r,name:s,color:a,shouldBootstrap:c,cursorsContainerRef:i,initialEditorState:d,awarenessData:u,collabContext:l,binding:p,setDoc:m,syncCursorPositionsFn:f}){const g=G(t,e,o,r,s,a,c,p,m,i,d,u,f);return function(t,e){O(t,S(()=>n(e,e.root.getSharedType()),[e]))}(t,p),K(t,o,s,a,u),g}function X({id:o,doc:r,provider:s,__shouldBootstrapUnsafe:p,username:m,cursorColor:f,cursorsContainerRef:C,excludedProperties:h,awarenessData:y}){const v=t(m,f),{yjsDocMap:_,name:w,color:P}=v,[B]=e();Y(v,B);const R=function(t,e,o,r,n,s,p,m={}){const{awarenessData:f,excludedProperties:C,rootName:h,__shouldBootstrapUnsafe:y}=m,v=S(()=>({current:!1}),[]),_=S(()=>a(t,e,o,n,{excludedProperties:C,rootName:h}),[t,e,o,n,C,h]);E(()=>(n.set(e,o),()=>{n.delete(e)}),[o,n,e]);const w=x(()=>{const{root:e}=_;y&&0===e._length&&Q(t)},[_,t,y]),[P,B]=b();return E(()=>{D(t.registerCommand(c,()=>(B(null),i(_,r),!0),j),t.registerCommand(d,({prevSnapshot:t,snapshot:e})=>(B({prevSnapshot:t,snapshot:e}),!0),j))},[t,_,r]),E(()=>{const{root:e}=_;if(P)return void u(_,P.snapshot,P.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,normalizedNodes:n,tags:s})=>{s.has(k)||l(_,r,t,e,o,n,s)});return()=>{e.unobserveDeep(o),n()}},[_,r,t,P]),H(t,r,s,p,v,f,w),I(_,r),_}(B,o,r,s,_,w,P,{__shouldBootstrapUnsafe:p,awarenessData:y,excludedProperties:h});return function(t,e){O(t,S(()=>n(e,e.root),[e]))}(B,R),K(B,s,w,P,y),J(R,C)}const Y=(t,e)=>{E(()=>(t.isCollabActive=!0,()=>{null==e._parentEditor&&(t.isCollabActive=!1)}),[t,e])};export{V as CollaborationPlugin,X as CollaborationPluginV2__EXPERIMENTAL};