@lexical/react 0.45.1-nightly.20260618.0 → 0.45.1-nightly.20260622.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/dist/LexicalAutoEmbedPlugin.d.ts +25 -0
  2. package/dist/LexicalAutoEmbedPlugin.dev.js +19 -4
  3. package/dist/LexicalAutoEmbedPlugin.dev.mjs +19 -4
  4. package/dist/LexicalAutoEmbedPlugin.prod.js +1 -1
  5. package/dist/LexicalAutoEmbedPlugin.prod.mjs +1 -1
  6. package/dist/LexicalAutoFocusPlugin.d.ts +10 -0
  7. package/dist/LexicalAutoFocusPlugin.dev.js +14 -1
  8. package/dist/LexicalAutoFocusPlugin.dev.mjs +14 -1
  9. package/dist/LexicalAutoFocusPlugin.prod.js +1 -1
  10. package/dist/LexicalAutoFocusPlugin.prod.mjs +1 -1
  11. package/dist/LexicalAutoLinkPlugin.d.ts +13 -0
  12. package/dist/LexicalAutoLinkPlugin.dev.js +14 -0
  13. package/dist/LexicalAutoLinkPlugin.dev.mjs +14 -0
  14. package/dist/LexicalBlockWithAlignableContents.d.ts +9 -0
  15. package/dist/LexicalBlockWithAlignableContents.dev.js +11 -2
  16. package/dist/LexicalBlockWithAlignableContents.dev.mjs +12 -3
  17. package/dist/LexicalBlockWithAlignableContents.prod.js +1 -1
  18. package/dist/LexicalBlockWithAlignableContents.prod.mjs +1 -1
  19. package/dist/LexicalCharacterLimitPlugin.d.ts +10 -0
  20. package/dist/LexicalCharacterLimitPlugin.dev.js +14 -5
  21. package/dist/LexicalCharacterLimitPlugin.dev.mjs +14 -5
  22. package/dist/LexicalCharacterLimitPlugin.prod.js +2 -2
  23. package/dist/LexicalCharacterLimitPlugin.prod.mjs +2 -2
  24. package/dist/LexicalCheckListPlugin.d.ts +11 -0
  25. package/dist/LexicalCheckListPlugin.dev.js +12 -0
  26. package/dist/LexicalCheckListPlugin.dev.mjs +12 -0
  27. package/dist/LexicalClearEditorPlugin.d.ts +10 -0
  28. package/dist/LexicalClearEditorPlugin.dev.js +10 -0
  29. package/dist/LexicalClearEditorPlugin.dev.mjs +10 -0
  30. package/dist/LexicalClickableLinkPlugin.d.ts +10 -0
  31. package/dist/LexicalClickableLinkPlugin.dev.js +11 -0
  32. package/dist/LexicalClickableLinkPlugin.dev.mjs +11 -0
  33. package/dist/LexicalCollaborationContext.d.ts +25 -0
  34. package/dist/LexicalCollaborationContext.dev.js +23 -0
  35. package/dist/LexicalCollaborationContext.dev.mjs +23 -0
  36. package/dist/LexicalCollaborationPlugin.d.ts +18 -0
  37. package/dist/LexicalCollaborationPlugin.dev.js +26 -5
  38. package/dist/LexicalCollaborationPlugin.dev.mjs +24 -3
  39. package/dist/LexicalCollaborationPlugin.prod.js +1 -1
  40. package/dist/LexicalCollaborationPlugin.prod.mjs +1 -1
  41. package/dist/LexicalComposer.d.ts +22 -0
  42. package/dist/LexicalComposer.dev.js +28 -2
  43. package/dist/LexicalComposer.dev.mjs +29 -3
  44. package/dist/LexicalComposer.prod.js +1 -1
  45. package/dist/LexicalComposer.prod.mjs +1 -1
  46. package/dist/LexicalComposerContext.d.ts +35 -0
  47. package/dist/LexicalComposerContext.dev.js +39 -0
  48. package/dist/LexicalComposerContext.dev.mjs +39 -0
  49. package/dist/LexicalContentEditable.d.ts +13 -0
  50. package/dist/LexicalContentEditable.dev.js +26 -3
  51. package/dist/LexicalContentEditable.dev.mjs +26 -3
  52. package/dist/LexicalContentEditable.prod.js +2 -2
  53. package/dist/LexicalContentEditable.prod.mjs +2 -2
  54. package/dist/LexicalDecoratorBlockNode.d.ts +14 -0
  55. package/dist/LexicalDecoratorBlockNode.dev.js +17 -0
  56. package/dist/LexicalDecoratorBlockNode.dev.mjs +17 -0
  57. package/dist/LexicalDraggableBlockPlugin.d.ts +10 -0
  58. package/dist/LexicalDraggableBlockPlugin.dev.js +38 -20
  59. package/dist/LexicalDraggableBlockPlugin.dev.mjs +33 -15
  60. package/dist/LexicalDraggableBlockPlugin.prod.js +1 -1
  61. package/dist/LexicalDraggableBlockPlugin.prod.mjs +1 -1
  62. package/dist/LexicalErrorBoundary.d.ts +16 -2
  63. package/dist/LexicalErrorBoundary.dev.js +38 -10
  64. package/dist/LexicalErrorBoundary.dev.mjs +38 -10
  65. package/dist/LexicalErrorBoundary.js.flow +1 -0
  66. package/dist/LexicalErrorBoundary.prod.js +2 -2
  67. package/dist/LexicalErrorBoundary.prod.mjs +2 -2
  68. package/dist/LexicalExtensionComposer.d.ts +3 -0
  69. package/dist/LexicalExtensionEditorComposer.d.ts +3 -0
  70. package/dist/LexicalHashtagPlugin.d.ts +10 -0
  71. package/dist/LexicalHashtagPlugin.dev.js +11 -0
  72. package/dist/LexicalHashtagPlugin.dev.mjs +11 -0
  73. package/dist/LexicalHistoryPlugin.d.ts +11 -0
  74. package/dist/LexicalHistoryPlugin.dev.js +11 -0
  75. package/dist/LexicalHistoryPlugin.dev.mjs +11 -0
  76. package/dist/LexicalHorizontalRuleNode.dev.js +4 -5
  77. package/dist/LexicalHorizontalRuleNode.dev.mjs +2 -3
  78. package/dist/LexicalHorizontalRuleNode.prod.js +2 -2
  79. package/dist/LexicalHorizontalRuleNode.prod.mjs +2 -2
  80. package/dist/LexicalHorizontalRulePlugin.d.ts +5 -1
  81. package/dist/LexicalHorizontalRulePlugin.dev.js +5 -1
  82. package/dist/LexicalHorizontalRulePlugin.dev.mjs +5 -1
  83. package/dist/LexicalLinkPlugin.d.ts +12 -0
  84. package/dist/LexicalLinkPlugin.dev.js +12 -0
  85. package/dist/LexicalLinkPlugin.dev.mjs +12 -0
  86. package/dist/LexicalListPlugin.d.ts +13 -0
  87. package/dist/LexicalListPlugin.dev.js +15 -0
  88. package/dist/LexicalListPlugin.dev.mjs +15 -0
  89. package/dist/LexicalMarkdownShortcutPlugin.d.ts +13 -0
  90. package/dist/LexicalMarkdownShortcutPlugin.dev.js +14 -0
  91. package/dist/LexicalMarkdownShortcutPlugin.dev.mjs +14 -0
  92. package/dist/LexicalNestedComposer.d.ts +17 -0
  93. package/dist/LexicalNestedComposer.dev.js +15 -0
  94. package/dist/LexicalNestedComposer.dev.mjs +15 -0
  95. package/dist/LexicalNodeContextMenuPlugin.d.ts +21 -0
  96. package/dist/LexicalNodeContextMenuPlugin.dev.js +23 -0
  97. package/dist/LexicalNodeContextMenuPlugin.dev.mjs +23 -0
  98. package/dist/LexicalNodeEventPlugin.d.ts +8 -0
  99. package/dist/LexicalNodeEventPlugin.dev.js +10 -2
  100. package/dist/LexicalNodeEventPlugin.dev.mjs +10 -2
  101. package/dist/LexicalNodeEventPlugin.prod.js +1 -1
  102. package/dist/LexicalNodeEventPlugin.prod.mjs +1 -1
  103. package/dist/LexicalNodeMenuPlugin.d.ts +12 -0
  104. package/dist/LexicalNodeMenuPlugin.dev.js +123 -30
  105. package/dist/LexicalNodeMenuPlugin.dev.mjs +122 -29
  106. package/dist/LexicalNodeMenuPlugin.prod.js +1 -1
  107. package/dist/LexicalNodeMenuPlugin.prod.mjs +1 -1
  108. package/dist/LexicalOnChangePlugin.d.ts +8 -0
  109. package/dist/LexicalOnChangePlugin.dev.js +9 -0
  110. package/dist/LexicalOnChangePlugin.dev.mjs +9 -0
  111. package/dist/LexicalPlainTextPlugin.d.ts +12 -0
  112. package/dist/LexicalPlainTextPlugin.dev.js +3 -4
  113. package/dist/LexicalPlainTextPlugin.dev.mjs +2 -3
  114. package/dist/LexicalPlainTextPlugin.prod.js +1 -1
  115. package/dist/LexicalPlainTextPlugin.prod.mjs +1 -1
  116. package/dist/LexicalReactPluginHostExtension.dev.js +45 -2
  117. package/dist/LexicalReactPluginHostExtension.dev.mjs +45 -2
  118. package/dist/LexicalReactPluginHostExtension.prod.js +1 -1
  119. package/dist/LexicalReactPluginHostExtension.prod.mjs +1 -1
  120. package/dist/LexicalRichTextPlugin.d.ts +12 -0
  121. package/dist/LexicalRichTextPlugin.dev.js +3 -4
  122. package/dist/LexicalRichTextPlugin.dev.mjs +2 -3
  123. package/dist/LexicalRichTextPlugin.prod.js +1 -1
  124. package/dist/LexicalRichTextPlugin.prod.mjs +1 -1
  125. package/dist/LexicalSelectionAlwaysOnDisplay.d.ts +11 -0
  126. package/dist/LexicalSelectionAlwaysOnDisplay.dev.js +11 -0
  127. package/dist/LexicalSelectionAlwaysOnDisplay.dev.mjs +11 -0
  128. package/dist/LexicalTabIndentationPlugin.d.ts +3 -0
  129. package/dist/LexicalTabIndentationPlugin.dev.js +3 -0
  130. package/dist/LexicalTabIndentationPlugin.dev.mjs +3 -0
  131. package/dist/LexicalTableOfContentsPlugin.d.ts +13 -0
  132. package/dist/LexicalTableOfContentsPlugin.dev.js +18 -3
  133. package/dist/LexicalTableOfContentsPlugin.dev.mjs +18 -3
  134. package/dist/LexicalTableOfContentsPlugin.prod.js +1 -1
  135. package/dist/LexicalTableOfContentsPlugin.prod.mjs +1 -1
  136. package/dist/LexicalTablePlugin.d.ts +6 -0
  137. package/dist/LexicalTablePlugin.dev.js +8 -0
  138. package/dist/LexicalTablePlugin.dev.mjs +8 -0
  139. package/dist/LexicalTreeView.d.ts +4 -0
  140. package/dist/LexicalTreeView.dev.js +2 -2
  141. package/dist/LexicalTreeView.dev.mjs +1 -1
  142. package/dist/LexicalTreeView.prod.js +1 -1
  143. package/dist/LexicalTreeView.prod.mjs +1 -1
  144. package/dist/LexicalTreeViewExtension.dev.js +7 -0
  145. package/dist/LexicalTreeViewExtension.dev.mjs +7 -0
  146. package/dist/LexicalTypeaheadMenuPlugin.d.ts +32 -1
  147. package/dist/LexicalTypeaheadMenuPlugin.dev.js +152 -57
  148. package/dist/LexicalTypeaheadMenuPlugin.dev.mjs +151 -56
  149. package/dist/LexicalTypeaheadMenuPlugin.prod.js +1 -1
  150. package/dist/LexicalTypeaheadMenuPlugin.prod.mjs +1 -1
  151. package/dist/ReactPluginHostExtension.d.ts +50 -0
  152. package/dist/TreeViewExtension.d.ts +12 -0
  153. package/dist/shared/LexicalContentEditableElement.d.ts +16 -0
  154. package/dist/shared/LexicalMenu.d.ts +37 -2
  155. package/dist/shared/getScrollParent.d.ts +19 -0
  156. package/dist/shared/types.d.ts +21 -0
  157. package/dist/useExtensionComponent.d.ts +22 -0
  158. package/dist/useLexicalEditable.dev.js +7 -0
  159. package/dist/useLexicalEditable.dev.mjs +7 -0
  160. package/dist/useLexicalExtensionComponent.dev.js +24 -0
  161. package/dist/useLexicalExtensionComponent.dev.mjs +24 -0
  162. package/dist/useLexicalIsTextContentEmpty.d.ts +7 -0
  163. package/dist/useLexicalIsTextContentEmpty.dev.js +9 -1
  164. package/dist/useLexicalIsTextContentEmpty.dev.mjs +9 -1
  165. package/dist/useLexicalIsTextContentEmpty.prod.js +1 -1
  166. package/dist/useLexicalIsTextContentEmpty.prod.mjs +1 -1
  167. package/dist/useLexicalNodeSelection.dev.js +1 -1
  168. package/dist/useLexicalNodeSelection.dev.mjs +1 -1
  169. package/dist/useLexicalNodeSelection.prod.js +1 -1
  170. package/dist/useLexicalNodeSelection.prod.mjs +1 -1
  171. package/dist/useLexicalSubscription.d.ts +5 -0
  172. package/dist/useLexicalSubscription.dev.js +7 -0
  173. package/dist/useLexicalSubscription.dev.mjs +7 -0
  174. package/dist/useLexicalTextEntity.d.ts +7 -0
  175. package/dist/useLexicalTextEntity.dev.js +10 -2
  176. package/dist/useLexicalTextEntity.dev.mjs +9 -1
  177. package/dist/useLexicalTextEntity.prod.js +1 -1
  178. package/dist/useLexicalTextEntity.prod.mjs +1 -1
  179. package/package.json +19 -20
  180. package/src/LexicalAutoEmbedPlugin.tsx +28 -3
  181. package/src/LexicalAutoFocusPlugin.ts +15 -1
  182. package/src/LexicalAutoLinkPlugin.ts +13 -0
  183. package/src/LexicalBlockWithAlignableContents.tsx +13 -5
  184. package/src/LexicalCharacterLimitPlugin.tsx +10 -0
  185. package/src/LexicalCheckListPlugin.tsx +11 -0
  186. package/src/LexicalClearEditorPlugin.ts +10 -0
  187. package/src/LexicalClickableLinkPlugin.tsx +10 -0
  188. package/src/LexicalCollaborationContext.tsx +25 -0
  189. package/src/LexicalCollaborationPlugin.tsx +18 -0
  190. package/src/LexicalComposer.tsx +31 -2
  191. package/src/LexicalComposerContext.ts +35 -0
  192. package/src/LexicalContentEditable.tsx +13 -0
  193. package/src/LexicalDecoratorBlockNode.ts +14 -0
  194. package/src/LexicalDraggableBlockPlugin.tsx +44 -14
  195. package/src/LexicalErrorBoundary.tsx +59 -20
  196. package/src/LexicalExtensionComposer.tsx +3 -0
  197. package/src/LexicalExtensionEditorComposer.tsx +3 -0
  198. package/src/LexicalHashtagPlugin.ts +10 -0
  199. package/src/LexicalHistoryPlugin.ts +11 -0
  200. package/src/LexicalHorizontalRuleNode.tsx +5 -6
  201. package/src/LexicalHorizontalRulePlugin.ts +5 -1
  202. package/src/LexicalLinkPlugin.ts +12 -0
  203. package/src/LexicalListPlugin.ts +13 -0
  204. package/src/LexicalMarkdownShortcutPlugin.tsx +13 -0
  205. package/src/LexicalNestedComposer.tsx +17 -0
  206. package/src/LexicalNodeContextMenuPlugin.tsx +21 -0
  207. package/src/LexicalNodeEventPlugin.ts +9 -2
  208. package/src/LexicalNodeMenuPlugin.tsx +12 -0
  209. package/src/LexicalOnChangePlugin.ts +8 -0
  210. package/src/LexicalPlainTextPlugin.tsx +12 -0
  211. package/src/LexicalRichTextPlugin.tsx +12 -0
  212. package/src/LexicalSelectionAlwaysOnDisplay.tsx +11 -0
  213. package/src/LexicalTabIndentationPlugin.tsx +3 -0
  214. package/src/LexicalTableOfContentsPlugin.tsx +16 -3
  215. package/src/LexicalTablePlugin.ts +6 -0
  216. package/src/LexicalTreeView.tsx +5 -1
  217. package/src/LexicalTypeaheadMenuPlugin.tsx +41 -35
  218. package/src/ReactPluginHostExtension.tsx +51 -1
  219. package/src/TreeViewExtension.tsx +12 -0
  220. package/src/shared/LexicalContentEditableElement.tsx +16 -0
  221. package/src/shared/LexicalMenu.tsx +86 -38
  222. package/src/shared/getScrollParent.ts +54 -0
  223. package/src/shared/types.ts +21 -0
  224. package/src/shared/useCanShowPlaceholder.ts +5 -4
  225. package/src/shared/useCharacterLimit.ts +3 -6
  226. package/src/shared/usePlainTextSetup.ts +1 -1
  227. package/src/shared/useRichTextSetup.ts +1 -1
  228. package/src/shared/useYjsCollaboration.tsx +6 -2
  229. package/src/useExtensionComponent.tsx +22 -0
  230. package/src/useLexicalIsTextContentEmpty.ts +11 -3
  231. package/src/useLexicalNodeSelection.ts +1 -1
  232. package/src/useLexicalSubscription.tsx +5 -0
  233. package/src/useLexicalTextEntity.ts +8 -1
@@ -9,18 +9,43 @@ import type { CommandListenerPriority, LexicalNode } from 'lexical';
9
9
  import type { JSX } from 'react';
10
10
  import { MenuOption, type MenuRenderFn } from '@lexical/react/LexicalNodeMenuPlugin';
11
11
  import { LexicalCommand, LexicalEditor } from 'lexical';
12
+ /**
13
+ * The result of matching a URL for an embed: the matched `url`, an `id`
14
+ * identifying the embedded resource, and optional provider-specific `data`.
15
+ */
12
16
  export type EmbedMatchResult<TEmbedMatchResult = unknown> = {
13
17
  url: string;
14
18
  id: string;
15
19
  data?: TEmbedMatchResult;
16
20
  };
21
+ /**
22
+ * Describes a kind of embed (for example YouTube, a tweet, or Google Maps) that
23
+ * {@link LexicalAutoEmbedPlugin} can detect and insert. Each config has a `type`
24
+ * identifier, a `parseUrl` function that decides whether a URL matches and
25
+ * extracts its data, and an `insertNode` function that inserts the corresponding
26
+ * Lexical node.
27
+ */
17
28
  export interface EmbedConfig<TEmbedMatchResultData = unknown, TEmbedMatchResult = EmbedMatchResult<TEmbedMatchResultData>> {
18
29
  type: string;
19
30
  parseUrl: (text: string) => Promise<TEmbedMatchResult | null> | TEmbedMatchResult | null;
20
31
  insertNode: (editor: LexicalEditor, result: TEmbedMatchResult) => void;
21
32
  }
33
+ /**
34
+ * A general-purpose regular expression for detecting URLs, provided as a
35
+ * convenience for implementing an {@link EmbedConfig}'s `parseUrl`.
36
+ */
22
37
  export declare const URL_MATCHER: RegExp;
38
+ /**
39
+ * Command dispatched to start inserting an embed. Its payload is the `type` of
40
+ * the {@link EmbedConfig} to use; {@link LexicalAutoEmbedPlugin} listens for it
41
+ * and runs that config's URL detection flow.
42
+ */
23
43
  export declare const INSERT_EMBED_COMMAND: LexicalCommand<EmbedConfig['type']>;
44
+ /**
45
+ * A {@link MenuOption} for the auto-embed menu, pairing a display `title` with
46
+ * an `onSelect` callback invoked when the user chooses to embed the detected
47
+ * URL.
48
+ */
24
49
  export declare class AutoEmbedOption extends MenuOption {
25
50
  title: string;
26
51
  onSelect: (targetNode: LexicalNode | null) => void;
@@ -11,7 +11,6 @@
11
11
  var link = require('@lexical/link');
12
12
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
13
13
  var LexicalNodeMenuPlugin = require('@lexical/react/LexicalNodeMenuPlugin');
14
- var utils = require('@lexical/utils');
15
14
  var lexical = require('lexical');
16
15
  var react = require('react');
17
16
  var jsxRuntime = require('react/jsx-runtime');
@@ -24,8 +23,24 @@ var jsxRuntime = require('react/jsx-runtime');
24
23
  *
25
24
  */
26
25
 
26
+ /**
27
+ * A general-purpose regular expression for detecting URLs, provided as a
28
+ * convenience for implementing an {@link EmbedConfig}'s `parseUrl`.
29
+ */
27
30
  const URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
31
+
32
+ /**
33
+ * Command dispatched to start inserting an embed. Its payload is the `type` of
34
+ * the {@link EmbedConfig} to use; {@link LexicalAutoEmbedPlugin} listens for it
35
+ * and runs that config's URL detection flow.
36
+ */
28
37
  const INSERT_EMBED_COMMAND = /* @__PURE__ */lexical.createCommand('INSERT_EMBED_COMMAND');
38
+
39
+ /**
40
+ * A {@link MenuOption} for the auto-embed menu, pairing a display `title` with
41
+ * an `onSelect` callback invoked when the user chooses to embed the detected
42
+ * URL.
43
+ */
29
44
  class AutoEmbedOption extends LexicalNodeMenuPlugin.MenuOption {
30
45
  title;
31
46
  onSelect;
@@ -78,7 +93,7 @@ function LexicalAutoEmbedPlugin({
78
93
  setActiveEmbedConfig(null);
79
94
  }, []);
80
95
  const checkIfLinkNodeIsEmbeddable = react.useCallback(async key => {
81
- const url = editor.getEditorState().read(function () {
96
+ const url = editor.read('latest', function () {
82
97
  const linkNode = lexical.$getNodeByKey(key);
83
98
  if (link.$isLinkNode(linkNode)) {
84
99
  return linkNode.getURL();
@@ -108,7 +123,7 @@ function LexicalAutoEmbedPlugin({
108
123
  }
109
124
  }
110
125
  };
111
- return utils.mergeRegister(...[link.LinkNode, link.AutoLinkNode].map(Klass => editor.registerMutationListener(Klass, (...args) => listener(...args), {
126
+ return lexical.mergeRegister(...[link.LinkNode, link.AutoLinkNode].map(Klass => editor.registerMutationListener(Klass, (...args) => listener(...args), {
112
127
  skipInitialization: true
113
128
  })));
114
129
  }, [checkIfLinkNodeIsEmbeddable, editor, nodeKey, reset]);
@@ -127,7 +142,7 @@ function LexicalAutoEmbedPlugin({
127
142
  }, [editor, embedConfigs, onOpenEmbedModalForConfig]);
128
143
  const embedLinkViaActiveEmbedConfig = react.useCallback(async function () {
129
144
  if (activeEmbedConfig != null && nodeKey != null) {
130
- const linkNode = editor.getEditorState().read(() => {
145
+ const linkNode = editor.read('latest', () => {
131
146
  const node = lexical.$getNodeByKey(nodeKey);
132
147
  if (link.$isLinkNode(node)) {
133
148
  return node;
@@ -9,8 +9,7 @@
9
9
  import { $isLinkNode, LinkNode, AutoLinkNode } from '@lexical/link';
10
10
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
11
11
  import { MenuOption, LexicalNodeMenuPlugin } from '@lexical/react/LexicalNodeMenuPlugin';
12
- import { mergeRegister } from '@lexical/utils';
13
- import { createCommand, $getNodeByKey, COMMAND_PRIORITY_EDITOR, $getSelection, COMMAND_PRIORITY_LOW, PASTE_TAG } from 'lexical';
12
+ import { createCommand, $getNodeByKey, mergeRegister, COMMAND_PRIORITY_EDITOR, $getSelection, COMMAND_PRIORITY_LOW, PASTE_TAG } from 'lexical';
14
13
  import { useState, useCallback, useEffect, useMemo } from 'react';
15
14
  import { jsx } from 'react/jsx-runtime';
16
15
 
@@ -22,8 +21,24 @@ import { jsx } from 'react/jsx-runtime';
22
21
  *
23
22
  */
24
23
 
24
+ /**
25
+ * A general-purpose regular expression for detecting URLs, provided as a
26
+ * convenience for implementing an {@link EmbedConfig}'s `parseUrl`.
27
+ */
25
28
  const URL_MATCHER = /((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
29
+
30
+ /**
31
+ * Command dispatched to start inserting an embed. Its payload is the `type` of
32
+ * the {@link EmbedConfig} to use; {@link LexicalAutoEmbedPlugin} listens for it
33
+ * and runs that config's URL detection flow.
34
+ */
26
35
  const INSERT_EMBED_COMMAND = /* @__PURE__ */createCommand('INSERT_EMBED_COMMAND');
36
+
37
+ /**
38
+ * A {@link MenuOption} for the auto-embed menu, pairing a display `title` with
39
+ * an `onSelect` callback invoked when the user chooses to embed the detected
40
+ * URL.
41
+ */
27
42
  class AutoEmbedOption extends MenuOption {
28
43
  title;
29
44
  onSelect;
@@ -76,7 +91,7 @@ function LexicalAutoEmbedPlugin({
76
91
  setActiveEmbedConfig(null);
77
92
  }, []);
78
93
  const checkIfLinkNodeIsEmbeddable = useCallback(async key => {
79
- const url = editor.getEditorState().read(function () {
94
+ const url = editor.read('latest', function () {
80
95
  const linkNode = $getNodeByKey(key);
81
96
  if ($isLinkNode(linkNode)) {
82
97
  return linkNode.getURL();
@@ -125,7 +140,7 @@ function LexicalAutoEmbedPlugin({
125
140
  }, [editor, embedConfigs, onOpenEmbedModalForConfig]);
126
141
  const embedLinkViaActiveEmbedConfig = useCallback(async function () {
127
142
  if (activeEmbedConfig != null && nodeKey != null) {
128
- const linkNode = editor.getEditorState().read(() => {
143
+ const linkNode = editor.read('latest', () => {
129
144
  const node = $getNodeByKey(nodeKey);
130
145
  if ($isLinkNode(node)) {
131
146
  return node;
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/react/LexicalNodeMenuPlugin"),i=require("@lexical/utils"),o=require("lexical"),r=require("react"),l=require("react/jsx-runtime");const s=/* @__PURE__ */o.createCommand("INSERT_EMBED_COMMAND");class u extends n.MenuOption{title;onSelect;constructor(e,t){super(e),this.title=e,this.onSelect=t.onSelect.bind(this)}}exports.AutoEmbedOption=u,exports.INSERT_EMBED_COMMAND=s,exports.LexicalAutoEmbedPlugin=function({embedConfigs:u,onOpenEmbedModalForConfig:a,getMenuOptions:c,menuRenderFn:d,menuCommandPriority:m=o.COMMAND_PRIORITY_LOW}){const[p]=t.useLexicalComposerContext(),[f,x]=r.useState(null),[C,M]=r.useState(null),g=r.useCallback(()=>{x(null),M(null)},[]),E=r.useCallback(async t=>{const n=p.getEditorState().read(function(){const n=o.$getNodeByKey(t);if(e.$isLinkNode(n))return n.getURL()});if(void 0!==n)for(const e of u){null!=await Promise.resolve(e.parseUrl(n))&&(M(e),x(t))}},[p,u]);r.useEffect(()=>i.mergeRegister(...[e.LinkNode,e.AutoLinkNode].map(e=>p.registerMutationListener(e,(...e)=>((e,{updateTags:t,dirtyLeaves:n})=>{for(const[i,r]of e)"created"===r&&t.has(o.PASTE_TAG)&&n.size<=3?E(i):i===f&&g()})(...e),{skipInitialization:!0}))),[E,p,f,g]),r.useEffect(()=>{if(a)return p.registerCommand(s,e=>{const t=u.find(({type:t})=>t===e);return!!t&&(a(t),!0)},o.COMMAND_PRIORITY_EDITOR)},[p,u,a]);const N=r.useCallback(async function(){if(null!=C&&null!=f){const t=p.getEditorState().read(()=>{const t=o.$getNodeByKey(f);return e.$isLinkNode(t)?t:null});if(e.$isLinkNode(t)){const e=await Promise.resolve(C.parseUrl(t.__url));null!=e&&p.update(()=>{o.$getSelection()||t.selectEnd(),C.insertNode(p,e),t.isAttached()&&t.remove()})}}},[C,p,f]),L=r.useMemo(()=>null!=C&&null!=f?c(C,N,g):[],[C,N,c,f,g]),A=r.useCallback((e,t,n)=>{p.update(()=>{e.onSelect(t),n()})},[p]);return null!=f?/*#__PURE__*/l.jsx(n.LexicalNodeMenuPlugin,{nodeKey:f,onClose:g,onSelectOption:A,options:L,menuRenderFn:d,commandPriority:m}):null},exports.URL_MATCHER=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
9
+ "use strict";var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/react/LexicalNodeMenuPlugin"),o=require("lexical"),i=require("react"),l=require("react/jsx-runtime");const r=/* @__PURE__ */o.createCommand("INSERT_EMBED_COMMAND");class s extends n.MenuOption{title;onSelect;constructor(e,t){super(e),this.title=e,this.onSelect=t.onSelect.bind(this)}}exports.AutoEmbedOption=s,exports.INSERT_EMBED_COMMAND=r,exports.LexicalAutoEmbedPlugin=function({embedConfigs:s,onOpenEmbedModalForConfig:u,getMenuOptions:a,menuRenderFn:c,menuCommandPriority:d=o.COMMAND_PRIORITY_LOW}){const[m]=t.useLexicalComposerContext(),[p,f]=i.useState(null),[C,x]=i.useState(null),M=i.useCallback(()=>{f(null),x(null)},[]),N=i.useCallback(async t=>{const n=m.read("latest",function(){const n=o.$getNodeByKey(t);if(e.$isLinkNode(n))return n.getURL()});if(void 0!==n)for(const e of s){null!=await Promise.resolve(e.parseUrl(n))&&(x(e),f(t))}},[m,s]);i.useEffect(()=>o.mergeRegister(...[e.LinkNode,e.AutoLinkNode].map(e=>m.registerMutationListener(e,(...e)=>((e,{updateTags:t,dirtyLeaves:n})=>{for(const[i,l]of e)"created"===l&&t.has(o.PASTE_TAG)&&n.size<=3?N(i):i===p&&M()})(...e),{skipInitialization:!0}))),[N,m,p,M]),i.useEffect(()=>{if(u)return m.registerCommand(r,e=>{const t=s.find(({type:t})=>t===e);return!!t&&(u(t),!0)},o.COMMAND_PRIORITY_EDITOR)},[m,s,u]);const g=i.useCallback(async function(){if(null!=C&&null!=p){const t=m.read("latest",()=>{const t=o.$getNodeByKey(p);return e.$isLinkNode(t)?t:null});if(e.$isLinkNode(t)){const e=await Promise.resolve(C.parseUrl(t.__url));null!=e&&m.update(()=>{o.$getSelection()||t.selectEnd(),C.insertNode(m,e),t.isAttached()&&t.remove()})}}},[C,m,p]),E=i.useMemo(()=>null!=C&&null!=p?a(C,g,M):[],[C,g,a,p,M]),L=i.useCallback((e,t,n)=>{m.update(()=>{e.onSelect(t),n()})},[m]);return null!=p?/*#__PURE__*/l.jsx(n.LexicalNodeMenuPlugin,{nodeKey:p,onClose:M,onSelectOption:L,options:E,menuRenderFn:c,commandPriority:d}):null},exports.URL_MATCHER=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{$isLinkNode as e,LinkNode as t,AutoLinkNode as n}from"@lexical/link";import{useLexicalComposerContext as o}from"@lexical/react/LexicalComposerContext";import{MenuOption as r,LexicalNodeMenuPlugin as i}from"@lexical/react/LexicalNodeMenuPlugin";import{mergeRegister as l}from"@lexical/utils";import{createCommand as s,$getNodeByKey as a,COMMAND_PRIORITY_EDITOR as c,$getSelection as u,COMMAND_PRIORITY_LOW as m,PASTE_TAG as d}from"lexical";import{useState as p,useCallback as f,useEffect as x,useMemo as g}from"react";import{jsx as w}from"react/jsx-runtime";const C=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/,S=/* @__PURE__ */s("INSERT_EMBED_COMMAND");class y extends r{title;onSelect;constructor(e,t){super(e),this.title=e,this.onSelect=t.onSelect.bind(this)}}function E({embedConfigs:r,onOpenEmbedModalForConfig:s,getMenuOptions:C,menuRenderFn:y,menuCommandPriority:E=m}){const[M]=o(),[h,_]=p(null),[v,z]=p(null),A=f(()=>{_(null),z(null)},[]),L=f(async t=>{const n=M.getEditorState().read(function(){const n=a(t);if(e(n))return n.getURL()});if(void 0!==n)for(const e of r){null!=await Promise.resolve(e.parseUrl(n))&&(z(e),_(t))}},[M,r]);x(()=>l(...[t,n].map(e=>M.registerMutationListener(e,(...e)=>((e,{updateTags:t,dirtyLeaves:n})=>{for(const[o,r]of e)"created"===r&&t.has(d)&&n.size<=3?L(o):o===h&&A()})(...e),{skipInitialization:!0}))),[L,M,h,A]),x(()=>{if(s)return M.registerCommand(S,e=>{const t=r.find(({type:t})=>t===e);return!!t&&(s(t),!0)},c)},[M,r,s]);const P=f(async function(){if(null!=v&&null!=h){const t=M.getEditorState().read(()=>{const t=a(h);return e(t)?t:null});if(e(t)){const e=await Promise.resolve(v.parseUrl(t.__url));null!=e&&M.update(()=>{u()||t.selectEnd(),v.insertNode(M,e),t.isAttached()&&t.remove()})}}},[v,M,h]),b=g(()=>null!=v&&null!=h?C(v,P,A):[],[v,P,C,h,A]),N=f((e,t,n)=>{M.update(()=>{e.onSelect(t),n()})},[M]);return null!=h?/*#__PURE__*/w(i,{nodeKey:h,onClose:A,onSelectOption:N,options:b,menuRenderFn:y,commandPriority:E}):null}export{y as AutoEmbedOption,S as INSERT_EMBED_COMMAND,E as LexicalAutoEmbedPlugin,C as URL_MATCHER};
9
+ import{$isLinkNode as e,LinkNode as t,AutoLinkNode as n}from"@lexical/link";import{useLexicalComposerContext as o}from"@lexical/react/LexicalComposerContext";import{MenuOption as r,LexicalNodeMenuPlugin as i}from"@lexical/react/LexicalNodeMenuPlugin";import{createCommand as l,$getNodeByKey as s,mergeRegister as a,COMMAND_PRIORITY_EDITOR as c,$getSelection as u,COMMAND_PRIORITY_LOW as m,PASTE_TAG as d}from"lexical";import{useState as p,useCallback as f,useEffect as x,useMemo as g}from"react";import{jsx as w}from"react/jsx-runtime";const C=/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/,y=/* @__PURE__ */l("INSERT_EMBED_COMMAND");class M extends r{title;onSelect;constructor(e,t){super(e),this.title=e,this.onSelect=t.onSelect.bind(this)}}function h({embedConfigs:r,onOpenEmbedModalForConfig:l,getMenuOptions:C,menuRenderFn:M,menuCommandPriority:h=m}){const[S]=o(),[_,v]=p(null),[z,A]=p(null),E=f(()=>{v(null),A(null)},[]),L=f(async t=>{const n=S.read("latest",function(){const n=s(t);if(e(n))return n.getURL()});if(void 0!==n)for(const e of r){null!=await Promise.resolve(e.parseUrl(n))&&(A(e),v(t))}},[S,r]);x(()=>a(...[t,n].map(e=>S.registerMutationListener(e,(...e)=>((e,{updateTags:t,dirtyLeaves:n})=>{for(const[o,r]of e)"created"===r&&t.has(d)&&n.size<=3?L(o):o===_&&E()})(...e),{skipInitialization:!0}))),[L,S,_,E]),x(()=>{if(l)return S.registerCommand(y,e=>{const t=r.find(({type:t})=>t===e);return!!t&&(l(t),!0)},c)},[S,r,l]);const P=f(async function(){if(null!=z&&null!=_){const t=S.read("latest",()=>{const t=s(_);return e(t)?t:null});if(e(t)){const e=await Promise.resolve(z.parseUrl(t.__url));null!=e&&S.update(()=>{u()||t.selectEnd(),z.insertNode(S,e),t.isAttached()&&t.remove()})}}},[z,S,_]),b=g(()=>null!=z&&null!=_?C(z,P,E):[],[z,P,C,_,E]),N=f((e,t,n)=>{S.update(()=>{e.onSelect(t),n()})},[S]);return null!=_?/*#__PURE__*/w(i,{nodeKey:_,onClose:E,onSelectOption:N,options:b,menuRenderFn:M,commandPriority:h}):null}export{M as AutoEmbedOption,y as INSERT_EMBED_COMMAND,h as LexicalAutoEmbedPlugin,C as URL_MATCHER};
@@ -8,5 +8,15 @@
8
8
  type Props = {
9
9
  defaultSelection?: 'rootStart' | 'rootEnd';
10
10
  };
11
+ /**
12
+ * Focuses the editor when the component is mounted. Pass `defaultSelection`
13
+ * to control whether the selection is placed at the start (`'rootStart'`) or
14
+ * end (`'rootEnd'`) of the root when there is no existing selection to restore.
15
+ *
16
+ * This is a legacy plugin. When building an editor with the extension API,
17
+ * configure {@link AutoFocusExtension} instead.
18
+ *
19
+ * @returns `null`, this plugin renders no DOM of its own.
20
+ */
11
21
  export declare function AutoFocusPlugin({ defaultSelection }: Props): null;
12
22
  export {};
@@ -9,6 +9,7 @@
9
9
  'use strict';
10
10
 
11
11
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
12
+ var lexical = require('lexical');
12
13
  var react = require('react');
13
14
 
14
15
  /**
@@ -19,6 +20,16 @@ var react = require('react');
19
20
  *
20
21
  */
21
22
 
23
+ /**
24
+ * Focuses the editor when the component is mounted. Pass `defaultSelection`
25
+ * to control whether the selection is placed at the start (`'rootStart'`) or
26
+ * end (`'rootEnd'`) of the root when there is no existing selection to restore.
27
+ *
28
+ * This is a legacy plugin. When building an editor with the extension API,
29
+ * configure {@link AutoFocusExtension} instead.
30
+ *
31
+ * @returns `null`, this plugin renders no DOM of its own.
32
+ */
22
33
  function AutoFocusPlugin({
23
34
  defaultSelection
24
35
  }) {
@@ -29,8 +40,10 @@ function AutoFocusPlugin({
29
40
  // trigger a re-focus on the element. So in the case this occurs, we'll need to correct it.
30
41
  // Normally this is fine, Selection API !== Focus API, but fore the intents of the naming
31
42
  // of this plugin, which should preserve focus too.
32
- const activeElement = document.activeElement;
33
43
  const rootElement = editor.getRootElement();
44
+ // getActiveElement rather than document.activeElement, which reports
45
+ // the shadow host when the editor is in a shadow root.
46
+ const activeElement = rootElement !== null ? lexical.getActiveElement(rootElement) : null;
34
47
  if (rootElement !== null && (activeElement === null || !rootElement.contains(activeElement))) {
35
48
  // Note: preventScroll won't work in Webkit.
36
49
  rootElement.focus({
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
10
+ import { getActiveElement } from 'lexical';
10
11
  import { useEffect } from 'react';
11
12
 
12
13
  /**
@@ -17,6 +18,16 @@ import { useEffect } from 'react';
17
18
  *
18
19
  */
19
20
 
21
+ /**
22
+ * Focuses the editor when the component is mounted. Pass `defaultSelection`
23
+ * to control whether the selection is placed at the start (`'rootStart'`) or
24
+ * end (`'rootEnd'`) of the root when there is no existing selection to restore.
25
+ *
26
+ * This is a legacy plugin. When building an editor with the extension API,
27
+ * configure {@link AutoFocusExtension} instead.
28
+ *
29
+ * @returns `null`, this plugin renders no DOM of its own.
30
+ */
20
31
  function AutoFocusPlugin({
21
32
  defaultSelection
22
33
  }) {
@@ -27,8 +38,10 @@ function AutoFocusPlugin({
27
38
  // trigger a re-focus on the element. So in the case this occurs, we'll need to correct it.
28
39
  // Normally this is fine, Selection API !== Focus API, but fore the intents of the naming
29
40
  // of this plugin, which should preserve focus too.
30
- const activeElement = document.activeElement;
31
41
  const rootElement = editor.getRootElement();
42
+ // getActiveElement rather than document.activeElement, which reports
43
+ // the shadow host when the editor is in a shadow root.
44
+ const activeElement = rootElement !== null ? getActiveElement(rootElement) : null;
32
45
  if (rootElement !== null && (activeElement === null || !rootElement.contains(activeElement))) {
33
46
  // Note: preventScroll won't work in Webkit.
34
47
  rootElement.focus({
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react");exports.AutoFocusPlugin=function({defaultSelection:o}){const[c]=e.useLexicalComposerContext();return t.useEffect(()=>{c.focus(()=>{const e=document.activeElement,t=c.getRootElement();null===t||null!==e&&t.contains(e)||t.focus({preventScroll:!0})},{defaultSelection:o})},[o,c]),null};
9
+ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),l=require("react");exports.AutoFocusPlugin=function({defaultSelection:n}){const[o]=e.useLexicalComposerContext();return l.useEffect(()=>{o.focus(()=>{const e=o.getRootElement(),l=null!==e?t.getActiveElement(e):null;null===e||null!==l&&e.contains(l)||e.focus({preventScroll:!0})},{defaultSelection:n})},[n,o]),null};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useEffect as t}from"react";function o({defaultSelection:o}){const[l]=e();return t(()=>{l.focus(()=>{const e=document.activeElement,t=l.getRootElement();null===t||null!==e&&t.contains(e)||t.focus({preventScroll:!0})},{defaultSelection:o})},[o,l]),null}export{o as AutoFocusPlugin};
9
+ import{useLexicalComposerContext as l}from"@lexical/react/LexicalComposerContext";import{getActiveElement as o}from"lexical";import{useEffect as t}from"react";function e({defaultSelection:e}){const[n]=l();return t(()=>{n.focus(()=>{const l=n.getRootElement(),t=null!==l?o(l):null;null===l||null!==t&&l.contains(t)||l.focus({preventScroll:!0})},{defaultSelection:e})},[e,n]),null}export{e as AutoFocusPlugin};
@@ -9,6 +9,19 @@ import type { ChangeHandler, LinkMatcher } from '@lexical/link';
9
9
  import type { ElementNode } from 'lexical';
10
10
  import type { JSX } from 'react';
11
11
  export { type ChangeHandler, createLinkMatcherWithRegExp, type LinkMatcher, } from '@lexical/link';
12
+ /**
13
+ * Automatically converts text that matches one of the provided `matchers` into
14
+ * {@link AutoLinkNode}s as the user types, and reverts them back to plain text
15
+ * when they no longer match. Provide `onChange` to react to links being
16
+ * created, updated, or removed, and `excludeParents` to skip matching inside
17
+ * particular ancestor nodes. The editor must have the {@link AutoLinkNode}
18
+ * registered.
19
+ *
20
+ * This is a legacy plugin. When building an editor with the extension API,
21
+ * configure {@link AutoLinkExtension} instead.
22
+ *
23
+ * @returns `null`, this plugin renders no DOM of its own.
24
+ */
12
25
  export declare function AutoLinkPlugin({ matchers, onChange, excludeParents, }: {
13
26
  matchers: LinkMatcher[];
14
27
  onChange?: ChangeHandler;
@@ -42,6 +42,20 @@ function useAutoLink(editor, matchers, onChange, excludeParents) {
42
42
  });
43
43
  }, [editor, matchers, onChange, excludeParents]);
44
44
  }
45
+
46
+ /**
47
+ * Automatically converts text that matches one of the provided `matchers` into
48
+ * {@link AutoLinkNode}s as the user types, and reverts them back to plain text
49
+ * when they no longer match. Provide `onChange` to react to links being
50
+ * created, updated, or removed, and `excludeParents` to skip matching inside
51
+ * particular ancestor nodes. The editor must have the {@link AutoLinkNode}
52
+ * registered.
53
+ *
54
+ * This is a legacy plugin. When building an editor with the extension API,
55
+ * configure {@link AutoLinkExtension} instead.
56
+ *
57
+ * @returns `null`, this plugin renders no DOM of its own.
58
+ */
45
59
  function AutoLinkPlugin({
46
60
  matchers,
47
61
  onChange,
@@ -41,6 +41,20 @@ function useAutoLink(editor, matchers, onChange, excludeParents) {
41
41
  });
42
42
  }, [editor, matchers, onChange, excludeParents]);
43
43
  }
44
+
45
+ /**
46
+ * Automatically converts text that matches one of the provided `matchers` into
47
+ * {@link AutoLinkNode}s as the user types, and reverts them back to plain text
48
+ * when they no longer match. Provide `onChange` to react to links being
49
+ * created, updated, or removed, and `excludeParents` to skip matching inside
50
+ * particular ancestor nodes. The editor must have the {@link AutoLinkNode}
51
+ * registered.
52
+ *
53
+ * This is a legacy plugin. When building an editor with the extension API,
54
+ * configure {@link AutoLinkExtension} instead.
55
+ *
56
+ * @returns `null`, this plugin renders no DOM of its own.
57
+ */
44
58
  function AutoLinkPlugin({
45
59
  matchers,
46
60
  onChange,
@@ -17,5 +17,14 @@ type Props = Readonly<{
17
17
  focus: string;
18
18
  }>;
19
19
  }>;
20
+ /**
21
+ * A wrapper component for the contents of a {@link DecoratorBlockNode} that
22
+ * keeps the block in sync with node selection and element alignment. It renders
23
+ * its `children` inside a container that reflects the node's `format`
24
+ * alignment, responds to `FORMAT_ELEMENT_COMMAND` to update that alignment, and
25
+ * toggles the node's selection when the container is clicked.
26
+ *
27
+ * @returns The element to render for the decorator block.
28
+ */
20
29
  export declare function BlockWithAlignableContents({ children, format, nodeKey, className, }: Props): JSX.Element;
21
30
  export {};
@@ -24,6 +24,15 @@ var jsxRuntime = require('react/jsx-runtime');
24
24
  *
25
25
  */
26
26
 
27
+ /**
28
+ * A wrapper component for the contents of a {@link DecoratorBlockNode} that
29
+ * keeps the block in sync with node selection and element alignment. It renders
30
+ * its `children` inside a container that reflects the node's `format`
31
+ * alignment, responds to `FORMAT_ELEMENT_COMMAND` to update that alignment, and
32
+ * toggles the node's selection when the container is clicked.
33
+ *
34
+ * @returns The element to render for the decorator block.
35
+ */
27
36
  function BlockWithAlignableContents({
28
37
  children,
29
38
  format,
@@ -34,7 +43,7 @@ function BlockWithAlignableContents({
34
43
  const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection.useLexicalNodeSelection(nodeKey);
35
44
  const ref = react.useRef(null);
36
45
  react.useEffect(() => {
37
- return utils.mergeRegister(editor.registerCommand(lexical.FORMAT_ELEMENT_COMMAND, formatType => {
46
+ return lexical.mergeRegister(editor.registerCommand(lexical.FORMAT_ELEMENT_COMMAND, formatType => {
38
47
  if (isSelected) {
39
48
  const selection = lexical.$getSelection();
40
49
  if (lexical.$isNodeSelection(selection)) {
@@ -57,7 +66,7 @@ function BlockWithAlignableContents({
57
66
  }
58
67
  return false;
59
68
  }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.CLICK_COMMAND, event => {
60
- if (event.target === ref.current) {
69
+ if (lexical.getComposedEventTarget(event) === ref.current) {
61
70
  event.preventDefault();
62
71
  if (!event.shiftKey) {
63
72
  clearSelection();
@@ -9,8 +9,8 @@
9
9
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
10
10
  import { $isDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
11
11
  import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
12
- import { mergeRegister, $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';
13
- import { FORMAT_ELEMENT_COMMAND, $getSelection, $isNodeSelection, $getNodeByKey, $isRangeSelection, COMMAND_PRIORITY_LOW, CLICK_COMMAND } from 'lexical';
12
+ import { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';
13
+ import { mergeRegister, FORMAT_ELEMENT_COMMAND, $getSelection, $isNodeSelection, $getNodeByKey, $isRangeSelection, COMMAND_PRIORITY_LOW, CLICK_COMMAND, getComposedEventTarget } from 'lexical';
14
14
  import { useRef, useEffect } from 'react';
15
15
  import { jsx } from 'react/jsx-runtime';
16
16
 
@@ -22,6 +22,15 @@ import { jsx } from 'react/jsx-runtime';
22
22
  *
23
23
  */
24
24
 
25
+ /**
26
+ * A wrapper component for the contents of a {@link DecoratorBlockNode} that
27
+ * keeps the block in sync with node selection and element alignment. It renders
28
+ * its `children` inside a container that reflects the node's `format`
29
+ * alignment, responds to `FORMAT_ELEMENT_COMMAND` to update that alignment, and
30
+ * toggles the node's selection when the container is clicked.
31
+ *
32
+ * @returns The element to render for the decorator block.
33
+ */
25
34
  function BlockWithAlignableContents({
26
35
  children,
27
36
  format,
@@ -55,7 +64,7 @@ function BlockWithAlignableContents({
55
64
  }
56
65
  return false;
57
66
  }, COMMAND_PRIORITY_LOW), editor.registerCommand(CLICK_COMMAND, event => {
58
- if (event.target === ref.current) {
67
+ if (getComposedEventTarget(event) === ref.current) {
59
68
  event.preventDefault();
60
69
  if (!event.shiftKey) {
61
70
  clearSelection();
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("@lexical/react/LexicalDecoratorBlockNode"),r=require("@lexical/react/useLexicalNodeSelection"),o=require("@lexical/utils"),i=require("lexical"),l=require("react"),c=require("react/jsx-runtime");exports.BlockWithAlignableContents=function({children:s,format:a,nodeKey:n,className:u}){const[f]=e.useLexicalComposerContext(),[x,N,d]=r.useLexicalNodeSelection(n),m=l.useRef(null);return l.useEffect(()=>o.mergeRegister(f.registerCommand(i.FORMAT_ELEMENT_COMMAND,e=>{if(x){const r=i.$getSelection();if(i.$isNodeSelection(r)){const r=i.$getNodeByKey(n);t.$isDecoratorBlockNode(r)&&r.setFormat(e)}else if(i.$isRangeSelection(r)){const i=r.getNodes();for(const r of i)if(t.$isDecoratorBlockNode(r))r.setFormat(e);else{o.$getNearestBlockElementAncestorOrThrow(r).setFormat(e)}}return!0}return!1},i.COMMAND_PRIORITY_LOW),f.registerCommand(i.CLICK_COMMAND,e=>e.target===m.current&&(e.preventDefault(),e.shiftKey||d(),N(!x),!0),i.COMMAND_PRIORITY_LOW)),[d,f,x,n,N]),/*#__PURE__*/c.jsx("div",{className:[u.base,x?u.focus:null].filter(Boolean).join(" "),ref:m,style:{textAlign:a||void 0},children:s})};
9
+ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("@lexical/react/LexicalDecoratorBlockNode"),r=require("@lexical/react/useLexicalNodeSelection"),o=require("@lexical/utils"),i=require("lexical"),l=require("react"),c=require("react/jsx-runtime");exports.BlockWithAlignableContents=function({children:s,format:n,nodeKey:a,className:u}){const[d]=e.useLexicalComposerContext(),[f,m,x]=r.useLexicalNodeSelection(a),N=l.useRef(null);return l.useEffect(()=>i.mergeRegister(d.registerCommand(i.FORMAT_ELEMENT_COMMAND,e=>{if(f){const r=i.$getSelection();if(i.$isNodeSelection(r)){const r=i.$getNodeByKey(a);t.$isDecoratorBlockNode(r)&&r.setFormat(e)}else if(i.$isRangeSelection(r)){const i=r.getNodes();for(const r of i)if(t.$isDecoratorBlockNode(r))r.setFormat(e);else{o.$getNearestBlockElementAncestorOrThrow(r).setFormat(e)}}return!0}return!1},i.COMMAND_PRIORITY_LOW),d.registerCommand(i.CLICK_COMMAND,e=>i.getComposedEventTarget(e)===N.current&&(e.preventDefault(),e.shiftKey||x(),m(!f),!0),i.COMMAND_PRIORITY_LOW)),[x,d,f,a,m]),/*#__PURE__*/c.jsx("div",{className:[u.base,f?u.focus:null].filter(Boolean).join(" "),ref:N,style:{textAlign:n||void 0},children:s})};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{$isDecoratorBlockNode as t}from"@lexical/react/LexicalDecoratorBlockNode";import{useLexicalNodeSelection as r}from"@lexical/react/useLexicalNodeSelection";import{mergeRegister as o,$getNearestBlockElementAncestorOrThrow as i}from"@lexical/utils";import{FORMAT_ELEMENT_COMMAND as l,$getSelection as a,$isNodeSelection as c,$getNodeByKey as m,$isRangeSelection as n,COMMAND_PRIORITY_LOW as s,CLICK_COMMAND as f}from"lexical";import{useRef as u,useEffect as x}from"react";import{jsx as d}from"react/jsx-runtime";function p({children:p,format:g,nodeKey:N,className:C}){const[h]=e(),[v,y,F]=r(N),L=u(null);return x(()=>o(h.registerCommand(l,e=>{if(v){const r=a();if(c(r)){const r=m(N);t(r)&&r.setFormat(e)}else if(n(r)){const o=r.getNodes();for(const r of o)if(t(r))r.setFormat(e);else{i(r).setFormat(e)}}return!0}return!1},s),h.registerCommand(f,e=>e.target===L.current&&(e.preventDefault(),e.shiftKey||F(),y(!v),!0),s)),[F,h,v,N,y]),/*#__PURE__*/d("div",{className:[C.base,v?C.focus:null].filter(Boolean).join(" "),ref:L,style:{textAlign:g||void 0},children:p})}export{p as BlockWithAlignableContents};
9
+ import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{$isDecoratorBlockNode as r}from"@lexical/react/LexicalDecoratorBlockNode";import{useLexicalNodeSelection as t}from"@lexical/react/useLexicalNodeSelection";import{$getNearestBlockElementAncestorOrThrow as o}from"@lexical/utils";import{mergeRegister as i,FORMAT_ELEMENT_COMMAND as l,$getSelection as c,$isNodeSelection as a,$getNodeByKey as m,$isRangeSelection as n,COMMAND_PRIORITY_LOW as s,CLICK_COMMAND as f,getComposedEventTarget as u}from"lexical";import{useRef as x,useEffect as d}from"react";import{jsx as p}from"react/jsx-runtime";function N({children:N,format:g,nodeKey:C,className:h}){const[v]=e(),[y,F,L]=t(C),j=x(null);return d(()=>i(v.registerCommand(l,e=>{if(y){const t=c();if(a(t)){const t=m(C);r(t)&&t.setFormat(e)}else if(n(t)){const i=t.getNodes();for(const t of i)if(r(t))t.setFormat(e);else{o(t).setFormat(e)}}return!0}return!1},s),v.registerCommand(f,e=>u(e)===j.current&&(e.preventDefault(),e.shiftKey||L(),F(!y),!0),s)),[L,v,y,C,F]),/*#__PURE__*/p("div",{className:[h.base,y?h.focus:null].filter(Boolean).join(" "),ref:j,style:{textAlign:g||void 0},children:N})}export{N as BlockWithAlignableContents};
@@ -6,6 +6,16 @@
6
6
  *
7
7
  */
8
8
  import type { JSX } from 'react';
9
+ /**
10
+ * Tracks the length of the editor's text content against `maxLength` and
11
+ * renders the number of remaining characters, marking any overflowing text so
12
+ * it can be styled. Length is measured in either `'UTF-8'` or `'UTF-16'`
13
+ * (default) code units via the `charset` prop, and the display can be
14
+ * customized with the `renderer` prop.
15
+ *
16
+ * @returns The element produced by `renderer` (by default a `<span>` showing
17
+ * the number of remaining characters).
18
+ */
9
19
  export declare function CharacterLimitPlugin({ charset, maxLength, renderer, }: {
10
20
  charset: 'UTF-8' | 'UTF-16';
11
21
  maxLength: number;
@@ -46,11 +46,9 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
46
46
  }
47
47
  }, [editor]);
48
48
  react.useEffect(() => {
49
- let text$1 = editor.getEditorState().read(text.$rootTextContent, {
50
- editor
51
- });
49
+ let text$1 = editor.read('latest', text.$rootTextContent);
52
50
  let lastComputedTextLength = 0;
53
- return utils.mergeRegister(editor.registerTextContentListener(currentText => {
51
+ return lexical.mergeRegister(editor.registerTextContentListener(currentText => {
54
52
  text$1 = currentText;
55
53
  }), editor.registerUpdateListener(({
56
54
  dirtyLeaves,
@@ -145,7 +143,7 @@ function $wrapOverflowedNodes(offset) {
145
143
  // below. Element slot values need no special case: their interior is
146
144
  // counted leaf-by-leaf like any other subtree.
147
145
  const isSlotValueLeaf = lexical.$isLeafNode(node) && lexical.$getSlotHost(node) !== null;
148
- const needsOverflowParent = lexical.$isLeafNode(node) && !isSlotValueLeaf && !utils.$findMatchingParent(node, overflow.$isOverflowNode);
146
+ const needsOverflowParent = lexical.$isLeafNode(node) && !isSlotValueLeaf && !lexical.$findMatchingParent(node, overflow.$isOverflowNode);
149
147
  if (overflow.$isOverflowNode(node)) {
150
148
  const previousLength = accumulatedLength;
151
149
  const nextLength = accumulatedLength + node.getTextContentSize();
@@ -282,6 +280,17 @@ function DefaultRenderer({
282
280
  children: remainingCharacters
283
281
  });
284
282
  }
283
+
284
+ /**
285
+ * Tracks the length of the editor's text content against `maxLength` and
286
+ * renders the number of remaining characters, marking any overflowing text so
287
+ * it can be styled. Length is measured in either `'UTF-8'` or `'UTF-16'`
288
+ * (default) code units via the `charset` prop, and the display can be
289
+ * customized with the `renderer` prop.
290
+ *
291
+ * @returns The element produced by `renderer` (by default a `<span>` showing
292
+ * the number of remaining characters).
293
+ */
285
294
  function CharacterLimitPlugin({
286
295
  charset = 'UTF-16',
287
296
  maxLength = CHARACTER_LIMIT,
@@ -10,8 +10,8 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
10
10
  import { useEffect, useState, useMemo } from 'react';
11
11
  import { OverflowNode, $isOverflowNode, $createOverflowNode } from '@lexical/overflow';
12
12
  import { $rootTextContent } from '@lexical/text';
13
- import { mergeRegister, $dfsWithSlots, $findMatchingParent, $unwrapNode } from '@lexical/utils';
14
- import { HISTORY_MERGE_TAG, DELETE_CHARACTER_COMMAND, $getSelection, $isRangeSelection, $isElementNode, COMMAND_PRIORITY_LOW, $isLeafNode, $getSlotHost, $isTextNode, $setSelection } from 'lexical';
13
+ import { $dfsWithSlots, $unwrapNode } from '@lexical/utils';
14
+ import { mergeRegister, HISTORY_MERGE_TAG, DELETE_CHARACTER_COMMAND, $getSelection, $isRangeSelection, $isElementNode, COMMAND_PRIORITY_LOW, $isLeafNode, $getSlotHost, $findMatchingParent, $isTextNode, $setSelection } from 'lexical';
15
15
  import { jsx } from 'react/jsx-runtime';
16
16
 
17
17
  /**
@@ -44,9 +44,7 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
44
44
  }
45
45
  }, [editor]);
46
46
  useEffect(() => {
47
- let text = editor.getEditorState().read($rootTextContent, {
48
- editor
49
- });
47
+ let text = editor.read('latest', $rootTextContent);
50
48
  let lastComputedTextLength = 0;
51
49
  return mergeRegister(editor.registerTextContentListener(currentText => {
52
50
  text = currentText;
@@ -280,6 +278,17 @@ function DefaultRenderer({
280
278
  children: remainingCharacters
281
279
  });
282
280
  }
281
+
282
+ /**
283
+ * Tracks the length of the editor's text content against `maxLength` and
284
+ * renders the number of remaining characters, marking any overflowing text so
285
+ * it can be styled. Length is measured in either `'UTF-8'` or `'UTF-16'`
286
+ * (default) code units via the `charset` prop, and the display can be
287
+ * customized with the `renderer` prop.
288
+ *
289
+ * @returns The element produced by `renderer` (by default a `<span>` showing
290
+ * the number of remaining characters).
291
+ */
283
292
  function CharacterLimitPlugin({
284
293
  charset = 'UTF-16',
285
294
  maxLength = CHARACTER_LIMIT,
@@ -6,5 +6,5 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),n=require("@lexical/overflow"),r=require("@lexical/text"),i=require("@lexical/utils"),o=require("lexical"),s=require("react/jsx-runtime");function l(e,s,l=Object.freeze({})){const{strlen:f=e=>e.length,remainingCharacters:g=()=>{}}=l;t.useEffect(()=>{e.hasNodes([n.OverflowNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t.useEffect(()=>{let t=e.getEditorState().read(r.$rootTextContent,{editor:e}),l=0;return i.mergeRegister(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:r,dirtyElements:d})=>{const u=e.isComposing(),h=r.size>0||d.size>0;if(u||!h)return;const m=f(t),x=m>s||null!==l&&l>s;if(g(s-m),null===l||x){const r=function(e,t,n){let r=0,i=0;if("function"==typeof Intl.Segmenter){const o=(new Intl.Segmenter).segment(e);for(const{segment:e}of o){const o=i+n(e);if(o>t)break;i=o,r+=e.length}}else{const o=Array.from(e),s=o.length;for(let e=0;e<s;e++){const s=o[e],l=i+n(s);if(l>t)break;i=l,r+=s.length}}return r}(t,s,f);e.update(()=>{!function(e){const t=i.$dfsWithSlots(),r=t.length;let s=0;for(let l=0;l<r;l+=1){const{node:r}=t[l],f=o.$isLeafNode(r)&&null!==o.$getSlotHost(r),g=o.$isLeafNode(r)&&!f&&!i.$findMatchingParent(r,n.$isOverflowNode);if(n.$isOverflowNode(r)){const t=s;if(s+r.getTextContentSize()<=e){const e=r.getParent(),t=r.getPreviousSibling(),n=r.getNextSibling();i.$unwrapNode(r);const s=o.$getSelection();!o.$isRangeSelection(s)||s.anchor.getNode().isAttached()&&s.focus.getNode().isAttached()||(o.$isTextNode(t)?t.select():o.$isTextNode(n)?n.select():null!==e&&e.select())}else if(t<e){const n=r.getFirstDescendant(),s=t+(null!==n?n.getTextContentSize():0);(o.$isTextNode(n)&&n.isSimpleText()||s<=e)&&i.$unwrapNode(r)}}else if(f)s+=r.getTextContentSize();else if(g){const t=s;if(s+=r.getTextContentSize(),s>e&&!n.$isOverflowNode(r.getParent())){const n=o.$getSelection();let i;if(t<e&&o.$isTextNode(r)&&r.isSimpleText()){const[,n]=r.splitText(e-t);i=c(n)}else i=c(r);null!==n&&o.$setSelection(n),a(i)}}}}(r)},{tag:o.HISTORY_MERGE_TAG})}l=m}),e.registerCommand(o.DELETE_CHARACTER_COMMAND,e=>{const t=o.$getSelection();if(!o.$isRangeSelection(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,i=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():o.$isElementNode(i)&&i.isEmpty()&&i.remove(),!0},o.COMMAND_PRIORITY_LOW))},[e,s,g,f])}function c(e){const t=n.$createOverflowNode();return e.replace(t),t.append(e),t}function a(e){const t=e.getPreviousSibling();if(!n.$isOverflowNode(t))return;const r=e.getFirstChild(),i=t.getChildren(),s=i.length;if(null===r)e.append(...i);else for(let e=0;e<s;e++)r.insertBefore(i[e]);const l=o.$getSelection();if(o.$isRangeSelection(l)){const n=l.anchor,r=n.getNode(),i=l.focus,o=n.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),s+n.offset,"element"),o.is(t)?i.set(e.getKey(),i.offset,"element"):o.is(e)&&i.set(e.getKey(),s+i.offset,"element")}t.remove()}let f=null;function g(e){const t=void 0===window.TextEncoder?null:(null===f&&(f=new window.TextEncoder),f);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function d({remainingCharacters:e}){/*#__PURE__*/
10
- return s.jsx("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}exports.CharacterLimitPlugin=function({charset:n="UTF-16",maxLength:r=5,renderer:i=d}){const[o]=e.useLexicalComposerContext(),[s,c]=t.useState(r),a=t.useMemo(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===n)return g(e);if("UTF-16"===n)return e.length;throw new Error("Unrecognized charset")}}),[n]);return l(o,r,a),i({remainingCharacters:s})};
9
+ "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("react"),n=require("@lexical/overflow"),r=require("@lexical/text"),i=require("@lexical/utils"),o=require("lexical"),s=require("react/jsx-runtime");function l(e,s,l=Object.freeze({})){const{strlen:f=e=>e.length,remainingCharacters:g=()=>{}}=l;t.useEffect(()=>{e.hasNodes([n.OverflowNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(57)},[e]),t.useEffect(()=>{let t=e.read("latest",r.$rootTextContent),l=0;return o.mergeRegister(e.registerTextContentListener(e=>{t=e}),e.registerUpdateListener(({dirtyLeaves:r,dirtyElements:u})=>{const d=e.isComposing(),h=r.size>0||u.size>0;if(d||!h)return;const m=f(t),x=m>s||null!==l&&l>s;if(g(s-m),null===l||x){const r=function(e,t,n){let r=0,i=0;if("function"==typeof Intl.Segmenter){const o=(new Intl.Segmenter).segment(e);for(const{segment:e}of o){const o=i+n(e);if(o>t)break;i=o,r+=e.length}}else{const o=Array.from(e),s=o.length;for(let e=0;e<s;e++){const s=o[e],l=i+n(s);if(l>t)break;i=l,r+=s.length}}return r}(t,s,f);e.update(()=>{!function(e){const t=i.$dfsWithSlots(),r=t.length;let s=0;for(let l=0;l<r;l+=1){const{node:r}=t[l],f=o.$isLeafNode(r)&&null!==o.$getSlotHost(r),g=o.$isLeafNode(r)&&!f&&!o.$findMatchingParent(r,n.$isOverflowNode);if(n.$isOverflowNode(r)){const t=s;if(s+r.getTextContentSize()<=e){const e=r.getParent(),t=r.getPreviousSibling(),n=r.getNextSibling();i.$unwrapNode(r);const s=o.$getSelection();!o.$isRangeSelection(s)||s.anchor.getNode().isAttached()&&s.focus.getNode().isAttached()||(o.$isTextNode(t)?t.select():o.$isTextNode(n)?n.select():null!==e&&e.select())}else if(t<e){const n=r.getFirstDescendant(),s=t+(null!==n?n.getTextContentSize():0);(o.$isTextNode(n)&&n.isSimpleText()||s<=e)&&i.$unwrapNode(r)}}else if(f)s+=r.getTextContentSize();else if(g){const t=s;if(s+=r.getTextContentSize(),s>e&&!n.$isOverflowNode(r.getParent())){const n=o.$getSelection();let i;if(t<e&&o.$isTextNode(r)&&r.isSimpleText()){const[,n]=r.splitText(e-t);i=c(n)}else i=c(r);null!==n&&o.$setSelection(n),a(i)}}}}(r)},{tag:o.HISTORY_MERGE_TAG})}l=m}),e.registerCommand(o.DELETE_CHARACTER_COMMAND,e=>{const t=o.$getSelection();if(!o.$isRangeSelection(t))return!1;const n=t.anchor.getNode().getParent(),r=n?n.getParent():null,i=r?r.getNextSibling():null;return t.deleteCharacter(e),r&&r.isEmpty()?r.remove():o.$isElementNode(i)&&i.isEmpty()&&i.remove(),!0},o.COMMAND_PRIORITY_LOW))},[e,s,g,f])}function c(e){const t=n.$createOverflowNode();return e.replace(t),t.append(e),t}function a(e){const t=e.getPreviousSibling();if(!n.$isOverflowNode(t))return;const r=e.getFirstChild(),i=t.getChildren(),s=i.length;if(null===r)e.append(...i);else for(let e=0;e<s;e++)r.insertBefore(i[e]);const l=o.$getSelection();if(o.$isRangeSelection(l)){const n=l.anchor,r=n.getNode(),i=l.focus,o=n.getNode();r.is(t)?n.set(e.getKey(),n.offset,"element"):r.is(e)&&n.set(e.getKey(),s+n.offset,"element"),o.is(t)?i.set(e.getKey(),i.offset,"element"):o.is(e)&&i.set(e.getKey(),s+i.offset,"element")}t.remove()}let f=null;function g(e){const t=void 0===window.TextEncoder?null:(null===f&&(f=new window.TextEncoder),f);if(null===t){const t=encodeURIComponent(e).match(/%[89ABab]/g);return e.length+(t?t.length:0)}return t.encode(e).length}function u({remainingCharacters:e}){/*#__PURE__*/
10
+ return s.jsx("span",{className:"characters-limit "+(e<0?"characters-limit-exceeded":""),children:e})}exports.CharacterLimitPlugin=function({charset:n="UTF-16",maxLength:r=5,renderer:i=u}){const[o]=e.useLexicalComposerContext(),[s,c]=t.useState(r),a=t.useMemo(()=>({remainingCharacters:c,strlen:e=>{if("UTF-8"===n)return g(e);if("UTF-16"===n)return e.length;throw new Error("Unrecognized charset")}}),[n]);return l(o,r,a),i({remainingCharacters:s})};