@lexical/react 0.47.1-nightly.20260715.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -135,6 +135,14 @@ function $wrapOverflowedNodes(offset) {
135
135
  node
136
136
  } = dfsNodes[i];
137
137
 
138
+ // ElementNode.getTextContent() inserts '\n\n' after each non-inline
139
+ // element child that is not the last child. findOffset counts those
140
+ // separators (via $rootTextContent), so the DFS must count them too.
141
+ const prevSibling = node.getPreviousSibling();
142
+ if (lexical.$isElementNode(prevSibling) && !prevSibling.isInline()) {
143
+ accumulatedLength += 2;
144
+ }
145
+
138
146
  // Slot value roots (a non-inline DecoratorNode slotted into a host) are
139
147
  // leaf nodes with __parent === null; wrapping them in OverflowNode would
140
148
  // call node.replace() and throw, so they stay out of the wrap loop. Their
@@ -199,6 +207,10 @@ function $wrapOverflowedNodes(offset) {
199
207
  lexical.$setSelection(previousSelection);
200
208
  }
201
209
  $mergePrevious(overflowNode);
210
+ const nextNode = overflowNode.getNextSibling();
211
+ if (overflow.$isOverflowNode(nextNode)) {
212
+ $mergePrevious(nextNode);
213
+ }
202
214
  }
203
215
  }
204
216
  }
@@ -229,7 +241,7 @@ function $mergePrevious(overflowNode) {
229
241
  const anchor = selection.anchor;
230
242
  const anchorNode = anchor.getNode();
231
243
  const focus = selection.focus;
232
- const focusNode = anchor.getNode();
244
+ const focusNode = focus.getNode();
233
245
  if (anchorNode.is(previousNode)) {
234
246
  anchor.set(overflowNode.getKey(), anchor.offset, 'element');
235
247
  } else if (anchorNode.is(overflowNode)) {
@@ -133,6 +133,14 @@ function $wrapOverflowedNodes(offset) {
133
133
  node
134
134
  } = dfsNodes[i];
135
135
 
136
+ // ElementNode.getTextContent() inserts '\n\n' after each non-inline
137
+ // element child that is not the last child. findOffset counts those
138
+ // separators (via $rootTextContent), so the DFS must count them too.
139
+ const prevSibling = node.getPreviousSibling();
140
+ if ($isElementNode(prevSibling) && !prevSibling.isInline()) {
141
+ accumulatedLength += 2;
142
+ }
143
+
136
144
  // Slot value roots (a non-inline DecoratorNode slotted into a host) are
137
145
  // leaf nodes with __parent === null; wrapping them in OverflowNode would
138
146
  // call node.replace() and throw, so they stay out of the wrap loop. Their
@@ -197,6 +205,10 @@ function $wrapOverflowedNodes(offset) {
197
205
  $setSelection(previousSelection);
198
206
  }
199
207
  $mergePrevious(overflowNode);
208
+ const nextNode = overflowNode.getNextSibling();
209
+ if ($isOverflowNode(nextNode)) {
210
+ $mergePrevious(nextNode);
211
+ }
200
212
  }
201
213
  }
202
214
  }
@@ -227,7 +239,7 @@ function $mergePrevious(overflowNode) {
227
239
  const anchor = selection.anchor;
228
240
  const anchorNode = anchor.getNode();
229
241
  const focus = selection.focus;
230
- const focusNode = anchor.getNode();
242
+ const focusNode = focus.getNode();
231
243
  if (anchorNode.is(previousNode)) {
232
244
  anchor.set(overflowNode.getKey(), anchor.offset, 'element');
233
245
  } else if (anchorNode.is(overflowNode)) {
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),n=require("@lexical/overflow"),r=require("@lexical/text"),i=require("@lexical/utils"),o=require("lexical"),s=require("react/jsx-runtime");function l(e,s,l=Object.freeze({})){const{strlen:f=e=>e.length,remainingCharacters:g=()=>{}}=l;t.useEffect(()=>{e.hasNodes([n.OverflowNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t.useEffect(()=>{let t=e.read("latest",r.$rootTextContent),l=0;return o.mergeRegister(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:r,dirtyElements:u})=>{const d=e.isComposing(),h=r.size>0||u.size>0;if(d||!h)return;const m=f(t),x=m>s||null!==l&&l>s;if(g(s-m),null===l||x){const r=function(e,t,n){let r=0,i=0;if("function"==typeof Intl.Segmenter){const o=(new Intl.Segmenter).segment(e);for(const{segment:e}of o){const o=i+n(e);if(o>t)break;i=o,r+=e.length}}else{const o=Array.from(e),s=o.length;for(let e=0;e<s;e++){const s=o[e],l=i+n(s);if(l>t)break;i=l,r+=s.length}}return r}(t,s,f);e.update(()=>{!function(e){const t=i.$dfsWithSlots(),r=t.length;let s=0;for(let l=0;l<r;l+=1){const{node:r}=t[l],f=o.$isLeafNode(r)&&null!==o.$getSlotHost(r),g=o.$isLeafNode(r)&&!f&&!o.$findMatchingParent(r,n.$isOverflowNode);if(n.$isOverflowNode(r)){const t=s;if(s+r.getTextContentSize()<=e){const e=r.getParent(),t=r.getPreviousSibling(),n=r.getNextSibling();i.$unwrapNode(r);const s=o.$getSelection();!o.$isRangeSelection(s)||s.anchor.getNode().isAttached()&&s.focus.getNode().isAttached()||(o.$isTextNode(t)?t.select():o.$isTextNode(n)?n.select():null!==e&&e.select())}else if(t<e){const n=r.getFirstDescendant(),s=t+(null!==n?n.getTextContentSize():0);(o.$isTextNode(n)&&n.isSimpleText()||s<=e)&&i.$unwrapNode(r)}}else if(f)s+=r.getTextContentSize();else if(g){const t=s;if(s+=r.getTextContentSize(),s>e&&!n.$isOverflowNode(r.getParent())){const n=o.$getSelection();let i;if(t<e&&o.$isTextNode(r)&&r.isSimpleText()){const[,n]=r.splitText(e-t);i=c(n)}else i=c(r);null!==n&&o.$setSelection(n),a(i)}}}}(r)},{tag:o.HISTORY_MERGE_TAG})}l=m}),e.registerCommand(o.DELETE_CHARACTER_COMMAND,e=>{const t=o.$getSelection();if(!o.$isRangeSelection(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,i=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():o.$isElementNode(i)&&i.isEmpty()&&i.remove(),!0},o.COMMAND_PRIORITY_LOW))},[e,s,g,f])}function c(e){const t=n.$createOverflowNode();return e.replace(t),t.append(e),t}function a(e){const t=e.getPreviousSibling();if(!n.$isOverflowNode(t))return;const r=e.getFirstChild(),i=t.getChildren(),s=i.length;if(null===r)e.append(...i);else for(let e=0;e<s;e++)r.insertBefore(i[e]);const l=o.$getSelection();if(o.$isRangeSelection(l)){const n=l.anchor,r=n.getNode(),i=l.focus,o=n.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),s+n.offset,"element"),o.is(t)?i.set(e.getKey(),i.offset,"element"):o.is(e)&&i.set(e.getKey(),s+i.offset,"element")}t.remove()}let f=null;function g(e){const t=void 0===window.TextEncoder?null:(null===f&&(f=new window.TextEncoder),f);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function u({remainingCharacters:e}){
10
- return s.jsx("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}exports.CharacterLimitPlugin=function({charset:n="UTF-16",maxLength:r=5,renderer:i=u}){const[o]=e.useLexicalComposerContext(),[s,c]=t.useState(r),a=t.useMemo(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===n)return g(e);if("UTF-16"===n)return e.length;throw new Error("Unrecognized charset")}}),[n]);return l(o,r,a),i({remainingCharacters:s})};
9
+ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),n=require("@lexical/overflow"),r=require("@lexical/text"),i=require("@lexical/utils"),o=require("lexical"),s=require("react/jsx-runtime");function l(e,s,l=Object.freeze({})){const{strlen:g=e=>e.length,remainingCharacters:f=()=>{}}=l;t.useEffect(()=>{e.hasNodes([n.OverflowNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t.useEffect(()=>{let t=e.read("latest",r.$rootTextContent),l=0;return o.mergeRegister(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:r,dirtyElements:u})=>{const d=e.isComposing(),m=r.size>0||u.size>0;if(d||!m)return;const h=g(t),x=h>s||null!==l&&l>s;if(f(s-h),null===l||x){const r=function(e,t,n){let r=0,i=0;if("function"==typeof Intl.Segmenter){const o=(new Intl.Segmenter).segment(e);for(const{segment:e}of o){const o=i+n(e);if(o>t)break;i=o,r+=e.length}}else{const o=Array.from(e),s=o.length;for(let e=0;e<s;e++){const s=o[e],l=i+n(s);if(l>t)break;i=l,r+=s.length}}return r}(t,s,g);e.update(()=>{!function(e){const t=i.$dfsWithSlots(),r=t.length;let s=0;for(let l=0;l<r;l+=1){const{node:r}=t[l],g=r.getPreviousSibling();o.$isElementNode(g)&&!g.isInline()&&(s+=2);const f=o.$isLeafNode(r)&&null!==o.$getSlotHost(r),u=o.$isLeafNode(r)&&!f&&!o.$findMatchingParent(r,n.$isOverflowNode);if(n.$isOverflowNode(r)){const t=s;if(s+r.getTextContentSize()<=e){const e=r.getParent(),t=r.getPreviousSibling(),n=r.getNextSibling();i.$unwrapNode(r);const s=o.$getSelection();!o.$isRangeSelection(s)||s.anchor.getNode().isAttached()&&s.focus.getNode().isAttached()||(o.$isTextNode(t)?t.select():o.$isTextNode(n)?n.select():null!==e&&e.select())}else if(t<e){const n=r.getFirstDescendant(),s=t+(null!==n?n.getTextContentSize():0);(o.$isTextNode(n)&&n.isSimpleText()||s<=e)&&i.$unwrapNode(r)}}else if(f)s+=r.getTextContentSize();else if(u){const t=s;if(s+=r.getTextContentSize(),s>e&&!n.$isOverflowNode(r.getParent())){const i=o.$getSelection();let s;if(t<e&&o.$isTextNode(r)&&r.isSimpleText()){const[,n]=r.splitText(e-t);s=c(n)}else s=c(r);null!==i&&o.$setSelection(i),a(s);const l=s.getNextSibling();n.$isOverflowNode(l)&&a(l)}}}}(r)},{tag:o.HISTORY_MERGE_TAG})}l=h}),e.registerCommand(o.DELETE_CHARACTER_COMMAND,e=>{const t=o.$getSelection();if(!o.$isRangeSelection(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,i=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():o.$isElementNode(i)&&i.isEmpty()&&i.remove(),!0},o.COMMAND_PRIORITY_LOW))},[e,s,f,g])}function c(e){const t=n.$createOverflowNode();return e.replace(t),t.append(e),t}function a(e){const t=e.getPreviousSibling();if(!n.$isOverflowNode(t))return;const r=e.getFirstChild(),i=t.getChildren(),s=i.length;if(null===r)e.append(...i);else for(let e=0;e<s;e++)r.insertBefore(i[e]);const l=o.$getSelection();if(o.$isRangeSelection(l)){const n=l.anchor,r=n.getNode(),i=l.focus,o=i.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),s+n.offset,"element"),o.is(t)?i.set(e.getKey(),i.offset,"element"):o.is(e)&&i.set(e.getKey(),s+i.offset,"element")}t.remove()}let g=null;function f(e){const t=void 0===window.TextEncoder?null:(null===g&&(g=new window.TextEncoder),g);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function u({remainingCharacters:e}){
10
+ return s.jsx("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}exports.CharacterLimitPlugin=function({charset:n="UTF-16",maxLength:r=5,renderer:i=u}){const[o]=e.useLexicalComposerContext(),[s,c]=t.useState(r),a=t.useMemo(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===n)return f(e);if("UTF-16"===n)return e.length;throw new Error("Unrecognized charset")}}),[n]);return l(o,r,a),i({remainingCharacters:s})};
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useEffect as t,useState as n,useMemo as r}from"react";import{OverflowNode as o,$isOverflowNode as i,$createOverflowNode as s}from"@lexical/overflow";import{$rootTextContent as l}from"@lexical/text";import{$dfsWithSlots as c,$unwrapNode as a}from"@lexical/utils";import{mergeRegister as f,HISTORY_MERGE_TAG as g,DELETE_CHARACTER_COMMAND as m,$getSelection as u,$isRangeSelection as d,$isElementNode as h,COMMAND_PRIORITY_LOW as p,$isLeafNode as x,$getSlotHost as C,$findMatchingParent as S,$isTextNode as v,$setSelection as w}from"lexical";import{jsx as T}from"react/jsx-runtime";function y(e,n,r=Object.freeze({})){const{strlen:s=e=>e.length,remainingCharacters:T=()=>{}}=r;t(()=>{e.hasNodes([o])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t(()=>{let t=e.read("latest",l),r=0;return f(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:o,dirtyElements:l})=>{const f=e.isComposing(),m=o.size>0||l.size>0;if(f||!m)return;const h=s(t),p=h>n||null!==r&&r>n;if(T(n-h),null===r||p){const r=function(e,t,n){let r=0,o=0;if("function"==typeof Intl.Segmenter){const i=(new Intl.Segmenter).segment(e);for(const{segment:e}of i){const i=o+n(e);if(i>t)break;o=i,r+=e.length}}else{const i=Array.from(e),s=i.length;for(let e=0;e<s;e++){const s=i[e],l=o+n(s);if(l>t)break;o=l,r+=s.length}}return r}(t,n,s);e.update(()=>{!function(e){const t=c(),n=t.length;let r=0;for(let o=0;o<n;o+=1){const{node:n}=t[o],s=x(n)&&null!==C(n),l=x(n)&&!s&&!S(n,i);if(i(n)){const t=r;if(r+n.getTextContentSize()<=e){const e=n.getParent(),t=n.getPreviousSibling(),r=n.getNextSibling();a(n);const o=u();!d(o)||o.anchor.getNode().isAttached()&&o.focus.getNode().isAttached()||(v(t)?t.select():v(r)?r.select():null!==e&&e.select())}else if(t<e){const r=n.getFirstDescendant(),o=t+(null!==r?r.getTextContentSize():0);(v(r)&&r.isSimpleText()||o<=e)&&a(n)}}else if(s)r+=n.getTextContentSize();else if(l){const t=r;if(r+=n.getTextContentSize(),r>e&&!i(n.getParent())){const r=u();let o;if(t<e&&v(n)&&n.isSimpleText()){const[,r]=n.splitText(e-t);o=N(r)}else o=N(n);null!==r&&w(r),b(o)}}}}(r)},{tag:g})}r=h}),e.registerCommand(m,e=>{const t=u();if(!d(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,o=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():h(o)&&o.isEmpty()&&o.remove(),!0},p))},[e,n,T,s])}function N(e){const t=s();return e.replace(t),t.append(e),t}function b(e){const t=e.getPreviousSibling();if(!i(t))return;const n=e.getFirstChild(),r=t.getChildren(),o=r.length;if(null===n)e.append(...r);else for(let e=0;e<o;e++)n.insertBefore(r[e]);const s=u();if(d(s)){const n=s.anchor,r=n.getNode(),i=s.focus,l=n.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),o+n.offset,"element"),l.is(t)?i.set(e.getKey(),i.offset,"element"):l.is(e)&&i.set(e.getKey(),o+i.offset,"element")}t.remove()}let z=null;function L(e){const t=void 0===window.TextEncoder?null:(null===z&&(z=new window.TextEncoder),z);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function U({remainingCharacters:e}){
10
- return T("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}function E({charset:t="UTF-16",maxLength:o=5,renderer:i=U}){const[s]=e(),[l,c]=n(o);return y(s,o,r(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===t)return L(e);if("UTF-16"===t)return e.length;throw new Error("Unrecognized charset")}}),[t])),i({remainingCharacters:l})}export{E as CharacterLimitPlugin};
9
+ import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useEffect as t,useState as n,useMemo as r}from"react";import{OverflowNode as o,$isOverflowNode as i,$createOverflowNode as s}from"@lexical/overflow";import{$rootTextContent as l}from"@lexical/text";import{$dfsWithSlots as c,$unwrapNode as a}from"@lexical/utils";import{mergeRegister as f,HISTORY_MERGE_TAG as g,DELETE_CHARACTER_COMMAND as m,$getSelection as u,$isRangeSelection as d,$isElementNode as h,COMMAND_PRIORITY_LOW as p,$isLeafNode as x,$getSlotHost as C,$findMatchingParent as S,$isTextNode as v,$setSelection as w}from"lexical";import{jsx as T}from"react/jsx-runtime";function b(e,n,r=Object.freeze({})){const{strlen:s=e=>e.length,remainingCharacters:T=()=>{}}=r;t(()=>{e.hasNodes([o])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t(()=>{let t=e.read("latest",l),r=0;return f(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:o,dirtyElements:l})=>{const f=e.isComposing(),m=o.size>0||l.size>0;if(f||!m)return;const p=s(t),b=p>n||null!==r&&r>n;if(T(n-p),null===r||b){const r=function(e,t,n){let r=0,o=0;if("function"==typeof Intl.Segmenter){const i=(new Intl.Segmenter).segment(e);for(const{segment:e}of i){const i=o+n(e);if(i>t)break;o=i,r+=e.length}}else{const i=Array.from(e),s=i.length;for(let e=0;e<s;e++){const s=i[e],l=o+n(s);if(l>t)break;o=l,r+=s.length}}return r}(t,n,s);e.update(()=>{!function(e){const t=c(),n=t.length;let r=0;for(let o=0;o<n;o+=1){const{node:n}=t[o],s=n.getPreviousSibling();h(s)&&!s.isInline()&&(r+=2);const l=x(n)&&null!==C(n),c=x(n)&&!l&&!S(n,i);if(i(n)){const t=r;if(r+n.getTextContentSize()<=e){const e=n.getParent(),t=n.getPreviousSibling(),r=n.getNextSibling();a(n);const o=u();!d(o)||o.anchor.getNode().isAttached()&&o.focus.getNode().isAttached()||(v(t)?t.select():v(r)?r.select():null!==e&&e.select())}else if(t<e){const r=n.getFirstDescendant(),o=t+(null!==r?r.getTextContentSize():0);(v(r)&&r.isSimpleText()||o<=e)&&a(n)}}else if(l)r+=n.getTextContentSize();else if(c){const t=r;if(r+=n.getTextContentSize(),r>e&&!i(n.getParent())){const r=u();let o;if(t<e&&v(n)&&n.isSimpleText()){const[,r]=n.splitText(e-t);o=y(r)}else o=y(n);null!==r&&w(r),N(o);const s=o.getNextSibling();i(s)&&N(s)}}}}(r)},{tag:g})}r=p}),e.registerCommand(m,e=>{const t=u();if(!d(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,o=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():h(o)&&o.isEmpty()&&o.remove(),!0},p))},[e,n,T,s])}function y(e){const t=s();return e.replace(t),t.append(e),t}function N(e){const t=e.getPreviousSibling();if(!i(t))return;const n=e.getFirstChild(),r=t.getChildren(),o=r.length;if(null===n)e.append(...r);else for(let e=0;e<o;e++)n.insertBefore(r[e]);const s=u();if(d(s)){const n=s.anchor,r=n.getNode(),i=s.focus,l=i.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),o+n.offset,"element"),l.is(t)?i.set(e.getKey(),i.offset,"element"):l.is(e)&&i.set(e.getKey(),o+i.offset,"element")}t.remove()}let z=null;function L(e){const t=void 0===window.TextEncoder?null:(null===z&&(z=new window.TextEncoder),z);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function P({remainingCharacters:e}){
10
+ return T("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}function U({charset:t="UTF-16",maxLength:o=5,renderer:i=P}){const[s]=e(),[l,c]=n(o);return b(s,o,r(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===t)return L(e);if("UTF-16"===t)return e.length;throw new Error("Unrecognized charset")}}),[t])),i({remainingCharacters:l})}export{U as CharacterLimitPlugin};
@@ -26,6 +26,8 @@ type CollaborationPluginProps = {
26
26
  * Fallback to legacy method if not enabled or not supported.
27
27
  */
28
28
  selectionHighlight?: boolean;
29
+ /** Customize the Yjs shared-type key used for the root `XmlText`. Defaults to `'root'`. */
30
+ rootName?: string;
29
31
  };
30
32
  /**
31
33
  * Connects the editor to a Yjs document for real-time collaboration, syncing
@@ -36,7 +38,7 @@ type CollaborationPluginProps = {
36
38
  * @returns The element that renders collaborators' cursors (or an empty
37
39
  * fragment until the provider and binding are initialized).
38
40
  */
39
- export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, syncCursorPositionsFn, selectionHighlight, }: CollaborationPluginProps): JSX.Element;
41
+ export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, syncCursorPositionsFn, selectionHighlight, rootName, }: CollaborationPluginProps): JSX.Element;
40
42
  type CollaborationPluginV2Props = {
41
43
  id: string;
42
44
  doc: Doc;
@@ -51,6 +53,8 @@ type CollaborationPluginV2Props = {
51
53
  * Fallback to legacy method if not enabled or not supported.
52
54
  */
53
55
  selectionHighlight?: boolean;
56
+ /** Customize the Yjs shared-type key used for the root `XmlElement`. Defaults to `'root-v2'`. */
57
+ rootName?: string;
54
58
  };
55
59
  /**
56
60
  * A variant of {@link CollaborationPlugin} that takes an already-created Yjs
@@ -61,5 +65,5 @@ type CollaborationPluginV2Props = {
61
65
  * @experimental The API may change in a future release.
62
66
  * @returns The element that renders collaborators' cursors.
63
67
  */
64
- export declare function CollaborationPluginV2__EXPERIMENTAL({ id, doc, provider, __shouldBootstrapUnsafe, username, cursorColor, cursorsContainerRef, excludedProperties, awarenessData, selectionHighlight, }: CollaborationPluginV2Props): JSX.Element;
68
+ export declare function CollaborationPluginV2__EXPERIMENTAL({ id, doc, provider, __shouldBootstrapUnsafe, username, cursorColor, cursorsContainerRef, excludedProperties, awarenessData, selectionHighlight, rootName, }: CollaborationPluginV2Props): JSX.Element;
65
69
  export {};
@@ -500,7 +500,8 @@ function CollaborationPlugin({
500
500
  excludedProperties,
501
501
  awarenessData,
502
502
  syncCursorPositionsFn,
503
- selectionHighlight
503
+ selectionHighlight,
504
+ rootName
504
505
  }) {
505
506
  const isBindingInitialized = React.useRef(false);
506
507
  const isProviderInitialized = React.useRef(false);
@@ -534,13 +535,25 @@ function CollaborationPlugin({
534
535
  if (isBindingInitialized.current) {
535
536
  return;
536
537
  }
538
+ const resolvedDoc = doc || yjsDocMap.get(id);
539
+ if (!resolvedDoc) {
540
+ return;
541
+ }
537
542
  isBindingInitialized.current = true;
538
- const newBinding = yjs.createBinding(editor, provider, id, doc || yjsDocMap.get(id), yjsDocMap, excludedProperties);
543
+ const newBinding = yjs.createYjsBinding({
544
+ doc: resolvedDoc,
545
+ docMap: yjsDocMap,
546
+ editor,
547
+ excludedProperties,
548
+ id,
549
+ rootName
550
+ });
551
+ // eslint-disable-next-line react-hooks/set-state-in-effect
539
552
  setBinding(newBinding);
540
553
  return () => {
541
554
  newBinding.root.destroy(newBinding);
542
555
  };
543
- }, [editor, provider, id, yjsDocMap, doc, excludedProperties]);
556
+ }, [editor, provider, id, yjsDocMap, doc, excludedProperties, rootName]);
544
557
  if (!provider || !binding) {
545
558
  return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {});
546
559
  }
@@ -603,7 +616,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
603
616
  cursorsContainerRef,
604
617
  excludedProperties,
605
618
  awarenessData,
606
- selectionHighlight
619
+ selectionHighlight,
620
+ rootName
607
621
  }) {
608
622
  const collabContext = LexicalCollaborationContext.useCollaborationContext(username, cursorColor);
609
623
  const {
@@ -617,6 +631,7 @@ function CollaborationPluginV2__EXPERIMENTAL({
617
631
  __shouldBootstrapUnsafe,
618
632
  awarenessData,
619
633
  excludedProperties,
634
+ rootName,
620
635
  selectionHighlight
621
636
  });
622
637
  useYjsHistoryV2(editor, binding);
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { useCollaborationContext } from '@lexical/react/LexicalCollaborationContext';
10
10
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
11
- import { syncCursorPositions, syncLexicalUpdateToYjs, createUndoManager, setLocalStateFocus, createBindingV2__EXPERIMENTAL, CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL, syncYjsStateToLexicalV2__EXPERIMENTAL, DIFF_VERSIONS_COMMAND__EXPERIMENTAL, renderSnapshot__EXPERIMENTAL, syncLexicalUpdateToYjsV2__EXPERIMENTAL, syncYjsChangesToLexical, initLocalState, TOGGLE_CONNECT_COMMAND, syncYjsChangesToLexicalV2__EXPERIMENTAL, removeCursorHighlightRule, CONNECTED_COMMAND, createBinding } from '@lexical/yjs';
11
+ import { syncCursorPositions, syncLexicalUpdateToYjs, createUndoManager, setLocalStateFocus, createBindingV2__EXPERIMENTAL, CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL, syncYjsStateToLexicalV2__EXPERIMENTAL, DIFF_VERSIONS_COMMAND__EXPERIMENTAL, renderSnapshot__EXPERIMENTAL, syncLexicalUpdateToYjsV2__EXPERIMENTAL, syncYjsChangesToLexical, initLocalState, TOGGLE_CONNECT_COMMAND, syncYjsChangesToLexicalV2__EXPERIMENTAL, removeCursorHighlightRule, CONNECTED_COMMAND, createYjsBinding } from '@lexical/yjs';
12
12
  import * as React from 'react';
13
13
  import { useRef, useCallback, useEffect, useMemo, useState } from 'react';
14
14
  import { SKIP_COLLAB_TAG, mergeRegister, FOCUS_COMMAND, COMMAND_PRIORITY_EDITOR, BLUR_COMMAND, $getRoot, HISTORY_MERGE_TAG, $createParagraphNode, $getSelection, getActiveElement, registerEventListeners, UNDO_COMMAND, REDO_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND } from 'lexical';
@@ -486,7 +486,8 @@ function CollaborationPlugin({
486
486
  excludedProperties,
487
487
  awarenessData,
488
488
  syncCursorPositionsFn,
489
- selectionHighlight
489
+ selectionHighlight,
490
+ rootName
490
491
  }) {
491
492
  const isBindingInitialized = useRef(false);
492
493
  const isProviderInitialized = useRef(false);
@@ -520,13 +521,25 @@ function CollaborationPlugin({
520
521
  if (isBindingInitialized.current) {
521
522
  return;
522
523
  }
524
+ const resolvedDoc = doc || yjsDocMap.get(id);
525
+ if (!resolvedDoc) {
526
+ return;
527
+ }
523
528
  isBindingInitialized.current = true;
524
- const newBinding = createBinding(editor, provider, id, doc || yjsDocMap.get(id), yjsDocMap, excludedProperties);
529
+ const newBinding = createYjsBinding({
530
+ doc: resolvedDoc,
531
+ docMap: yjsDocMap,
532
+ editor,
533
+ excludedProperties,
534
+ id,
535
+ rootName
536
+ });
537
+ // eslint-disable-next-line react-hooks/set-state-in-effect
525
538
  setBinding(newBinding);
526
539
  return () => {
527
540
  newBinding.root.destroy(newBinding);
528
541
  };
529
- }, [editor, provider, id, yjsDocMap, doc, excludedProperties]);
542
+ }, [editor, provider, id, yjsDocMap, doc, excludedProperties, rootName]);
530
543
  if (!provider || !binding) {
531
544
  return /*#__PURE__*/jsx(Fragment, {});
532
545
  }
@@ -589,7 +602,8 @@ function CollaborationPluginV2__EXPERIMENTAL({
589
602
  cursorsContainerRef,
590
603
  excludedProperties,
591
604
  awarenessData,
592
- selectionHighlight
605
+ selectionHighlight,
606
+ rootName
593
607
  }) {
594
608
  const collabContext = useCollaborationContext(username, cursorColor);
595
609
  const {
@@ -603,6 +617,7 @@ function CollaborationPluginV2__EXPERIMENTAL({
603
617
  __shouldBootstrapUnsafe,
604
618
  awarenessData,
605
619
  excludedProperties,
620
+ rootName,
606
621
  selectionHighlight
607
622
  });
608
623
  useYjsHistoryV2(editor, binding);
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalCollaborationContext"),t=require("@lexical/react/LexicalComposerContext"),o=require("@lexical/yjs"),r=require("react"),n=require("lexical"),s=require("react-dom"),a=require("yjs"),c=require("react/jsx-runtime");function i(e){var t=Object.create(null);if(e)for(var o in e)t[o]=e[o];return t.default=e,t}var l=/*#__PURE__*/i(r);const u=Symbol.for("@lexical/yjs/UndoManager");function d(e,t,s,c,i,l,u,d,C,p,m,h,M=o.syncCursorPositions,R=!1){const O=r.useRef(!1),D=r.useCallback(()=>{const{root:t}=d;u&&t.isEmpty()&&0===t._xmlText._length&&_(e,m)},[d,e,m,u]);return r.useEffect(()=>{const{root:t}=d,r=(e,t)=>{const r=t.origin;if(r!==d){const t=r instanceof a.UndoManager;o.syncYjsChangesToLexical(d,s,e,t,M)}};t.getSharedType().observeDeep(r);const c=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyLeaves:r,dirtyElements:a,normalizedNodes:c,tags:i})=>{i.has(n.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjs(d,s,e,t,a,r,c,i)});return()=>{t.getSharedType().unobserveDeep(r),c()}},[d,s,e,C,c,t,M]),r.useEffect(()=>{const r=r=>{!function(e,t){if(e.update(()=>{const e=n.$getRoot();e.clear(),e.select()},{tag:n.SKIP_COLLAB_TAG}),null==t.cursors)return;const r=t.cursors;if(null==r)return;const s=t.cursorsContainer;if(null==s)return;for(const e of r.values()){const r=e.selection;if(null!==r){null!==r.highlight&&(CSS.highlights.delete(r.highlightName),o.removeCursorHighlightRule(t,r.highlightName)),r.caret.parentNode===s&&s.removeChild(r.caret);for(const e of r.selections)e.parentNode===s&&s.removeChild(e);e.selection=null}}}(e,d),C(r),c.set(t,r),O.current=!0},a=()=>{O.current=!1};return s.on("reload",r),s.on("sync",a),()=>{s.off("reload",r),s.off("sync",a)}},[d,s,e,C,c,t]),f(e,s,i,l,O,h,D),g(d,s,R),E(d,p)}function f(e,t,s,a,c,i,l){const u=r.useCallback(()=>t.connect(),[t]),d=r.useCallback(()=>{try{t.disconnect()}catch(e){}},[t]);r.useEffect(()=>{const r=({status:t})=>{e.dispatchCommand(o.CONNECTED_COMMAND,"connected"===t)},f=e=>{e&&!1===c.current&&l&&l()},g=e.getRootElement();o.initLocalState(t,s,a,null!==g&&n.getActiveElement(g)===g,i||{}),t.on("status",r),t.on("sync",f);const E=u();return()=>{!1===c.current&&(E?E.then(d):d()),t.off("sync",f),t.off("status",r)}},[e,t,s,a,c,i,l,u,d]),r.useEffect(()=>e.registerCommand(o.TOGGLE_CONNECT_COMMAND,e=>(e?(console.log("Collaboration connected!"),u()):(console.log("Collaboration disconnected!"),d()),!0),n.COMMAND_PRIORITY_EDITOR),[u,d,e]),r.useEffect(()=>{const e=()=>{try{t.awareness.setLocalState(null)}catch(e){}};return n.registerEventListeners(window,{beforeunload:e,pagehide:e})},[t])}function g(e,t,n){r.useEffect(()=>{const{awareness:r}=t,s=()=>{o.syncCursorPositions(e,t,{selectionHighlight:n})};return r.on("update",s),()=>{r.off("update",s)}},[e,t,n])}function E(e,t){return r.useMemo(()=>/*#__PURE__*/s.createPortal(/*#__PURE__*/c.jsx("div",{ref:t=>{e.cursorsContainer=t}}),t&&t.current||document.body),[e,t])}function C(e,t,s,a,c){r.useEffect(()=>n.mergeRegister(e.registerCommand(n.FOCUS_COMMAND,()=>(o.setLocalStateFocus(t,s,a,!0,c||{}),!1),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.BLUR_COMMAND,()=>(o.setLocalStateFocus(t,s,a,!1,c||{}),!1),n.COMMAND_PRIORITY_EDITOR)),[a,e,s,t,c])}function p(e,t){r.useEffect(()=>n.mergeRegister(e.registerCommand(n.UNDO_COMMAND,()=>(t.undo(),!0),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.REDO_COMMAND,()=>(t.redo(),!0),n.COMMAND_PRIORITY_EDITOR))),r.useEffect(()=>{const o=e;return o[u]=t,()=>{o[u]===t&&delete o[u]}},[e,t]);const o=r.useCallback(()=>{t.clear()},[t]);return l.useEffect(()=>{const o=()=>{e.dispatchCommand(n.CAN_UNDO_COMMAND,t.undoStack.length>0),e.dispatchCommand(n.CAN_REDO_COMMAND,t.redoStack.length>0)};return t.on("stack-item-added",o),t.on("stack-item-popped",o),t.on("stack-cleared",o),()=>{t.off("stack-item-added",o),t.off("stack-item-popped",o),t.off("stack-cleared",o)}},[e,t]),o}function _(e,t){e.update(()=>{const o=n.$getRoot();if(o.isEmpty())if(t)switch(typeof t){case"string":{const o=e.parseEditorState(t);e.setEditorState(o,{tag:n.HISTORY_MERGE_TAG});break}case"object":e.setEditorState(t,{tag:n.HISTORY_MERGE_TAG});break;case"function":e.update(()=>{n.$getRoot().isEmpty()&&t(e)},{tag:n.HISTORY_MERGE_TAG})}else{const t=n.$createParagraphNode();o.append(t);const r=e.getRootElement();(null!==n.$getSelection()||null!==r&&n.getActiveElement(r)===r)&&t.select()}},{tag:n.HISTORY_MERGE_TAG})}function m({editor:e,id:t,provider:n,yjsDocMap:s,name:a,color:c,shouldBootstrap:i,cursorsContainerRef:l,initialEditorState:u,awarenessData:f,collabContext:g,binding:E,setDoc:_,syncCursorPositionsFn:m,selectionHighlight:h}){const M=d(e,t,n,s,a,c,i,E,_,l,u,f,m,h);return function(e,t){p(e,r.useMemo(()=>o.createUndoManager(t,t.root.getSharedType()),[t]))}(e,E),C(e,n,a,c,f),M}const h=(e,t)=>{r.useEffect(()=>(e.isCollabActive=!0,()=>{null==t._parentEditor&&(e.isCollabActive=!1)}),[e,t])};exports.CollaborationPlugin=function({id:n,providerFactory:s,shouldBootstrap:a,username:i,cursorColor:l,cursorsContainerRef:u,initialEditorState:d,excludedProperties:f,awarenessData:g,syncCursorPositionsFn:E,selectionHighlight:C}){const p=r.useRef(!1),_=r.useRef(!1),M=e.useCollaborationContext(i,l),{yjsDocMap:R,name:O,color:D}=M,[T]=t.useLexicalComposerContext();h(M,T);const[N,S]=r.useState(),[A,I]=r.useState();r.useEffect(()=>{if(_.current)return;_.current=!0;const e=s(n,R);return S(e),I(R.get(n)),()=>{e.disconnect()}},[n,s,R]);const[y,x]=r.useState();return r.useEffect(()=>{if(!N)return;if(p.current)return;p.current=!0;const e=o.createBinding(T,N,n,A||R.get(n),R,f);return x(e),()=>{e.root.destroy(e)}},[T,N,n,R,A,f]),N&&y?/*#__PURE__*/c.jsx(m,{awarenessData:g,binding:y,collabContext:M,color:D,cursorsContainerRef:u,editor:T,id:n,initialEditorState:d,name:O,provider:N,setDoc:I,shouldBootstrap:a,yjsDocMap:R,syncCursorPositionsFn:E,selectionHighlight:C}):/*#__PURE__*/c.jsx(c.Fragment,{})},exports.CollaborationPluginV2__EXPERIMENTAL=function({id:s,doc:c,provider:i,__shouldBootstrapUnsafe:l,username:u,cursorColor:d,cursorsContainerRef:m,excludedProperties:M,awarenessData:R,selectionHighlight:O}){const D=e.useCollaborationContext(u,d),{yjsDocMap:T,name:N,color:S}=D,[A]=t.useLexicalComposerContext();h(D,A);const I=function(e,t,s,c,i,l,u,d={}){const{awarenessData:E,excludedProperties:C,rootName:p,selectionHighlight:m=!1,__shouldBootstrapUnsafe:h}=d,M=r.useMemo(()=>({current:!1}),[]),R=r.useMemo(()=>o.createBindingV2__EXPERIMENTAL(e,t,s,i,{excludedProperties:C,rootName:p}),[e,t,s,i,C,p]);r.useEffect(()=>(i.set(t,s),()=>{i.delete(t)}),[s,i,t]);const O=r.useCallback(()=>{const{root:t}=R;h&&0===t._length&&_(e)},[R,e,h]),[D,T]=r.useState();return r.useEffect(()=>{n.mergeRegister(e.registerCommand(o.CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL,()=>(T(null),o.syncYjsStateToLexicalV2__EXPERIMENTAL(R,c),!0),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(o.DIFF_VERSIONS_COMMAND__EXPERIMENTAL,({prevSnapshot:e,snapshot:t})=>(T({prevSnapshot:e,snapshot:t}),!0),n.COMMAND_PRIORITY_EDITOR))},[e,R,c]),r.useEffect(()=>{const{root:t}=R;if(D)return void o.renderSnapshot__EXPERIMENTAL(R,D.snapshot,D.prevSnapshot);const r=(e,t)=>{const r=t.origin;if(r!==R){const n=r instanceof a.UndoManager;o.syncYjsChangesToLexicalV2__EXPERIMENTAL(R,c,e,t,n)}};t.observeDeep(r);const s=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyElements:r,dirtyLeaves:s,normalizedNodes:a,tags:i})=>{i.has(n.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjsV2__EXPERIMENTAL(R,c,e,t,r,s,a,i)});return()=>{t.unobserveDeep(r),s()}},[R,c,e,D]),f(e,c,l,u,M,E,O),g(R,c,m),R}(A,s,c,i,T,N,S,{__shouldBootstrapUnsafe:l,awarenessData:R,excludedProperties:M,selectionHighlight:O});return function(e,t){p(e,r.useMemo(()=>o.createUndoManager(t,t.root),[t]))}(A,I),C(A,i,N,S,R),E(I,m)};
9
+ "use strict";var e=require("@lexical/react/LexicalCollaborationContext"),t=require("@lexical/react/LexicalComposerContext"),o=require("@lexical/yjs"),r=require("react"),n=require("lexical"),s=require("react-dom"),a=require("yjs"),c=require("react/jsx-runtime");function i(e){var t=Object.create(null);if(e)for(var o in e)t[o]=e[o];return t.default=e,t}var l=/*#__PURE__*/i(r);const u=Symbol.for("@lexical/yjs/UndoManager");function d(e,t,s,c,i,l,u,d,C,p,m,h,M=o.syncCursorPositions,R=!1){const O=r.useRef(!1),N=r.useCallback(()=>{const{root:t}=d;u&&t.isEmpty()&&0===t._xmlText._length&&_(e,m)},[d,e,m,u]);return r.useEffect(()=>{const{root:t}=d,r=(e,t)=>{const r=t.origin;if(r!==d){const t=r instanceof a.UndoManager;o.syncYjsChangesToLexical(d,s,e,t,M)}};t.getSharedType().observeDeep(r);const c=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyLeaves:r,dirtyElements:a,normalizedNodes:c,tags:i})=>{i.has(n.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjs(d,s,e,t,a,r,c,i)});return()=>{t.getSharedType().unobserveDeep(r),c()}},[d,s,e,C,c,t,M]),r.useEffect(()=>{const r=r=>{!function(e,t){if(e.update(()=>{const e=n.$getRoot();e.clear(),e.select()},{tag:n.SKIP_COLLAB_TAG}),null==t.cursors)return;const r=t.cursors;if(null==r)return;const s=t.cursorsContainer;if(null==s)return;for(const e of r.values()){const r=e.selection;if(null!==r){null!==r.highlight&&(CSS.highlights.delete(r.highlightName),o.removeCursorHighlightRule(t,r.highlightName)),r.caret.parentNode===s&&s.removeChild(r.caret);for(const e of r.selections)e.parentNode===s&&s.removeChild(e);e.selection=null}}}(e,d),C(r),c.set(t,r),O.current=!0},a=()=>{O.current=!1};return s.on("reload",r),s.on("sync",a),()=>{s.off("reload",r),s.off("sync",a)}},[d,s,e,C,c,t]),f(e,s,i,l,O,h,N),g(d,s,R),E(d,p)}function f(e,t,s,a,c,i,l){const u=r.useCallback(()=>t.connect(),[t]),d=r.useCallback(()=>{try{t.disconnect()}catch(e){}},[t]);r.useEffect(()=>{const r=({status:t})=>{e.dispatchCommand(o.CONNECTED_COMMAND,"connected"===t)},f=e=>{e&&!1===c.current&&l&&l()},g=e.getRootElement();o.initLocalState(t,s,a,null!==g&&n.getActiveElement(g)===g,i||{}),t.on("status",r),t.on("sync",f);const E=u();return()=>{!1===c.current&&(E?E.then(d):d()),t.off("sync",f),t.off("status",r)}},[e,t,s,a,c,i,l,u,d]),r.useEffect(()=>e.registerCommand(o.TOGGLE_CONNECT_COMMAND,e=>(e?(console.log("Collaboration connected!"),u()):(console.log("Collaboration disconnected!"),d()),!0),n.COMMAND_PRIORITY_EDITOR),[u,d,e]),r.useEffect(()=>{const e=()=>{try{t.awareness.setLocalState(null)}catch(e){}};return n.registerEventListeners(window,{beforeunload:e,pagehide:e})},[t])}function g(e,t,n){r.useEffect(()=>{const{awareness:r}=t,s=()=>{o.syncCursorPositions(e,t,{selectionHighlight:n})};return r.on("update",s),()=>{r.off("update",s)}},[e,t,n])}function E(e,t){return r.useMemo(()=>/*#__PURE__*/s.createPortal(/*#__PURE__*/c.jsx("div",{ref:t=>{e.cursorsContainer=t}}),t&&t.current||document.body),[e,t])}function C(e,t,s,a,c){r.useEffect(()=>n.mergeRegister(e.registerCommand(n.FOCUS_COMMAND,()=>(o.setLocalStateFocus(t,s,a,!0,c||{}),!1),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.BLUR_COMMAND,()=>(o.setLocalStateFocus(t,s,a,!1,c||{}),!1),n.COMMAND_PRIORITY_EDITOR)),[a,e,s,t,c])}function p(e,t){r.useEffect(()=>n.mergeRegister(e.registerCommand(n.UNDO_COMMAND,()=>(t.undo(),!0),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.REDO_COMMAND,()=>(t.redo(),!0),n.COMMAND_PRIORITY_EDITOR))),r.useEffect(()=>{const o=e;return o[u]=t,()=>{o[u]===t&&delete o[u]}},[e,t]);const o=r.useCallback(()=>{t.clear()},[t]);return l.useEffect(()=>{const o=()=>{e.dispatchCommand(n.CAN_UNDO_COMMAND,t.undoStack.length>0),e.dispatchCommand(n.CAN_REDO_COMMAND,t.redoStack.length>0)};return t.on("stack-item-added",o),t.on("stack-item-popped",o),t.on("stack-cleared",o),()=>{t.off("stack-item-added",o),t.off("stack-item-popped",o),t.off("stack-cleared",o)}},[e,t]),o}function _(e,t){e.update(()=>{const o=n.$getRoot();if(o.isEmpty())if(t)switch(typeof t){case"string":{const o=e.parseEditorState(t);e.setEditorState(o,{tag:n.HISTORY_MERGE_TAG});break}case"object":e.setEditorState(t,{tag:n.HISTORY_MERGE_TAG});break;case"function":e.update(()=>{n.$getRoot().isEmpty()&&t(e)},{tag:n.HISTORY_MERGE_TAG})}else{const t=n.$createParagraphNode();o.append(t);const r=e.getRootElement();(null!==n.$getSelection()||null!==r&&n.getActiveElement(r)===r)&&t.select()}},{tag:n.HISTORY_MERGE_TAG})}function m({editor:e,id:t,provider:n,yjsDocMap:s,name:a,color:c,shouldBootstrap:i,cursorsContainerRef:l,initialEditorState:u,awarenessData:f,collabContext:g,binding:E,setDoc:_,syncCursorPositionsFn:m,selectionHighlight:h}){const M=d(e,t,n,s,a,c,i,E,_,l,u,f,m,h);return function(e,t){p(e,r.useMemo(()=>o.createUndoManager(t,t.root.getSharedType()),[t]))}(e,E),C(e,n,a,c,f),M}const h=(e,t)=>{r.useEffect(()=>(e.isCollabActive=!0,()=>{null==t._parentEditor&&(e.isCollabActive=!1)}),[e,t])};exports.CollaborationPlugin=function({id:n,providerFactory:s,shouldBootstrap:a,username:i,cursorColor:l,cursorsContainerRef:u,initialEditorState:d,excludedProperties:f,awarenessData:g,syncCursorPositionsFn:E,selectionHighlight:C,rootName:p}){const _=r.useRef(!1),M=r.useRef(!1),R=e.useCollaborationContext(i,l),{yjsDocMap:O,name:N,color:D}=R,[T]=t.useLexicalComposerContext();h(R,T);const[S,A]=r.useState(),[I,y]=r.useState();r.useEffect(()=>{if(M.current)return;M.current=!0;const e=s(n,O);return A(e),y(O.get(n)),()=>{e.disconnect()}},[n,s,O]);const[x,L]=r.useState();return r.useEffect(()=>{if(!S)return;if(_.current)return;const e=I||O.get(n);if(!e)return;_.current=!0;const t=o.createYjsBinding({doc:e,docMap:O,editor:T,excludedProperties:f,id:n,rootName:p});return L(t),()=>{t.root.destroy(t)}},[T,S,n,O,I,f,p]),S&&x?/*#__PURE__*/c.jsx(m,{awarenessData:g,binding:x,collabContext:R,color:D,cursorsContainerRef:u,editor:T,id:n,initialEditorState:d,name:N,provider:S,setDoc:y,shouldBootstrap:a,yjsDocMap:O,syncCursorPositionsFn:E,selectionHighlight:C}):/*#__PURE__*/c.jsx(c.Fragment,{})},exports.CollaborationPluginV2__EXPERIMENTAL=function({id:s,doc:c,provider:i,__shouldBootstrapUnsafe:l,username:u,cursorColor:d,cursorsContainerRef:m,excludedProperties:M,awarenessData:R,selectionHighlight:O,rootName:N}){const D=e.useCollaborationContext(u,d),{yjsDocMap:T,name:S,color:A}=D,[I]=t.useLexicalComposerContext();h(D,I);const y=function(e,t,s,c,i,l,u,d={}){const{awarenessData:E,excludedProperties:C,rootName:p,selectionHighlight:m=!1,__shouldBootstrapUnsafe:h}=d,M=r.useMemo(()=>({current:!1}),[]),R=r.useMemo(()=>o.createBindingV2__EXPERIMENTAL(e,t,s,i,{excludedProperties:C,rootName:p}),[e,t,s,i,C,p]);r.useEffect(()=>(i.set(t,s),()=>{i.delete(t)}),[s,i,t]);const O=r.useCallback(()=>{const{root:t}=R;h&&0===t._length&&_(e)},[R,e,h]),[N,D]=r.useState();return r.useEffect(()=>{n.mergeRegister(e.registerCommand(o.CLEAR_DIFF_VERSIONS_COMMAND__EXPERIMENTAL,()=>(D(null),o.syncYjsStateToLexicalV2__EXPERIMENTAL(R,c),!0),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(o.DIFF_VERSIONS_COMMAND__EXPERIMENTAL,({prevSnapshot:e,snapshot:t})=>(D({prevSnapshot:e,snapshot:t}),!0),n.COMMAND_PRIORITY_EDITOR))},[e,R,c]),r.useEffect(()=>{const{root:t}=R;if(N)return void o.renderSnapshot__EXPERIMENTAL(R,N.snapshot,N.prevSnapshot);const r=(e,t)=>{const r=t.origin;if(r!==R){const n=r instanceof a.UndoManager;o.syncYjsChangesToLexicalV2__EXPERIMENTAL(R,c,e,t,n)}};t.observeDeep(r);const s=e.registerUpdateListener(({prevEditorState:e,editorState:t,dirtyElements:r,dirtyLeaves:s,normalizedNodes:a,tags:i})=>{i.has(n.SKIP_COLLAB_TAG)||o.syncLexicalUpdateToYjsV2__EXPERIMENTAL(R,c,e,t,r,s,a,i)});return()=>{t.unobserveDeep(r),s()}},[R,c,e,N]),f(e,c,l,u,M,E,O),g(R,c,m),R}(I,s,c,i,T,S,A,{__shouldBootstrapUnsafe:l,awarenessData:R,excludedProperties:M,rootName:N,selectionHighlight:O});return function(e,t){p(e,r.useMemo(()=>o.createUndoManager(t,t.root),[t]))}(I,y),C(I,i,S,A,R),E(y,m)};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- 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 i,syncYjsStateToLexicalV2__EXPERIMENTAL as c,DIFF_VERSIONS_COMMAND__EXPERIMENTAL as l,renderSnapshot__EXPERIMENTAL as d,syncLexicalUpdateToYjsV2__EXPERIMENTAL as u,syncYjsChangesToLexical as p,initLocalState as f,TOGGLE_CONNECT_COMMAND as m,syncYjsChangesToLexicalV2__EXPERIMENTAL as g,removeCursorHighlightRule as h,CONNECTED_COMMAND as C,createBinding as y}from"@lexical/yjs";import*as v from"react";import{useRef as S,useCallback as x,useEffect as b,useMemo as E,useState as D}from"react";import{SKIP_COLLAB_TAG as w,mergeRegister as k,FOCUS_COMMAND as _,COMMAND_PRIORITY_EDITOR as j,BLUR_COMMAND as N,$getRoot as P,HISTORY_MERGE_TAG as H,$createParagraphNode as L,$getSelection as B,getActiveElement as R,registerEventListeners as U,UNDO_COMMAND as M,REDO_COMMAND as F,CAN_UNDO_COMMAND as T,CAN_REDO_COMMAND as z}from"lexical";import{createPortal as A}from"react-dom";import{UndoManager as q}from"yjs";import{jsx as G,Fragment as I}from"react/jsx-runtime";const J=Symbol.for("@lexical/yjs/UndoManager");function K(t,e,n,s,a,i,c,l,d,u,f,m,g=o,C=!1){const y=S(!1),v=x(()=>{const{root:e}=l;c&&e.isEmpty()&&0===e._xmlText._length&&Y(t,f)},[l,t,f,c]);return b(()=>{const{root:e}=l,o=(t,e)=>{const o=e.origin;if(o!==l){p(l,n,t,o instanceof q,g)}};e.getSharedType().observeDeep(o);const s=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyLeaves:o,dirtyElements:s,normalizedNodes:a,tags:i})=>{i.has(w)||r(l,n,t,e,s,o,a,i)});return()=>{e.getSharedType().unobserveDeep(o),s()}},[l,n,t,d,s,e,g]),b(()=>{const o=o=>{!function(t,e){if(t.update(()=>{const t=P();t.clear(),t.select()},{tag:w}),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),y.current=!0},r=()=>{y.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]),O(t,n,a,i,y,m,v),Q(l,n,C),V(l,u)}function O(t,e,o,r,n,s,a){const i=x(()=>e.connect(),[e]),c=x(()=>{try{e.disconnect()}catch(t){}},[e]);b(()=>{const l=({status:e})=>{t.dispatchCommand(C,"connected"===e)},d=t=>{t&&!1===n.current&&a&&a()},u=t.getRootElement();f(e,o,r,null!==u&&R(u)===u,s||{}),e.on("status",l),e.on("sync",d);const p=i();return()=>{!1===n.current&&(p?p.then(c):c()),e.off("sync",d),e.off("status",l)}},[t,e,o,r,n,s,a,i,c]),b(()=>t.registerCommand(m,t=>(t?(console.log("Collaboration connected!"),i()):(console.log("Collaboration disconnected!"),c()),!0),j),[i,c,t]),b(()=>{const t=()=>{try{e.awareness.setLocalState(null)}catch(t){}};return U(window,{beforeunload:t,pagehide:t})},[e])}function Q(t,e,r){b(()=>{const{awareness:n}=e,s=()=>{o(t,e,{selectionHighlight:r})};return n.on("update",s),()=>{n.off("update",s)}},[t,e,r])}function V(t,e){return E(()=>/*#__PURE__*/A(/*#__PURE__*/G("div",{ref:e=>{t.cursorsContainer=e}}),e&&e.current||document.body),[t,e])}function W(t,e,o,r,n){b(()=>k(t.registerCommand(_,()=>(s(e,o,r,!0,n||{}),!1),j),t.registerCommand(N,()=>(s(e,o,r,!1,n||{}),!1),j)),[r,t,o,e,n])}function X(t,e){b(()=>k(t.registerCommand(M,()=>(e.undo(),!0),j),t.registerCommand(F,()=>(e.redo(),!0),j))),b(()=>{const o=t;return o[J]=e,()=>{o[J]===e&&delete o[J]}},[t,e]);const o=x(()=>{e.clear()},[e]);return v.useEffect(()=>{const o=()=>{t.dispatchCommand(T,e.undoStack.length>0),t.dispatchCommand(z,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){t.update(()=>{const o=P();if(o.isEmpty())if(e)switch(typeof e){case"string":{const o=t.parseEditorState(e);t.setEditorState(o,{tag:H});break}case"object":t.setEditorState(e,{tag:H});break;case"function":t.update(()=>{P().isEmpty()&&e(t)},{tag:H})}else{const e=L();o.append(e);const r=t.getRootElement();(null!==B()||null!==r&&R(r)===r)&&e.select()}},{tag:H})}function Z({id:o,providerFactory:r,shouldBootstrap:n,username:s,cursorColor:a,cursorsContainerRef:i,initialEditorState:c,excludedProperties:l,awarenessData:d,syncCursorPositionsFn:u,selectionHighlight:p}){const f=S(!1),m=S(!1),g=t(s,a),{yjsDocMap:h,name:C,color:v}=g,[x]=e();et(g,x);const[E,w]=D(),[k,_]=D();b(()=>{if(m.current)return;m.current=!0;const t=r(o,h);return w(t),_(h.get(o)),()=>{t.disconnect()}},[o,r,h]);const[j,N]=D();return b(()=>{if(!E)return;if(f.current)return;f.current=!0;const t=y(x,E,o,k||h.get(o),h,l);return N(t),()=>{t.root.destroy(t)}},[x,E,o,h,k,l]),E&&j?/*#__PURE__*/G($,{awarenessData:d,binding:j,collabContext:g,color:v,cursorsContainerRef:i,editor:x,id:o,initialEditorState:c,name:C,provider:E,setDoc:_,shouldBootstrap:n,yjsDocMap:h,syncCursorPositionsFn:u,selectionHighlight:p}):/*#__PURE__*/G(I,{})}function $({editor:t,id:e,provider:o,yjsDocMap:r,name:s,color:a,shouldBootstrap:i,cursorsContainerRef:c,initialEditorState:l,awarenessData:d,collabContext:u,binding:p,setDoc:f,syncCursorPositionsFn:m,selectionHighlight:g}){const h=K(t,e,o,r,s,a,i,p,f,c,l,d,m,g);return function(t,e){X(t,E(()=>n(e,e.root.getSharedType()),[e]))}(t,p),W(t,o,s,a,d),h}function tt({id:o,doc:r,provider:s,__shouldBootstrapUnsafe:p,username:f,cursorColor:m,cursorsContainerRef:h,excludedProperties:C,awarenessData:y,selectionHighlight:v}){const S=t(f,m),{yjsDocMap:_,name:N,color:P}=S,[H]=e();et(S,H);const L=function(t,e,o,r,n,s,p,f={}){const{awarenessData:m,excludedProperties:h,rootName:C,selectionHighlight:y=!1,__shouldBootstrapUnsafe:v}=f,S=E(()=>({current:!1}),[]),_=E(()=>a(t,e,o,n,{excludedProperties:h,rootName:C}),[t,e,o,n,h,C]);b(()=>(n.set(e,o),()=>{n.delete(e)}),[o,n,e]);const N=x(()=>{const{root:e}=_;v&&0===e._length&&Y(t)},[_,t,v]),[P,H]=D();return b(()=>{k(t.registerCommand(i,()=>(H(null),c(_,r),!0),j),t.registerCommand(l,({prevSnapshot:t,snapshot:e})=>(H({prevSnapshot:t,snapshot:e}),!0),j))},[t,_,r]),b(()=>{const{root:e}=_;if(P)return void d(_,P.snapshot,P.prevSnapshot);const o=(t,e)=>{const o=e.origin;o!==_&&g(_,r,t,e,o instanceof q)};e.observeDeep(o);const n=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyElements:o,dirtyLeaves:n,normalizedNodes:s,tags:a})=>{a.has(w)||u(_,r,t,e,o,n,s,a)});return()=>{e.unobserveDeep(o),n()}},[_,r,t,P]),O(t,r,s,p,S,m,N),Q(_,r,y),_}(H,o,r,s,_,N,P,{__shouldBootstrapUnsafe:p,awarenessData:y,excludedProperties:C,selectionHighlight:v});return function(t,e){X(t,E(()=>n(e,e.root),[e]))}(H,L),W(H,s,N,P,y),V(L,h)}const et=(t,e)=>{b(()=>(t.isCollabActive=!0,()=>{null==e._parentEditor&&(t.isCollabActive=!1)}),[t,e])};export{Z as CollaborationPlugin,tt as CollaborationPluginV2__EXPERIMENTAL};
9
+ 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 i,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 C,createYjsBinding as y}from"@lexical/yjs";import*as v from"react";import{useRef as S,useCallback as x,useEffect as b,useMemo as E,useState as D}from"react";import{SKIP_COLLAB_TAG as N,mergeRegister as w,FOCUS_COMMAND as k,COMMAND_PRIORITY_EDITOR as _,BLUR_COMMAND as j,$getRoot as P,HISTORY_MERGE_TAG as H,$createParagraphNode as L,$getSelection as B,getActiveElement as M,registerEventListeners as R,UNDO_COMMAND as U,REDO_COMMAND as F,CAN_UNDO_COMMAND as T,CAN_REDO_COMMAND as z}from"lexical";import{createPortal as A}from"react-dom";import{UndoManager as q}from"yjs";import{jsx as G,Fragment as I}from"react/jsx-runtime";const J=Symbol.for("@lexical/yjs/UndoManager");function K(t,e,n,s,a,i,c,l,d,u,m,f,g=o,C=!1){const y=S(!1),v=x(()=>{const{root:e}=l;c&&e.isEmpty()&&0===e._xmlText._length&&Y(t,m)},[l,t,m,c]);return b(()=>{const{root:e}=l,o=(t,e)=>{const o=e.origin;if(o!==l){p(l,n,t,o instanceof q,g)}};e.getSharedType().observeDeep(o);const s=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyLeaves:o,dirtyElements:s,normalizedNodes:a,tags:i})=>{i.has(N)||r(l,n,t,e,s,o,a,i)});return()=>{e.getSharedType().unobserveDeep(o),s()}},[l,n,t,d,s,e,g]),b(()=>{const o=o=>{!function(t,e){if(t.update(()=>{const t=P();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),y.current=!0},r=()=>{y.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]),O(t,n,a,i,y,f,v),Q(l,n,C),V(l,u)}function O(t,e,o,r,n,s,a){const i=x(()=>e.connect(),[e]),c=x(()=>{try{e.disconnect()}catch(t){}},[e]);b(()=>{const l=({status:e})=>{t.dispatchCommand(C,"connected"===e)},d=t=>{t&&!1===n.current&&a&&a()},u=t.getRootElement();m(e,o,r,null!==u&&M(u)===u,s||{}),e.on("status",l),e.on("sync",d);const p=i();return()=>{!1===n.current&&(p?p.then(c):c()),e.off("sync",d),e.off("status",l)}},[t,e,o,r,n,s,a,i,c]),b(()=>t.registerCommand(f,t=>(t?(console.log("Collaboration connected!"),i()):(console.log("Collaboration disconnected!"),c()),!0),_),[i,c,t]),b(()=>{const t=()=>{try{e.awareness.setLocalState(null)}catch(t){}};return R(window,{beforeunload:t,pagehide:t})},[e])}function Q(t,e,r){b(()=>{const{awareness:n}=e,s=()=>{o(t,e,{selectionHighlight:r})};return n.on("update",s),()=>{n.off("update",s)}},[t,e,r])}function V(t,e){return E(()=>/*#__PURE__*/A(/*#__PURE__*/G("div",{ref:e=>{t.cursorsContainer=e}}),e&&e.current||document.body),[t,e])}function W(t,e,o,r,n){b(()=>w(t.registerCommand(k,()=>(s(e,o,r,!0,n||{}),!1),_),t.registerCommand(j,()=>(s(e,o,r,!1,n||{}),!1),_)),[r,t,o,e,n])}function X(t,e){b(()=>w(t.registerCommand(U,()=>(e.undo(),!0),_),t.registerCommand(F,()=>(e.redo(),!0),_))),b(()=>{const o=t;return o[J]=e,()=>{o[J]===e&&delete o[J]}},[t,e]);const o=x(()=>{e.clear()},[e]);return v.useEffect(()=>{const o=()=>{t.dispatchCommand(T,e.undoStack.length>0),t.dispatchCommand(z,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){t.update(()=>{const o=P();if(o.isEmpty())if(e)switch(typeof e){case"string":{const o=t.parseEditorState(e);t.setEditorState(o,{tag:H});break}case"object":t.setEditorState(e,{tag:H});break;case"function":t.update(()=>{P().isEmpty()&&e(t)},{tag:H})}else{const e=L();o.append(e);const r=t.getRootElement();(null!==B()||null!==r&&M(r)===r)&&e.select()}},{tag:H})}function Z({id:o,providerFactory:r,shouldBootstrap:n,username:s,cursorColor:a,cursorsContainerRef:i,initialEditorState:c,excludedProperties:l,awarenessData:d,syncCursorPositionsFn:u,selectionHighlight:p,rootName:m}){const f=S(!1),g=S(!1),h=t(s,a),{yjsDocMap:C,name:v,color:x}=h,[E]=e();et(h,E);const[N,w]=D(),[k,_]=D();b(()=>{if(g.current)return;g.current=!0;const t=r(o,C);return w(t),_(C.get(o)),()=>{t.disconnect()}},[o,r,C]);const[j,P]=D();return b(()=>{if(!N)return;if(f.current)return;const t=k||C.get(o);if(!t)return;f.current=!0;const e=y({doc:t,docMap:C,editor:E,excludedProperties:l,id:o,rootName:m});return P(e),()=>{e.root.destroy(e)}},[E,N,o,C,k,l,m]),N&&j?/*#__PURE__*/G($,{awarenessData:d,binding:j,collabContext:h,color:x,cursorsContainerRef:i,editor:E,id:o,initialEditorState:c,name:v,provider:N,setDoc:_,shouldBootstrap:n,yjsDocMap:C,syncCursorPositionsFn:u,selectionHighlight:p}):/*#__PURE__*/G(I,{})}function $({editor:t,id:e,provider:o,yjsDocMap:r,name:s,color:a,shouldBootstrap:i,cursorsContainerRef:c,initialEditorState:l,awarenessData:d,collabContext:u,binding:p,setDoc:m,syncCursorPositionsFn:f,selectionHighlight:g}){const h=K(t,e,o,r,s,a,i,p,m,c,l,d,f,g);return function(t,e){X(t,E(()=>n(e,e.root.getSharedType()),[e]))}(t,p),W(t,o,s,a,d),h}function tt({id:o,doc:r,provider:s,__shouldBootstrapUnsafe:p,username:m,cursorColor:f,cursorsContainerRef:h,excludedProperties:C,awarenessData:y,selectionHighlight:v,rootName:S}){const k=t(m,f),{yjsDocMap:j,name:P,color:H}=k,[L]=e();et(k,L);const B=function(t,e,o,r,n,s,p,m={}){const{awarenessData:f,excludedProperties:h,rootName:C,selectionHighlight:y=!1,__shouldBootstrapUnsafe:v}=m,S=E(()=>({current:!1}),[]),k=E(()=>a(t,e,o,n,{excludedProperties:h,rootName:C}),[t,e,o,n,h,C]);b(()=>(n.set(e,o),()=>{n.delete(e)}),[o,n,e]);const j=x(()=>{const{root:e}=k;v&&0===e._length&&Y(t)},[k,t,v]),[P,H]=D();return b(()=>{w(t.registerCommand(i,()=>(H(null),c(k,r),!0),_),t.registerCommand(l,({prevSnapshot:t,snapshot:e})=>(H({prevSnapshot:t,snapshot:e}),!0),_))},[t,k,r]),b(()=>{const{root:e}=k;if(P)return void d(k,P.snapshot,P.prevSnapshot);const o=(t,e)=>{const o=e.origin;o!==k&&g(k,r,t,e,o instanceof q)};e.observeDeep(o);const n=t.registerUpdateListener(({prevEditorState:t,editorState:e,dirtyElements:o,dirtyLeaves:n,normalizedNodes:s,tags:a})=>{a.has(N)||u(k,r,t,e,o,n,s,a)});return()=>{e.unobserveDeep(o),n()}},[k,r,t,P]),O(t,r,s,p,S,f,j),Q(k,r,y),k}(L,o,r,s,j,P,H,{__shouldBootstrapUnsafe:p,awarenessData:y,excludedProperties:C,rootName:S,selectionHighlight:v});return function(t,e){X(t,E(()=>n(e,e.root),[e]))}(L,B),W(L,s,P,H,y),V(B,h)}const et=(t,e)=>{b(()=>(t.isCollabActive=!0,()=>{null==e._parentEditor&&(t.isCollabActive=!1)}),[t,e])};export{Z as CollaborationPlugin,tt as CollaborationPluginV2__EXPERIMENTAL};
@@ -43,7 +43,7 @@ function formatDevErrorMessage(message) {
43
43
  * Most code should read it through {@link useLexicalComposerContext} rather than
44
44
  * consuming the context directly.
45
45
  */
46
- const LexicalComposerContext = /*#__PURE__*/react.createContext(null);
46
+ const LexicalComposerContext = react.createContext(null);
47
47
 
48
48
  /**
49
49
  * Creates a {@link LexicalComposerContextType} for a composer. Theme resolution
@@ -41,7 +41,7 @@ function formatDevErrorMessage(message) {
41
41
  * Most code should read it through {@link useLexicalComposerContext} rather than
42
42
  * consuming the context directly.
43
43
  */
44
- const LexicalComposerContext = /*#__PURE__*/createContext(null);
44
+ const LexicalComposerContext = createContext(null);
45
45
 
46
46
  /**
47
47
  * Creates a {@link LexicalComposerContextType} for a composer. Theme resolution
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("react");const n=/*#__PURE__*/e.createContext(null);exports.LexicalComposerContext=n,exports.createLexicalComposerContext=function(e,n){let t=null;return null!=e&&(t=e[1]),{getTheme:function(){return null!=n?n:null!=t?t.getTheme():null}}},exports.useLexicalComposerContext=function(){const t=e.useContext(n);return null==t&&function(e,...n){const t=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of n)r.append("v",e);throw t.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${t.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(8),t};
9
+ "use strict";var e=require("react");const n=e.createContext(null);exports.LexicalComposerContext=n,exports.createLexicalComposerContext=function(e,n){let t=null;return null!=e&&(t=e[1]),{getTheme:function(){return null!=n?n:null!=t?t.getTheme():null}}},exports.useLexicalComposerContext=function(){const t=e.useContext(n);return null==t&&function(e,...n){const t=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of n)r.append("v",e);throw t.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${t.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(8),t};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{createContext as n,useContext as e}from"react";const r=/*#__PURE__*/n(null);function t(n,e){let r=null;return null!=n&&(r=n[1]),{getTheme:function(){return null!=e?e:null!=r?r.getTheme():null}}}function o(){const n=e(r);return null==n&&function(n,...e){const r=new URL("https://lexical.dev/docs/error"),t=new URLSearchParams;t.append("code",n);for(const n of e)t.append("v",n);throw r.search=t.toString(),Error(`Minified Lexical error #${n}; visit ${r.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(8),n}export{r as LexicalComposerContext,t as createLexicalComposerContext,o as useLexicalComposerContext};
9
+ import{createContext as n,useContext as e}from"react";const r=n(null);function t(n,e){let r=null;return null!=n&&(r=n[1]),{getTheme:function(){return null!=e?e:null!=r?r.getTheme():null}}}function o(){const n=e(r);return null==n&&function(n,...e){const r=new URL("https://lexical.dev/docs/error"),t=new URLSearchParams;t.append("code",n);for(const n of e)t.append("v",n);throw r.search=t.toString(),Error(`Minified Lexical error #${n}; visit ${r.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(8),n}export{r as LexicalComposerContext,t as createLexicalComposerContext,o as useLexicalComposerContext};
@@ -128,7 +128,7 @@ function ContentEditableElementImpl({
128
128
  role: role,
129
129
  spellCheck: spellCheck,
130
130
  style: style,
131
- tabIndex: tabIndex,
131
+ tabIndex: tabIndex ?? (isEditable ? undefined : -1),
132
132
  ...rest
133
133
  });
134
134
  }
@@ -126,7 +126,7 @@ function ContentEditableElementImpl({
126
126
  role: role,
127
127
  spellCheck: spellCheck,
128
128
  style: style,
129
- tabIndex: tabIndex,
129
+ tabIndex: tabIndex ?? (isEditable ? undefined : -1),
130
130
  ...rest
131
131
  });
132
132
  }
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),a=require("lexical"),r=require("react/jsx-runtime"),i=require("@lexical/text");const n=a.CAN_USE_DOM?t.useLayoutEffect:t.useEffect;function l({editor:e,ariaActiveDescendant:a,ariaAutoComplete:i,ariaControls:l,ariaDescribedBy:o,ariaErrorMessage:s,ariaExpanded:u,ariaInvalid:d,ariaLabel:c,ariaLabelledBy:f,ariaMultiline:b,ariaOwns:x,ariaRequired:m,autoCapitalize:E,className:p,id:C,role:v="textbox",spellCheck:y=!0,style:g,tabIndex:L,"data-testid":h,...w},q){const[j,R]=t.useState(e.isEditable()),D=t.useCallback(t=>{t&&t.ownerDocument&&t.ownerDocument.defaultView?e.setRootElement(t):e.setRootElement(null)},[e]),S=t.useMemo(()=>function(...e){return t=>{for(const a of e)"function"==typeof a?a(t):null!=a&&(a.current=t)}}(q,D),[D,q]);return n(()=>(R(e.isEditable()),e.registerEditableListener(e=>{R(e)})),[e]),/*#__PURE__*/r.jsx("div",{"aria-activedescendant":j?a:void 0,"aria-autocomplete":j?i:"none","aria-controls":j?l:void 0,"aria-describedby":o,...null!=s?{"aria-errormessage":s}:{},"aria-expanded":j&&"combobox"===v?!!u:void 0,...null!=d?{"aria-invalid":d}:{},"aria-label":c,"aria-labelledby":f,"aria-multiline":b,"aria-owns":j?x:void 0,"aria-readonly":!j||void 0,"aria-required":m,autoCapitalize:E,className:p,contentEditable:j,"data-testid":h,id:C,ref:S,role:v,spellCheck:y,style:g,tabIndex:L,...w})}const o=/*#__PURE__*/t.forwardRef(l);function s(e){return e.read("latest",i.$canShowPlaceholderCurry(e.isComposing()))}const u=/*#__PURE__*/t.forwardRef(d);function d(t,a){const{placeholder:i,...n}=t,[l]=e.useLexicalComposerContext();
10
- return r.jsxs(r.Fragment,{children:[/*#__PURE__*/r.jsx(o,{editor:l,...n,ref:a}),null!=i&&/*#__PURE__*/r.jsx(c,{editor:l,content:i})]})}function c({content:e,editor:i}){const l=function(e){const[r,i]=t.useState(()=>s(e));return n(()=>{function t(){const t=s(e);i(t)}return t(),a.mergeRegister(e.registerUpdateListener(()=>{t()}),e.registerEditableListener(()=>{t()}))},[e]),r}(i),[o,u]=t.useState(i.isEditable());if(t.useLayoutEffect(()=>(u(i.isEditable()),i.registerEditableListener(e=>{u(e)})),[i]),!l)return null;let d=null;return"function"==typeof e?d=e(o):null!==e&&(d=e),null===d?null:/*#__PURE__*/r.jsx("div",{"aria-hidden":!0,children:d})}exports.ContentEditable=u,exports.ContentEditableElement=o;
9
+ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),a=require("lexical"),r=require("react/jsx-runtime"),i=require("@lexical/text");const n=a.CAN_USE_DOM?t.useLayoutEffect:t.useEffect;function o({editor:e,ariaActiveDescendant:a,ariaAutoComplete:i,ariaControls:o,ariaDescribedBy:l,ariaErrorMessage:s,ariaExpanded:d,ariaInvalid:u,ariaLabel:c,ariaLabelledBy:f,ariaMultiline:b,ariaOwns:x,ariaRequired:m,autoCapitalize:E,className:p,id:C,role:v="textbox",spellCheck:y=!0,style:g,tabIndex:L,"data-testid":h,...w},q){const[j,R]=t.useState(e.isEditable()),D=t.useCallback(t=>{t&&t.ownerDocument&&t.ownerDocument.defaultView?e.setRootElement(t):e.setRootElement(null)},[e]),S=t.useMemo(()=>function(...e){return t=>{for(const a of e)"function"==typeof a?a(t):null!=a&&(a.current=t)}}(q,D),[D,q]);return n(()=>(R(e.isEditable()),e.registerEditableListener(e=>{R(e)})),[e]),/*#__PURE__*/r.jsx("div",{"aria-activedescendant":j?a:void 0,"aria-autocomplete":j?i:"none","aria-controls":j?o:void 0,"aria-describedby":l,...null!=s?{"aria-errormessage":s}:{},"aria-expanded":j&&"combobox"===v?!!d:void 0,...null!=u?{"aria-invalid":u}:{},"aria-label":c,"aria-labelledby":f,"aria-multiline":b,"aria-owns":j?x:void 0,"aria-readonly":!j||void 0,"aria-required":m,autoCapitalize:E,className:p,contentEditable:j,"data-testid":h,id:C,ref:S,role:v,spellCheck:y,style:g,tabIndex:L??(j?void 0:-1),...w})}const l=/*#__PURE__*/t.forwardRef(o);function s(e){return e.read("latest",i.$canShowPlaceholderCurry(e.isComposing()))}const d=/*#__PURE__*/t.forwardRef(u);function u(t,a){const{placeholder:i,...n}=t,[o]=e.useLexicalComposerContext();
10
+ return r.jsxs(r.Fragment,{children:[/*#__PURE__*/r.jsx(l,{editor:o,...n,ref:a}),null!=i&&/*#__PURE__*/r.jsx(c,{editor:o,content:i})]})}function c({content:e,editor:i}){const o=function(e){const[r,i]=t.useState(()=>s(e));return n(()=>{function t(){const t=s(e);i(t)}return t(),a.mergeRegister(e.registerUpdateListener(()=>{t()}),e.registerEditableListener(()=>{t()}))},[e]),r}(i),[l,d]=t.useState(i.isEditable());if(t.useLayoutEffect(()=>(d(i.isEditable()),i.registerEditableListener(e=>{d(e)})),[i]),!o)return null;let u=null;return"function"==typeof e?u=e(l):null!==e&&(u=e),null===u?null:/*#__PURE__*/r.jsx("div",{"aria-hidden":!0,children:u})}exports.ContentEditable=d,exports.ContentEditableElement=l;
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useLayoutEffect as t,useEffect as i,forwardRef as a,useState as r,useCallback as n,useMemo as o}from"react";import{CAN_USE_DOM as l,mergeRegister as d}from"lexical";import{jsx as s,jsxs as c,Fragment as u}from"react/jsx-runtime";import{$canShowPlaceholderCurry as m}from"@lexical/text";const f=l?t:i;function b({editor:e,ariaActiveDescendant:t,ariaAutoComplete:i,ariaControls:a,ariaDescribedBy:l,ariaErrorMessage:d,ariaExpanded:c,ariaInvalid:u,ariaLabel:m,ariaLabelledBy:b,ariaMultiline:p,ariaOwns:x,ariaRequired:E,autoCapitalize:v,className:y,id:C,role:g="textbox",spellCheck:L=!0,style:h,tabIndex:w,"data-testid":D,...I},R){const[k,q]=r(e.isEditable()),z=n(t=>{t&&t.ownerDocument&&t.ownerDocument.defaultView?e.setRootElement(t):e.setRootElement(null)},[e]),A=o(()=>function(...e){return t=>{for(const i of e)"function"==typeof i?i(t):null!=i&&(i.current=t)}}(R,z),[z,R]);return f(()=>(q(e.isEditable()),e.registerEditableListener(e=>{q(e)})),[e]),/*#__PURE__*/s("div",{"aria-activedescendant":k?t:void 0,"aria-autocomplete":k?i:"none","aria-controls":k?a:void 0,"aria-describedby":l,...null!=d?{"aria-errormessage":d}:{},"aria-expanded":k&&"combobox"===g?!!c:void 0,...null!=u?{"aria-invalid":u}:{},"aria-label":m,"aria-labelledby":b,"aria-multiline":p,"aria-owns":k?x:void 0,"aria-readonly":!k||void 0,"aria-required":E,autoCapitalize:v,className:y,contentEditable:k,"data-testid":D,id:C,ref:A,role:g,spellCheck:L,style:h,tabIndex:w,...I})}const p=/*#__PURE__*/a(b);function x(e){return e.read("latest",m(e.isComposing()))}const E=/*#__PURE__*/a(v);function v(t,i){const{placeholder:a,...r}=t,[n]=e();
10
- return c(u,{children:[/*#__PURE__*/s(p,{editor:n,...r,ref:i}),null!=a&&/*#__PURE__*/s(y,{editor:n,content:a})]})}function y({content:e,editor:i}){const a=function(e){const[t,i]=r(()=>x(e));return f(()=>{function t(){const t=x(e);i(t)}return t(),d(e.registerUpdateListener(()=>{t()}),e.registerEditableListener(()=>{t()}))},[e]),t}(i),[n,o]=r(i.isEditable());if(t(()=>(o(i.isEditable()),i.registerEditableListener(e=>{o(e)})),[i]),!a)return null;let l=null;return"function"==typeof e?l=e(n):null!==e&&(l=e),null===l?null:/*#__PURE__*/s("div",{"aria-hidden":!0,children:l})}export{E as ContentEditable,p as ContentEditableElement};
9
+ import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useLayoutEffect as t,useEffect as i,forwardRef as a,useState as r,useCallback as n,useMemo as o}from"react";import{CAN_USE_DOM as l,mergeRegister as d}from"lexical";import{jsx as s,jsxs as c,Fragment as u}from"react/jsx-runtime";import{$canShowPlaceholderCurry as m}from"@lexical/text";const f=l?t:i;function b({editor:e,ariaActiveDescendant:t,ariaAutoComplete:i,ariaControls:a,ariaDescribedBy:l,ariaErrorMessage:d,ariaExpanded:c,ariaInvalid:u,ariaLabel:m,ariaLabelledBy:b,ariaMultiline:p,ariaOwns:x,ariaRequired:v,autoCapitalize:E,className:y,id:C,role:g="textbox",spellCheck:L=!0,style:h,tabIndex:w,"data-testid":D,...I},R){const[k,q]=r(e.isEditable()),z=n(t=>{t&&t.ownerDocument&&t.ownerDocument.defaultView?e.setRootElement(t):e.setRootElement(null)},[e]),A=o(()=>function(...e){return t=>{for(const i of e)"function"==typeof i?i(t):null!=i&&(i.current=t)}}(R,z),[z,R]);return f(()=>(q(e.isEditable()),e.registerEditableListener(e=>{q(e)})),[e]),/*#__PURE__*/s("div",{"aria-activedescendant":k?t:void 0,"aria-autocomplete":k?i:"none","aria-controls":k?a:void 0,"aria-describedby":l,...null!=d?{"aria-errormessage":d}:{},"aria-expanded":k&&"combobox"===g?!!c:void 0,...null!=u?{"aria-invalid":u}:{},"aria-label":m,"aria-labelledby":b,"aria-multiline":p,"aria-owns":k?x:void 0,"aria-readonly":!k||void 0,"aria-required":v,autoCapitalize:E,className:y,contentEditable:k,"data-testid":D,id:C,ref:A,role:g,spellCheck:L,style:h,tabIndex:w??(k?void 0:-1),...I})}const p=/*#__PURE__*/a(b);function x(e){return e.read("latest",m(e.isComposing()))}const v=/*#__PURE__*/a(E);function E(t,i){const{placeholder:a,...r}=t,[n]=e();
10
+ return c(u,{children:[/*#__PURE__*/s(p,{editor:n,...r,ref:i}),null!=a&&/*#__PURE__*/s(y,{editor:n,content:a})]})}function y({content:e,editor:i}){const a=function(e){const[t,i]=r(()=>x(e));return f(()=>{function t(){const t=x(e);i(t)}return t(),d(e.registerUpdateListener(()=>{t()}),e.registerEditableListener(()=>{t()}))},[e]),t}(i),[n,o]=r(i.isEditable());if(t(()=>(o(i.isEditable()),i.registerEditableListener(e=>{o(e)})),[i]),!a)return null;let l=null;return"function"==typeof e?l=e(n):null!==e&&(l=e),null===l?null:/*#__PURE__*/s("div",{"aria-hidden":!0,children:l})}export{v as ContentEditable,p as ContentEditableElement};
package/package.json CHANGED
@@ -8,28 +8,28 @@
8
8
  "rich-text"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.47.1-nightly.20260715.0",
11
+ "version": "0.48.0",
12
12
  "dependencies": {
13
13
  "@floating-ui/react": "^0.27.19",
14
- "@lexical/devtools-core": "0.47.1-nightly.20260715.0",
15
- "@lexical/dragon": "0.47.1-nightly.20260715.0",
16
- "@lexical/hashtag": "0.47.1-nightly.20260715.0",
17
- "@lexical/history": "0.47.1-nightly.20260715.0",
18
- "@lexical/a11y": "0.47.1-nightly.20260715.0",
19
- "@lexical/list": "0.47.1-nightly.20260715.0",
20
- "@lexical/extension": "0.47.1-nightly.20260715.0",
21
- "@lexical/markdown": "0.47.1-nightly.20260715.0",
22
- "@lexical/plain-text": "0.47.1-nightly.20260715.0",
23
- "@lexical/overflow": "0.47.1-nightly.20260715.0",
24
- "@lexical/mark": "0.47.1-nightly.20260715.0",
25
- "@lexical/link": "0.47.1-nightly.20260715.0",
26
- "@lexical/rich-text": "0.47.1-nightly.20260715.0",
27
- "@lexical/internal": "0.47.1-nightly.20260715.0",
28
- "@lexical/table": "0.47.1-nightly.20260715.0",
29
- "@lexical/text": "0.47.1-nightly.20260715.0",
30
- "@lexical/yjs": "0.47.1-nightly.20260715.0",
31
- "@lexical/utils": "0.47.1-nightly.20260715.0",
32
- "lexical": "0.47.1-nightly.20260715.0"
14
+ "@lexical/a11y": "0.48.0",
15
+ "@lexical/devtools-core": "0.48.0",
16
+ "@lexical/dragon": "0.48.0",
17
+ "@lexical/hashtag": "0.48.0",
18
+ "@lexical/extension": "0.48.0",
19
+ "@lexical/history": "0.48.0",
20
+ "@lexical/link": "0.48.0",
21
+ "@lexical/mark": "0.48.0",
22
+ "@lexical/internal": "0.48.0",
23
+ "@lexical/list": "0.48.0",
24
+ "@lexical/markdown": "0.48.0",
25
+ "@lexical/plain-text": "0.48.0",
26
+ "@lexical/rich-text": "0.48.0",
27
+ "@lexical/table": "0.48.0",
28
+ "@lexical/overflow": "0.48.0",
29
+ "@lexical/text": "0.48.0",
30
+ "@lexical/yjs": "0.48.0",
31
+ "lexical": "0.48.0",
32
+ "@lexical/utils": "0.48.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": ">=18.x",
@@ -17,7 +17,7 @@ import {
17
17
  import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
18
18
  import {
19
19
  type Binding,
20
- createBinding,
20
+ createYjsBinding,
21
21
  type ExcludedProperties,
22
22
  type Provider,
23
23
  type SyncCursorPositionsFn,
@@ -52,6 +52,8 @@ type CollaborationPluginProps = {
52
52
  * Fallback to legacy method if not enabled or not supported.
53
53
  */
54
54
  selectionHighlight?: boolean;
55
+ /** Customize the Yjs shared-type key used for the root `XmlText`. Defaults to `'root'`. */
56
+ rootName?: string;
55
57
  };
56
58
 
57
59
  /**
@@ -75,6 +77,7 @@ export function CollaborationPlugin({
75
77
  awarenessData,
76
78
  syncCursorPositionsFn,
77
79
  selectionHighlight,
80
+ rootName,
78
81
  }: CollaborationPluginProps): JSX.Element {
79
82
  const isBindingInitialized = useRef(false);
80
83
  const isProviderInitialized = useRef(false);
@@ -116,22 +119,27 @@ export function CollaborationPlugin({
116
119
  return;
117
120
  }
118
121
 
119
- isBindingInitialized.current = true;
122
+ const resolvedDoc = doc || yjsDocMap.get(id);
123
+ if (!resolvedDoc) {
124
+ return;
125
+ }
120
126
 
121
- const newBinding = createBinding(
127
+ isBindingInitialized.current = true;
128
+ const newBinding = createYjsBinding({
129
+ doc: resolvedDoc,
130
+ docMap: yjsDocMap,
122
131
  editor,
123
- provider,
124
- id,
125
- doc || yjsDocMap.get(id),
126
- yjsDocMap,
127
132
  excludedProperties,
128
- );
133
+ id,
134
+ rootName,
135
+ });
136
+ // eslint-disable-next-line react-hooks/set-state-in-effect
129
137
  setBinding(newBinding);
130
138
 
131
139
  return () => {
132
140
  newBinding.root.destroy(newBinding);
133
141
  };
134
- }, [editor, provider, id, yjsDocMap, doc, excludedProperties]);
142
+ }, [editor, provider, id, yjsDocMap, doc, excludedProperties, rootName]);
135
143
 
136
144
  if (!provider || !binding) {
137
145
  return <></>;
@@ -232,6 +240,8 @@ type CollaborationPluginV2Props = {
232
240
  * Fallback to legacy method if not enabled or not supported.
233
241
  */
234
242
  selectionHighlight?: boolean;
243
+ /** Customize the Yjs shared-type key used for the root `XmlElement`. Defaults to `'root-v2'`. */
244
+ rootName?: string;
235
245
  };
236
246
 
237
247
  /**
@@ -254,6 +264,7 @@ export function CollaborationPluginV2__EXPERIMENTAL({
254
264
  excludedProperties,
255
265
  awarenessData,
256
266
  selectionHighlight,
267
+ rootName,
257
268
  }: CollaborationPluginV2Props): JSX.Element {
258
269
  const collabContext = useCollaborationContext(username, cursorColor);
259
270
  const {yjsDocMap, name, color} = collabContext;
@@ -273,6 +284,7 @@ export function CollaborationPluginV2__EXPERIMENTAL({
273
284
  __shouldBootstrapUnsafe,
274
285
  awarenessData,
275
286
  excludedProperties,
287
+ rootName,
276
288
  selectionHighlight,
277
289
  },
278
290
  );
@@ -132,7 +132,7 @@ function ContentEditableElementImpl(
132
132
  role={role}
133
133
  spellCheck={spellCheck}
134
134
  style={style}
135
- tabIndex={tabIndex}
135
+ tabIndex={tabIndex ?? (isEditable ? undefined : -1)}
136
136
  {...rest}
137
137
  />
138
138
  );
@@ -180,6 +180,14 @@ export function $wrapOverflowedNodes(offset: number): void {
180
180
  for (let i = 0; i < dfsNodesLength; i += 1) {
181
181
  const {node} = dfsNodes[i];
182
182
 
183
+ // ElementNode.getTextContent() inserts '\n\n' after each non-inline
184
+ // element child that is not the last child. findOffset counts those
185
+ // separators (via $rootTextContent), so the DFS must count them too.
186
+ const prevSibling = node.getPreviousSibling();
187
+ if ($isElementNode(prevSibling) && !prevSibling.isInline()) {
188
+ accumulatedLength += 2;
189
+ }
190
+
183
191
  // Slot value roots (a non-inline DecoratorNode slotted into a host) are
184
192
  // leaf nodes with __parent === null; wrapping them in OverflowNode would
185
193
  // call node.replace() and throw, so they stay out of the wrap loop. Their
@@ -266,6 +274,10 @@ export function $wrapOverflowedNodes(offset: number): void {
266
274
  }
267
275
 
268
276
  $mergePrevious(overflowNode);
277
+ const nextNode = overflowNode.getNextSibling();
278
+ if ($isOverflowNode(nextNode)) {
279
+ $mergePrevious(nextNode);
280
+ }
269
281
  }
270
282
  }
271
283
  }
@@ -303,7 +315,7 @@ export function $mergePrevious(overflowNode: OverflowNode): void {
303
315
  const anchor = selection.anchor;
304
316
  const anchorNode = anchor.getNode();
305
317
  const focus = selection.focus;
306
- const focusNode = anchor.getNode();
318
+ const focusNode = focus.getNode();
307
319
 
308
320
  if (anchorNode.is(previousNode)) {
309
321
  anchor.set(overflowNode.getKey(), anchor.offset, 'element');