@lexical/react 0.10.0 → 0.11.1
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.
- package/LexicalAutoEmbedPlugin.d.ts +2 -2
- package/LexicalAutoEmbedPlugin.dev.js +4 -4
- package/LexicalAutoEmbedPlugin.js.flow +2 -2
- package/LexicalAutoEmbedPlugin.prod.js +2 -2
- package/LexicalCharacterLimitPlugin.dev.js +4 -3
- package/LexicalCharacterLimitPlugin.prod.js +6 -6
- package/LexicalClickableLinkPlugin.dev.js +12 -9
- package/LexicalClickableLinkPlugin.prod.js +3 -4
- package/LexicalCollaborationPlugin.d.ts +2 -1
- package/LexicalCollaborationPlugin.dev.js +11 -10
- package/LexicalCollaborationPlugin.js.flow +13 -3
- package/LexicalCollaborationPlugin.prod.js +9 -9
- package/LexicalContentEditable.d.ts +1 -1
- package/LexicalContentEditable.dev.js +21 -10
- package/LexicalContentEditable.prod.js +3 -3
- package/LexicalContextMenuPlugin.d.ts +29 -0
- package/LexicalContextMenuPlugin.dev.js +508 -0
- package/LexicalContextMenuPlugin.js +9 -0
- package/LexicalContextMenuPlugin.prod.js +21 -0
- package/LexicalDecoratorBlockNode.d.ts +1 -0
- package/LexicalDecoratorBlockNode.dev.js +4 -0
- package/LexicalDecoratorBlockNode.prod.js +1 -1
- package/LexicalNodeEventPlugin.d.ts +1 -1
- package/LexicalNodeEventPlugin.dev.js +26 -33
- package/LexicalNodeEventPlugin.prod.js +2 -2
- package/LexicalNodeMenuPlugin.d.ts +22 -0
- package/LexicalNodeMenuPlugin.dev.js +521 -0
- package/LexicalNodeMenuPlugin.js +9 -0
- package/LexicalNodeMenuPlugin.js.flow +64 -0
- package/LexicalNodeMenuPlugin.prod.js +21 -0
- package/LexicalPlainTextPlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.prod.js +4 -4
- package/LexicalRichTextPlugin.dev.js +1 -1
- package/LexicalRichTextPlugin.prod.js +4 -4
- package/LexicalTabIndentationPlugin.d.ts +2 -0
- package/LexicalTabIndentationPlugin.dev.js +69 -10
- package/LexicalTabIndentationPlugin.js.flow +6 -0
- package/LexicalTabIndentationPlugin.prod.js +3 -1
- package/LexicalTypeaheadMenuPlugin.d.ts +10 -40
- package/LexicalTypeaheadMenuPlugin.dev.js +237 -210
- package/LexicalTypeaheadMenuPlugin.js.flow +7 -26
- package/LexicalTypeaheadMenuPlugin.prod.js +20 -20
- package/package.json +19 -19
- package/shared/LexicalMenu.d.ts +49 -0
- package/shared/useYjsCollaboration.d.ts +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
import type { LexicalNode } from 'lexical';
|
|
10
|
-
import {
|
|
10
|
+
import { MenuOption, MenuRenderFn } from '@lexical/react/LexicalNodeMenuPlugin';
|
|
11
11
|
import { LexicalCommand, LexicalEditor } from 'lexical';
|
|
12
12
|
export declare type EmbedMatchResult<TEmbedMatchResult = unknown> = {
|
|
13
13
|
url: string;
|
|
@@ -21,7 +21,7 @@ export interface EmbedConfig<TEmbedMatchResultData = unknown, TEmbedMatchResult
|
|
|
21
21
|
}
|
|
22
22
|
export declare const URL_MATCHER: RegExp;
|
|
23
23
|
export declare const INSERT_EMBED_COMMAND: LexicalCommand<EmbedConfig['type']>;
|
|
24
|
-
export declare class AutoEmbedOption extends
|
|
24
|
+
export declare class AutoEmbedOption extends MenuOption {
|
|
25
25
|
title: string;
|
|
26
26
|
onSelect: (targetNode: LexicalNode | null) => void;
|
|
27
27
|
constructor(title: string, options: {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
var link = require('@lexical/link');
|
|
10
10
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
11
|
-
var
|
|
11
|
+
var LexicalNodeMenuPlugin = require('@lexical/react/LexicalNodeMenuPlugin');
|
|
12
12
|
var utils = require('@lexical/utils');
|
|
13
13
|
var lexical = require('lexical');
|
|
14
14
|
var React = require('react');
|
|
@@ -22,7 +22,7 @@ var React = require('react');
|
|
|
22
22
|
*/
|
|
23
23
|
const URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
|
24
24
|
const INSERT_EMBED_COMMAND = lexical.createCommand('INSERT_EMBED_COMMAND');
|
|
25
|
-
class AutoEmbedOption extends
|
|
25
|
+
class AutoEmbedOption extends LexicalNodeMenuPlugin.MenuOption {
|
|
26
26
|
constructor(title, options) {
|
|
27
27
|
super(title);
|
|
28
28
|
this.title = title;
|
|
@@ -66,7 +66,7 @@ function LexicalAutoEmbedPlugin({
|
|
|
66
66
|
dirtyLeaves
|
|
67
67
|
}) => {
|
|
68
68
|
for (const [key, mutation] of nodeMutations) {
|
|
69
|
-
if (mutation === 'created' && updateTags.has('paste') && dirtyLeaves.size
|
|
69
|
+
if (mutation === 'created' && updateTags.has('paste') && dirtyLeaves.size <= 3) {
|
|
70
70
|
checkIfLinkNodeIsEmbeddable(key);
|
|
71
71
|
} else if (key === nodeKey) {
|
|
72
72
|
reset();
|
|
@@ -130,7 +130,7 @@ function LexicalAutoEmbedPlugin({
|
|
|
130
130
|
closeMenu();
|
|
131
131
|
});
|
|
132
132
|
}, [editor]);
|
|
133
|
-
return nodeKey != null ? /*#__PURE__*/React.createElement(
|
|
133
|
+
return nodeKey != null ? /*#__PURE__*/React.createElement(LexicalNodeMenuPlugin.LexicalNodeMenuPlugin, {
|
|
134
134
|
nodeKey: nodeKey,
|
|
135
135
|
onClose: reset,
|
|
136
136
|
onSelectOption: onSelectOption,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import type {LexicalNode, MutationListener} from 'lexical';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import {MenuOption} from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
|
13
13
|
import type {LexicalCommand, LexicalEditor, NodeKey, TextNode} from 'lexical';
|
|
14
14
|
import * as React from 'react';
|
|
15
15
|
import {createCommand} from 'lexical';
|
|
@@ -46,7 +46,7 @@ type LexicalAutoEmbedPluginProps<TEmbedConfig> = {
|
|
|
46
46
|
menuRenderFn: MenuRenderFn<AutoEmbedOption>,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
declare export class AutoEmbedOption extends
|
|
49
|
+
declare export class AutoEmbedOption extends MenuOption {
|
|
50
50
|
title: string;
|
|
51
51
|
icon: React.MixedElement;
|
|
52
52
|
onSelect: (targetNode: LexicalNode | null) => void;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
'use strict';var e=require("@lexical/link"),k=require("@lexical/react/LexicalComposerContext"),l=require("@lexical/react/
|
|
7
|
+
'use strict';var e=require("@lexical/link"),k=require("@lexical/react/LexicalComposerContext"),l=require("@lexical/react/LexicalNodeMenuPlugin"),q=require("@lexical/utils"),r=require("lexical"),z=require("react");let A=r.createCommand("INSERT_EMBED_COMMAND");class B extends l.MenuOption{constructor(f,n){super(f);this.title=f;this.onSelect=n.onSelect.bind(this)}}exports.AutoEmbedOption=B;exports.INSERT_EMBED_COMMAND=A;
|
|
8
8
|
exports.LexicalAutoEmbedPlugin=function({embedConfigs:f,onOpenEmbedModalForConfig:n,getMenuOptions:t,menuRenderFn:C}){let [c]=k.useLexicalComposerContext(),[g,u]=z.useState(null),[h,v]=z.useState(null),m=z.useCallback(()=>{u(null);v(null)},[]),w=z.useCallback(b=>{c.getEditorState().read(async()=>{const a=r.$getNodeByKey(b);if(e.$isLinkNode(a))for(let d=0;d<f.length;d++){const p=f[d];null!=await Promise.resolve(p.parseUrl(a.__url))&&(v(p),u(a.getKey()))}})},[c,f]);z.useEffect(()=>{let b=(a,{updateTags:d,
|
|
9
|
-
dirtyLeaves:p})=>{for(const [x,D]of a)"created"===D&&d.has("paste")&&
|
|
9
|
+
dirtyLeaves:p})=>{for(const [x,D]of a)"created"===D&&d.has("paste")&&3>=p.size?w(x):x===g&&m()};return q.mergeRegister(...[e.LinkNode,e.AutoLinkNode].map(a=>c.registerMutationListener(a,(...d)=>b(...d))))},[w,c,f,g,m]);z.useEffect(()=>c.registerCommand(A,b=>{let a=f.find(({type:d})=>d===b);return a?(n(a),!0):!1},r.COMMAND_PRIORITY_EDITOR),[c,f,n]);let y=z.useCallback(async()=>{if(null!=h&&null!=g){const b=c.getEditorState().read(()=>{const a=r.$getNodeByKey(g);return e.$isLinkNode(a)?a:null});if(e.$isLinkNode(b)){const a=
|
|
10
10
|
await Promise.resolve(h.parseUrl(b.__url));null!=a&&c.update(()=>{r.$getSelection()||b.selectEnd();h.insertNode(c,a);b.isAttached()&&b.remove()})}}},[h,c,g]),E=z.useMemo(()=>null!=h&&null!=g?t(h,y,m):[],[h,y,t,g,m]),F=z.useCallback((b,a,d)=>{c.update(()=>{b.onSelect(a);d()})},[c]);return null!=g?z.createElement(l.LexicalNodeMenuPlugin,{nodeKey:g,onClose:m,onSelectOption:F,options:E,menuRenderFn:C}):null};exports.URL_MATCHER=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/
|
|
@@ -41,12 +41,13 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
|
|
|
41
41
|
return utils.mergeRegister(editor.registerTextContentListener(currentText => {
|
|
42
42
|
text$1 = currentText;
|
|
43
43
|
}), editor.registerUpdateListener(({
|
|
44
|
-
dirtyLeaves
|
|
44
|
+
dirtyLeaves,
|
|
45
|
+
dirtyElements
|
|
45
46
|
}) => {
|
|
46
47
|
const isComposing = editor.isComposing();
|
|
47
|
-
const
|
|
48
|
+
const hasContentChanges = dirtyLeaves.size > 0 || dirtyElements.size > 0;
|
|
48
49
|
|
|
49
|
-
if (isComposing || !
|
|
50
|
+
if (isComposing || !hasContentChanges) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
'use strict';var n=require("@lexical/react/LexicalComposerContext"),u=require("react"),v=require("@lexical/overflow"),z=require("@lexical/text"),A=require("@lexical/utils"),C=require("lexical");
|
|
8
|
-
function D(b,c,p=Object.freeze({})){let {strlen:e=l=>l.length,remainingCharacters:q=()=>{}}=p;u.useEffect(()=>{if(!b.hasNodes([v.OverflowNode]))throw Error("Minified Lexical error #57; visit https://lexical.dev/docs/error?code=57 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");},[b]);u.useEffect(()=>{let l=b.getEditorState().read(z.$rootTextContent),d=0;return A.mergeRegister(b.registerTextContentListener(f=>{l=f}),b.registerUpdateListener(({dirtyLeaves:f
|
|
9
|
-
{var w=b.isComposing();f=0<f.size;if(!w&&f){w=e(l);f=w>c||null!==d&&d>c;q(c-w);if(null===d||f){let r=F(l,c,e);b.update(()=>{let B=A.$dfs(),
|
|
10
|
-
null!==h&&h.select())}else g<r&&(h=a.getFirstDescendant(),k=null!==h?h.getTextContentSize():0,g+=k,h=C.$isTextNode(h)&&h.isSimpleText(),g=g<=r,(h||g)&&G(a))}else if(C.$isLeafNode(a)&&(g=x,x+=a.getTextContentSize(),x>r&&!v.$isOverflowNode(a.getParent())&&(h=C.$getSelection(),g<r&&C.$isTextNode(a)&&a.isSimpleText()?([,a]=a.splitText(r-g),a=H(a)):a=H(a),null!==h&&C.$setSelection(h),g=a.getPreviousSibling(),v.$isOverflowNode(g)))){k=a.getFirstChild();var t=g.getChildren();
|
|
11
|
-
else for(var m=0;m<h;m++)k.insertBefore(t[m]);m=C.$getSelection();if(C.$isRangeSelection(m)){k=m.anchor;t=k.getNode();m=m.focus;let E=k.getNode();t.is(g)?k.set(a.getKey(),k.offset,"element"):t.is(a)&&k.set(a.getKey(),h+k.offset,"element");E.is(g)?m.set(a.getKey(),m.offset,"element"):E.is(a)&&m.set(a.getKey(),h+m.offset,"element")}g.remove()}}},{tag:"history-merge"})}d=w}}))},[b,c,q,e])}
|
|
12
|
-
function F(b,c,p){var e=Intl.Segmenter;let q=0;var l=0;if("function"===typeof e){b=(new e).segment(b);for(var {segment:d}of b){l+=p(d);if(l>c)break;q+=d.length}}else for(d=Array.from(b),b=d.length,e=0;e<b;e++){let f=d[e];l+=p(f);if(l>c)break;q+=f.length}return q}function H(b){let c=v.$createOverflowNode();b.insertBefore(c);c.append(b);return c}function G(b){let c=b.getChildren(),p=c.length;for(let e=0;e<p;e++)b.insertBefore(c[e]);b.remove();return 0<p?c[p-1]:null}let
|
|
13
|
-
exports.CharacterLimitPlugin=function({charset:b="UTF-16",maxLength:c=5}){let [p]=n.useLexicalComposerContext(),[e,q]=u.useState(c),l=u.useMemo(()=>({remainingCharacters:q,strlen:d=>{if("UTF-8"===b){if(void 0===window.TextEncoder)var f=null;else null===
|
|
8
|
+
function D(b,c,p=Object.freeze({})){let {strlen:e=l=>l.length,remainingCharacters:q=()=>{}}=p;u.useEffect(()=>{if(!b.hasNodes([v.OverflowNode]))throw Error("Minified Lexical error #57; visit https://lexical.dev/docs/error?code=57 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");},[b]);u.useEffect(()=>{let l=b.getEditorState().read(z.$rootTextContent),d=0;return A.mergeRegister(b.registerTextContentListener(f=>{l=f}),b.registerUpdateListener(({dirtyLeaves:f,
|
|
9
|
+
dirtyElements:I})=>{var w=b.isComposing();f=0<f.size||0<I.size;if(!w&&f){w=e(l);f=w>c||null!==d&&d>c;q(c-w);if(null===d||f){let r=F(l,c,e);b.update(()=>{let B=A.$dfs(),K=B.length,x=0;for(let y=0;y<K;y+=1){var {node:a}=B[y];if(v.$isOverflowNode(a)){var g=x;if(x+a.getTextContentSize()<=r){var h=a.getParent();g=a.getPreviousSibling();var k=a.getNextSibling();G(a);a=C.$getSelection();!C.$isRangeSelection(a)||a.anchor.getNode().isAttached()&&a.focus.getNode().isAttached()||(C.$isTextNode(g)?g.select():
|
|
10
|
+
C.$isTextNode(k)?k.select():null!==h&&h.select())}else g<r&&(h=a.getFirstDescendant(),k=null!==h?h.getTextContentSize():0,g+=k,h=C.$isTextNode(h)&&h.isSimpleText(),g=g<=r,(h||g)&&G(a))}else if(C.$isLeafNode(a)&&(g=x,x+=a.getTextContentSize(),x>r&&!v.$isOverflowNode(a.getParent())&&(h=C.$getSelection(),g<r&&C.$isTextNode(a)&&a.isSimpleText()?([,a]=a.splitText(r-g),a=H(a)):a=H(a),null!==h&&C.$setSelection(h),g=a.getPreviousSibling(),v.$isOverflowNode(g)))){k=a.getFirstChild();var t=g.getChildren();
|
|
11
|
+
h=t.length;if(null===k)a.append(...t);else for(var m=0;m<h;m++)k.insertBefore(t[m]);m=C.$getSelection();if(C.$isRangeSelection(m)){k=m.anchor;t=k.getNode();m=m.focus;let E=k.getNode();t.is(g)?k.set(a.getKey(),k.offset,"element"):t.is(a)&&k.set(a.getKey(),h+k.offset,"element");E.is(g)?m.set(a.getKey(),m.offset,"element"):E.is(a)&&m.set(a.getKey(),h+m.offset,"element")}g.remove()}}},{tag:"history-merge"})}d=w}}))},[b,c,q,e])}
|
|
12
|
+
function F(b,c,p){var e=Intl.Segmenter;let q=0;var l=0;if("function"===typeof e){b=(new e).segment(b);for(var {segment:d}of b){l+=p(d);if(l>c)break;q+=d.length}}else for(d=Array.from(b),b=d.length,e=0;e<b;e++){let f=d[e];l+=p(f);if(l>c)break;q+=f.length}return q}function H(b){let c=v.$createOverflowNode();b.insertBefore(c);c.append(b);return c}function G(b){let c=b.getChildren(),p=c.length;for(let e=0;e<p;e++)b.insertBefore(c[e]);b.remove();return 0<p?c[p-1]:null}let J=null;
|
|
13
|
+
exports.CharacterLimitPlugin=function({charset:b="UTF-16",maxLength:c=5}){let [p]=n.useLexicalComposerContext(),[e,q]=u.useState(c),l=u.useMemo(()=>({remainingCharacters:q,strlen:d=>{if("UTF-8"===b){if(void 0===window.TextEncoder)var f=null;else null===J&&(J=new window.TextEncoder),f=J;null===f?(f=encodeURIComponent(d).match(/%[89ABab]/g),d=d.length+(f?f.length:0)):d=f.encode(d).length;return d}if("UTF-16"===b)return d.length;throw Error("Unrecognized charset");}}),[b]);D(p,c,l);return u.createElement("span",
|
|
14
14
|
{className:`characters-limit ${0>e?"characters-limit-exceeded":""}`},e)}
|
|
@@ -20,15 +20,15 @@ var react = require('react');
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
function
|
|
24
|
-
let
|
|
23
|
+
function findMatchingDOM(startNode, predicate) {
|
|
24
|
+
let node = startNode;
|
|
25
25
|
|
|
26
|
-
while (
|
|
27
|
-
if (predicate(
|
|
28
|
-
return
|
|
26
|
+
while (node != null) {
|
|
27
|
+
if (predicate(node)) {
|
|
28
|
+
return node;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
node = node.parentNode;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
return null;
|
|
@@ -64,9 +64,12 @@ function LexicalClickableLinkPlugin({
|
|
|
64
64
|
url = maybeLinkNode.getURL();
|
|
65
65
|
urlTarget = maybeLinkNode.getTarget();
|
|
66
66
|
} else {
|
|
67
|
-
const a =
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const a = findMatchingDOM(target, utils.isHTMLAnchorElement);
|
|
68
|
+
|
|
69
|
+
if (a !== null) {
|
|
70
|
+
url = a.href;
|
|
71
|
+
urlTarget = a.target;
|
|
72
|
+
}
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
});
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
'use strict';var e=require("@lexical/link"),
|
|
8
|
-
module.exports=function({newTab:n=!0}){let [h]=
|
|
9
|
-
|
|
10
|
-
[h,n]);return null}
|
|
7
|
+
'use strict';var e=require("@lexical/link"),m=require("@lexical/react/LexicalComposerContext"),q=require("@lexical/utils"),r=require("lexical"),t=require("react");
|
|
8
|
+
module.exports=function({newTab:n=!0}){let [h]=m.useLexicalComposerContext();t.useEffect(()=>{let l=a=>{const c=a.target;if(c instanceof Node){var d=r.getNearestEditorFromDOMNode(c);if(null!==d){var f=null,k=null;d.update(()=>{var b=r.$getNearestNodeFromDOMNode(c);if(null!==b)if(b=q.$findMatchingParent(b,r.$isElementNode),e.$isLinkNode(b))f=b.getURL(),k=b.getTarget();else{a:{b=q.isHTMLAnchorElement;let g=c;for(;null!=g;){if(b(g)){b=g;break a}g=g.parentNode}b=null}null!==b&&(f=b.href,k=b.target)}});
|
|
9
|
+
if(null!==f&&""!==f){d=h.getEditorState().read(r.$getSelection);if(!r.$isRangeSelection(d)||d.isCollapsed())d="auxclick"===a.type&&1===a.button,window.open(f,n||d||a.metaKey||a.ctrlKey||"_blank"===k?"_blank":"_self");a.preventDefault()}}}},p=a=>{1===a.button&&h.isEditable()&&l(a)};return h.registerRootListener((a,c)=>{null!==c&&(c.removeEventListener("click",l),c.removeEventListener("mouseup",p));null!==a&&(a.addEventListener("click",l),a.addEventListener("mouseup",p))})},[h,n]);return null}
|
|
@@ -19,6 +19,7 @@ declare type Props = {
|
|
|
19
19
|
cursorsContainerRef?: CursorsContainerRef;
|
|
20
20
|
initialEditorState?: InitialEditorStateType;
|
|
21
21
|
excludedProperties?: ExcludedProperties;
|
|
22
|
+
awarenessData?: object;
|
|
22
23
|
};
|
|
23
|
-
export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, }: Props): JSX.Element;
|
|
24
|
+
export declare function CollaborationPlugin({ id, providerFactory, shouldBootstrap, username, cursorColor, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData, }: Props): JSX.Element;
|
|
24
25
|
export {};
|
|
@@ -22,7 +22,7 @@ var yjs$1 = require('yjs');
|
|
|
22
22
|
* LICENSE file in the root directory of this source tree.
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
|
-
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, cursorsContainerRef, initialEditorState, excludedProperties) {
|
|
25
|
+
function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBootstrap, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData) {
|
|
26
26
|
const isReloadingDoc = React.useRef(false);
|
|
27
27
|
const [doc, setDoc] = React.useState(docMap.get(id));
|
|
28
28
|
const binding = React.useMemo(() => yjs.createBinding(editor, provider, id, doc, docMap, excludedProperties), [editor, provider, id, docMap, doc, excludedProperties]);
|
|
@@ -70,7 +70,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
yjs.initLocalState(provider, name, color, document.activeElement === editor.getRootElement());
|
|
73
|
+
yjs.initLocalState(provider, name, color, document.activeElement === editor.getRootElement(), awarenessData || {});
|
|
74
74
|
|
|
75
75
|
const onProviderDocReload = ydoc => {
|
|
76
76
|
clearEditorSkipCollab(editor, binding);
|
|
@@ -111,7 +111,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
111
111
|
docMap.delete(id);
|
|
112
112
|
removeListener();
|
|
113
113
|
};
|
|
114
|
-
}, [binding, color, connect, disconnect, docMap, editor, id, initialEditorState, name, provider, shouldBootstrap]);
|
|
114
|
+
}, [binding, color, connect, disconnect, docMap, editor, id, initialEditorState, name, provider, shouldBootstrap, awarenessData]);
|
|
115
115
|
const cursorsContainer = React.useMemo(() => {
|
|
116
116
|
const ref = element => {
|
|
117
117
|
binding.cursorsContainer = element;
|
|
@@ -142,16 +142,16 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
142
142
|
}, [connect, disconnect, editor]);
|
|
143
143
|
return [cursorsContainer, binding];
|
|
144
144
|
}
|
|
145
|
-
function useYjsFocusTracking(editor, provider, name, color) {
|
|
145
|
+
function useYjsFocusTracking(editor, provider, name, color, awarenessData) {
|
|
146
146
|
React.useEffect(() => {
|
|
147
147
|
return utils.mergeRegister(editor.registerCommand(lexical.FOCUS_COMMAND, () => {
|
|
148
|
-
yjs.setLocalStateFocus(provider, name, color, true);
|
|
148
|
+
yjs.setLocalStateFocus(provider, name, color, true, awarenessData || {});
|
|
149
149
|
return false;
|
|
150
150
|
}, lexical.COMMAND_PRIORITY_EDITOR), editor.registerCommand(lexical.BLUR_COMMAND, () => {
|
|
151
|
-
yjs.setLocalStateFocus(provider, name, color, false);
|
|
151
|
+
yjs.setLocalStateFocus(provider, name, color, false, awarenessData || {});
|
|
152
152
|
return false;
|
|
153
153
|
}, lexical.COMMAND_PRIORITY_EDITOR));
|
|
154
|
-
}, [color, editor, name, provider]);
|
|
154
|
+
}, [color, editor, name, provider, awarenessData]);
|
|
155
155
|
}
|
|
156
156
|
function useYjsHistory(editor, binding) {
|
|
157
157
|
const undoManager = React.useMemo(() => yjs.createUndoManager(binding, binding.root.getSharedType()), [binding]);
|
|
@@ -291,7 +291,8 @@ function CollaborationPlugin({
|
|
|
291
291
|
cursorColor,
|
|
292
292
|
cursorsContainerRef,
|
|
293
293
|
initialEditorState,
|
|
294
|
-
excludedProperties
|
|
294
|
+
excludedProperties,
|
|
295
|
+
awarenessData
|
|
295
296
|
}) {
|
|
296
297
|
const collabContext = LexicalCollaborationContext.useCollaborationContext(username, cursorColor);
|
|
297
298
|
const {
|
|
@@ -311,10 +312,10 @@ function CollaborationPlugin({
|
|
|
311
312
|
};
|
|
312
313
|
}, [collabContext, editor]);
|
|
313
314
|
const provider = React.useMemo(() => providerFactory(id, yjsDocMap), [id, providerFactory, yjsDocMap]);
|
|
314
|
-
const [cursors, binding] = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, cursorsContainerRef, initialEditorState, excludedProperties);
|
|
315
|
+
const [cursors, binding] = useYjsCollaboration(editor, id, provider, yjsDocMap, name, color, shouldBootstrap, cursorsContainerRef, initialEditorState, excludedProperties, awarenessData);
|
|
315
316
|
collabContext.clientID = binding.clientID;
|
|
316
317
|
useYjsHistory(editor, binding);
|
|
317
|
-
useYjsFocusTracking(editor, provider, name, color);
|
|
318
|
+
useYjsFocusTracking(editor, provider, name, color, awarenessData);
|
|
318
319
|
return cursors;
|
|
319
320
|
}
|
|
320
321
|
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type {InitialEditorStateType} from '@lexical/react/LexicalComposer';
|
|
11
|
+
import type {ExcludedProperties, ProviderAwareness} from '@lexical/yjs';
|
|
11
12
|
import type {Doc, RelativePosition} from 'yjs';
|
|
12
13
|
|
|
13
14
|
export interface Provider {
|
|
@@ -31,10 +32,19 @@ export type ProviderFactory = (
|
|
|
31
32
|
yjsDocMap: Map<string, Doc>,
|
|
32
33
|
) => Provider;
|
|
33
34
|
|
|
35
|
+
export type CursorsContainerRef = {current: null | HTMLElement};
|
|
36
|
+
|
|
34
37
|
declare export function CollaborationPlugin(arg0: {
|
|
35
38
|
id: string,
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
providerFactory: (
|
|
40
|
+
// eslint-disable-next-line no-shadow
|
|
41
|
+
id: string,
|
|
42
|
+
yjsDocMap: Map<string, Doc>,
|
|
43
|
+
) => Provider,
|
|
38
44
|
shouldBootstrap: boolean,
|
|
39
45
|
username?: string,
|
|
46
|
+
cursorColor?: string,
|
|
47
|
+
cursorsContainerRef?: CursorsContainerRef,
|
|
48
|
+
initialEditorState?: InitialEditorStateType,
|
|
49
|
+
excludedProperties?: ExcludedProperties,
|
|
40
50
|
}): React$Node;
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
'use strict';var e=require("@lexical/react/LexicalCollaborationContext"),f=require("@lexical/react/LexicalComposerContext"),
|
|
8
|
-
function
|
|
9
|
-
g&&
|
|
10
|
-
|
|
11
|
-
[
|
|
12
|
-
function
|
|
13
|
-
function
|
|
14
|
-
function
|
|
15
|
-
exports.CollaborationPlugin=function({id:b,providerFactory:c,shouldBootstrap:a,username:d,cursorColor:
|
|
7
|
+
'use strict';var e=require("@lexical/react/LexicalCollaborationContext"),f=require("@lexical/react/LexicalComposerContext"),k=require("react"),B=require("@lexical/utils"),J=require("@lexical/yjs"),K=require("lexical"),L=require("react-dom"),M=require("yjs");
|
|
8
|
+
function N(b,c,a,d,h,z,A,v,w,n,t){let q=k.useRef(!1),[x,r]=k.useState(d.get(c)),g=k.useMemo(()=>J.createBinding(b,a,c,x,d,n),[b,a,c,d,x,n]),p=k.useCallback(()=>{a.connect()},[a]),y=k.useCallback(()=>{try{a.disconnect()}catch(m){}},[a]);k.useEffect(()=>{let {root:m}=g,{awareness:C}=a,D=({status:l})=>{b.dispatchCommand(J.CONNECTED_COMMAND,"connected"===l)},E=l=>{A&&l&&m.isEmpty()&&0===m._xmlText._length&&!1===q.current&&O(b,w);q.current=!1},F=()=>{J.syncCursorPositions(g,a)},G=(l,u)=>{u=u.origin;u!==
|
|
9
|
+
g&&J.syncYjsChangesToLexical(g,a,l,u instanceof M.UndoManager)};J.initLocalState(a,h,z,document.activeElement===b.getRootElement(),t||{});let H=l=>{P(b,g);r(l);d.set(c,l);q.current=!0};a.on("reload",H);a.on("status",D);a.on("sync",E);C.on("update",F);m.getSharedType().observeDeep(G);let T=b.registerUpdateListener(({prevEditorState:l,editorState:u,dirtyLeaves:Q,dirtyElements:R,normalizedNodes:S,tags:I})=>{!1===I.has("skip-collab")&&J.syncLexicalUpdateToYjs(g,a,l,u,R,Q,S,I)});p();return()=>{!1===q.current&&
|
|
10
|
+
y();a.off("sync",E);a.off("status",D);a.off("reload",H);C.off("update",F);m.getSharedType().unobserveDeep(G);d.delete(c);T()}},[g,z,p,y,d,b,c,w,h,a,A,t]);let U=k.useMemo(()=>L.createPortal(k.createElement("div",{ref:m=>{g.cursorsContainer=m}}),v&&v.current||document.body),[g,v]);k.useEffect(()=>b.registerCommand(J.TOGGLE_CONNECT_COMMAND,m=>{void 0!==p&&void 0!==y&&(m?(console.log("Collaboration connected!"),p()):(console.log("Collaboration disconnected!"),y()));return!0},K.COMMAND_PRIORITY_EDITOR),
|
|
11
|
+
[p,y,b]);return[U,g]}function V(b,c,a,d,h){k.useEffect(()=>B.mergeRegister(b.registerCommand(K.FOCUS_COMMAND,()=>{J.setLocalStateFocus(c,a,d,!0,h||{});return!1},K.COMMAND_PRIORITY_EDITOR),b.registerCommand(K.BLUR_COMMAND,()=>{J.setLocalStateFocus(c,a,d,!1,h||{});return!1},K.COMMAND_PRIORITY_EDITOR)),[d,b,a,c,h])}
|
|
12
|
+
function W(b,c){let a=k.useMemo(()=>J.createUndoManager(c,c.root.getSharedType()),[c]);k.useEffect(()=>B.mergeRegister(b.registerCommand(K.UNDO_COMMAND,()=>{a.undo();return!0},K.COMMAND_PRIORITY_EDITOR),b.registerCommand(K.REDO_COMMAND,()=>{a.redo();return!0},K.COMMAND_PRIORITY_EDITOR)));return k.useCallback(()=>{a.clear()},[a])}
|
|
13
|
+
function O(b,c){b.update(()=>{var a=K.$getRoot();if(a.isEmpty())if(c)switch(typeof c){case "string":var d=b.parseEditorState(c);b.setEditorState(d,{tag:"history-merge"});break;case "object":b.setEditorState(c,{tag:"history-merge"});break;case "function":b.update(()=>{K.$getRoot().isEmpty()&&c(b)},{tag:"history-merge"})}else d=K.$createParagraphNode(),a.append(d),{activeElement:a}=document,(null!==K.$getSelection()||null!==a&&a===b.getRootElement())&&d.select()},{tag:"history-merge"})}
|
|
14
|
+
function P(b,c){b.update(()=>{let d=K.$getRoot();d.clear();d.select()},{tag:"skip-collab"});if(null!=c.cursors&&(b=c.cursors,null!=b&&(c=c.cursorsContainer,null!=c))){b=Array.from(b.values());for(let d=0;d<b.length;d++){var a=b[d].selection;if(a&&null!=a.selections){a=a.selections;for(let h=0;h<a.length;h++)c.removeChild(a[d])}}}}
|
|
15
|
+
exports.CollaborationPlugin=function({id:b,providerFactory:c,shouldBootstrap:a,username:d,cursorColor:h,cursorsContainerRef:z,initialEditorState:A,excludedProperties:v,awarenessData:w}){let n=e.useCollaborationContext(d,h),{yjsDocMap:t,name:q,color:x}=n,[r]=f.useLexicalComposerContext();k.useEffect(()=>{n.isCollabActive=!0;return()=>{null==r._parentEditor&&(n.isCollabActive=!1)}},[n,r]);d=k.useMemo(()=>c(b,t),[b,c,t]);let [g,p]=N(r,b,d,t,q,x,a,z,A,v,w);n.clientID=p.clientID;W(r,p);V(r,d,q,x,w);return g}
|
|
@@ -20,4 +20,4 @@ export declare type Props = {
|
|
|
20
20
|
autoCapitalize?: HTMLDivElement['autocapitalize'];
|
|
21
21
|
'data-testid'?: string | null | undefined;
|
|
22
22
|
} & React.AllHTMLAttributes<HTMLDivElement>;
|
|
23
|
-
export declare function ContentEditable({ ariaActiveDescendant, ariaAutoComplete, ariaControls, ariaDescribedBy, ariaExpanded, ariaLabel, ariaLabelledBy, ariaMultiline, ariaOwns, ariaRequired, autoCapitalize, className, id, role, spellCheck, style, tabIndex, 'data-testid': testid, }: Props): JSX.Element;
|
|
23
|
+
export declare function ContentEditable({ ariaActiveDescendant, ariaAutoComplete, ariaControls, ariaDescribedBy, ariaExpanded, ariaLabel, ariaLabelledBy, ariaMultiline, ariaOwns, ariaRequired, autoCapitalize, className, id, role, spellCheck, style, tabIndex, 'data-testid': testid, ...rest }: Props): JSX.Element;
|
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
10
|
var React = require('react');
|
|
11
11
|
|
|
12
|
+
function _extends() {
|
|
13
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
14
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
15
|
+
var source = arguments[i];
|
|
16
|
+
|
|
17
|
+
for (var key in source) {
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
19
|
+
target[key] = source[key];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return target;
|
|
25
|
+
};
|
|
26
|
+
return _extends.apply(this, arguments);
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
/**
|
|
13
30
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14
31
|
*
|
|
@@ -28,13 +45,6 @@ const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !==
|
|
|
28
45
|
const useLayoutEffectImpl = CAN_USE_DOM ? React.useLayoutEffect : React.useEffect;
|
|
29
46
|
var useLayoutEffect = useLayoutEffectImpl;
|
|
30
47
|
|
|
31
|
-
/**
|
|
32
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
33
|
-
*
|
|
34
|
-
* This source code is licensed under the MIT license found in the
|
|
35
|
-
* LICENSE file in the root directory of this source tree.
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
48
|
function ContentEditable({
|
|
39
49
|
ariaActiveDescendant,
|
|
40
50
|
ariaAutoComplete,
|
|
@@ -53,7 +63,8 @@ function ContentEditable({
|
|
|
53
63
|
spellCheck = true,
|
|
54
64
|
style,
|
|
55
65
|
tabIndex,
|
|
56
|
-
'data-testid': testid
|
|
66
|
+
'data-testid': testid,
|
|
67
|
+
...rest
|
|
57
68
|
}) {
|
|
58
69
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
59
70
|
const [isEditable, setEditable] = React.useState(false);
|
|
@@ -66,7 +77,7 @@ function ContentEditable({
|
|
|
66
77
|
setEditable(currentIsEditable);
|
|
67
78
|
});
|
|
68
79
|
}, [editor]);
|
|
69
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
80
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
70
81
|
"aria-activedescendant": !isEditable ? undefined : ariaActiveDescendant,
|
|
71
82
|
"aria-autocomplete": !isEditable ? 'none' : ariaAutoComplete,
|
|
72
83
|
"aria-controls": !isEditable ? undefined : ariaControls,
|
|
@@ -87,7 +98,7 @@ function ContentEditable({
|
|
|
87
98
|
spellCheck: spellCheck,
|
|
88
99
|
style: style,
|
|
89
100
|
tabIndex: tabIndex
|
|
90
|
-
});
|
|
101
|
+
}));
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
exports.ContentEditable = ContentEditable;
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
'use strict';var
|
|
8
|
-
exports.ContentEditable=function({ariaActiveDescendant:
|
|
9
|
-
{"aria-activedescendant":a?
|
|
7
|
+
'use strict';var c=require("@lexical/react/LexicalComposerContext"),h=require("react");function n(){n=Object.assign?Object.assign.bind():function(g){for(var d=1;d<arguments.length;d++){var e=arguments[d],b;for(b in e)Object.prototype.hasOwnProperty.call(e,b)&&(g[b]=e[b])}return g};return n.apply(this,arguments)}var p="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?h.useLayoutEffect:h.useEffect;
|
|
8
|
+
exports.ContentEditable=function({ariaActiveDescendant:g,ariaAutoComplete:d,ariaControls:e,ariaDescribedBy:b,ariaExpanded:q,ariaLabel:r,ariaLabelledBy:t,ariaMultiline:u,ariaOwns:v,ariaRequired:w,autoCapitalize:x,className:y,id:z,role:l="textbox",spellCheck:A=!0,style:B,tabIndex:C,"data-testid":D,...E}){let [f]=c.useLexicalComposerContext(),[a,m]=h.useState(!1),F=h.useCallback(k=>{f.setRootElement(k)},[f]);p(()=>{m(f.isEditable());return f.registerEditableListener(k=>{m(k)})},[f]);return h.createElement("div",
|
|
9
|
+
n({},E,{"aria-activedescendant":a?g:void 0,"aria-autocomplete":a?d:"none","aria-controls":a?e:void 0,"aria-describedby":b,"aria-expanded":a?"combobox"===l?!!q:void 0:void 0,"aria-label":r,"aria-labelledby":t,"aria-multiline":u,"aria-owns":a?v:void 0,"aria-required":w,autoCapitalize:x,className:y,contentEditable:a,"data-testid":D,id:z,ref:F,role:a?l:void 0,spellCheck:A,style:B,tabIndex:C}))}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import type { MenuRenderFn, MenuResolution } from './shared/LexicalMenu';
|
|
9
|
+
import { LexicalNode } from 'lexical';
|
|
10
|
+
import { MutableRefObject, ReactPortal } from 'react';
|
|
11
|
+
import { MenuOption } from './shared/LexicalMenu';
|
|
12
|
+
export declare type ContextMenuRenderFn<TOption extends MenuOption> = (anchorElementRef: MutableRefObject<HTMLElement | null>, itemProps: {
|
|
13
|
+
selectedIndex: number | null;
|
|
14
|
+
selectOptionAndCleanUp: (option: TOption) => void;
|
|
15
|
+
setHighlightedIndex: (index: number) => void;
|
|
16
|
+
options: Array<TOption>;
|
|
17
|
+
}, menuProps: {
|
|
18
|
+
setMenuRef: (element: HTMLElement | null) => void;
|
|
19
|
+
}) => ReactPortal | JSX.Element | null;
|
|
20
|
+
export declare type LexicalContextMenuPluginProps<TOption extends MenuOption> = {
|
|
21
|
+
onSelectOption: (option: TOption, textNodeContainingQuery: LexicalNode | null, closeMenu: () => void, matchingString: string) => void;
|
|
22
|
+
options: Array<TOption>;
|
|
23
|
+
onClose?: () => void;
|
|
24
|
+
onOpen?: (resolution: MenuResolution) => void;
|
|
25
|
+
menuRenderFn: ContextMenuRenderFn<TOption>;
|
|
26
|
+
anchorClassName?: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function LexicalContextMenuPlugin<TOption extends MenuOption>({ options, onClose, onOpen, onSelectOption, menuRenderFn: contextMenuRenderFn, anchorClassName, }: LexicalContextMenuPluginProps<TOption>): JSX.Element | null;
|
|
29
|
+
export { MenuOption, MenuRenderFn, MenuResolution };
|