@tiptap/react 3.0.0 → 3.0.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 (215) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +5 -1
  3. package/dist/index.cjs +1030 -1163
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +350 -0
  6. package/dist/index.d.ts +350 -0
  7. package/dist/index.js +970 -1138
  8. package/dist/index.js.map +1 -1
  9. package/dist/menus/index.cjs +142 -0
  10. package/dist/menus/index.cjs.map +1 -0
  11. package/dist/menus/index.d.cts +19 -0
  12. package/dist/menus/index.d.ts +19 -0
  13. package/dist/menus/index.js +104 -0
  14. package/dist/menus/index.js.map +1 -0
  15. package/package.json +34 -21
  16. package/src/Context.tsx +18 -12
  17. package/src/Editor.ts +10 -11
  18. package/src/EditorContent.tsx +104 -64
  19. package/src/NodeViewContent.tsx +13 -8
  20. package/src/NodeViewWrapper.tsx +3 -2
  21. package/src/ReactMarkViewRenderer.tsx +111 -0
  22. package/src/ReactNodeViewRenderer.tsx +184 -67
  23. package/src/ReactRenderer.tsx +152 -51
  24. package/src/index.ts +2 -3
  25. package/src/menus/BubbleMenu.tsx +68 -0
  26. package/src/menus/FloatingMenu.tsx +68 -0
  27. package/src/menus/index.ts +2 -0
  28. package/src/types.ts +6 -0
  29. package/src/useEditor.ts +286 -166
  30. package/src/useEditorState.ts +133 -85
  31. package/src/useReactNodeView.ts +21 -5
  32. package/dist/index.umd.js +0 -1219
  33. package/dist/index.umd.js.map +0 -1
  34. package/dist/packages/core/src/CommandManager.d.ts +0 -20
  35. package/dist/packages/core/src/Editor.d.ts +0 -161
  36. package/dist/packages/core/src/EventEmitter.d.ts +0 -11
  37. package/dist/packages/core/src/Extension.d.ts +0 -343
  38. package/dist/packages/core/src/ExtensionManager.d.ts +0 -55
  39. package/dist/packages/core/src/InputRule.d.ts +0 -42
  40. package/dist/packages/core/src/Mark.d.ts +0 -451
  41. package/dist/packages/core/src/Node.d.ts +0 -611
  42. package/dist/packages/core/src/NodePos.d.ts +0 -44
  43. package/dist/packages/core/src/NodeView.d.ts +0 -31
  44. package/dist/packages/core/src/PasteRule.d.ts +0 -50
  45. package/dist/packages/core/src/Tracker.d.ts +0 -11
  46. package/dist/packages/core/src/commands/blur.d.ts +0 -13
  47. package/dist/packages/core/src/commands/clearContent.d.ts +0 -14
  48. package/dist/packages/core/src/commands/clearNodes.d.ts +0 -13
  49. package/dist/packages/core/src/commands/command.d.ts +0 -18
  50. package/dist/packages/core/src/commands/createParagraphNear.d.ts +0 -13
  51. package/dist/packages/core/src/commands/cut.d.ts +0 -20
  52. package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +0 -13
  53. package/dist/packages/core/src/commands/deleteNode.d.ts +0 -15
  54. package/dist/packages/core/src/commands/deleteRange.d.ts +0 -14
  55. package/dist/packages/core/src/commands/deleteSelection.d.ts +0 -13
  56. package/dist/packages/core/src/commands/enter.d.ts +0 -13
  57. package/dist/packages/core/src/commands/exitCode.d.ts +0 -13
  58. package/dist/packages/core/src/commands/extendMarkRange.d.ts +0 -25
  59. package/dist/packages/core/src/commands/first.d.ts +0 -14
  60. package/dist/packages/core/src/commands/focus.d.ts +0 -27
  61. package/dist/packages/core/src/commands/forEach.d.ts +0 -14
  62. package/dist/packages/core/src/commands/index.d.ts +0 -55
  63. package/dist/packages/core/src/commands/insertContent.d.ts +0 -34
  64. package/dist/packages/core/src/commands/insertContentAt.d.ts +0 -47
  65. package/dist/packages/core/src/commands/join.d.ts +0 -41
  66. package/dist/packages/core/src/commands/joinItemBackward.d.ts +0 -13
  67. package/dist/packages/core/src/commands/joinItemForward.d.ts +0 -13
  68. package/dist/packages/core/src/commands/joinTextblockBackward.d.ts +0 -12
  69. package/dist/packages/core/src/commands/joinTextblockForward.d.ts +0 -12
  70. package/dist/packages/core/src/commands/keyboardShortcut.d.ts +0 -14
  71. package/dist/packages/core/src/commands/lift.d.ts +0 -17
  72. package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +0 -13
  73. package/dist/packages/core/src/commands/liftListItem.d.ts +0 -15
  74. package/dist/packages/core/src/commands/newlineInCode.d.ts +0 -13
  75. package/dist/packages/core/src/commands/resetAttributes.d.ts +0 -16
  76. package/dist/packages/core/src/commands/scrollIntoView.d.ts +0 -13
  77. package/dist/packages/core/src/commands/selectAll.d.ts +0 -13
  78. package/dist/packages/core/src/commands/selectNodeBackward.d.ts +0 -13
  79. package/dist/packages/core/src/commands/selectNodeForward.d.ts +0 -13
  80. package/dist/packages/core/src/commands/selectParentNode.d.ts +0 -13
  81. package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +0 -13
  82. package/dist/packages/core/src/commands/selectTextblockStart.d.ts +0 -13
  83. package/dist/packages/core/src/commands/setContent.d.ts +0 -40
  84. package/dist/packages/core/src/commands/setMark.d.ts +0 -15
  85. package/dist/packages/core/src/commands/setMeta.d.ts +0 -15
  86. package/dist/packages/core/src/commands/setNode.d.ts +0 -16
  87. package/dist/packages/core/src/commands/setNodeSelection.d.ts +0 -14
  88. package/dist/packages/core/src/commands/setTextSelection.d.ts +0 -14
  89. package/dist/packages/core/src/commands/sinkListItem.d.ts +0 -15
  90. package/dist/packages/core/src/commands/splitBlock.d.ts +0 -17
  91. package/dist/packages/core/src/commands/splitListItem.d.ts +0 -15
  92. package/dist/packages/core/src/commands/toggleList.d.ts +0 -18
  93. package/dist/packages/core/src/commands/toggleMark.d.ts +0 -30
  94. package/dist/packages/core/src/commands/toggleNode.d.ts +0 -17
  95. package/dist/packages/core/src/commands/toggleWrap.d.ts +0 -16
  96. package/dist/packages/core/src/commands/undoInputRule.d.ts +0 -13
  97. package/dist/packages/core/src/commands/unsetAllMarks.d.ts +0 -13
  98. package/dist/packages/core/src/commands/unsetMark.d.ts +0 -25
  99. package/dist/packages/core/src/commands/updateAttributes.d.ts +0 -24
  100. package/dist/packages/core/src/commands/wrapIn.d.ts +0 -16
  101. package/dist/packages/core/src/commands/wrapInList.d.ts +0 -16
  102. package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +0 -5
  103. package/dist/packages/core/src/extensions/commands.d.ts +0 -3
  104. package/dist/packages/core/src/extensions/editable.d.ts +0 -2
  105. package/dist/packages/core/src/extensions/focusEvents.d.ts +0 -2
  106. package/dist/packages/core/src/extensions/index.d.ts +0 -6
  107. package/dist/packages/core/src/extensions/keymap.d.ts +0 -2
  108. package/dist/packages/core/src/extensions/tabindex.d.ts +0 -2
  109. package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +0 -10
  110. package/dist/packages/core/src/helpers/createChainableState.d.ts +0 -10
  111. package/dist/packages/core/src/helpers/createDocument.d.ts +0 -12
  112. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +0 -15
  113. package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +0 -7
  114. package/dist/packages/core/src/helpers/findChildren.d.ts +0 -9
  115. package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +0 -10
  116. package/dist/packages/core/src/helpers/findParentNode.d.ts +0 -16
  117. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +0 -17
  118. package/dist/packages/core/src/helpers/generateHTML.d.ts +0 -8
  119. package/dist/packages/core/src/helpers/generateJSON.d.ts +0 -8
  120. package/dist/packages/core/src/helpers/generateText.d.ts +0 -12
  121. package/dist/packages/core/src/helpers/getAttributes.d.ts +0 -9
  122. package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +0 -6
  123. package/dist/packages/core/src/helpers/getChangedRanges.d.ts +0 -11
  124. package/dist/packages/core/src/helpers/getDebugJSON.d.ts +0 -8
  125. package/dist/packages/core/src/helpers/getExtensionField.d.ts +0 -9
  126. package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +0 -2
  127. package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +0 -3
  128. package/dist/packages/core/src/helpers/getMarkRange.d.ts +0 -3
  129. package/dist/packages/core/src/helpers/getMarkType.d.ts +0 -2
  130. package/dist/packages/core/src/helpers/getMarksBetween.d.ts +0 -3
  131. package/dist/packages/core/src/helpers/getNodeAtPosition.d.ts +0 -11
  132. package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +0 -3
  133. package/dist/packages/core/src/helpers/getNodeType.d.ts +0 -2
  134. package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +0 -3
  135. package/dist/packages/core/src/helpers/getSchema.d.ts +0 -4
  136. package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +0 -10
  137. package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +0 -8
  138. package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +0 -8
  139. package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +0 -9
  140. package/dist/packages/core/src/helpers/getText.d.ts +0 -15
  141. package/dist/packages/core/src/helpers/getTextBetween.d.ts +0 -14
  142. package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +0 -8
  143. package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +0 -8
  144. package/dist/packages/core/src/helpers/index.d.ts +0 -50
  145. package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +0 -9
  146. package/dist/packages/core/src/helpers/isActive.d.ts +0 -2
  147. package/dist/packages/core/src/helpers/isAtEndOfNode.d.ts +0 -2
  148. package/dist/packages/core/src/helpers/isAtStartOfNode.d.ts +0 -2
  149. package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +0 -2
  150. package/dist/packages/core/src/helpers/isList.d.ts +0 -2
  151. package/dist/packages/core/src/helpers/isMarkActive.d.ts +0 -3
  152. package/dist/packages/core/src/helpers/isNodeActive.d.ts +0 -3
  153. package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +0 -2
  154. package/dist/packages/core/src/helpers/isNodeSelection.d.ts +0 -2
  155. package/dist/packages/core/src/helpers/isTextSelection.d.ts +0 -2
  156. package/dist/packages/core/src/helpers/posToDOMRect.d.ts +0 -2
  157. package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +0 -4
  158. package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +0 -2
  159. package/dist/packages/core/src/helpers/splitExtensions.d.ts +0 -9
  160. package/dist/packages/core/src/index.d.ts +0 -24
  161. package/dist/packages/core/src/inputRules/index.d.ts +0 -5
  162. package/dist/packages/core/src/inputRules/markInputRule.d.ts +0 -13
  163. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +0 -23
  164. package/dist/packages/core/src/inputRules/textInputRule.d.ts +0 -10
  165. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +0 -15
  166. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +0 -28
  167. package/dist/packages/core/src/pasteRules/index.d.ts +0 -3
  168. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +0 -13
  169. package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +0 -13
  170. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +0 -10
  171. package/dist/packages/core/src/style.d.ts +0 -1
  172. package/dist/packages/core/src/types.d.ts +0 -255
  173. package/dist/packages/core/src/utilities/callOrReturn.d.ts +0 -9
  174. package/dist/packages/core/src/utilities/createStyleTag.d.ts +0 -1
  175. package/dist/packages/core/src/utilities/deleteProps.d.ts +0 -6
  176. package/dist/packages/core/src/utilities/elementFromString.d.ts +0 -1
  177. package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +0 -1
  178. package/dist/packages/core/src/utilities/findDuplicates.d.ts +0 -1
  179. package/dist/packages/core/src/utilities/fromString.d.ts +0 -1
  180. package/dist/packages/core/src/utilities/index.d.ts +0 -20
  181. package/dist/packages/core/src/utilities/isAndroid.d.ts +0 -1
  182. package/dist/packages/core/src/utilities/isEmptyObject.d.ts +0 -1
  183. package/dist/packages/core/src/utilities/isFunction.d.ts +0 -1
  184. package/dist/packages/core/src/utilities/isMacOS.d.ts +0 -1
  185. package/dist/packages/core/src/utilities/isNumber.d.ts +0 -1
  186. package/dist/packages/core/src/utilities/isPlainObject.d.ts +0 -1
  187. package/dist/packages/core/src/utilities/isRegExp.d.ts +0 -1
  188. package/dist/packages/core/src/utilities/isString.d.ts +0 -1
  189. package/dist/packages/core/src/utilities/isiOS.d.ts +0 -1
  190. package/dist/packages/core/src/utilities/mergeAttributes.d.ts +0 -1
  191. package/dist/packages/core/src/utilities/mergeDeep.d.ts +0 -1
  192. package/dist/packages/core/src/utilities/minMax.d.ts +0 -1
  193. package/dist/packages/core/src/utilities/objectIncludes.d.ts +0 -8
  194. package/dist/packages/core/src/utilities/removeDuplicates.d.ts +0 -8
  195. package/dist/packages/extension-bubble-menu/src/bubble-menu-plugin.d.ts +0 -76
  196. package/dist/packages/extension-bubble-menu/src/bubble-menu.d.ts +0 -15
  197. package/dist/packages/extension-bubble-menu/src/index.d.ts +0 -4
  198. package/dist/packages/extension-floating-menu/src/floating-menu-plugin.d.ts +0 -66
  199. package/dist/packages/extension-floating-menu/src/floating-menu.d.ts +0 -15
  200. package/dist/packages/extension-floating-menu/src/index.d.ts +0 -4
  201. package/dist/packages/react/src/BubbleMenu.d.ts +0 -11
  202. package/dist/packages/react/src/Context.d.ts +0 -23
  203. package/dist/packages/react/src/Editor.d.ts +0 -12
  204. package/dist/packages/react/src/EditorContent.d.ts +0 -24
  205. package/dist/packages/react/src/FloatingMenu.d.ts +0 -10
  206. package/dist/packages/react/src/NodeViewContent.d.ts +0 -6
  207. package/dist/packages/react/src/NodeViewWrapper.d.ts +0 -6
  208. package/dist/packages/react/src/ReactNodeViewRenderer.d.ts +0 -16
  209. package/dist/packages/react/src/ReactRenderer.d.ts +0 -62
  210. package/dist/packages/react/src/index.d.ts +0 -13
  211. package/dist/packages/react/src/useEditor.d.ts +0 -39
  212. package/dist/packages/react/src/useEditorState.d.ts +0 -22
  213. package/dist/packages/react/src/useReactNodeView.d.ts +0 -6
  214. package/src/BubbleMenu.tsx +0 -57
  215. package/src/FloatingMenu.tsx +0 -64
@@ -0,0 +1,104 @@
1
+ // src/menus/BubbleMenu.tsx
2
+ import { BubbleMenuPlugin } from "@tiptap/extension-bubble-menu";
3
+ import { useCurrentEditor } from "@tiptap/react";
4
+ import React, { useEffect, useRef } from "react";
5
+ import { createPortal } from "react-dom";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var BubbleMenu = React.forwardRef(
8
+ ({ pluginKey = "bubbleMenu", editor, updateDelay, resizeDelay, shouldShow = null, options, children, ...restProps }, ref) => {
9
+ const menuEl = useRef(document.createElement("div"));
10
+ if (typeof ref === "function") {
11
+ ref(menuEl.current);
12
+ } else if (ref) {
13
+ ref.current = menuEl.current;
14
+ }
15
+ const { editor: currentEditor } = useCurrentEditor();
16
+ useEffect(() => {
17
+ const bubbleMenuElement = menuEl.current;
18
+ bubbleMenuElement.style.visibility = "hidden";
19
+ bubbleMenuElement.style.position = "absolute";
20
+ if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
21
+ return;
22
+ }
23
+ const attachToEditor = editor || currentEditor;
24
+ if (!attachToEditor) {
25
+ console.warn("BubbleMenu component is not rendered inside of an editor component or does not have editor prop.");
26
+ return;
27
+ }
28
+ const plugin = BubbleMenuPlugin({
29
+ updateDelay,
30
+ resizeDelay,
31
+ editor: attachToEditor,
32
+ element: bubbleMenuElement,
33
+ pluginKey,
34
+ shouldShow,
35
+ options
36
+ });
37
+ attachToEditor.registerPlugin(plugin);
38
+ return () => {
39
+ attachToEditor.unregisterPlugin(pluginKey);
40
+ window.requestAnimationFrame(() => {
41
+ if (bubbleMenuElement.parentNode) {
42
+ bubbleMenuElement.parentNode.removeChild(bubbleMenuElement);
43
+ }
44
+ });
45
+ };
46
+ }, [editor, currentEditor]);
47
+ return createPortal(/* @__PURE__ */ jsx("div", { ...restProps, children }), menuEl.current);
48
+ }
49
+ );
50
+
51
+ // src/menus/FloatingMenu.tsx
52
+ import { FloatingMenuPlugin } from "@tiptap/extension-floating-menu";
53
+ import { useCurrentEditor as useCurrentEditor2 } from "@tiptap/react";
54
+ import React2, { useEffect as useEffect2, useRef as useRef2 } from "react";
55
+ import { createPortal as createPortal2 } from "react-dom";
56
+ import { jsx as jsx2 } from "react/jsx-runtime";
57
+ var FloatingMenu = React2.forwardRef(
58
+ ({ pluginKey = "floatingMenu", editor, shouldShow = null, options, children, ...restProps }, ref) => {
59
+ const menuEl = useRef2(document.createElement("div"));
60
+ if (typeof ref === "function") {
61
+ ref(menuEl.current);
62
+ } else if (ref) {
63
+ ref.current = menuEl.current;
64
+ }
65
+ const { editor: currentEditor } = useCurrentEditor2();
66
+ useEffect2(() => {
67
+ const floatingMenuElement = menuEl.current;
68
+ floatingMenuElement.style.visibility = "hidden";
69
+ floatingMenuElement.style.position = "absolute";
70
+ if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
71
+ return;
72
+ }
73
+ const attachToEditor = editor || currentEditor;
74
+ if (!attachToEditor) {
75
+ console.warn(
76
+ "FloatingMenu component is not rendered inside of an editor component or does not have editor prop."
77
+ );
78
+ return;
79
+ }
80
+ const plugin = FloatingMenuPlugin({
81
+ editor: attachToEditor,
82
+ element: floatingMenuElement,
83
+ pluginKey,
84
+ shouldShow,
85
+ options
86
+ });
87
+ attachToEditor.registerPlugin(plugin);
88
+ return () => {
89
+ attachToEditor.unregisterPlugin(pluginKey);
90
+ window.requestAnimationFrame(() => {
91
+ if (floatingMenuElement.parentNode) {
92
+ floatingMenuElement.parentNode.removeChild(floatingMenuElement);
93
+ }
94
+ });
95
+ };
96
+ }, [editor, currentEditor]);
97
+ return createPortal2(/* @__PURE__ */ jsx2("div", { ...restProps, children }), menuEl.current);
98
+ }
99
+ );
100
+ export {
101
+ BubbleMenu,
102
+ FloatingMenu
103
+ };
104
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/menus/BubbleMenu.tsx","../../src/menus/FloatingMenu.tsx"],"sourcesContent":["import { type BubbleMenuPluginProps, BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type BubbleMenuProps = Optional<Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'>, 'editor'> &\n React.HTMLAttributes<HTMLDivElement>\n\nexport const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(\n (\n { pluginKey = 'bubbleMenu', editor, updateDelay, resizeDelay, shouldShow = null, options, children, ...restProps },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n useEffect(() => {\n const bubbleMenuElement = menuEl.current\n\n bubbleMenuElement.style.visibility = 'hidden'\n bubbleMenuElement.style.position = 'absolute'\n\n if (editor?.isDestroyed || (currentEditor as any)?.isDestroyed) {\n return\n }\n\n const attachToEditor = editor || currentEditor\n\n if (!attachToEditor) {\n console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')\n return\n }\n\n const plugin = BubbleMenuPlugin({\n updateDelay,\n resizeDelay,\n editor: attachToEditor,\n element: bubbleMenuElement,\n pluginKey,\n shouldShow,\n options,\n })\n\n attachToEditor.registerPlugin(plugin)\n\n return () => {\n attachToEditor.unregisterPlugin(pluginKey)\n window.requestAnimationFrame(() => {\n if (bubbleMenuElement.parentNode) {\n bubbleMenuElement.parentNode.removeChild(bubbleMenuElement)\n }\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor, currentEditor])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element' | 'editor'> & {\n editor: FloatingMenuPluginProps['editor'] | null\n options?: FloatingMenuPluginProps['options']\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(\n ({ pluginKey = 'floatingMenu', editor, shouldShow = null, options, children, ...restProps }, ref) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n useEffect(() => {\n const floatingMenuElement = menuEl.current\n\n floatingMenuElement.style.visibility = 'hidden'\n floatingMenuElement.style.position = 'absolute'\n\n if (editor?.isDestroyed || (currentEditor as any)?.isDestroyed) {\n return\n }\n\n const attachToEditor = editor || currentEditor\n\n if (!attachToEditor) {\n console.warn(\n 'FloatingMenu component is not rendered inside of an editor component or does not have editor prop.',\n )\n return\n }\n\n const plugin = FloatingMenuPlugin({\n editor: attachToEditor,\n element: floatingMenuElement,\n pluginKey,\n shouldShow,\n options,\n })\n\n attachToEditor.registerPlugin(plugin)\n\n return () => {\n attachToEditor.unregisterPlugin(pluginKey)\n window.requestAnimationFrame(() => {\n if (floatingMenuElement.parentNode) {\n floatingMenuElement.parentNode.removeChild(floatingMenuElement)\n }\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor, currentEditor])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n"],"mappings":"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","names":["useCurrentEditor","React","useEffect","useRef","createPortal","jsx"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/react",
3
3
  "description": "React components for tiptap",
4
- "version": "3.0.0",
4
+ "version": "3.0.1",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -14,39 +14,52 @@
14
14
  },
15
15
  "exports": {
16
16
  ".": {
17
- "types": "./dist/packages/react/src/index.d.ts",
17
+ "types": {
18
+ "import": "./dist/index.d.ts",
19
+ "require": "./dist/index.d.cts"
20
+ },
18
21
  "import": "./dist/index.js",
19
22
  "require": "./dist/index.cjs"
23
+ },
24
+ "./menus": {
25
+ "types": {
26
+ "import": "./dist/menus/index.d.ts",
27
+ "require": "./dist/menus/index.d.cts"
28
+ },
29
+ "import": "./dist/menus/index.js",
30
+ "require": "./dist/menus/index.cjs"
20
31
  }
21
32
  },
22
33
  "main": "dist/index.cjs",
23
34
  "module": "dist/index.js",
24
- "umd": "dist/index.umd.js",
25
- "types": "dist/packages/react/src/index.d.ts",
35
+ "types": "dist/index.d.ts",
26
36
  "type": "module",
27
37
  "files": [
28
38
  "src",
29
39
  "dist"
30
40
  ],
31
41
  "dependencies": {
32
- "@tiptap/extension-bubble-menu": "^3.0.0",
33
- "@tiptap/extension-floating-menu": "^3.0.0",
34
- "use-sync-external-store": "^1.2.2",
35
- "@types/use-sync-external-store": "^0.0.6"
42
+ "@types/use-sync-external-store": "^0.0.6",
43
+ "fast-deep-equal": "^3.1.3",
44
+ "use-sync-external-store": "^1.4.0"
36
45
  },
37
46
  "devDependencies": {
38
- "@tiptap/core": "^3.0.0",
39
- "@tiptap/pm": "^3.0.0",
40
- "@types/react": "^18.2.14",
41
- "@types/react-dom": "^18.2.6",
42
- "react": "^18.0.0",
43
- "react-dom": "^18.0.0"
47
+ "@types/react": "^18.3.18",
48
+ "@types/react-dom": "^18.3.5",
49
+ "react": "^19.0.0",
50
+ "react-dom": "^19.0.0",
51
+ "@tiptap/core": "^3.0.1",
52
+ "@tiptap/pm": "^3.0.1"
53
+ },
54
+ "optionalDependencies": {
55
+ "@tiptap/extension-bubble-menu": "^3.0.1",
56
+ "@tiptap/extension-floating-menu": "^3.0.1"
44
57
  },
45
58
  "peerDependencies": {
46
- "@tiptap/core": "^3.0.0",
47
- "@tiptap/pm": "^3.0.0",
48
- "react": "^17.0.0 || ^18.0.0",
49
- "react-dom": "^17.0.0 || ^18.0.0"
59
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
60
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
61
+ "@tiptap/core": "^3.0.1",
62
+ "@tiptap/pm": "^3.0.1"
50
63
  },
51
64
  "repository": {
52
65
  "type": "git",
@@ -55,7 +68,7 @@
55
68
  },
56
69
  "sideEffects": false,
57
70
  "scripts": {
58
- "clean": "rm -rf dist",
59
- "build": "npm run clean && rollup -c"
71
+ "build": "tsup",
72
+ "lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
60
73
  }
61
- }
74
+ }
package/src/Context.tsx CHANGED
@@ -1,11 +1,13 @@
1
- import React, { createContext, ReactNode, useContext } from 'react'
1
+ import type { Editor } from '@tiptap/core'
2
+ import type { HTMLAttributes, ReactNode } from 'react'
3
+ import React, { createContext, useContext, useMemo } from 'react'
2
4
 
3
- import { Editor } from './Editor.js'
4
5
  import { EditorContent } from './EditorContent.js'
5
- import { useEditor, UseEditorOptions } from './useEditor.js'
6
+ import type { UseEditorOptions } from './useEditor.js'
7
+ import { useEditor } from './useEditor.js'
6
8
 
7
9
  export type EditorContextValue = {
8
- editor: Editor | null;
10
+ editor: Editor | null
9
11
  }
10
12
 
11
13
  export const EditorContext = createContext<EditorContextValue>({
@@ -20,9 +22,10 @@ export const EditorConsumer = EditorContext.Consumer
20
22
  export const useCurrentEditor = () => useContext(EditorContext)
21
23
 
22
24
  export type EditorProviderProps = {
23
- children?: ReactNode;
24
- slotBefore?: ReactNode;
25
- slotAfter?: ReactNode;
25
+ children?: ReactNode
26
+ slotBefore?: ReactNode
27
+ slotAfter?: ReactNode
28
+ editorContainerProps?: HTMLAttributes<HTMLDivElement>
26
29
  } & UseEditorOptions
27
30
 
28
31
  /**
@@ -31,21 +34,24 @@ export type EditorProviderProps = {
31
34
  * with `useCurrentEditor`.
32
35
  */
33
36
  export function EditorProvider({
34
- children, slotAfter, slotBefore, ...editorOptions
37
+ children,
38
+ slotAfter,
39
+ slotBefore,
40
+ editorContainerProps = {},
41
+ ...editorOptions
35
42
  }: EditorProviderProps) {
36
43
  const editor = useEditor(editorOptions)
44
+ const contextValue = useMemo(() => ({ editor }), [editor])
37
45
 
38
46
  if (!editor) {
39
47
  return null
40
48
  }
41
49
 
42
50
  return (
43
- <EditorContext.Provider value={{ editor }}>
51
+ <EditorContext.Provider value={contextValue}>
44
52
  {slotBefore}
45
53
  <EditorConsumer>
46
- {({ editor: currentEditor }) => (
47
- <EditorContent editor={currentEditor} />
48
- )}
54
+ {({ editor: currentEditor }) => <EditorContent editor={currentEditor} {...editorContainerProps} />}
49
55
  </EditorConsumer>
50
56
  {children}
51
57
  {slotAfter}
package/src/Editor.ts CHANGED
@@ -1,14 +1,13 @@
1
- import { Editor as CoreEditor } from '@tiptap/core'
2
- import React from 'react'
1
+ import type { Editor } from '@tiptap/core'
2
+ import type { ReactPortal } from 'react'
3
3
 
4
- import { EditorContentProps, EditorContentState } from './EditorContent.js'
5
- import { ReactRenderer } from './ReactRenderer.js'
4
+ import type { ReactRenderer } from './ReactRenderer.js'
6
5
 
7
- type ContentComponent = React.Component<EditorContentProps, EditorContentState> & {
8
- setRenderer(id: string, renderer: ReactRenderer): void;
9
- removeRenderer(id: string): void;
10
- }
11
-
12
- export class Editor extends CoreEditor {
13
- public contentComponent: ContentComponent | null = null
6
+ export type EditorWithContentComponent = Editor & { contentComponent?: ContentComponent | null }
7
+ export type ContentComponent = {
8
+ setRenderer(id: string, renderer: ReactRenderer): void
9
+ removeRenderer(id: string): void
10
+ subscribe: (callback: () => void) => () => void
11
+ getSnapshot: () => Record<string, ReactPortal>
12
+ getServerSnapshot: () => Record<string, ReactPortal>
14
13
  }
@@ -1,56 +1,105 @@
1
- import React, {
2
- ForwardedRef, forwardRef, HTMLProps, LegacyRef, MutableRefObject,
3
- } from 'react'
4
- import ReactDOM, { flushSync } from 'react-dom'
1
+ import type { Editor } from '@tiptap/core'
2
+ import type { ForwardedRef, HTMLProps, LegacyRef, MutableRefObject } from 'react'
3
+ import React, { forwardRef } from 'react'
4
+ import ReactDOM from 'react-dom'
5
+ import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js'
5
6
 
6
- import { Editor } from './Editor.js'
7
- import { ReactRenderer } from './ReactRenderer.js'
7
+ import type { ContentComponent, EditorWithContentComponent } from './Editor.js'
8
+ import type { ReactRenderer } from './ReactRenderer.js'
8
9
 
9
- const mergeRefs = <T extends HTMLDivElement>(
10
- ...refs: Array<MutableRefObject<T> | LegacyRef<T> | undefined>
11
- ) => {
10
+ const mergeRefs = <T extends HTMLDivElement>(...refs: Array<MutableRefObject<T> | LegacyRef<T> | undefined>) => {
12
11
  return (node: T) => {
13
12
  refs.forEach(ref => {
14
13
  if (typeof ref === 'function') {
15
14
  ref(node)
16
15
  } else if (ref) {
17
- (ref as MutableRefObject<T | null>).current = node
16
+ ;(ref as MutableRefObject<T | null>).current = node
18
17
  }
19
18
  })
20
19
  }
21
20
  }
22
21
 
23
- const Portals: React.FC<{ renderers: Record<string, ReactRenderer> }> = ({ renderers }) => {
24
- return (
25
- <>
26
- {Object.entries(renderers).map(([key, renderer]) => {
27
- return ReactDOM.createPortal(renderer.reactElement, renderer.element, key)
28
- })}
29
- </>
22
+ /**
23
+ * This component renders all of the editor's node views.
24
+ */
25
+ const Portals: React.FC<{ contentComponent: ContentComponent }> = ({ contentComponent }) => {
26
+ // For performance reasons, we render the node view portals on state changes only
27
+ const renderers = useSyncExternalStore(
28
+ contentComponent.subscribe,
29
+ contentComponent.getSnapshot,
30
+ contentComponent.getServerSnapshot,
30
31
  )
32
+
33
+ // This allows us to directly render the portals without any additional wrapper
34
+ return <>{Object.values(renderers)}</>
31
35
  }
32
36
 
33
37
  export interface EditorContentProps extends HTMLProps<HTMLDivElement> {
34
- editor: Editor | null;
35
- innerRef?: ForwardedRef<HTMLDivElement | null>;
38
+ editor: Editor | null
39
+ innerRef?: ForwardedRef<HTMLDivElement | null>
36
40
  }
37
41
 
38
- export interface EditorContentState {
39
- renderers: Record<string, ReactRenderer>;
42
+ function getInstance(): ContentComponent {
43
+ const subscribers = new Set<() => void>()
44
+ let renderers: Record<string, React.ReactPortal> = {}
45
+
46
+ return {
47
+ /**
48
+ * Subscribe to the editor instance's changes.
49
+ */
50
+ subscribe(callback: () => void) {
51
+ subscribers.add(callback)
52
+ return () => {
53
+ subscribers.delete(callback)
54
+ }
55
+ },
56
+ getSnapshot() {
57
+ return renderers
58
+ },
59
+ getServerSnapshot() {
60
+ return renderers
61
+ },
62
+ /**
63
+ * Adds a new NodeView Renderer to the editor.
64
+ */
65
+ setRenderer(id: string, renderer: ReactRenderer) {
66
+ renderers = {
67
+ ...renderers,
68
+ [id]: ReactDOM.createPortal(renderer.reactElement, renderer.element, id),
69
+ }
70
+
71
+ subscribers.forEach(subscriber => subscriber())
72
+ },
73
+ /**
74
+ * Removes a NodeView Renderer from the editor.
75
+ */
76
+ removeRenderer(id: string) {
77
+ const nextRenderers = { ...renderers }
78
+
79
+ delete nextRenderers[id]
80
+ renderers = nextRenderers
81
+ subscribers.forEach(subscriber => subscriber())
82
+ },
83
+ }
40
84
  }
41
85
 
42
- export class PureEditorContent extends React.Component<EditorContentProps, EditorContentState> {
86
+ export class PureEditorContent extends React.Component<
87
+ EditorContentProps,
88
+ { hasContentComponentInitialized: boolean }
89
+ > {
43
90
  editorContentRef: React.RefObject<any>
44
91
 
45
92
  initialized: boolean
46
93
 
94
+ unsubscribeToContentComponent?: () => void
95
+
47
96
  constructor(props: EditorContentProps) {
48
97
  super(props)
49
98
  this.editorContentRef = React.createRef()
50
99
  this.initialized = false
51
100
 
52
101
  this.state = {
53
- renderers: {},
102
+ hasContentComponentInitialized: Boolean((props.editor as EditorWithContentComponent | null)?.contentComponent),
54
103
  }
55
104
  }
56
105
 
@@ -63,7 +112,7 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
63
112
  }
64
113
 
65
114
  init() {
66
- const { editor } = this.props
115
+ const editor = this.props.editor as EditorWithContentComponent | null
67
116
 
68
117
  if (editor && !editor.isDestroyed && editor.options.element) {
69
118
  if (editor.contentComponent) {
@@ -78,7 +127,27 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
78
127
  element,
79
128
  })
80
129
 
81
- editor.contentComponent = this
130
+ editor.contentComponent = getInstance()
131
+
132
+ // Has the content component been initialized?
133
+ if (!this.state.hasContentComponentInitialized) {
134
+ // Subscribe to the content component
135
+ this.unsubscribeToContentComponent = editor.contentComponent.subscribe(() => {
136
+ this.setState(prevState => {
137
+ if (!prevState.hasContentComponentInitialized) {
138
+ return {
139
+ hasContentComponentInitialized: true,
140
+ }
141
+ }
142
+ return prevState
143
+ })
144
+
145
+ // Unsubscribe to previous content component
146
+ if (this.unsubscribeToContentComponent) {
147
+ this.unsubscribeToContentComponent()
148
+ }
149
+ })
150
+ }
82
151
 
83
152
  editor.createNodeViews()
84
153
 
@@ -86,43 +155,8 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
86
155
  }
87
156
  }
88
157
 
89
- maybeFlushSync(fn: () => void) {
90
- // Avoid calling flushSync until the editor is initialized.
91
- // Initialization happens during the componentDidMount or componentDidUpdate
92
- // lifecycle methods, and React doesn't allow calling flushSync from inside
93
- // a lifecycle method.
94
- if (this.initialized) {
95
- flushSync(fn)
96
- } else {
97
- fn()
98
- }
99
- }
100
-
101
- setRenderer(id: string, renderer: ReactRenderer) {
102
- this.maybeFlushSync(() => {
103
- this.setState(({ renderers }) => ({
104
- renderers: {
105
- ...renderers,
106
- [id]: renderer,
107
- },
108
- }))
109
- })
110
- }
111
-
112
- removeRenderer(id: string) {
113
- this.maybeFlushSync(() => {
114
- this.setState(({ renderers }) => {
115
- const nextRenderers = { ...renderers }
116
-
117
- delete nextRenderers[id]
118
-
119
- return { renderers: nextRenderers }
120
- })
121
- })
122
- }
123
-
124
158
  componentWillUnmount() {
125
- const { editor } = this.props
159
+ const editor = this.props.editor as EditorWithContentComponent | null
126
160
 
127
161
  if (!editor) {
128
162
  return
@@ -136,12 +170,17 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
136
170
  })
137
171
  }
138
172
 
173
+ if (this.unsubscribeToContentComponent) {
174
+ this.unsubscribeToContentComponent()
175
+ }
176
+
139
177
  editor.contentComponent = null
140
178
 
141
- if (!editor.options.element.firstChild) {
179
+ if (!editor.options.element?.firstChild) {
142
180
  return
143
181
  }
144
182
 
183
+ // TODO using the new editor.mount method might allow us to remove this
145
184
  const newElement = document.createElement('div')
146
185
 
147
186
  newElement.append(...editor.options.element.childNodes)
@@ -158,7 +197,7 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
158
197
  <>
159
198
  <div ref={mergeRefs(innerRef, this.editorContentRef)} {...rest} />
160
199
  {/* @ts-ignore */}
161
- <Portals renderers={this.state.renderers} />
200
+ {editor?.contentComponent && <Portals contentComponent={editor.contentComponent} />}
162
201
  </>
163
202
  )
164
203
  }
@@ -168,7 +207,8 @@ export class PureEditorContent extends React.Component<EditorContentProps, Edito
168
207
  const EditorContentWithKey = forwardRef<HTMLDivElement, EditorContentProps>(
169
208
  (props: Omit<EditorContentProps, 'innerRef'>, ref) => {
170
209
  const key = React.useMemo(() => {
171
- return Math.floor(Math.random() * 0xFFFFFFFF).toString()
210
+ return Math.floor(Math.random() * 0xffffffff).toString()
211
+ // eslint-disable-next-line react-hooks/exhaustive-deps
172
212
  }, [props.editor])
173
213
 
174
214
  // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
@@ -1,17 +1,20 @@
1
+ import type { ComponentProps } from 'react'
1
2
  import React from 'react'
2
3
 
3
4
  import { useReactNodeView } from './useReactNodeView.js'
4
5
 
5
- export interface NodeViewContentProps {
6
- [key: string]: any,
7
- as?: React.ElementType,
8
- }
6
+ export type NodeViewContentProps<T extends keyof React.JSX.IntrinsicElements = 'div'> = {
7
+ as?: NoInfer<T>
8
+ } & ComponentProps<T>
9
9
 
10
- export const NodeViewContent: React.FC<NodeViewContentProps> = props => {
11
- const Tag = props.as || 'div'
12
- const { nodeViewContentRef } = useReactNodeView()
10
+ export function NodeViewContent<T extends keyof React.JSX.IntrinsicElements = 'div'>({
11
+ as: Tag = 'div' as T,
12
+ ...props
13
+ }: NodeViewContentProps<T>) {
14
+ const { nodeViewContentRef, nodeViewContentChildren } = useReactNodeView()
13
15
 
14
16
  return (
17
+ // @ts-ignore
15
18
  <Tag
16
19
  {...props}
17
20
  ref={nodeViewContentRef}
@@ -20,6 +23,8 @@ export const NodeViewContent: React.FC<NodeViewContentProps> = props => {
20
23
  whiteSpace: 'pre-wrap',
21
24
  ...props.style,
22
25
  }}
23
- />
26
+ >
27
+ {nodeViewContentChildren}
28
+ </Tag>
24
29
  )
25
30
  }
@@ -3,8 +3,8 @@ import React from 'react'
3
3
  import { useReactNodeView } from './useReactNodeView.js'
4
4
 
5
5
  export interface NodeViewWrapperProps {
6
- [key: string]: any,
7
- as?: React.ElementType,
6
+ [key: string]: any
7
+ as?: React.ElementType
8
8
  }
9
9
 
10
10
  export const NodeViewWrapper: React.FC<NodeViewWrapperProps> = React.forwardRef((props, ref) => {
@@ -12,6 +12,7 @@ export const NodeViewWrapper: React.FC<NodeViewWrapperProps> = React.forwardRef(
12
12
  const Tag = props.as || 'div'
13
13
 
14
14
  return (
15
+ // @ts-ignore
15
16
  <Tag
16
17
  {...props}
17
18
  ref={ref}