@lexical/react 0.6.1-next.0 → 0.6.3

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.
@@ -5,8 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
+ import type { LinkAttributes } from '@lexical/link';
8
9
  declare type ChangeHandler = (url: string | null, prevUrl: string | null) => void;
9
10
  declare type LinkMatcherResult = {
11
+ attributes?: LinkAttributes;
10
12
  index: number;
11
13
  length: number;
12
14
  text: string;
@@ -99,7 +99,7 @@ function handleLinkCreation(node, matchers, onChange) {
99
99
  [, linkTextNode, remainingTextNode] = remainingTextNode.splitText(invalidMatchEnd + matchStart, invalidMatchEnd + matchStart + matchLength);
100
100
  }
101
101
 
102
- const linkNode = link.$createAutoLinkNode(match.url);
102
+ const linkNode = link.$createAutoLinkNode(match.url, match.attributes);
103
103
  const textNode = lexical.$createTextNode(match.text);
104
104
  textNode.setFormat(linkTextNode.getFormat());
105
105
  textNode.setDetail(linkTextNode.getDetail());
@@ -149,10 +149,26 @@ function handleLinkEdit(linkNode, matchers, onChange) {
149
149
 
150
150
  const url = linkNode.getURL();
151
151
 
152
- if (match !== null && url !== match.url) {
152
+ if (url !== match.url) {
153
153
  linkNode.setURL(match.url);
154
154
  onChange(match.url, url);
155
155
  }
156
+
157
+ if (match.attributes) {
158
+ const rel = linkNode.getRel();
159
+
160
+ if (rel !== match.attributes.rel) {
161
+ linkNode.setRel(match.attributes.rel || null);
162
+ onChange(match.attributes.rel || null, rel);
163
+ }
164
+
165
+ const target = linkNode.getTarget();
166
+
167
+ if (target !== match.attributes.target) {
168
+ linkNode.setTarget(match.attributes.target || null);
169
+ onChange(match.attributes.target || null, target);
170
+ }
171
+ }
156
172
  } // Bad neighbours are edits in neighbor nodes that make AutoLinks incompatible.
157
173
  // Given the creation preconditions, these can only be simple text nodes.
158
174
 
@@ -7,13 +7,16 @@
7
7
  * @flow strict
8
8
  */
9
9
 
10
+ import type {LinkAttributes} from '@lexical/link';
11
+
10
12
  type ChangeHandler = (url: string | null, prevUrl: string | null) => void;
11
13
 
12
14
  type LinkMatcherResult = {
15
+ attributes?: LinkAttributes,
16
+ index: number,
17
+ length: number,
13
18
  text: string,
14
19
  url: string,
15
- length: number,
16
- index: number,
17
20
  };
18
21
 
19
22
  export type LinkMatcher = (text: string) => LinkMatcherResult | null;
@@ -4,9 +4,9 @@
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 h=require("@lexical/link"),l=require("@lexical/react/LexicalComposerContext"),m=require("@lexical/utils"),q=require("lexical"),y=require("react");function z(b,e){for(let c=0;c<e.length;c++){let a=e[c](b);if(a)return a}return null}let A=/[.,;\s]/;function C(b){b=b.getPreviousSibling();q.$isElementNode(b)&&(b=b.getLastDescendant());var e;!(e=null===b||q.$isLineBreakNode(b))&&(e=q.$isTextNode(b))&&(b=b.getTextContent(),e=A.test(b[b.length-1]));return e}
8
- function D(b){b=b.getNextSibling();q.$isElementNode(b)&&(b=b.getFirstDescendant());return null===b||q.$isLineBreakNode(b)||q.$isTextNode(b)&&A.test(b.getTextContent()[0])}function E(b){let e=b.getChildren();var c=e.length;for(--c;0<=c;c--)b.insertAfter(e[c]);b.remove();return e.map(a=>a.getLatest())}
9
- function F(b,e,c){y.useEffect(()=>{if(!b.hasNodes([h.AutoLinkNode]))throw Error("Minified Lexical error #77; visit https://lexical.dev/docs/error?code=77 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");return m.mergeRegister(b.registerNodeTransform(q.TextNode,a=>{var f=a.getParentOrThrow();if(h.$isAutoLinkNode(f))a:{a=f.getChildren();var d=a.length;for(var g=0;g<d;g++){var n=a[g];if(!q.$isTextNode(n)||!n.isSimpleText()){E(f);a=f.getURL();
10
- c&&c(null,a);break a}}d=f.getTextContent();a=z(d,e);null===a||a.text!==d?(E(f),a=f.getURL(),c&&c(null,a)):C(f)&&D(f)?(d=f.getURL(),null!==a&&d!==a.url&&(f.setURL(a.url),c&&c(a.url,d))):(E(f),a=f.getURL(),c&&c(null,a))}else if(!h.$isLinkNode(f)){if(a.isSimpleText()){n=f=a.getTextContent();let k=0,u=a;for(;(d=z(n,e))&&null!==d;){let r=d.index,v=d.length,w=r+v;var t=k+r,p=k+w,x=f,B=a;(0<t?A.test(x[t-1]):C(B))&&(p<x.length?A.test(x[p]):D(B))?(0===k+r?[g,u]=u.splitText(k+v):[,g,u]=u.splitText(k+r,k+r+
11
- v),t=h.$createAutoLinkNode(d.url),p=q.$createTextNode(d.text),p.setFormat(g.getFormat()),p.setDetail(g.getDetail()),t.append(p),g.replace(t),c&&c(d.url,null),k=0):k+=w;n=n.substring(w)}}g=a.getPreviousSibling();d=a.getNextSibling();a=a.getTextContent();h.$isAutoLinkNode(g)&&!A.test(a[0])&&(E(g),g=g.getURL(),c&&c(null,g));h.$isAutoLinkNode(d)&&!A.test(a[a.length-1])&&(E(d),a=d.getURL(),c&&c(null,a))}}))},[b,e,c])}
12
- exports.AutoLinkPlugin=function({matchers:b,onChange:e}){let [c]=l.useLexicalComposerContext();F(c,b,e);return null}
7
+ 'use strict';var h=require("@lexical/link"),l=require("@lexical/react/LexicalComposerContext"),m=require("@lexical/utils"),q=require("lexical"),y=require("react");function z(b,f){for(let c=0;c<f.length;c++){let a=f[c](b);if(a)return a}return null}let A=/[.,;\s]/;function C(b){b=b.getPreviousSibling();q.$isElementNode(b)&&(b=b.getLastDescendant());var f;!(f=null===b||q.$isLineBreakNode(b))&&(f=q.$isTextNode(b))&&(b=b.getTextContent(),f=A.test(b[b.length-1]));return f}
8
+ function D(b){b=b.getNextSibling();q.$isElementNode(b)&&(b=b.getFirstDescendant());return null===b||q.$isLineBreakNode(b)||q.$isTextNode(b)&&A.test(b.getTextContent()[0])}function E(b){let f=b.getChildren();var c=f.length;for(--c;0<=c;c--)b.insertAfter(f[c]);b.remove();return f.map(a=>a.getLatest())}
9
+ function F(b,f,c){y.useEffect(()=>{if(!b.hasNodes([h.AutoLinkNode]))throw Error("Minified Lexical error #77; visit https://lexical.dev/docs/error?code=77 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");return m.mergeRegister(b.registerNodeTransform(q.TextNode,a=>{var e=a.getParentOrThrow();if(h.$isAutoLinkNode(e))a:{a=e.getChildren();var d=a.length;for(var g=0;g<d;g++){var n=a[g];if(!q.$isTextNode(n)||!n.isSimpleText()){E(e);a=e.getURL();
10
+ c&&c(null,a);break a}}d=e.getTextContent();a=z(d,f);null===a||a.text!==d?(E(e),a=e.getURL(),c&&c(null,a)):C(e)&&D(e)?(d=e.getURL(),d!==a.url&&(e.setURL(a.url),c&&c(a.url,d)),a.attributes&&(d=e.getRel(),d!==a.attributes.rel&&(e.setRel(a.attributes.rel||null),c&&c(a.attributes.rel||null,d)),d=e.getTarget(),d!==a.attributes.target&&(e.setTarget(a.attributes.target||null),c&&c(a.attributes.target||null,d)))):(E(e),a=e.getURL(),c&&c(null,a))}else if(!h.$isLinkNode(e)){if(a.isSimpleText()){n=e=a.getTextContent();
11
+ let k=0,u=a;for(;(d=z(n,f))&&null!==d;){let r=d.index,v=d.length,w=r+v;var t=k+r,p=k+w,x=e,B=a;(0<t?A.test(x[t-1]):C(B))&&(p<x.length?A.test(x[p]):D(B))?(0===k+r?[g,u]=u.splitText(k+v):[,g,u]=u.splitText(k+r,k+r+v),t=h.$createAutoLinkNode(d.url,d.attributes),p=q.$createTextNode(d.text),p.setFormat(g.getFormat()),p.setDetail(g.getDetail()),t.append(p),g.replace(t),c&&c(d.url,null),k=0):k+=w;n=n.substring(w)}}g=a.getPreviousSibling();d=a.getNextSibling();a=a.getTextContent();h.$isAutoLinkNode(g)&&!A.test(a[0])&&
12
+ (E(g),g=g.getURL(),c&&c(null,g));h.$isAutoLinkNode(d)&&!A.test(a[a.length-1])&&(E(d),a=d.getURL(),c&&c(null,a))}}))},[b,f,c])}exports.AutoLinkPlugin=function({matchers:b,onChange:f}){let [c]=l.useLexicalComposerContext();F(c,b,f);return null}
@@ -74,9 +74,9 @@ function BlockWithAlignableContents({
74
74
 
75
75
  return false;
76
76
  }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.CLICK_COMMAND, event => {
77
- event.preventDefault();
78
-
79
77
  if (event.target === ref.current) {
78
+ event.preventDefault();
79
+
80
80
  if (!event.shiftKey) {
81
81
  clearSelection();
82
82
  }
@@ -6,5 +6,5 @@
6
6
  */
7
7
  'use strict';var a=require("@lexical/react/LexicalComposerContext"),h=require("@lexical/react/LexicalDecoratorBlockNode"),m=require("@lexical/react/useLexicalNodeSelection"),n=require("@lexical/utils"),u=require("lexical"),v=require("react");
8
8
  exports.BlockWithAlignableContents=function({children:w,format:p,nodeKey:g,className:q}){let [d]=a.useLexicalComposerContext(),[e,k,r]=m.useLexicalNodeSelection(g),t=v.useRef(null),l=v.useCallback(b=>{e&&u.$isNodeSelection(u.$getSelection())&&(b.preventDefault(),d.update(()=>{const c=u.$getNodeByKey(g);u.$isDecoratorNode(c)&&c.remove();k(!1)}));return!1},[d,e,g,k]);v.useEffect(()=>n.mergeRegister(d.registerCommand(u.FORMAT_ELEMENT_COMMAND,b=>{if(e){var c=u.$getSelection();if(u.$isNodeSelection(c)){var f=
9
- u.$getNodeByKey(g);h.$isDecoratorBlockNode(f)&&f.setFormat(b)}else if(u.$isRangeSelection(c)){c=c.getNodes();for(f of c)h.$isDecoratorBlockNode(f)?f.setFormat(b):n.$getNearestBlockElementAncestorOrThrow(f).setFormat(b)}return!0}return!1},u.COMMAND_PRIORITY_LOW),d.registerCommand(u.CLICK_COMMAND,b=>{b.preventDefault();return b.target===t.current?(b.shiftKey||r(),k(!e),!0):!1},u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_DELETE_COMMAND,l,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_BACKSPACE_COMMAND,
10
- l,u.COMMAND_PRIORITY_LOW)),[r,d,e,g,l,k]);return v.createElement("div",{className:[q.base,e?q.focus:null].filter(Boolean).join(" "),ref:t,style:{textAlign:p?p:void 0}},w)}
9
+ u.$getNodeByKey(g);h.$isDecoratorBlockNode(f)&&f.setFormat(b)}else if(u.$isRangeSelection(c)){c=c.getNodes();for(f of c)h.$isDecoratorBlockNode(f)?f.setFormat(b):n.$getNearestBlockElementAncestorOrThrow(f).setFormat(b)}return!0}return!1},u.COMMAND_PRIORITY_LOW),d.registerCommand(u.CLICK_COMMAND,b=>b.target===t.current?(b.preventDefault(),b.shiftKey||r(),k(!e),!0):!1,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_DELETE_COMMAND,l,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_BACKSPACE_COMMAND,l,
10
+ u.COMMAND_PRIORITY_LOW)),[r,d,e,g,l,k]);return v.createElement("div",{className:[q.base,e?q.focus:null].filter(Boolean).join(" "),ref:t,style:{textAlign:p?p:void 0}},w)}
@@ -15,7 +15,7 @@ var react = require('react');
15
15
  * LICENSE file in the root directory of this source tree.
16
16
  *
17
17
  */
18
- const entries = [['Cat', 'rgb(255,165,0)'], ['Dog', 'rgb(0,200,55)'], ['Rabbit', 'rgb(160,0,200)'], ['Frog', 'rgb(0,172,200)'], ['Fox', 'rgb(197,200,0)'], ['Hedgehog', 'rgb(31,200,0)'], ['Pigeon', 'rgb(200,0,0)'], ['Squirrel', 'rgb(200,0,148)'], ['Bear', 'rgb(255,235,0)'], ['Tiger', 'rgb(86,255,0)'], ['Leopard', 'rgb(0,255,208)'], ['Zebra', 'rgb(0,243,255)'], ['Wolf', 'rgb(0,102,255)'], ['Owl', 'rgb(147,0,255)'], ['Gull', 'rgb(255,0,153)'], ['Squid', 'rgb(0,220,255)']];
18
+ const entries = [['Cat', 'rgb(125, 50, 0)'], ['Dog', 'rgb(100, 0, 0)'], ['Rabbit', 'rgb(150, 0, 0)'], ['Frog', 'rgb(200, 0, 0)'], ['Fox', 'rgb(200, 75, 0)'], ['Hedgehog', 'rgb(0, 75, 0)'], ['Pigeon', 'rgb(0, 125, 0)'], ['Squirrel', 'rgb(75, 100, 0)'], ['Bear', 'rgb(125, 100, 0)'], ['Tiger', 'rgb(0, 0, 150)'], ['Leopard', 'rgb(0, 0, 200)'], ['Zebra', 'rgb(0, 0, 250)'], ['Wolf', 'rgb(0, 100, 150)'], ['Owl', 'rgb(0, 100, 100)'], ['Gull', 'rgb(100, 0, 100)'], ['Squid', 'rgb(150, 0, 150)']];
19
19
  const randomEntry = entries[Math.floor(Math.random() * entries.length)];
20
20
  const CollaborationContext = /*#__PURE__*/react.createContext({
21
21
  clientID: 0,
@@ -5,5 +5,5 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  'use strict';var b=require("react");
8
- let c=[["Cat","rgb(255,165,0)"],["Dog","rgb(0,200,55)"],["Rabbit","rgb(160,0,200)"],["Frog","rgb(0,172,200)"],["Fox","rgb(197,200,0)"],["Hedgehog","rgb(31,200,0)"],["Pigeon","rgb(200,0,0)"],["Squirrel","rgb(200,0,148)"],["Bear","rgb(255,235,0)"],["Tiger","rgb(86,255,0)"],["Leopard","rgb(0,255,208)"],["Zebra","rgb(0,243,255)"],["Wolf","rgb(0,102,255)"],["Owl","rgb(147,0,255)"],["Gull","rgb(255,0,153)"],["Squid","rgb(0,220,255)"]],d=c[Math.floor(Math.random()*c.length)],e=b.createContext({clientID:0,
8
+ let c=[["Cat","rgb(125, 50, 0)"],["Dog","rgb(100, 0, 0)"],["Rabbit","rgb(150, 0, 0)"],["Frog","rgb(200, 0, 0)"],["Fox","rgb(200, 75, 0)"],["Hedgehog","rgb(0, 75, 0)"],["Pigeon","rgb(0, 125, 0)"],["Squirrel","rgb(75, 100, 0)"],["Bear","rgb(125, 100, 0)"],["Tiger","rgb(0, 0, 150)"],["Leopard","rgb(0, 0, 200)"],["Zebra","rgb(0, 0, 250)"],["Wolf","rgb(0, 100, 150)"],["Owl","rgb(0, 100, 100)"],["Gull","rgb(100, 0, 100)"],["Squid","rgb(150, 0, 150)"]],d=c[Math.floor(Math.random()*c.length)],e=b.createContext({clientID:0,
9
9
  color:d[1],isCollabActive:!1,name:d[0],yjsDocMap:new Map});exports.CollaborationContext=e;exports.useCollaborationContext=function(f,g){let a=b.useContext(e);null!=f&&(a.name=f);null!=g&&(a.color=g);return a}
@@ -12,7 +12,12 @@ declare type Props = {
12
12
  initialConfig: Readonly<{
13
13
  editor__DEPRECATED?: LexicalEditor | null;
14
14
  namespace: string;
15
- nodes?: ReadonlyArray<Klass<LexicalNode>>;
15
+ nodes?: ReadonlyArray<Klass<LexicalNode> | {
16
+ replace: Klass<LexicalNode>;
17
+ with: <T extends {
18
+ new (...args: any): any;
19
+ }>(node: InstanceType<T>) => LexicalNode;
20
+ }>;
16
21
  onError: (error: Error, editor: LexicalEditor) => void;
17
22
  editable?: boolean;
18
23
  theme?: EditorThemeClasses;
@@ -25,7 +25,10 @@ type Props = {
25
25
  editor__DEPRECATED?: LexicalEditor | null,
26
26
  editable?: boolean,
27
27
  namespace: string,
28
- nodes?: $ReadOnlyArray<Class<LexicalNode>>,
28
+ nodes?: $ReadOnlyArray<
29
+ | Class<LexicalNode>
30
+ | {replace: Class<LexicalNode>, with: (node: LexicalNode) => LexicalNode},
31
+ >,
29
32
  theme?: EditorThemeClasses,
30
33
  editorState?: InitialEditorStateType,
31
34
  onError: (error: Error, editor: LexicalEditor) => void,
@@ -132,7 +132,7 @@ function convertHorizontalRuleElement() {
132
132
  }
133
133
 
134
134
  function $createHorizontalRuleNode() {
135
- return new HorizontalRuleNode();
135
+ return lexical.$applyNodeReplacement(new HorizontalRuleNode());
136
136
  }
137
137
  function $isHorizontalRuleNode(node) {
138
138
  return node instanceof HorizontalRuleNode;
@@ -8,4 +8,4 @@
8
8
  function r({nodeKey:b}){let [f]=a.useLexicalComposerContext(),m=p.useRef(null),[e,g,n]=d.useLexicalNodeSelection(b),k=p.useCallback(c=>{e&&l.$isNodeSelection(l.$getSelection())&&(c.preventDefault(),c=l.$getNodeByKey(b),t(c)&&c.remove(),g(!1));return!1},[e,b,g]);p.useEffect(()=>h.mergeRegister(f.registerCommand(l.CLICK_COMMAND,c=>c.target===m.current?(c.shiftKey||n(),g(!e),!0):!1,l.COMMAND_PRIORITY_LOW),f.registerCommand(l.KEY_DELETE_COMMAND,k,l.COMMAND_PRIORITY_LOW),f.registerCommand(l.KEY_BACKSPACE_COMMAND,
9
9
  k,l.COMMAND_PRIORITY_LOW)),[n,f,e,k,g]);return p.createElement("hr",{ref:m,className:e?"selected":void 0})}
10
10
  class u extends l.DecoratorNode{static getType(){return"horizontalrule"}static clone(b){return new u(b.__key)}static importJSON(){return v()}static importDOM(){return{hr:()=>({conversion:w,priority:0})}}exportJSON(){return{type:"horizontalrule",version:1}}exportDOM(){return{element:document.createElement("hr")}}createDOM(){let b=document.createElement("div");b.style.display="contents";return b}getTextContent(){return"\n"}isInline(){return!1}updateDOM(){return!1}decorate(){return p.createElement(r,{nodeKey:this.__key})}}
11
- function w(){return{node:v()}}function v(){return new u}function t(b){return b instanceof u}exports.$createHorizontalRuleNode=v;exports.$isHorizontalRuleNode=t;exports.HorizontalRuleNode=u;exports.INSERT_HORIZONTAL_RULE_COMMAND=q
11
+ function w(){return{node:v()}}function v(){return l.$applyNodeReplacement(new u)}function t(b){return b instanceof u}exports.$createHorizontalRuleNode=v;exports.$isHorizontalRuleNode=t;exports.HorizontalRuleNode=u;exports.INSERT_HORIZONTAL_RULE_COMMAND=q
@@ -5,4 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- export declare function LinkPlugin(): null;
8
+ declare type Props = {
9
+ validateUrl?: (url: string) => boolean;
10
+ };
11
+ export declare function LinkPlugin({ validateUrl }: Props): null;
12
+ export {};
@@ -8,6 +8,7 @@
8
8
 
9
9
  var link = require('@lexical/link');
10
10
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
11
+ var utils = require('@lexical/utils');
11
12
  var lexical = require('lexical');
12
13
  var react = require('react');
13
14
 
@@ -18,17 +19,26 @@ var react = require('react');
18
19
  * LICENSE file in the root directory of this source tree.
19
20
  *
20
21
  */
21
- function LinkPlugin() {
22
+ function LinkPlugin({
23
+ validateUrl
24
+ }) {
22
25
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
23
26
  react.useEffect(() => {
24
27
  if (!editor.hasNodes([link.LinkNode])) {
25
28
  throw new Error('LinkPlugin: LinkNode not registered on editor');
26
29
  }
27
- }, [editor]);
28
- react.useEffect(() => {
29
- return editor.registerCommand(link.TOGGLE_LINK_COMMAND, payload => {
30
- if (typeof payload === 'string' || payload === null) {
30
+
31
+ return utils.mergeRegister(editor.registerCommand(link.TOGGLE_LINK_COMMAND, payload => {
32
+ if (payload === null) {
31
33
  link.toggleLink(payload);
34
+ return true;
35
+ } else if (typeof payload === 'string') {
36
+ if (validateUrl === undefined || validateUrl(payload)) {
37
+ link.toggleLink(payload);
38
+ return true;
39
+ }
40
+
41
+ return false;
32
42
  } else {
33
43
  const {
34
44
  url,
@@ -39,11 +49,27 @@ function LinkPlugin() {
39
49
  rel,
40
50
  target
41
51
  });
52
+ return true;
53
+ }
54
+ }, lexical.COMMAND_PRIORITY_LOW), validateUrl !== undefined ? editor.registerCommand(lexical.PASTE_COMMAND, event => {
55
+ const selection = lexical.$getSelection();
56
+
57
+ if (!lexical.$isRangeSelection(selection) || selection.isCollapsed() || !(event instanceof ClipboardEvent) || event.clipboardData == null) {
58
+ return false;
59
+ }
60
+
61
+ const clipboardText = event.clipboardData.getData('text');
62
+
63
+ if (!validateUrl(clipboardText)) {
64
+ return false;
42
65
  }
43
66
 
67
+ editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, clipboardText);
68
+ event.preventDefault();
44
69
  return true;
45
- }, lexical.COMMAND_PRIORITY_EDITOR);
46
- }, [editor]);
70
+ }, lexical.COMMAND_PRIORITY_LOW) : () => {// Don't paste arbritrary text as a link when there's no validate function
71
+ });
72
+ }, [editor, validateUrl]);
47
73
  return null;
48
74
  }
49
75
 
@@ -7,4 +7,8 @@
7
7
  * @flow strict
8
8
  */
9
9
 
10
- declare export function LinkPlugin(): null;
10
+ type Props = $ReadOnly<{
11
+ validateUrl?: (url: string) => boolean,
12
+ }>;
13
+
14
+ declare export function LinkPlugin(props: Props): null;
@@ -4,5 +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 a=require("@lexical/link"),d=require("@lexical/react/LexicalComposerContext"),e=require("lexical"),f=require("react");
8
- exports.LinkPlugin=function(){let [b]=d.useLexicalComposerContext();f.useEffect(()=>{if(!b.hasNodes([a.LinkNode]))throw Error("LinkPlugin: LinkNode not registered on editor");},[b]);f.useEffect(()=>b.registerCommand(a.TOGGLE_LINK_COMMAND,c=>{if("string"===typeof c||null===c)a.toggleLink(c);else{let {url:g,target:h,rel:k}=c;a.toggleLink(g,{rel:k,target:h})}return!0},e.COMMAND_PRIORITY_EDITOR),[b]);return null}
7
+ 'use strict';var c=require("@lexical/link"),d=require("@lexical/react/LexicalComposerContext"),g=require("@lexical/utils"),h=require("lexical"),k=require("react");
8
+ exports.LinkPlugin=function({validateUrl:e}){let [f]=d.useLexicalComposerContext();k.useEffect(()=>{if(!f.hasNodes([c.LinkNode]))throw Error("LinkPlugin: LinkNode not registered on editor");return g.mergeRegister(f.registerCommand(c.TOGGLE_LINK_COMMAND,a=>{if(null===a)return c.toggleLink(a),!0;if("string"===typeof a)return void 0===e||e(a)?(c.toggleLink(a),!0):!1;let {url:b,target:l,rel:m}=a;c.toggleLink(b,{rel:m,target:l});return!0},h.COMMAND_PRIORITY_LOW),void 0!==e?f.registerCommand(h.PASTE_COMMAND,
9
+ a=>{var b=h.$getSelection();if(!h.$isRangeSelection(b)||b.isCollapsed()||!(a instanceof ClipboardEvent)||null==a.clipboardData)return!1;b=a.clipboardData.getData("text");if(!e(b))return!1;f.dispatchCommand(c.TOGGLE_LINK_COMMAND,b);a.preventDefault();return!0},h.COMMAND_PRIORITY_LOW):()=>{})},[f,e]);return null}
@@ -50,6 +50,7 @@ function LexicalNestedComposer({
50
50
  for (const [type, entry] of parentNodes) {
51
51
  initialEditor._nodes.set(type, {
52
52
  klass: entry.klass,
53
+ replace: entry.replace,
53
54
  transforms: new Set()
54
55
  });
55
56
  }
@@ -59,6 +60,7 @@ function LexicalNestedComposer({
59
60
 
60
61
  initialEditor._nodes.set(type, {
61
62
  klass,
63
+ replace: null,
62
64
  transforms: new Set()
63
65
  });
64
66
  }
@@ -4,6 +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 b=require("@lexical/react/LexicalCollaborationContext"),e=require("@lexical/react/LexicalComposerContext"),m=require("react");
8
- exports.LexicalNestedComposer=function({initialEditor:a,children:n,initialNodes:k,initialTheme:p,skipCollabChecks:q}){let l=m.useRef(!1),f=m.useContext(e.LexicalComposerContext);if(null==f)throw Error("Minified Lexical error #9; visit https://lexical.dev/docs/error?code=9 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");let w=m.useMemo(()=>{const [g,r]=f;var c=p||r.getTheme()||void 0;const t=e.createLexicalComposerContext(f,c);void 0!==
9
- c&&(a._config.theme=c);a._parentEditor=g;if(k)for(var d of k)c=d.getType(),a._nodes.set(c,{klass:d,transforms:new Set});else{d=a._nodes=new Map(g._nodes);for(const [u,v]of d)a._nodes.set(u,{klass:v.klass,transforms:new Set})}a._config.namespace=g._config.namespace;return[a,t]},[]),{isCollabActive:x,yjsDocMap:y}=b.useCollaborationContext(),h=q||l.current||y.has(a.getKey());m.useEffect(()=>{h&&(l.current=!0)},[h]);return m.createElement(e.LexicalComposerContext.Provider,{value:w},!x||h?n:null)}
7
+ 'use strict';var b=require("@lexical/react/LexicalCollaborationContext"),e=require("@lexical/react/LexicalComposerContext"),n=require("react");
8
+ exports.LexicalNestedComposer=function({initialEditor:a,children:p,initialNodes:k,initialTheme:q,skipCollabChecks:r}){let l=n.useRef(!1),f=n.useContext(e.LexicalComposerContext);if(null==f)throw Error("Minified Lexical error #9; visit https://lexical.dev/docs/error?code=9 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");let w=n.useMemo(()=>{const [g,t]=f;var c=q||t.getTheme()||void 0;const u=e.createLexicalComposerContext(f,c);void 0!==
9
+ c&&(a._config.theme=c);a._parentEditor=g;if(k)for(var d of k)c=d.getType(),a._nodes.set(c,{klass:d,replace:null,transforms:new Set});else{d=a._nodes=new Map(g._nodes);for(const [v,m]of d)a._nodes.set(v,{klass:m.klass,replace:m.replace,transforms:new Set})}a._config.namespace=g._config.namespace;return[a,u]},[]),{isCollabActive:x,yjsDocMap:y}=b.useCollaborationContext(),h=r||l.current||y.has(a.getKey());n.useEffect(()=>{h&&(l.current=!0)},[h]);return n.createElement(e.LexicalComposerContext.Provider,
10
+ {value:w},!x||h?p:null)}
@@ -0,0 +1,13 @@
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 Klass, type LexicalEditor, type LexicalNode, type NodeKey } from 'lexical';
9
+ export declare function NodeEventPlugin({ nodeType, eventType, eventListener, }: {
10
+ nodeType: Klass<LexicalNode>;
11
+ eventType: string;
12
+ eventListener: (event: Event, editor: LexicalEditor, nodeKey: NodeKey) => void;
13
+ }): null;
@@ -7,7 +7,6 @@
7
7
  'use strict';
8
8
 
9
9
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
10
- var lexical = require('lexical');
11
10
  var react = require('react');
12
11
 
13
12
  /**
@@ -36,44 +35,31 @@ var useLayoutEffect = useLayoutEffectImpl;
36
35
  * LICENSE file in the root directory of this source tree.
37
36
  *
38
37
  */
39
- function AutoScrollPlugin({
40
- scrollRef
38
+ function NodeEventPlugin({
39
+ nodeType,
40
+ eventType,
41
+ eventListener
41
42
  }) {
42
43
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
44
+ const listenerRef = react.useRef(eventListener);
45
+ listenerRef.current = eventListener;
43
46
  useLayoutEffect(() => {
44
- return editor.registerUpdateListener(({
45
- tags,
46
- editorState
47
- }) => {
48
- const scrollElement = scrollRef.current;
47
+ return editor.registerMutationListener(nodeType, mutations => {
48
+ editor.getEditorState().read(() => {
49
+ for (const [key, mutation] of mutations) {
50
+ const element = editor.getElementByKey(key);
49
51
 
50
- if (scrollElement === null || !tags.has('scroll-into-view')) {
51
- return;
52
- }
53
-
54
- const selection = editorState.read(() => lexical.$getSelection());
55
-
56
- if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed()) {
57
- return;
58
- }
59
-
60
- const anchorElement = editor.getElementByKey(selection.anchor.key);
61
-
62
- if (anchorElement === null) {
63
- return;
64
- }
65
-
66
- const scrollRect = scrollElement.getBoundingClientRect();
67
- const rect = anchorElement.getBoundingClientRect();
68
-
69
- if (rect.bottom > scrollRect.bottom) {
70
- anchorElement.scrollIntoView(false);
71
- } else if (rect.top < scrollRect.top) {
72
- anchorElement.scrollIntoView();
73
- }
74
- });
75
- }, [editor, scrollRef]);
52
+ if (mutation === 'created' && element !== null) {
53
+ element.addEventListener(eventType, event => {
54
+ listenerRef.current(event, editor, key);
55
+ });
56
+ }
57
+ }
58
+ });
59
+ }); // wW intentionally don't respect changes to eventType.
60
+ // eslint-disable-next-line react-hooks/exhaustive-deps
61
+ }, [editor, nodeType]);
76
62
  return null;
77
63
  }
78
64
 
79
- exports.AutoScrollPlugin = AutoScrollPlugin;
65
+ exports.NodeEventPlugin = NodeEventPlugin;
@@ -0,0 +1,9 @@
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
+ 'use strict'
8
+ const LexicalNodeEventPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalNodeEventPlugin.dev.js') : require('./LexicalNodeEventPlugin.prod.js')
9
+ module.exports = LexicalNodeEventPlugin;
@@ -0,0 +1,8 @@
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
+ 'use strict';var b=require("@lexical/react/LexicalComposerContext"),h=require("react"),k="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?h.useLayoutEffect:h.useEffect;
8
+ exports.NodeEventPlugin=function({nodeType:c,eventType:l,eventListener:d}){let [a]=b.useLexicalComposerContext(),e=h.useRef(d);e.current=d;k(()=>a.registerMutationListener(c,m=>{a.getEditorState().read(()=>{for(let [f,n]of m){let g=a.getElementByKey(f);"created"===n&&null!==g&&g.addEventListener(l,p=>{e.current(p,a,f)})}})}),[a,c]);return null}
package/package.json CHANGED
@@ -8,29 +8,29 @@
8
8
  "rich-text"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.6.1-next.0",
11
+ "version": "0.6.3",
12
12
  "dependencies": {
13
- "@lexical/clipboard": "0.6.1-next.0",
14
- "@lexical/code": "0.6.1-next.0",
15
- "@lexical/dragon": "0.6.1-next.0",
16
- "@lexical/hashtag": "0.6.1-next.0",
17
- "@lexical/history": "0.6.1-next.0",
18
- "@lexical/link": "0.6.1-next.0",
19
- "@lexical/list": "0.6.1-next.0",
20
- "@lexical/mark": "0.6.1-next.0",
21
- "@lexical/markdown": "0.6.1-next.0",
22
- "@lexical/overflow": "0.6.1-next.0",
23
- "@lexical/plain-text": "0.6.1-next.0",
24
- "@lexical/rich-text": "0.6.1-next.0",
25
- "@lexical/selection": "0.6.1-next.0",
26
- "@lexical/table": "0.6.1-next.0",
27
- "@lexical/text": "0.6.1-next.0",
28
- "@lexical/utils": "0.6.1-next.0",
29
- "@lexical/yjs": "0.6.1-next.0",
13
+ "@lexical/clipboard": "0.6.3",
14
+ "@lexical/code": "0.6.3",
15
+ "@lexical/dragon": "0.6.3",
16
+ "@lexical/hashtag": "0.6.3",
17
+ "@lexical/history": "0.6.3",
18
+ "@lexical/link": "0.6.3",
19
+ "@lexical/list": "0.6.3",
20
+ "@lexical/mark": "0.6.3",
21
+ "@lexical/markdown": "0.6.3",
22
+ "@lexical/overflow": "0.6.3",
23
+ "@lexical/plain-text": "0.6.3",
24
+ "@lexical/rich-text": "0.6.3",
25
+ "@lexical/selection": "0.6.3",
26
+ "@lexical/table": "0.6.3",
27
+ "@lexical/text": "0.6.3",
28
+ "@lexical/utils": "0.6.3",
29
+ "@lexical/yjs": "0.6.3",
30
30
  "react-error-boundary": "^3.1.4"
31
31
  },
32
32
  "peerDependencies": {
33
- "lexical": "0.6.1-next.0",
33
+ "lexical": "0.6.3",
34
34
  "react": ">=17.x",
35
35
  "react-dom": ">=17.x"
36
36
  },
@@ -1,14 +0,0 @@
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
- declare type Props = Readonly<{
9
- scrollRef: {
10
- current: HTMLElement | null;
11
- };
12
- }>;
13
- export declare function AutoScrollPlugin({ scrollRef }: Props): JSX.Element | null;
14
- export {};
@@ -1,9 +0,0 @@
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
- 'use strict'
8
- const LexicalAutoScrollPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalAutoScrollPlugin.dev.js') : require('./LexicalAutoScrollPlugin.prod.js')
9
- module.exports = LexicalAutoScrollPlugin;
@@ -1,12 +0,0 @@
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
- * @flow strict
8
- */
9
- type Props = $ReadOnly<{
10
- scrollRef: {current: HTMLElement | null},
11
- }>;
12
- declare export function AutoScrollPlugin(props: Props): React$Node;
@@ -1,8 +0,0 @@
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
- 'use strict';var e=require("@lexical/react/LexicalComposerContext"),f=require("lexical"),h=require("react"),k="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?h.useLayoutEffect:h.useEffect;
8
- exports.AutoScrollPlugin=function({scrollRef:g}){let [d]=e.useLexicalComposerContext();k(()=>d.registerUpdateListener(({tags:a,editorState:c})=>{var b=g.current;null!==b&&a.has("scroll-into-view")&&(a=c.read(()=>f.$getSelection()),f.$isRangeSelection(a)&&a.isCollapsed()&&(a=d.getElementByKey(a.anchor.key),null!==a&&(b=b.getBoundingClientRect(),c=a.getBoundingClientRect(),c.bottom>b.bottom?a.scrollIntoView(!1):c.top<b.top&&a.scrollIntoView())))}),[d,g]);return null}