@lexical/react 0.13.1 → 0.14.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.
Files changed (179) hide show
  1. package/LexicalAutoEmbedPlugin.dev.esm.js +131 -0
  2. package/LexicalAutoEmbedPlugin.esm.js +13 -0
  3. package/LexicalAutoEmbedPlugin.js +1 -1
  4. package/LexicalAutoEmbedPlugin.prod.esm.js +7 -0
  5. package/LexicalAutoFocusPlugin.dev.esm.js +42 -0
  6. package/LexicalAutoFocusPlugin.esm.js +10 -0
  7. package/LexicalAutoFocusPlugin.js +1 -1
  8. package/LexicalAutoFocusPlugin.prod.esm.js +7 -0
  9. package/LexicalAutoLinkPlugin.dev.esm.js +312 -0
  10. package/LexicalAutoLinkPlugin.dev.js +3 -1
  11. package/LexicalAutoLinkPlugin.esm.js +11 -0
  12. package/LexicalAutoLinkPlugin.js +1 -1
  13. package/LexicalAutoLinkPlugin.prod.esm.js +7 -0
  14. package/LexicalBlockWithAlignableContents.dev.esm.js +86 -0
  15. package/LexicalBlockWithAlignableContents.dev.js +1 -0
  16. package/LexicalBlockWithAlignableContents.esm.js +10 -0
  17. package/LexicalBlockWithAlignableContents.js +1 -1
  18. package/LexicalBlockWithAlignableContents.prod.esm.js +7 -0
  19. package/LexicalBlockWithAlignableContents.prod.js +1 -1
  20. package/LexicalCharacterLimitPlugin.d.ts +4 -1
  21. package/LexicalCharacterLimitPlugin.dev.esm.js +272 -0
  22. package/LexicalCharacterLimitPlugin.dev.js +12 -4
  23. package/LexicalCharacterLimitPlugin.esm.js +10 -0
  24. package/LexicalCharacterLimitPlugin.js +1 -1
  25. package/LexicalCharacterLimitPlugin.prod.esm.js +7 -0
  26. package/LexicalCharacterLimitPlugin.prod.js +9 -9
  27. package/LexicalCheckListPlugin.dev.esm.js +203 -0
  28. package/LexicalCheckListPlugin.esm.js +10 -0
  29. package/LexicalCheckListPlugin.js +1 -1
  30. package/LexicalCheckListPlugin.prod.esm.js +7 -0
  31. package/LexicalClearEditorPlugin.dev.esm.js +64 -0
  32. package/LexicalClearEditorPlugin.esm.js +10 -0
  33. package/LexicalClearEditorPlugin.js +1 -1
  34. package/LexicalClearEditorPlugin.prod.esm.js +7 -0
  35. package/LexicalClickableLinkPlugin.dev.esm.js +95 -0
  36. package/LexicalClickableLinkPlugin.esm.js +10 -0
  37. package/LexicalClickableLinkPlugin.js +1 -1
  38. package/LexicalClickableLinkPlugin.prod.esm.js +7 -0
  39. package/LexicalCollaborationContext.dev.esm.js +36 -0
  40. package/LexicalCollaborationContext.esm.js +11 -0
  41. package/LexicalCollaborationContext.js +1 -1
  42. package/LexicalCollaborationContext.prod.esm.js +7 -0
  43. package/LexicalCollaborationPlugin.dev.esm.js +308 -0
  44. package/LexicalCollaborationPlugin.esm.js +10 -0
  45. package/LexicalCollaborationPlugin.js +1 -1
  46. package/LexicalCollaborationPlugin.prod.esm.js +7 -0
  47. package/LexicalComposer.dev.esm.js +129 -0
  48. package/LexicalComposer.esm.js +10 -0
  49. package/LexicalComposer.js +1 -1
  50. package/LexicalComposer.prod.esm.js +7 -0
  51. package/LexicalComposerContext.dev.esm.js +42 -0
  52. package/LexicalComposerContext.esm.js +12 -0
  53. package/LexicalComposerContext.js +1 -1
  54. package/LexicalComposerContext.prod.esm.js +7 -0
  55. package/LexicalContentEditable.dev.esm.js +107 -0
  56. package/LexicalContentEditable.dev.js +5 -1
  57. package/LexicalContentEditable.esm.js +10 -0
  58. package/LexicalContentEditable.js +1 -1
  59. package/LexicalContentEditable.prod.esm.js +7 -0
  60. package/LexicalContentEditable.prod.js +3 -3
  61. package/LexicalContextMenuPlugin.dev.esm.js +455 -0
  62. package/LexicalContextMenuPlugin.dev.js +3 -1
  63. package/LexicalContextMenuPlugin.esm.js +11 -0
  64. package/LexicalContextMenuPlugin.js +1 -1
  65. package/LexicalContextMenuPlugin.prod.esm.js +7 -0
  66. package/LexicalDecoratorBlockNode.dev.esm.js +46 -0
  67. package/LexicalDecoratorBlockNode.esm.js +11 -0
  68. package/LexicalDecoratorBlockNode.js +1 -1
  69. package/LexicalDecoratorBlockNode.prod.esm.js +7 -0
  70. package/LexicalEditorRefPlugin.dev.esm.js +40 -0
  71. package/LexicalEditorRefPlugin.dev.js +10 -5
  72. package/LexicalEditorRefPlugin.esm.js +10 -0
  73. package/LexicalEditorRefPlugin.js +1 -1
  74. package/LexicalEditorRefPlugin.prod.esm.js +7 -0
  75. package/LexicalEditorRefPlugin.prod.js +1 -1
  76. package/LexicalErrorBoundary.dev.esm.js +157 -0
  77. package/LexicalErrorBoundary.esm.js +10 -0
  78. package/LexicalErrorBoundary.js +1 -1
  79. package/LexicalErrorBoundary.prod.esm.js +7 -0
  80. package/LexicalHashtagPlugin.dev.esm.js +163 -0
  81. package/LexicalHashtagPlugin.esm.js +10 -0
  82. package/LexicalHashtagPlugin.js +1 -1
  83. package/LexicalHashtagPlugin.prod.esm.js +7 -0
  84. package/LexicalHistoryPlugin.dev.esm.js +41 -0
  85. package/LexicalHistoryPlugin.esm.js +11 -0
  86. package/LexicalHistoryPlugin.js +1 -1
  87. package/LexicalHistoryPlugin.prod.esm.js +7 -0
  88. package/LexicalHorizontalRuleNode.dev.esm.js +118 -0
  89. package/LexicalHorizontalRuleNode.dev.js +1 -0
  90. package/LexicalHorizontalRuleNode.esm.js +13 -0
  91. package/LexicalHorizontalRuleNode.js +1 -1
  92. package/LexicalHorizontalRuleNode.prod.esm.js +7 -0
  93. package/LexicalHorizontalRuleNode.prod.js +1 -1
  94. package/LexicalHorizontalRulePlugin.dev.esm.js +39 -0
  95. package/LexicalHorizontalRulePlugin.esm.js +10 -0
  96. package/LexicalHorizontalRulePlugin.js +1 -1
  97. package/LexicalHorizontalRulePlugin.prod.esm.js +7 -0
  98. package/LexicalLinkPlugin.dev.esm.js +79 -0
  99. package/LexicalLinkPlugin.dev.js +6 -2
  100. package/LexicalLinkPlugin.esm.js +10 -0
  101. package/LexicalLinkPlugin.js +1 -1
  102. package/LexicalLinkPlugin.prod.esm.js +7 -0
  103. package/LexicalLinkPlugin.prod.js +1 -1
  104. package/LexicalListPlugin.dev.esm.js +59 -0
  105. package/LexicalListPlugin.esm.js +10 -0
  106. package/LexicalListPlugin.js +1 -1
  107. package/LexicalListPlugin.prod.esm.js +7 -0
  108. package/LexicalMarkdownShortcutPlugin.dev.esm.js +49 -0
  109. package/LexicalMarkdownShortcutPlugin.esm.js +11 -0
  110. package/LexicalMarkdownShortcutPlugin.js +1 -1
  111. package/LexicalMarkdownShortcutPlugin.prod.esm.js +7 -0
  112. package/LexicalNestedComposer.dev.esm.js +105 -0
  113. package/LexicalNestedComposer.esm.js +10 -0
  114. package/LexicalNestedComposer.js +1 -1
  115. package/LexicalNestedComposer.prod.esm.js +7 -0
  116. package/LexicalNodeEventPlugin.dev.esm.js +56 -0
  117. package/LexicalNodeEventPlugin.esm.js +10 -0
  118. package/LexicalNodeEventPlugin.js +1 -1
  119. package/LexicalNodeEventPlugin.prod.esm.js +7 -0
  120. package/LexicalNodeMenuPlugin.dev.esm.js +466 -0
  121. package/LexicalNodeMenuPlugin.dev.js +3 -1
  122. package/LexicalNodeMenuPlugin.esm.js +11 -0
  123. package/LexicalNodeMenuPlugin.js +1 -1
  124. package/LexicalNodeMenuPlugin.prod.esm.js +7 -0
  125. package/LexicalOnChangePlugin.dev.esm.js +62 -0
  126. package/LexicalOnChangePlugin.esm.js +10 -0
  127. package/LexicalOnChangePlugin.js +1 -1
  128. package/LexicalOnChangePlugin.prod.esm.js +7 -0
  129. package/LexicalPlainTextPlugin.dev.esm.js +161 -0
  130. package/LexicalPlainTextPlugin.esm.js +10 -0
  131. package/LexicalPlainTextPlugin.js +1 -1
  132. package/LexicalPlainTextPlugin.prod.esm.js +7 -0
  133. package/LexicalRichTextPlugin.dev.esm.js +161 -0
  134. package/LexicalRichTextPlugin.esm.js +10 -0
  135. package/LexicalRichTextPlugin.js +1 -1
  136. package/LexicalRichTextPlugin.prod.esm.js +7 -0
  137. package/LexicalTabIndentationPlugin.dev.esm.js +76 -0
  138. package/LexicalTabIndentationPlugin.esm.js +11 -0
  139. package/LexicalTabIndentationPlugin.js +1 -1
  140. package/LexicalTabIndentationPlugin.prod.esm.js +7 -0
  141. package/LexicalTableOfContents.dev.esm.js +157 -0
  142. package/LexicalTableOfContents.esm.js +10 -0
  143. package/LexicalTableOfContents.js +1 -1
  144. package/LexicalTableOfContents.prod.esm.js +7 -0
  145. package/LexicalTablePlugin.dev.esm.js +163 -0
  146. package/LexicalTablePlugin.esm.js +10 -0
  147. package/LexicalTablePlugin.js +1 -1
  148. package/LexicalTablePlugin.prod.esm.js +7 -0
  149. package/LexicalTreeView.dev.esm.js +483 -0
  150. package/LexicalTreeView.dev.js +3 -1
  151. package/LexicalTreeView.esm.js +10 -0
  152. package/LexicalTreeView.js +1 -1
  153. package/LexicalTreeView.prod.esm.js +7 -0
  154. package/LexicalTypeaheadMenuPlugin.dev.esm.js +569 -0
  155. package/LexicalTypeaheadMenuPlugin.dev.js +3 -1
  156. package/LexicalTypeaheadMenuPlugin.esm.js +16 -0
  157. package/LexicalTypeaheadMenuPlugin.js +1 -1
  158. package/LexicalTypeaheadMenuPlugin.prod.esm.js +7 -0
  159. package/package.json +583 -20
  160. package/useLexicalEditable.dev.esm.js +82 -0
  161. package/useLexicalEditable.esm.js +10 -0
  162. package/useLexicalEditable.js +1 -1
  163. package/useLexicalEditable.prod.esm.js +7 -0
  164. package/useLexicalIsTextContentEmpty.dev.esm.js +51 -0
  165. package/useLexicalIsTextContentEmpty.esm.js +10 -0
  166. package/useLexicalIsTextContentEmpty.js +1 -1
  167. package/useLexicalIsTextContentEmpty.prod.esm.js +7 -0
  168. package/useLexicalNodeSelection.dev.esm.js +69 -0
  169. package/useLexicalNodeSelection.esm.js +10 -0
  170. package/useLexicalNodeSelection.js +1 -1
  171. package/useLexicalNodeSelection.prod.esm.js +7 -0
  172. package/useLexicalSubscription.dev.esm.js +63 -0
  173. package/useLexicalSubscription.esm.js +10 -0
  174. package/useLexicalSubscription.js +1 -1
  175. package/useLexicalSubscription.prod.esm.js +7 -0
  176. package/useLexicalTextEntity.dev.esm.js +26 -0
  177. package/useLexicalTextEntity.esm.js +10 -0
  178. package/useLexicalTextEntity.js +1 -1
  179. package/useLexicalTextEntity.prod.esm.js +7 -0
@@ -0,0 +1,157 @@
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
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
8
+ import { $isHeadingNode, HeadingNode } from '@lexical/rich-text';
9
+ import { $getRoot, $getNodeByKey, TextNode } from 'lexical';
10
+ import { useState, useEffect } from 'react';
11
+
12
+ /**
13
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ *
18
+ */
19
+ function toEntry(heading) {
20
+ return [heading.getKey(), heading.getTextContent(), heading.getTag()];
21
+ }
22
+ function $insertHeadingIntoTableOfContents(prevHeading, newHeading, currentTableOfContents) {
23
+ if (newHeading === null) {
24
+ return currentTableOfContents;
25
+ }
26
+ const newEntry = toEntry(newHeading);
27
+ let newTableOfContents = [];
28
+ if (prevHeading === null) {
29
+ newTableOfContents = [newEntry, ...currentTableOfContents];
30
+ } else {
31
+ for (let i = 0; i < currentTableOfContents.length; i++) {
32
+ const key = currentTableOfContents[i][0];
33
+ newTableOfContents.push(currentTableOfContents[i]);
34
+ if (key === prevHeading.getKey() && key !== newHeading.getKey()) {
35
+ newTableOfContents.push(newEntry);
36
+ }
37
+ }
38
+ }
39
+ return newTableOfContents;
40
+ }
41
+ function $deleteHeadingFromTableOfContents(key, currentTableOfContents) {
42
+ const newTableOfContents = [];
43
+ for (const heading of currentTableOfContents) {
44
+ if (heading[0] !== key) {
45
+ newTableOfContents.push(heading);
46
+ }
47
+ }
48
+ return newTableOfContents;
49
+ }
50
+ function $updateHeadingInTableOfContents(heading, currentTableOfContents) {
51
+ const newTableOfContents = [];
52
+ for (const oldHeading of currentTableOfContents) {
53
+ if (oldHeading[0] === heading.getKey()) {
54
+ newTableOfContents.push(toEntry(heading));
55
+ } else {
56
+ newTableOfContents.push(oldHeading);
57
+ }
58
+ }
59
+ return newTableOfContents;
60
+ }
61
+
62
+ /**
63
+ * Returns the updated table of contents, placing the given `heading` before the given `prevHeading`. If `prevHeading`
64
+ * is undefined, `heading` is placed at the start of table of contents
65
+ */
66
+ function $updateHeadingPosition(prevHeading, heading, currentTableOfContents) {
67
+ const newTableOfContents = [];
68
+ const newEntry = toEntry(heading);
69
+ if (!prevHeading) {
70
+ newTableOfContents.push(newEntry);
71
+ }
72
+ for (const oldHeading of currentTableOfContents) {
73
+ if (oldHeading[0] === heading.getKey()) {
74
+ continue;
75
+ }
76
+ newTableOfContents.push(oldHeading);
77
+ if (prevHeading && oldHeading[0] === prevHeading.getKey()) {
78
+ newTableOfContents.push(newEntry);
79
+ }
80
+ }
81
+ return newTableOfContents;
82
+ }
83
+ function LexicalTableOfContentsPlugin({
84
+ children
85
+ }) {
86
+ const [tableOfContents, setTableOfContents] = useState([]);
87
+ const [editor] = useLexicalComposerContext();
88
+ useEffect(() => {
89
+ // Set table of contents initial state
90
+ let currentTableOfContents = [];
91
+ editor.getEditorState().read(() => {
92
+ const root = $getRoot();
93
+ const rootChildren = root.getChildren();
94
+ for (const child of rootChildren) {
95
+ if ($isHeadingNode(child)) {
96
+ currentTableOfContents.push([child.getKey(), child.getTextContent(), child.getTag()]);
97
+ }
98
+ }
99
+ setTableOfContents(currentTableOfContents);
100
+ });
101
+
102
+ // Listen to updates to heading mutations and update state
103
+ const removeHeaderMutationListener = editor.registerMutationListener(HeadingNode, mutatedNodes => {
104
+ editor.getEditorState().read(() => {
105
+ for (const [nodeKey, mutation] of mutatedNodes) {
106
+ if (mutation === 'created') {
107
+ const newHeading = $getNodeByKey(nodeKey);
108
+ if (newHeading !== null) {
109
+ let prevHeading = newHeading.getPreviousSibling();
110
+ while (prevHeading !== null && !$isHeadingNode(prevHeading)) {
111
+ prevHeading = prevHeading.getPreviousSibling();
112
+ }
113
+ currentTableOfContents = $insertHeadingIntoTableOfContents(prevHeading, newHeading, currentTableOfContents);
114
+ }
115
+ } else if (mutation === 'destroyed') {
116
+ currentTableOfContents = $deleteHeadingFromTableOfContents(nodeKey, currentTableOfContents);
117
+ } else if (mutation === 'updated') {
118
+ const newHeading = $getNodeByKey(nodeKey);
119
+ if (newHeading !== null) {
120
+ let prevHeading = newHeading.getPreviousSibling();
121
+ while (prevHeading !== null && !$isHeadingNode(prevHeading)) {
122
+ prevHeading = prevHeading.getPreviousSibling();
123
+ }
124
+ currentTableOfContents = $updateHeadingPosition(prevHeading, newHeading, currentTableOfContents);
125
+ }
126
+ }
127
+ }
128
+ setTableOfContents(currentTableOfContents);
129
+ });
130
+ });
131
+
132
+ // Listen to text node mutation updates
133
+ const removeTextNodeMutationListener = editor.registerMutationListener(TextNode, mutatedNodes => {
134
+ editor.getEditorState().read(() => {
135
+ for (const [nodeKey, mutation] of mutatedNodes) {
136
+ if (mutation === 'updated') {
137
+ const currNode = $getNodeByKey(nodeKey);
138
+ if (currNode !== null) {
139
+ const parentNode = currNode.getParentOrThrow();
140
+ if ($isHeadingNode(parentNode)) {
141
+ currentTableOfContents = $updateHeadingInTableOfContents(parentNode, currentTableOfContents);
142
+ setTableOfContents(currentTableOfContents);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ });
148
+ });
149
+ return () => {
150
+ removeHeaderMutationListener();
151
+ removeTextNodeMutationListener();
152
+ };
153
+ }, [editor]);
154
+ return children(tableOfContents, editor);
155
+ }
156
+
157
+ export { LexicalTableOfContentsPlugin as default };
@@ -0,0 +1,10 @@
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
+ import * as modDev from './LexicalTableOfContents.dev.esm.js';
8
+ import * as modProd from './LexicalTableOfContents.prod.esm.js';
9
+ const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
10
+ export default mod.default;
@@ -5,5 +5,5 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  'use strict'
8
- const LexicalTableOfContents = process.env.NODE_ENV === 'development' ? require('./LexicalTableOfContents.dev.js') : require('./LexicalTableOfContents.prod.js')
8
+ const LexicalTableOfContents = process.env.NODE_ENV === 'development' ? require('./LexicalTableOfContents.dev.js') : require('./LexicalTableOfContents.prod.js');
9
9
  module.exports = LexicalTableOfContents;
@@ -0,0 +1,7 @@
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
+ import{useLexicalComposerContext as t}from"@lexical/react/LexicalComposerContext";import{$isHeadingNode as e,HeadingNode as o}from"@lexical/rich-text";import{$getRoot as n,$getNodeByKey as r,TextNode as i}from"lexical";import{useState as s,useEffect as u}from"react";function l(t){return[t.getKey(),t.getTextContent(),t.getTag()]}function f(t,e,o){if(null===e)return o;const n=l(e);let r=[];if(null===t)r=[n,...o];else for(let i=0;i<o.length;i++){const s=o[i][0];r.push(o[i]),s===t.getKey()&&s!==e.getKey()&&r.push(n)}return r}function c(t,e){const o=[];for(const n of e)n[0]!==t&&o.push(n);return o}function g(t,e){const o=[];for(const n of e)n[0]===t.getKey()?o.push(l(t)):o.push(n);return o}function a(t,e,o){const n=[],r=l(e);t||n.push(r);for(const i of o)i[0]!==e.getKey()&&(n.push(i),t&&i[0]===t.getKey()&&n.push(r));return n}function p({children:l}){const[p,d]=s([]),[h]=t();return u((()=>{let t=[];h.getEditorState().read((()=>{const o=n().getChildren();for(const n of o)e(n)&&t.push([n.getKey(),n.getTextContent(),n.getTag()]);d(t)}));const s=h.registerMutationListener(o,(o=>{h.getEditorState().read((()=>{for(const[n,i]of o)if("created"===i){const o=r(n);if(null!==o){let n=o.getPreviousSibling();for(;null!==n&&!e(n);)n=n.getPreviousSibling();t=f(n,o,t)}}else if("destroyed"===i)t=c(n,t);else if("updated"===i){const o=r(n);if(null!==o){let n=o.getPreviousSibling();for(;null!==n&&!e(n);)n=n.getPreviousSibling();t=a(n,o,t)}}d(t)}))})),u=h.registerMutationListener(i,(o=>{h.getEditorState().read((()=>{for(const[n,i]of o)if("updated"===i){const o=r(n);if(null!==o){const n=o.getParentOrThrow();e(n)&&(t=g(n,t),d(t))}}}))}));return()=>{s(),u()}}),[h]),l(p,h)}export{p as default};
@@ -0,0 +1,163 @@
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
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
8
+ import { TableNode, TableCellNode, TableRowNode, INSERT_TABLE_COMMAND, $createTableNodeWithDimensions, $isTableNode, $getNodeTriplet, $computeTableMap, $isTableRowNode, $isTableCellNode, $createTableCellNode, applyTableHandlers } from '@lexical/table';
9
+ import { $insertNodeToNearestRoot, $insertFirst } from '@lexical/utils';
10
+ import { $isTextNode, COMMAND_PRIORITY_EDITOR, $nodesOfType, $getNodeByKey } from 'lexical';
11
+ import { useEffect } from 'react';
12
+
13
+ /**
14
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
15
+ *
16
+ * This source code is licensed under the MIT license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ *
19
+ */
20
+ function TablePlugin({
21
+ hasCellMerge = true,
22
+ hasCellBackgroundColor = true,
23
+ hasTabHandler = true
24
+ }) {
25
+ const [editor] = useLexicalComposerContext();
26
+ useEffect(() => {
27
+ if (!editor.hasNodes([TableNode, TableCellNode, TableRowNode])) {
28
+ {
29
+ throw Error(`TablePlugin: TableNode, TableCellNode or TableRowNode not registered on editor`);
30
+ }
31
+ }
32
+ return editor.registerCommand(INSERT_TABLE_COMMAND, ({
33
+ columns,
34
+ rows,
35
+ includeHeaders
36
+ }) => {
37
+ const tableNode = $createTableNodeWithDimensions(Number(rows), Number(columns), includeHeaders);
38
+ $insertNodeToNearestRoot(tableNode);
39
+ const firstDescendant = tableNode.getFirstDescendant();
40
+ if ($isTextNode(firstDescendant)) {
41
+ firstDescendant.select();
42
+ }
43
+ return true;
44
+ }, COMMAND_PRIORITY_EDITOR);
45
+ }, [editor]);
46
+ useEffect(() => {
47
+ const tableSelections = new Map();
48
+ const initializeTableNode = tableNode => {
49
+ const nodeKey = tableNode.getKey();
50
+ const tableElement = editor.getElementByKey(nodeKey);
51
+ if (tableElement && !tableSelections.has(nodeKey)) {
52
+ const tableSelection = applyTableHandlers(tableNode, tableElement, editor, hasTabHandler);
53
+ tableSelections.set(nodeKey, tableSelection);
54
+ }
55
+ };
56
+
57
+ // Plugins might be loaded _after_ initial content is set, hence existing table nodes
58
+ // won't be initialized from mutation[create] listener. Instead doing it here,
59
+ editor.getEditorState().read(() => {
60
+ const tableNodes = $nodesOfType(TableNode);
61
+ for (const tableNode of tableNodes) {
62
+ if ($isTableNode(tableNode)) {
63
+ initializeTableNode(tableNode);
64
+ }
65
+ }
66
+ });
67
+ const unregisterMutationListener = editor.registerMutationListener(TableNode, nodeMutations => {
68
+ for (const [nodeKey, mutation] of nodeMutations) {
69
+ if (mutation === 'created') {
70
+ editor.getEditorState().read(() => {
71
+ const tableNode = $getNodeByKey(nodeKey);
72
+ if ($isTableNode(tableNode)) {
73
+ initializeTableNode(tableNode);
74
+ }
75
+ });
76
+ } else if (mutation === 'destroyed') {
77
+ const tableSelection = tableSelections.get(nodeKey);
78
+ if (tableSelection !== undefined) {
79
+ tableSelection.removeListeners();
80
+ tableSelections.delete(nodeKey);
81
+ }
82
+ }
83
+ }
84
+ });
85
+ return () => {
86
+ unregisterMutationListener();
87
+ // Hook might be called multiple times so cleaning up tables listeners as well,
88
+ // as it'll be reinitialized during recurring call
89
+ for (const [, tableSelection] of tableSelections) {
90
+ tableSelection.removeListeners();
91
+ }
92
+ };
93
+ }, [editor, hasTabHandler]);
94
+
95
+ // Unmerge cells when the feature isn't enabled
96
+ useEffect(() => {
97
+ if (hasCellMerge) {
98
+ return;
99
+ }
100
+ return editor.registerNodeTransform(TableCellNode, node => {
101
+ if (node.getColSpan() > 1 || node.getRowSpan() > 1) {
102
+ // When we have rowSpan we have to map the entire Table to understand where the new Cells
103
+ // fit best; let's analyze all Cells at once to save us from further transform iterations
104
+ const [,, gridNode] = $getNodeTriplet(node);
105
+ const [gridMap] = $computeTableMap(gridNode, node, node);
106
+ // TODO this function expects Tables to be normalized. Look into this once it exists
107
+ const rowsCount = gridMap.length;
108
+ const columnsCount = gridMap[0].length;
109
+ let row = gridNode.getFirstChild();
110
+ if (!$isTableRowNode(row)) {
111
+ throw Error(`Expected TableNode first child to be a RowNode`);
112
+ }
113
+ const unmerged = [];
114
+ for (let i = 0; i < rowsCount; i++) {
115
+ if (i !== 0) {
116
+ row = row.getNextSibling();
117
+ if (!$isTableRowNode(row)) {
118
+ throw Error(`Expected TableNode first child to be a RowNode`);
119
+ }
120
+ }
121
+ let lastRowCell = null;
122
+ for (let j = 0; j < columnsCount; j++) {
123
+ const cellMap = gridMap[i][j];
124
+ const cell = cellMap.cell;
125
+ if (cellMap.startRow === i && cellMap.startColumn === j) {
126
+ lastRowCell = cell;
127
+ unmerged.push(cell);
128
+ } else if (cell.getColSpan() > 1 || cell.getRowSpan() > 1) {
129
+ if (!$isTableCellNode(cell)) {
130
+ throw Error(`Expected TableNode cell to be a TableCellNode`);
131
+ }
132
+ const newCell = $createTableCellNode(cell.__headerState);
133
+ if (lastRowCell !== null) {
134
+ lastRowCell.insertAfter(newCell);
135
+ } else {
136
+ $insertFirst(row, newCell);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ for (const cell of unmerged) {
142
+ cell.setColSpan(1);
143
+ cell.setRowSpan(1);
144
+ }
145
+ }
146
+ });
147
+ }, [editor, hasCellMerge]);
148
+
149
+ // Remove cell background color when feature is disabled
150
+ useEffect(() => {
151
+ if (hasCellBackgroundColor) {
152
+ return;
153
+ }
154
+ return editor.registerNodeTransform(TableCellNode, node => {
155
+ if (node.getBackgroundColor() !== null) {
156
+ node.setBackgroundColor(null);
157
+ }
158
+ });
159
+ }, [editor, hasCellBackgroundColor, hasCellMerge]);
160
+ return null;
161
+ }
162
+
163
+ export { TablePlugin };
@@ -0,0 +1,10 @@
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
+ import * as modDev from './LexicalTablePlugin.dev.esm.js';
8
+ import * as modProd from './LexicalTablePlugin.prod.esm.js';
9
+ const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
10
+ export const TablePlugin = mod.TablePlugin;
@@ -5,5 +5,5 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  'use strict'
8
- const LexicalTablePlugin = process.env.NODE_ENV === 'development' ? require('./LexicalTablePlugin.dev.js') : require('./LexicalTablePlugin.prod.js')
8
+ const LexicalTablePlugin = process.env.NODE_ENV === 'development' ? require('./LexicalTablePlugin.dev.js') : require('./LexicalTablePlugin.prod.js');
9
9
  module.exports = LexicalTablePlugin;
@@ -0,0 +1,7 @@
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
+ import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{TableNode as t,TableCellNode as o,TableRowNode as r,INSERT_TABLE_COMMAND as n,$createTableNodeWithDimensions as l,$isTableNode as s,$getNodeTriplet as a,$computeTableMap as i,$isTableRowNode as c,$isTableCellNode as d,$createTableCellNode as f,applyTableHandlers as g}from"@lexical/table";import{$insertNodeToNearestRoot as u,$insertFirst as m}from"@lexical/utils";import{$isTextNode as p,COMMAND_PRIORITY_EDITOR as h,$nodesOfType as w,$getNodeByKey as C}from"lexical";import{useEffect as x}from"react";var b=function(e){const t=new URLSearchParams;t.append("code",e);for(let e=1;e<arguments.length;e++)t.append("v",arguments[e]);throw Error(`Minified Lexical error #${e}; visit https://lexical.dev/docs/error?${t} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)};function N({hasCellMerge:N=!0,hasCellBackgroundColor:S=!0,hasTabHandler:E=!0}){const[v]=e();return x((()=>(v.hasNodes([t,o,r])||b(10),v.registerCommand(n,(({columns:e,rows:t,includeHeaders:o})=>{const r=l(Number(t),Number(e),o);u(r);const n=r.getFirstDescendant();return p(n)&&n.select(),!0}),h))),[v]),x((()=>{const e=new Map,o=t=>{const o=t.getKey(),r=v.getElementByKey(o);if(r&&!e.has(o)){const n=g(t,r,v,E);e.set(o,n)}};v.getEditorState().read((()=>{const e=w(t);for(const t of e)s(t)&&o(t)}));const r=v.registerMutationListener(t,(t=>{for(const[r,n]of t)if("created"===n)v.getEditorState().read((()=>{const e=C(r);s(e)&&o(e)}));else if("destroyed"===n){const t=e.get(r);void 0!==t&&(t.removeListeners(),e.delete(r))}}));return()=>{r();for(const[,t]of e)t.removeListeners()}}),[v,E]),x((()=>{if(!N)return v.registerNodeTransform(o,(e=>{if(e.getColSpan()>1||e.getRowSpan()>1){const[,,t]=a(e),[o]=i(t,e,e),r=o.length,n=o[0].length;let l=t.getFirstChild();if(!c(l))throw Error("Expected TableNode first child to be a RowNode");const s=[];for(let e=0;e<r;e++){if(0!==e&&(l=l.getNextSibling(),!c(l)))throw Error("Expected TableNode first child to be a RowNode");let t=null;for(let r=0;r<n;r++){const n=o[e][r],a=n.cell;if(n.startRow===e&&n.startColumn===r)t=a,s.push(a);else if(a.getColSpan()>1||a.getRowSpan()>1){if(!d(a))throw Error("Expected TableNode cell to be a TableCellNode");const e=f(a.__headerState);null!==t?t.insertAfter(e):m(l,e)}}}for(const e of s)e.setColSpan(1),e.setRowSpan(1)}}))}),[v,N]),x((()=>{if(!S)return v.registerNodeTransform(o,(e=>{null!==e.getBackgroundColor()&&e.setBackgroundColor(null)}))}),[v,S,N]),null}export{N as TablePlugin};