@liveblocks/react-lexical 1.12.0-lexical6 → 2.0.0-alpha3

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.
Files changed (80) hide show
  1. package/dist/classnames.js +8 -0
  2. package/dist/classnames.js.map +1 -0
  3. package/dist/classnames.mjs +6 -0
  4. package/dist/classnames.mjs.map +1 -0
  5. package/dist/comments/ThreadPanel.js +41 -16
  6. package/dist/comments/ThreadPanel.js.map +1 -1
  7. package/dist/comments/ThreadPanel.mjs +43 -18
  8. package/dist/comments/ThreadPanel.mjs.map +1 -1
  9. package/dist/comments/comment-plugin-provider.js +18 -106
  10. package/dist/comments/comment-plugin-provider.js.map +1 -1
  11. package/dist/comments/comment-plugin-provider.mjs +17 -104
  12. package/dist/comments/comment-plugin-provider.mjs.map +1 -1
  13. package/dist/comments/floating-composer.js +226 -15
  14. package/dist/comments/floating-composer.js.map +1 -1
  15. package/dist/comments/floating-composer.mjs +224 -15
  16. package/dist/comments/floating-composer.mjs.map +1 -1
  17. package/dist/create-dom-range.js +63 -0
  18. package/dist/create-dom-range.js.map +1 -0
  19. package/dist/create-dom-range.mjs +61 -0
  20. package/dist/create-dom-range.mjs.map +1 -0
  21. package/dist/create-rects-from-dom-range.js +36 -0
  22. package/dist/create-rects-from-dom-range.js.map +1 -0
  23. package/dist/create-rects-from-dom-range.mjs +34 -0
  24. package/dist/create-rects-from-dom-range.mjs.map +1 -0
  25. package/dist/index.d.mts +30 -40
  26. package/dist/index.d.ts +30 -40
  27. package/dist/index.js +5 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +3 -4
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/liveblocks-config.js +3 -75
  32. package/dist/liveblocks-config.js.map +1 -1
  33. package/dist/liveblocks-config.mjs +4 -56
  34. package/dist/liveblocks-config.mjs.map +1 -1
  35. package/dist/liveblocks-plugin-provider.js +39 -43
  36. package/dist/liveblocks-plugin-provider.js.map +1 -1
  37. package/dist/liveblocks-plugin-provider.mjs +41 -44
  38. package/dist/liveblocks-plugin-provider.mjs.map +1 -1
  39. package/dist/mentions/avatar.js +10 -6
  40. package/dist/mentions/avatar.js.map +1 -1
  41. package/dist/mentions/avatar.mjs +10 -6
  42. package/dist/mentions/avatar.mjs.map +1 -1
  43. package/dist/mentions/mention-component.js +5 -18
  44. package/dist/mentions/mention-component.js.map +1 -1
  45. package/dist/mentions/mention-component.mjs +7 -19
  46. package/dist/mentions/mention-component.mjs.map +1 -1
  47. package/dist/mentions/mention-node.js +76 -80
  48. package/dist/mentions/mention-node.js.map +1 -1
  49. package/dist/mentions/mention-node.mjs +75 -81
  50. package/dist/mentions/mention-node.mjs.map +1 -1
  51. package/dist/mentions/mention-plugin.js +102 -90
  52. package/dist/mentions/mention-plugin.js.map +1 -1
  53. package/dist/mentions/mention-plugin.mjs +87 -71
  54. package/dist/mentions/mention-plugin.mjs.map +1 -1
  55. package/dist/mentions/suggestions.js +34 -6
  56. package/dist/mentions/suggestions.js.map +1 -1
  57. package/dist/mentions/suggestions.mjs +28 -3
  58. package/dist/mentions/suggestions.mjs.map +1 -1
  59. package/dist/mentions/user.js +8 -5
  60. package/dist/mentions/user.js.map +1 -1
  61. package/dist/mentions/user.mjs +8 -5
  62. package/dist/mentions/user.mjs.map +1 -1
  63. package/dist/version.js +1 -1
  64. package/dist/version.js.map +1 -1
  65. package/dist/version.mjs +1 -1
  66. package/dist/version.mjs.map +1 -1
  67. package/package.json +13 -13
  68. package/src/styles/constants.css +1 -0
  69. package/src/styles/index.css +158 -5
  70. package/src/styles/utils.css +6 -0
  71. package/styles.css +1 -1
  72. package/styles.css.map +1 -1
  73. package/dist/active-selection.js +0 -143
  74. package/dist/active-selection.js.map +0 -1
  75. package/dist/active-selection.mjs +0 -123
  76. package/dist/active-selection.mjs.map +0 -1
  77. package/dist/floating-selection-container.js +0 -157
  78. package/dist/floating-selection-container.js.map +0 -1
  79. package/dist/floating-selection-container.mjs +0 -155
  80. package/dist/floating-selection-container.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"mention-node.js","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport { nanoid } from \"nanoid\";\nimport type { ComponentType, JSX } from \"react\";\nimport * as React from \"react\";\n\nimport type { MentionProps } from \"../liveblocks-config\";\nimport { MentionWrapper } from \"./mention-component\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\n\nexport function createMentionNodeFactory(\n Component: ComponentType<MentionProps>\n): any {\n class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(\n element.getAttribute(\"data-lexical-lb-mention\")!\n );\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <MentionWrapper nodeKey={this.getKey()}>\n <Component userId={this.__userId} />\n </MentionWrapper>\n );\n }\n }\n\n function $isMentionNode(\n node: LexicalNode | null | undefined\n ): node is MentionNode {\n return node instanceof MentionNode;\n }\n\n function $createMentionNode(userId: string): MentionNode {\n const id = `in_${nanoid()}`;\n const node = new MentionNode(id, userId);\n return $applyNodeReplacement(node);\n }\n\n return {\n MentionNode,\n $isMentionNode,\n $createMentionNode,\n };\n}\n"],"names":["DecoratorNode","React","MentionWrapper","nanoid","$applyNodeReplacement"],"mappings":"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"}
1
+ {"version":3,"file":"mention-node.js","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport { nanoid } from \"nanoid\";\nimport type { JSX } from \"react\";\nimport * as React from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const id = `in_${nanoid()}`;\n const node = new MentionNode(id, userId);\n return $applyNodeReplacement(node);\n}\n"],"names":["DecoratorNode","React","Mention","User","nanoid","$applyNodeReplacement"],"mappings":"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"}
@@ -1,91 +1,85 @@
1
1
  import { DecoratorNode, $applyNodeReplacement } from 'lexical';
2
2
  import { nanoid } from 'nanoid';
3
3
  import * as React from 'react';
4
- import { MentionWrapper } from './mention-component.mjs';
4
+ import { Mention } from './mention-component.mjs';
5
+ import { User } from './user.mjs';
5
6
 
6
- function createMentionNodeFactory(Component) {
7
- class MentionNode extends DecoratorNode {
8
- constructor(id, userId, key) {
9
- super(key);
10
- this.__id = id;
11
- this.__userId = userId;
12
- }
13
- static getType() {
14
- return "lb-mention";
15
- }
16
- static clone(node) {
17
- return new MentionNode(node.__id, node.__userId);
18
- }
19
- createDOM() {
20
- const element = document.createElement("span");
21
- element.style.display = "inline-block";
22
- return element;
23
- }
24
- updateDOM() {
25
- return false;
26
- }
27
- static importDom() {
28
- return {
29
- span: () => ({
30
- conversion: (element) => {
31
- const value = atob(
32
- element.getAttribute("data-lexical-lb-mention")
33
- );
34
- const node = $createMentionNode(value);
35
- return { node };
36
- },
37
- priority: 1
38
- })
39
- };
40
- }
41
- exportDOM() {
42
- const element = document.createElement("span");
43
- const value = this.getTextContent();
44
- element.setAttribute("data-lexical-lb-mention", btoa(value));
45
- element.textContent = this.getTextContent();
46
- return { element };
47
- }
48
- static importJSON(serializedNode) {
49
- const node = $createMentionNode(serializedNode.userId);
50
- return node;
51
- }
52
- exportJSON() {
53
- return {
54
- userId: this.__userId,
55
- type: "lb-mention",
56
- version: 1
57
- };
58
- }
59
- getUserId() {
60
- const self = this.getLatest();
61
- return self.__userId;
62
- }
63
- getId() {
64
- const self = this.getLatest();
65
- return self.__id;
66
- }
67
- decorate() {
68
- return /* @__PURE__ */ React.createElement(MentionWrapper, {
69
- nodeKey: this.getKey()
70
- }, /* @__PURE__ */ React.createElement(Component, {
71
- userId: this.__userId
72
- }));
73
- }
7
+ const MENTION_CHARACTER = "@";
8
+ class MentionNode extends DecoratorNode {
9
+ constructor(id, userId, key) {
10
+ super(key);
11
+ this.__id = id;
12
+ this.__userId = userId;
74
13
  }
75
- function $isMentionNode(node) {
76
- return node instanceof MentionNode;
14
+ static getType() {
15
+ return "lb-mention";
77
16
  }
78
- function $createMentionNode(userId) {
79
- const id = `in_${nanoid()}`;
80
- const node = new MentionNode(id, userId);
81
- return $applyNodeReplacement(node);
17
+ static clone(node) {
18
+ return new MentionNode(node.__id, node.__userId);
82
19
  }
83
- return {
84
- MentionNode,
85
- $isMentionNode,
86
- $createMentionNode
87
- };
20
+ createDOM() {
21
+ const element = document.createElement("span");
22
+ element.style.display = "inline-block";
23
+ element.style.userSelect = "none";
24
+ return element;
25
+ }
26
+ updateDOM() {
27
+ return false;
28
+ }
29
+ static importDom() {
30
+ return {
31
+ span: () => ({
32
+ conversion: (element) => {
33
+ const value = atob(element.getAttribute("data-lexical-lb-mention"));
34
+ const node = $createMentionNode(value);
35
+ return { node };
36
+ },
37
+ priority: 1
38
+ })
39
+ };
40
+ }
41
+ exportDOM() {
42
+ const element = document.createElement("span");
43
+ const value = this.getTextContent();
44
+ element.setAttribute("data-lexical-lb-mention", btoa(value));
45
+ element.textContent = this.getTextContent();
46
+ return { element };
47
+ }
48
+ static importJSON(serializedNode) {
49
+ const node = $createMentionNode(serializedNode.userId);
50
+ return node;
51
+ }
52
+ exportJSON() {
53
+ return {
54
+ userId: this.__userId,
55
+ type: "lb-mention",
56
+ version: 1
57
+ };
58
+ }
59
+ getUserId() {
60
+ const self = this.getLatest();
61
+ return self.__userId;
62
+ }
63
+ getId() {
64
+ const self = this.getLatest();
65
+ return self.__id;
66
+ }
67
+ decorate() {
68
+ return /* @__PURE__ */ React.createElement(Mention, {
69
+ nodeKey: this.getKey()
70
+ }, MENTION_CHARACTER, /* @__PURE__ */ React.createElement(User, {
71
+ userId: this.getUserId()
72
+ }));
73
+ }
74
+ }
75
+ function $isMentionNode(node) {
76
+ return node instanceof MentionNode;
77
+ }
78
+ function $createMentionNode(userId) {
79
+ const id = `in_${nanoid()}`;
80
+ const node = new MentionNode(id, userId);
81
+ return $applyNodeReplacement(node);
88
82
  }
89
83
 
90
- export { createMentionNodeFactory };
84
+ export { $createMentionNode, $isMentionNode, MentionNode };
91
85
  //# sourceMappingURL=mention-node.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mention-node.mjs","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport { nanoid } from \"nanoid\";\nimport type { ComponentType, JSX } from \"react\";\nimport * as React from \"react\";\n\nimport type { MentionProps } from \"../liveblocks-config\";\nimport { MentionWrapper } from \"./mention-component\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\n\nexport function createMentionNodeFactory(\n Component: ComponentType<MentionProps>\n): any {\n class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(\n element.getAttribute(\"data-lexical-lb-mention\")!\n );\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <MentionWrapper nodeKey={this.getKey()}>\n <Component userId={this.__userId} />\n </MentionWrapper>\n );\n }\n }\n\n function $isMentionNode(\n node: LexicalNode | null | undefined\n ): node is MentionNode {\n return node instanceof MentionNode;\n }\n\n function $createMentionNode(userId: string): MentionNode {\n const id = `in_${nanoid()}`;\n const node = new MentionNode(id, userId);\n return $applyNodeReplacement(node);\n }\n\n return {\n MentionNode,\n $isMentionNode,\n $createMentionNode,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mention-node.mjs","sources":["../../src/mentions/mention-node.tsx"],"sourcesContent":["import type {\n DOMConversionMap,\n DOMExportOutput,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $applyNodeReplacement, DecoratorNode } from \"lexical\";\nimport { nanoid } from \"nanoid\";\nimport type { JSX } from \"react\";\nimport * as React from \"react\";\n\nimport { Mention } from \"./mention-component\";\nimport { User } from \"./user\";\n\nconst MENTION_CHARACTER = \"@\";\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n },\n SerializedLexicalNode\n>;\nexport class MentionNode extends DecoratorNode<JSX.Element> {\n __id: string;\n __userId: string;\n\n constructor(id: string, userId: string, key?: NodeKey) {\n super(key);\n this.__id = id;\n this.__userId = userId;\n }\n\n static getType(): string {\n return \"lb-mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__id, node.__userId);\n }\n\n createDOM(): HTMLElement {\n const element = document.createElement(\"span\");\n element.style.display = \"inline-block\";\n element.style.userSelect = \"none\";\n return element;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n static importDom(): DOMConversionMap<HTMLElement> | null {\n return {\n span: () => ({\n conversion: (element) => {\n const value = atob(element.getAttribute(\"data-lexical-lb-mention\")!);\n const node = $createMentionNode(value);\n return { node };\n },\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"span\");\n const value = this.getTextContent();\n element.setAttribute(\"data-lexical-lb-mention\", btoa(value));\n element.textContent = this.getTextContent();\n return { element };\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n const node = $createMentionNode(serializedNode.userId);\n return node;\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n userId: this.__userId,\n type: \"lb-mention\",\n version: 1,\n };\n }\n\n getUserId(): string {\n const self = this.getLatest();\n return self.__userId;\n }\n\n getId(): string {\n const self = this.getLatest();\n return self.__id;\n }\n\n decorate(): JSX.Element {\n return (\n <Mention nodeKey={this.getKey()}>\n {MENTION_CHARACTER}\n <User userId={this.getUserId()} />\n </Mention>\n );\n }\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n\nexport function $createMentionNode(userId: string): MentionNode {\n const id = `in_${nanoid()}`;\n const node = new MentionNode(id, userId);\n return $applyNodeReplacement(node);\n}\n"],"names":[],"mappings":";;;;;;AAgBA,MAAM,iBAAoB,GAAA,GAAA,CAAA;AAQnB,MAAM,oBAAoB,aAA2B,CAAA;AAAA,EAI1D,WAAA,CAAY,EAAY,EAAA,MAAA,EAAgB,GAAe,EAAA;AACrD,IAAA,KAAA,CAAM,GAAG,CAAA,CAAA;AACT,IAAA,IAAA,CAAK,IAAO,GAAA,EAAA,CAAA;AACZ,IAAA,IAAA,CAAK,QAAW,GAAA,MAAA,CAAA;AAAA,GAClB;AAAA,EAEA,OAAO,OAAkB,GAAA;AACvB,IAAO,OAAA,YAAA,CAAA;AAAA,GACT;AAAA,EAEA,OAAO,MAAM,IAAgC,EAAA;AAC3C,IAAA,OAAO,IAAI,WAAA,CAAY,IAAK,CAAA,IAAA,EAAM,KAAK,QAAQ,CAAA,CAAA;AAAA,GACjD;AAAA,EAEA,SAAyB,GAAA;AACvB,IAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC7C,IAAA,OAAA,CAAQ,MAAM,OAAU,GAAA,cAAA,CAAA;AACxB,IAAA,OAAA,CAAQ,MAAM,UAAa,GAAA,MAAA,CAAA;AAC3B,IAAO,OAAA,OAAA,CAAA;AAAA,GACT;AAAA,EAEA,SAAqB,GAAA;AACnB,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAAA,EAEA,OAAO,SAAkD,GAAA;AACvD,IAAO,OAAA;AAAA,MACL,MAAM,OAAO;AAAA,QACX,UAAA,EAAY,CAAC,OAAY,KAAA;AACvB,UAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,YAAA,CAAa,yBAAyB,CAAE,CAAA,CAAA;AACnE,UAAM,MAAA,IAAA,GAAO,mBAAmB,KAAK,CAAA,CAAA;AACrC,UAAA,OAAO,EAAE,IAAK,EAAA,CAAA;AAAA,SAChB;AAAA,QACA,QAAU,EAAA,CAAA;AAAA,OACZ,CAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,SAA6B,GAAA;AAC3B,IAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC7C,IAAM,MAAA,KAAA,GAAQ,KAAK,cAAe,EAAA,CAAA;AAClC,IAAA,OAAA,CAAQ,YAAa,CAAA,yBAAA,EAA2B,IAAK,CAAA,KAAK,CAAC,CAAA,CAAA;AAC3D,IAAQ,OAAA,CAAA,WAAA,GAAc,KAAK,cAAe,EAAA,CAAA;AAC1C,IAAA,OAAO,EAAE,OAAQ,EAAA,CAAA;AAAA,GACnB;AAAA,EAEA,OAAO,WAAW,cAAoD,EAAA;AACpE,IAAM,MAAA,IAAA,GAAO,kBAAmB,CAAA,cAAA,CAAe,MAAM,CAAA,CAAA;AACrD,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAAA,EAEA,UAAoC,GAAA;AAClC,IAAO,OAAA;AAAA,MACL,QAAQ,IAAK,CAAA,QAAA;AAAA,MACb,IAAM,EAAA,YAAA;AAAA,MACN,OAAS,EAAA,CAAA;AAAA,KACX,CAAA;AAAA,GACF;AAAA,EAEA,SAAoB,GAAA;AAClB,IAAM,MAAA,IAAA,GAAO,KAAK,SAAU,EAAA,CAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,QAAA,CAAA;AAAA,GACd;AAAA,EAEA,KAAgB,GAAA;AACd,IAAM,MAAA,IAAA,GAAO,KAAK,SAAU,EAAA,CAAA;AAC5B,IAAA,OAAO,IAAK,CAAA,IAAA,CAAA;AAAA,GACd;AAAA,EAEA,QAAwB,GAAA;AACtB,IAAA,uBACG,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA;AAAA,MAAQ,OAAA,EAAS,KAAK,MAAO,EAAA;AAAA,KAAA,EAC3B,mCACA,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,MAAK,MAAA,EAAQ,KAAK,SAAU,EAAA;AAAA,KAAG,CAClC,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA;AAEO,SAAS,eACd,IACqB,EAAA;AACrB,EAAA,OAAO,IAAgB,YAAA,WAAA,CAAA;AACzB,CAAA;AAEO,SAAS,mBAAmB,MAA6B,EAAA;AAC9D,EAAM,MAAA,EAAA,GAAK,MAAM,MAAO,EAAA,CAAA,CAAA,CAAA;AACxB,EAAA,MAAM,IAAO,GAAA,IAAI,WAAY,CAAA,EAAA,EAAI,MAAM,CAAA,CAAA;AACvC,EAAA,OAAO,sBAAsB,IAAI,CAAA,CAAA;AACnC;;;;"}
@@ -1,14 +1,17 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
3
+ var reactDom$1 = require('@floating-ui/react-dom');
5
4
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
6
5
  var core = require('@liveblocks/core');
7
6
  var react = require('@liveblocks/react');
7
+ var reactUi = require('@liveblocks/react-ui');
8
8
  var lexical = require('lexical');
9
9
  var React = require('react');
10
10
  var reactDom = require('react-dom');
11
- var liveblocksPluginProvider = require('../liveblocks-plugin-provider.js');
11
+ var avatar = require('./avatar.js');
12
+ var mentionNode = require('./mention-node.js');
13
+ var suggestions = require('./suggestions.js');
14
+ var user = require('./user.js');
12
15
 
13
16
  const MENTION_TRIGGER = "@";
14
17
  const PUNCTUATIONS = `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'"~=<>_:;`;
@@ -31,8 +34,8 @@ function $getAnchorNodeTextContent() {
31
34
  const anchorOffset = anchor.offset;
32
35
  return anchorNode.getTextContent().slice(0, anchorOffset);
33
36
  }
34
- function getFullMatchOffset(documentText, entryText, offset) {
35
- let triggerOffset = offset;
37
+ function getFullMatchOffset(documentText, entryText, offset2) {
38
+ let triggerOffset = offset2;
36
39
  for (let i = triggerOffset; i <= entryText.length; i++) {
37
40
  if (documentText.substr(-i) === entryText.substr(0, i)) {
38
41
  triggerOffset = i;
@@ -40,8 +43,8 @@ function getFullMatchOffset(documentText, entryText, offset) {
40
43
  }
41
44
  return triggerOffset;
42
45
  }
43
- function $isCurrentSelectionAtBoundary(offset) {
44
- if (offset !== 0)
46
+ function $isCurrentSelectionAtBoundary(offset2) {
47
+ if (offset2 !== 0)
45
48
  return false;
46
49
  const selection = lexical.$getSelection();
47
50
  if (!lexical.$isRangeSelection(selection))
@@ -78,30 +81,17 @@ function $getRangeAtMatch(match) {
78
81
  return null;
79
82
  }
80
83
  }
81
- const SuggestionsContext = React.createContext(null);
82
- const OnValueSelectCallbackContext = React.createContext(null);
83
- const OnResetMatchCallbackContext = React.createContext(null);
84
84
  function MentionPlugin() {
85
85
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
86
- const {
87
- mentions: {
88
- factory: { $isMentionNode, $createMentionNode, MentionNode },
89
- components: { MentionSuggestions }
90
- }
91
- } = liveblocksPluginProvider.useLiveblocksLexicalConfigContext();
92
- if (!editor.hasNodes([MentionNode])) {
86
+ if (!editor.hasNodes([mentionNode.MentionNode])) {
93
87
  throw new Error("MentionPlugin: MentionNode not registered on editor");
94
88
  }
95
89
  const [match, setMatch] = React.useState(null);
96
90
  const matchingString = match?.[3];
97
- const {
98
- [core.kInternal]: { useMentionSuggestions }
99
- } = react.useRoomContextBundle();
100
- const suggestions = useMentionSuggestions(matchingString);
101
- const { useRoom } = react.useRoomContextBundle();
102
- const room = useRoom();
91
+ const suggestions$1 = reactUi.useMentionSuggestions(matchingString);
92
+ const room = react.useRoom();
103
93
  React.useEffect(() => {
104
- async function $handleMutation(mutations, {
94
+ function $handleMutation(mutations, {
105
95
  prevEditorState
106
96
  }) {
107
97
  for (const [key, mutation] of mutations) {
@@ -110,7 +100,7 @@ function MentionPlugin() {
110
100
  const node = lexical.$getNodeByKey(key);
111
101
  if (node === null)
112
102
  return;
113
- if (!$isMentionNode(node))
103
+ if (!mentionNode.$isMentionNode(node))
114
104
  return;
115
105
  room[core.kInternal].createTextMention(node.getUserId(), node.getId()).catch((err) => {
116
106
  console.error(err);
@@ -121,7 +111,7 @@ function MentionPlugin() {
121
111
  const node = lexical.$getNodeByKey(key);
122
112
  if (node === null)
123
113
  return;
124
- if (!$isMentionNode(node))
114
+ if (!mentionNode.$isMentionNode(node))
125
115
  return;
126
116
  room[core.kInternal].deleteTextMention(node.getId()).catch((err) => {
127
117
  console.error(err);
@@ -131,14 +121,14 @@ function MentionPlugin() {
131
121
  }
132
122
  }
133
123
  return editor.registerMutationListener(
134
- MentionNode,
124
+ mentionNode.MentionNode,
135
125
  (mutations, payload) => {
136
126
  if (payload.updateTags.has("collaboration"))
137
127
  return;
138
128
  $handleMutation(mutations, payload);
139
129
  }
140
130
  );
141
- }, [editor, MentionNode, $isMentionNode, room]);
131
+ }, [editor, room]);
142
132
  React.useEffect(() => {
143
133
  function $onStateRead() {
144
134
  const text = $getAnchorNodeTextContent();
@@ -153,6 +143,15 @@ function MentionPlugin() {
153
143
  state.read($onStateRead);
154
144
  });
155
145
  }, [editor]);
146
+ React.useEffect(() => {
147
+ const root = editor.getRootElement();
148
+ if (root === null)
149
+ return;
150
+ root.classList.add("lb-root");
151
+ return () => {
152
+ root.classList.remove("lb-root");
153
+ };
154
+ }, [editor]);
156
155
  React.useEffect(() => {
157
156
  function $handleBackspace(event) {
158
157
  const selection = lexical.$getSelection();
@@ -163,7 +162,7 @@ function MentionPlugin() {
163
162
  if (nodes.length !== 1)
164
163
  return false;
165
164
  const node = nodes[0];
166
- if (!$isMentionNode(node))
165
+ if (!mentionNode.$isMentionNode(node))
167
166
  return false;
168
167
  const text = lexical.$createTextNode("@");
169
168
  node.replace(text);
@@ -177,7 +176,7 @@ function MentionPlugin() {
177
176
  return false;
178
177
  const anchor = selection.anchor.getNode();
179
178
  const prevSibling = anchor.getPreviousSibling();
180
- if (selection.anchor.offset === 0 && $isMentionNode(prevSibling)) {
179
+ if (selection.anchor.offset === 0 && mentionNode.$isMentionNode(prevSibling)) {
181
180
  const text = lexical.$createTextNode("@");
182
181
  prevSibling.replace(text);
183
182
  const newSelection = lexical.$createRangeSelection();
@@ -187,7 +186,7 @@ function MentionPlugin() {
187
186
  return true;
188
187
  } else if (lexical.$isElementNode(anchor)) {
189
188
  const child = anchor.getChildAtIndex(selection.anchor.offset - 1);
190
- if (!$isMentionNode(child))
189
+ if (!mentionNode.$isMentionNode(child))
191
190
  return false;
192
191
  const text = lexical.$createTextNode("@");
193
192
  child.replace(text);
@@ -206,7 +205,7 @@ function MentionPlugin() {
206
205
  $handleBackspace,
207
206
  lexical.COMMAND_PRIORITY_LOW
208
207
  );
209
- }, [editor, $isMentionNode]);
208
+ }, [editor]);
210
209
  const handleValueSelect = React.useCallback(
211
210
  (userId) => {
212
211
  function $onValueSelect() {
@@ -231,88 +230,101 @@ function MentionPlugin() {
231
230
  const startOffset = selectionOffset - queryOffset;
232
231
  if (startOffset < 0)
233
232
  return;
234
- const mentionNode = $createMentionNode(userId);
233
+ const mentionNode$1 = mentionNode.$createMentionNode(userId);
235
234
  if (startOffset === 0) {
236
235
  const [node] = anchorNode.splitText(selectionOffset);
237
- node.replace(mentionNode);
236
+ node.replace(mentionNode$1);
238
237
  } else {
239
238
  const [, node] = anchorNode.splitText(startOffset, selectionOffset);
240
- node.replace(mentionNode);
239
+ node.replace(mentionNode$1);
241
240
  }
242
241
  }
243
242
  editor.update($onValueSelect);
244
243
  },
245
- [editor, match, $createMentionNode]
244
+ [editor, match]
246
245
  );
247
246
  if (match === null || matchingString === void 0)
248
247
  return null;
249
- if (suggestions === void 0 || suggestions.length === 0)
248
+ if (suggestions$1 === void 0 || suggestions$1.length === 0)
250
249
  return null;
251
250
  const range = editor.getEditorState().read(() => $getRangeAtMatch(match));
252
251
  if (range === null)
253
252
  return null;
254
- const rect = range.getBoundingClientRect();
255
253
  return reactDom.createPortal(
256
- /* @__PURE__ */ React.createElement(SuggestionsContext.Provider, {
257
- value: suggestions
258
- }, /* @__PURE__ */ React.createElement(OnValueSelectCallbackContext.Provider, {
254
+ /* @__PURE__ */ React.createElement(suggestions.SuggestionsContext.Provider, {
255
+ value: suggestions$1
256
+ }, /* @__PURE__ */ React.createElement(suggestions.OnValueSelectCallbackContext.Provider, {
259
257
  value: handleValueSelect
260
- }, /* @__PURE__ */ React.createElement(OnResetMatchCallbackContext.Provider, {
258
+ }, /* @__PURE__ */ React.createElement(suggestions.OnResetMatchCallbackContext.Provider, {
261
259
  value: () => setMatch(null)
262
- }, /* @__PURE__ */ React.createElement(SuggestionsRoot, {
263
- rect,
260
+ }, /* @__PURE__ */ React.createElement(SuggestionsPortal, {
261
+ range,
262
+ container: document.body,
264
263
  key: matchingString
265
- }, /* @__PURE__ */ React.createElement(MentionSuggestions, {
266
- userIds: suggestions
267
- }))))),
264
+ }, /* @__PURE__ */ React.createElement(suggestions.List, {
265
+ className: "lb-lexical-suggestions-list lb-lexical-mention-suggestions-list"
266
+ }, suggestions$1.map((userId) => /* @__PURE__ */ React.createElement(suggestions.Item, {
267
+ key: userId,
268
+ value: userId,
269
+ className: "lb-lexical-suggestions-list-item lb-lexical-mention-suggestion"
270
+ }, /* @__PURE__ */ React.createElement(avatar.Avatar, {
271
+ userId,
272
+ className: "lb-lexical-mention-suggestion-avatar"
273
+ }), /* @__PURE__ */ React.createElement(user.User, {
274
+ userId,
275
+ className: "lb-lexical-mention-suggestion-user"
276
+ })))))))),
268
277
  document.body
269
278
  );
270
279
  }
271
- function SuggestionsRoot({
272
- rect,
273
- children
280
+ const SUGGESTIONS_COLLISION_PADDING = 10;
281
+ function SuggestionsPortal({
282
+ children,
283
+ range,
284
+ container
274
285
  }) {
275
- const [editor] = LexicalComposerContext.useLexicalComposerContext();
276
- const divRef = React.useRef(null);
286
+ const {
287
+ refs: { setReference, setFloating },
288
+ strategy,
289
+ x,
290
+ y
291
+ } = reactDom$1.useFloating({
292
+ strategy: "fixed",
293
+ placement: "top-start",
294
+ middleware: [
295
+ reactDom$1.flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),
296
+ reactDom$1.offset(10),
297
+ reactDom$1.hide({ padding: SUGGESTIONS_COLLISION_PADDING }),
298
+ reactDom$1.shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: reactDom$1.limitShift() }),
299
+ reactDom$1.size({ padding: SUGGESTIONS_COLLISION_PADDING })
300
+ ],
301
+ whileElementsMounted: (...args) => {
302
+ return reactDom$1.autoUpdate(...args, {
303
+ animationFrame: true
304
+ });
305
+ }
306
+ });
277
307
  React.useLayoutEffect(() => {
278
- const root = editor.getRootElement();
279
- if (root === null)
280
- return;
281
- const div = divRef.current;
282
- if (div === null)
283
- return;
284
- div.style.left = `${rect.left + window.scrollX}px`;
285
- div.style.top = `${rect.bottom + window.scrollY}px`;
286
- }, [editor, rect]);
287
- return /* @__PURE__ */ React.createElement("div", {
288
- ref: divRef,
289
- style: { position: "absolute" }
290
- }, children);
291
- }
292
- function useSuggestions() {
293
- const suggestions = React.useContext(SuggestionsContext);
294
- if (suggestions === null) {
295
- throw new Error("useSuggestions: SuggestionsContext not found");
296
- }
297
- return suggestions;
298
- }
299
- function useOnValueSelectCallback() {
300
- const onValueSelect = React.useContext(OnValueSelectCallbackContext);
301
- if (onValueSelect === null) {
302
- throw new Error("useOnValueSelectCallback: OnValueSelectContext not found");
303
- }
304
- return onValueSelect;
305
- }
306
- function useOnResetMatchCallback() {
307
- const onResetMatch = React.useContext(OnResetMatchCallbackContext);
308
- if (onResetMatch === null) {
309
- throw new Error("useOnResetMatchCallback: OnResetMatchContext not found");
310
- }
311
- return onResetMatch;
308
+ setReference({
309
+ getBoundingClientRect: () => range.getBoundingClientRect()
310
+ });
311
+ }, [setReference, range]);
312
+ return reactDom.createPortal(
313
+ /* @__PURE__ */ React.createElement("div", {
314
+ ref: setFloating,
315
+ style: {
316
+ position: strategy,
317
+ top: 0,
318
+ left: 0,
319
+ transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,
320
+ minWidth: "max-content"
321
+ },
322
+ className: "lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions"
323
+ }, children),
324
+ container
325
+ );
312
326
  }
313
327
 
314
- exports.default = MentionPlugin;
315
- exports.useOnResetMatchCallback = useOnResetMatchCallback;
316
- exports.useOnValueSelectCallback = useOnValueSelectCallback;
317
- exports.useSuggestions = useSuggestions;
328
+ exports.MentionPlugin = MentionPlugin;
329
+ exports.SUGGESTIONS_COLLISION_PADDING = SUGGESTIONS_COLLISION_PADDING;
318
330
  //# sourceMappingURL=mention-plugin.js.map