@tiptap/react 2.5.0-beta.2 → 2.5.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/index.cjs +529 -536
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +527 -527
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.umd.js +529 -536
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/packages/core/src/CommandManager.d.ts +20 -0
  8. package/dist/packages/core/src/Editor.d.ts +161 -0
  9. package/dist/packages/core/src/EventEmitter.d.ts +11 -0
  10. package/dist/packages/core/src/Extension.d.ts +343 -0
  11. package/dist/packages/core/src/ExtensionManager.d.ts +55 -0
  12. package/dist/packages/core/src/InputRule.d.ts +42 -0
  13. package/dist/packages/core/src/Mark.d.ts +451 -0
  14. package/dist/packages/core/src/Node.d.ts +611 -0
  15. package/dist/packages/core/src/NodePos.d.ts +44 -0
  16. package/dist/packages/core/src/NodeView.d.ts +31 -0
  17. package/dist/packages/core/src/PasteRule.d.ts +50 -0
  18. package/dist/packages/core/src/Tracker.d.ts +11 -0
  19. package/dist/packages/core/src/commands/blur.d.ts +13 -0
  20. package/dist/packages/core/src/commands/clearContent.d.ts +14 -0
  21. package/dist/packages/core/src/commands/clearNodes.d.ts +13 -0
  22. package/dist/packages/core/src/commands/command.d.ts +18 -0
  23. package/dist/packages/core/src/commands/createParagraphNear.d.ts +13 -0
  24. package/dist/packages/core/src/commands/cut.d.ts +20 -0
  25. package/dist/packages/core/src/commands/deleteCurrentNode.d.ts +13 -0
  26. package/dist/packages/core/src/commands/deleteNode.d.ts +15 -0
  27. package/dist/packages/core/src/commands/deleteRange.d.ts +14 -0
  28. package/dist/packages/core/src/commands/deleteSelection.d.ts +13 -0
  29. package/dist/packages/core/src/commands/enter.d.ts +13 -0
  30. package/dist/packages/core/src/commands/exitCode.d.ts +13 -0
  31. package/dist/packages/core/src/commands/extendMarkRange.d.ts +25 -0
  32. package/dist/packages/core/src/commands/first.d.ts +14 -0
  33. package/dist/packages/core/src/commands/focus.d.ts +27 -0
  34. package/dist/packages/core/src/commands/forEach.d.ts +14 -0
  35. package/dist/packages/core/src/commands/index.d.ts +55 -0
  36. package/dist/packages/core/src/commands/insertContent.d.ts +34 -0
  37. package/dist/packages/core/src/commands/insertContentAt.d.ts +47 -0
  38. package/dist/packages/core/src/commands/join.d.ts +41 -0
  39. package/dist/packages/core/src/commands/joinItemBackward.d.ts +13 -0
  40. package/dist/packages/core/src/commands/joinItemForward.d.ts +13 -0
  41. package/dist/packages/core/src/commands/joinTextblockBackward.d.ts +12 -0
  42. package/dist/packages/core/src/commands/joinTextblockForward.d.ts +12 -0
  43. package/dist/packages/core/src/commands/keyboardShortcut.d.ts +14 -0
  44. package/dist/packages/core/src/commands/lift.d.ts +17 -0
  45. package/dist/packages/core/src/commands/liftEmptyBlock.d.ts +13 -0
  46. package/dist/packages/core/src/commands/liftListItem.d.ts +15 -0
  47. package/dist/packages/core/src/commands/newlineInCode.d.ts +13 -0
  48. package/dist/packages/core/src/commands/resetAttributes.d.ts +16 -0
  49. package/dist/packages/core/src/commands/scrollIntoView.d.ts +13 -0
  50. package/dist/packages/core/src/commands/selectAll.d.ts +13 -0
  51. package/dist/packages/core/src/commands/selectNodeBackward.d.ts +13 -0
  52. package/dist/packages/core/src/commands/selectNodeForward.d.ts +13 -0
  53. package/dist/packages/core/src/commands/selectParentNode.d.ts +13 -0
  54. package/dist/packages/core/src/commands/selectTextblockEnd.d.ts +13 -0
  55. package/dist/packages/core/src/commands/selectTextblockStart.d.ts +13 -0
  56. package/dist/packages/core/src/commands/setContent.d.ts +40 -0
  57. package/dist/packages/core/src/commands/setMark.d.ts +15 -0
  58. package/dist/packages/core/src/commands/setMeta.d.ts +15 -0
  59. package/dist/packages/core/src/commands/setNode.d.ts +16 -0
  60. package/dist/packages/core/src/commands/setNodeSelection.d.ts +14 -0
  61. package/dist/packages/core/src/commands/setTextSelection.d.ts +14 -0
  62. package/dist/packages/core/src/commands/sinkListItem.d.ts +15 -0
  63. package/dist/packages/core/src/commands/splitBlock.d.ts +17 -0
  64. package/dist/packages/core/src/commands/splitListItem.d.ts +15 -0
  65. package/dist/packages/core/src/commands/toggleList.d.ts +18 -0
  66. package/dist/packages/core/src/commands/toggleMark.d.ts +30 -0
  67. package/dist/packages/core/src/commands/toggleNode.d.ts +17 -0
  68. package/dist/packages/core/src/commands/toggleWrap.d.ts +16 -0
  69. package/dist/packages/core/src/commands/undoInputRule.d.ts +13 -0
  70. package/dist/packages/core/src/commands/unsetAllMarks.d.ts +13 -0
  71. package/dist/packages/core/src/commands/unsetMark.d.ts +25 -0
  72. package/dist/packages/core/src/commands/updateAttributes.d.ts +24 -0
  73. package/dist/packages/core/src/commands/wrapIn.d.ts +16 -0
  74. package/dist/packages/core/src/commands/wrapInList.d.ts +16 -0
  75. package/dist/packages/core/src/extensions/clipboardTextSerializer.d.ts +5 -0
  76. package/dist/packages/core/src/extensions/commands.d.ts +3 -0
  77. package/dist/packages/core/src/extensions/editable.d.ts +2 -0
  78. package/dist/packages/core/src/extensions/focusEvents.d.ts +2 -0
  79. package/dist/packages/core/src/extensions/index.d.ts +6 -0
  80. package/dist/packages/core/src/extensions/keymap.d.ts +2 -0
  81. package/dist/packages/core/src/extensions/tabindex.d.ts +2 -0
  82. package/dist/packages/core/src/helpers/combineTransactionSteps.d.ts +10 -0
  83. package/dist/packages/core/src/helpers/createChainableState.d.ts +10 -0
  84. package/dist/packages/core/src/helpers/createDocument.d.ts +12 -0
  85. package/dist/packages/core/src/helpers/createNodeFromContent.d.ts +15 -0
  86. package/dist/packages/core/src/helpers/defaultBlockAt.d.ts +7 -0
  87. package/dist/packages/core/src/helpers/findChildren.d.ts +9 -0
  88. package/dist/packages/core/src/helpers/findChildrenInRange.d.ts +10 -0
  89. package/dist/packages/core/src/helpers/findParentNode.d.ts +16 -0
  90. package/dist/packages/core/src/helpers/findParentNodeClosestToPos.d.ts +17 -0
  91. package/dist/packages/core/src/helpers/generateHTML.d.ts +8 -0
  92. package/dist/packages/core/src/helpers/generateJSON.d.ts +8 -0
  93. package/dist/packages/core/src/helpers/generateText.d.ts +12 -0
  94. package/dist/packages/core/src/helpers/getAttributes.d.ts +9 -0
  95. package/dist/packages/core/src/helpers/getAttributesFromExtensions.d.ts +6 -0
  96. package/dist/packages/core/src/helpers/getChangedRanges.d.ts +11 -0
  97. package/dist/packages/core/src/helpers/getDebugJSON.d.ts +8 -0
  98. package/dist/packages/core/src/helpers/getExtensionField.d.ts +9 -0
  99. package/dist/packages/core/src/helpers/getHTMLFromFragment.d.ts +2 -0
  100. package/dist/packages/core/src/helpers/getMarkAttributes.d.ts +3 -0
  101. package/dist/packages/core/src/helpers/getMarkRange.d.ts +3 -0
  102. package/dist/packages/core/src/helpers/getMarkType.d.ts +2 -0
  103. package/dist/packages/core/src/helpers/getMarksBetween.d.ts +3 -0
  104. package/dist/packages/core/src/helpers/getNodeAtPosition.d.ts +11 -0
  105. package/dist/packages/core/src/helpers/getNodeAttributes.d.ts +3 -0
  106. package/dist/packages/core/src/helpers/getNodeType.d.ts +2 -0
  107. package/dist/packages/core/src/helpers/getRenderedAttributes.d.ts +3 -0
  108. package/dist/packages/core/src/helpers/getSchema.d.ts +4 -0
  109. package/dist/packages/core/src/helpers/getSchemaByResolvedExtensions.d.ts +10 -0
  110. package/dist/packages/core/src/helpers/getSchemaTypeByName.d.ts +8 -0
  111. package/dist/packages/core/src/helpers/getSchemaTypeNameByName.d.ts +8 -0
  112. package/dist/packages/core/src/helpers/getSplittedAttributes.d.ts +9 -0
  113. package/dist/packages/core/src/helpers/getText.d.ts +15 -0
  114. package/dist/packages/core/src/helpers/getTextBetween.d.ts +14 -0
  115. package/dist/packages/core/src/helpers/getTextContentFromNodes.d.ts +8 -0
  116. package/dist/packages/core/src/helpers/getTextSerializersFromSchema.d.ts +8 -0
  117. package/dist/packages/core/src/helpers/index.d.ts +50 -0
  118. package/dist/packages/core/src/helpers/injectExtensionAttributesToParseRule.d.ts +9 -0
  119. package/dist/packages/core/src/helpers/isActive.d.ts +2 -0
  120. package/dist/packages/core/src/helpers/isAtEndOfNode.d.ts +2 -0
  121. package/dist/packages/core/src/helpers/isAtStartOfNode.d.ts +2 -0
  122. package/dist/packages/core/src/helpers/isExtensionRulesEnabled.d.ts +2 -0
  123. package/dist/packages/core/src/helpers/isList.d.ts +2 -0
  124. package/dist/packages/core/src/helpers/isMarkActive.d.ts +3 -0
  125. package/dist/packages/core/src/helpers/isNodeActive.d.ts +3 -0
  126. package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +2 -0
  127. package/dist/packages/core/src/helpers/isNodeSelection.d.ts +2 -0
  128. package/dist/packages/core/src/helpers/isTextSelection.d.ts +2 -0
  129. package/dist/packages/core/src/helpers/posToDOMRect.d.ts +2 -0
  130. package/dist/packages/core/src/helpers/resolveFocusPosition.d.ts +4 -0
  131. package/dist/packages/core/src/helpers/selectionToInsertionEnd.d.ts +2 -0
  132. package/dist/packages/core/src/helpers/splitExtensions.d.ts +9 -0
  133. package/dist/packages/core/src/index.d.ts +24 -0
  134. package/dist/packages/core/src/inputRules/index.d.ts +5 -0
  135. package/dist/packages/core/src/inputRules/markInputRule.d.ts +13 -0
  136. package/dist/packages/core/src/inputRules/nodeInputRule.d.ts +23 -0
  137. package/dist/packages/core/src/inputRules/textInputRule.d.ts +10 -0
  138. package/dist/packages/core/src/inputRules/textblockTypeInputRule.d.ts +15 -0
  139. package/dist/packages/core/src/inputRules/wrappingInputRule.d.ts +28 -0
  140. package/dist/packages/core/src/pasteRules/index.d.ts +3 -0
  141. package/dist/packages/core/src/pasteRules/markPasteRule.d.ts +13 -0
  142. package/dist/packages/core/src/pasteRules/nodePasteRule.d.ts +13 -0
  143. package/dist/packages/core/src/pasteRules/textPasteRule.d.ts +10 -0
  144. package/dist/packages/core/src/style.d.ts +1 -0
  145. package/dist/packages/core/src/types.d.ts +250 -0
  146. package/dist/packages/core/src/utilities/callOrReturn.d.ts +9 -0
  147. package/dist/packages/core/src/utilities/createStyleTag.d.ts +1 -0
  148. package/dist/packages/core/src/utilities/deleteProps.d.ts +6 -0
  149. package/dist/packages/core/src/utilities/elementFromString.d.ts +1 -0
  150. package/dist/packages/core/src/utilities/escapeForRegEx.d.ts +1 -0
  151. package/dist/packages/core/src/utilities/findDuplicates.d.ts +1 -0
  152. package/dist/packages/core/src/utilities/fromString.d.ts +1 -0
  153. package/dist/packages/core/src/utilities/index.d.ts +20 -0
  154. package/dist/packages/core/src/utilities/isAndroid.d.ts +1 -0
  155. package/dist/packages/core/src/utilities/isEmptyObject.d.ts +1 -0
  156. package/dist/packages/core/src/utilities/isFunction.d.ts +1 -0
  157. package/dist/packages/core/src/utilities/isMacOS.d.ts +1 -0
  158. package/dist/packages/core/src/utilities/isNumber.d.ts +1 -0
  159. package/dist/packages/core/src/utilities/isPlainObject.d.ts +1 -0
  160. package/dist/packages/core/src/utilities/isRegExp.d.ts +1 -0
  161. package/dist/packages/core/src/utilities/isString.d.ts +1 -0
  162. package/dist/packages/core/src/utilities/isiOS.d.ts +1 -0
  163. package/dist/packages/core/src/utilities/mergeAttributes.d.ts +1 -0
  164. package/dist/packages/core/src/utilities/mergeDeep.d.ts +1 -0
  165. package/dist/packages/core/src/utilities/minMax.d.ts +1 -0
  166. package/dist/packages/core/src/utilities/objectIncludes.d.ts +8 -0
  167. package/dist/packages/core/src/utilities/removeDuplicates.d.ts +8 -0
  168. package/dist/packages/extension-bubble-menu/src/bubble-menu-plugin.d.ts +76 -0
  169. package/dist/packages/extension-bubble-menu/src/bubble-menu.d.ts +15 -0
  170. package/dist/packages/extension-bubble-menu/src/index.d.ts +4 -0
  171. package/dist/packages/extension-floating-menu/src/floating-menu-plugin.d.ts +66 -0
  172. package/dist/packages/extension-floating-menu/src/floating-menu.d.ts +15 -0
  173. package/dist/packages/extension-floating-menu/src/index.d.ts +4 -0
  174. package/dist/packages/react/src/BubbleMenu.d.ts +11 -11
  175. package/dist/packages/react/src/Context.d.ts +15 -15
  176. package/dist/packages/react/src/Editor.d.ts +12 -12
  177. package/dist/packages/react/src/EditorContent.d.ts +24 -24
  178. package/dist/packages/react/src/FloatingMenu.d.ts +10 -10
  179. package/dist/packages/react/src/NodeViewContent.d.ts +6 -6
  180. package/dist/packages/react/src/NodeViewWrapper.d.ts +6 -6
  181. package/dist/packages/react/src/ReactNodeViewRenderer.d.ts +16 -16
  182. package/dist/packages/react/src/ReactRenderer.d.ts +62 -62
  183. package/dist/packages/react/src/index.d.ts +12 -12
  184. package/dist/packages/react/src/useEditor.d.ts +11 -11
  185. package/dist/packages/react/src/useReactNodeView.d.ts +7 -7
  186. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -5,553 +5,553 @@ import { Editor as Editor$1, NodeView } from '@tiptap/core';
5
5
  export * from '@tiptap/core';
6
6
  import { FloatingMenuPlugin } from '@tiptap/extension-floating-menu';
7
7
 
8
- const mergeRefs = (...refs) => {
9
- return (node) => {
10
- refs.forEach(ref => {
11
- if (typeof ref === 'function') {
12
- ref(node);
13
- }
14
- else if (ref) {
15
- ref.current = node;
16
- }
17
- });
18
- };
19
- };
20
- const Portals = ({ renderers }) => {
21
- return (React.createElement(React.Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
22
- return ReactDOM.createPortal(renderer.reactElement, renderer.element, key);
23
- })));
24
- };
25
- class PureEditorContent extends React.Component {
26
- constructor(props) {
27
- super(props);
28
- this.editorContentRef = React.createRef();
29
- this.initialized = false;
30
- this.state = {
31
- renderers: {},
32
- };
33
- }
34
- componentDidMount() {
35
- this.init();
36
- }
37
- componentDidUpdate() {
38
- this.init();
39
- }
40
- init() {
41
- const { editor } = this.props;
42
- if (editor && !editor.isDestroyed && editor.options.element) {
43
- if (editor.contentComponent) {
44
- return;
45
- }
46
- const element = this.editorContentRef.current;
47
- element.append(...editor.options.element.childNodes);
48
- editor.setOptions({
49
- element,
50
- });
51
- editor.contentComponent = this;
52
- editor.createNodeViews();
53
- this.initialized = true;
54
- }
55
- }
56
- maybeFlushSync(fn) {
57
- // Avoid calling flushSync until the editor is initialized.
58
- // Initialization happens during the componentDidMount or componentDidUpdate
59
- // lifecycle methods, and React doesn't allow calling flushSync from inside
60
- // a lifecycle method.
61
- if (this.initialized) {
62
- flushSync(fn);
63
- }
64
- else {
65
- fn();
66
- }
67
- }
68
- setRenderer(id, renderer) {
69
- this.maybeFlushSync(() => {
70
- this.setState(({ renderers }) => ({
71
- renderers: {
72
- ...renderers,
73
- [id]: renderer,
74
- },
75
- }));
76
- });
77
- }
78
- removeRenderer(id) {
79
- this.maybeFlushSync(() => {
80
- this.setState(({ renderers }) => {
81
- const nextRenderers = { ...renderers };
82
- delete nextRenderers[id];
83
- return { renderers: nextRenderers };
84
- });
85
- });
86
- }
87
- componentWillUnmount() {
88
- const { editor } = this.props;
89
- if (!editor) {
90
- return;
91
- }
92
- this.initialized = false;
93
- if (!editor.isDestroyed) {
94
- editor.view.setProps({
95
- nodeViews: {},
96
- });
97
- }
98
- editor.contentComponent = null;
99
- if (!editor.options.element.firstChild) {
100
- return;
101
- }
102
- const newElement = document.createElement('div');
103
- newElement.append(...editor.options.element.childNodes);
104
- editor.setOptions({
105
- element: newElement,
106
- });
107
- }
108
- render() {
109
- const { editor, innerRef, ...rest } = this.props;
110
- return (React.createElement(React.Fragment, null,
111
- React.createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
112
- React.createElement(Portals, { renderers: this.state.renderers })));
113
- }
114
- }
115
- // EditorContent should be re-created whenever the Editor instance changes
116
- const EditorContentWithKey = forwardRef((props, ref) => {
117
- const key = React.useMemo(() => {
118
- return Math.floor(Math.random() * 0xFFFFFFFF).toString();
119
- }, [props.editor]);
120
- // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
121
- return React.createElement(PureEditorContent, {
122
- key,
123
- innerRef: ref,
124
- ...props,
125
- });
126
- });
8
+ const mergeRefs = (...refs) => {
9
+ return (node) => {
10
+ refs.forEach(ref => {
11
+ if (typeof ref === 'function') {
12
+ ref(node);
13
+ }
14
+ else if (ref) {
15
+ ref.current = node;
16
+ }
17
+ });
18
+ };
19
+ };
20
+ const Portals = ({ renderers }) => {
21
+ return (React.createElement(React.Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
22
+ return ReactDOM.createPortal(renderer.reactElement, renderer.element, key);
23
+ })));
24
+ };
25
+ class PureEditorContent extends React.Component {
26
+ constructor(props) {
27
+ super(props);
28
+ this.editorContentRef = React.createRef();
29
+ this.initialized = false;
30
+ this.state = {
31
+ renderers: {},
32
+ };
33
+ }
34
+ componentDidMount() {
35
+ this.init();
36
+ }
37
+ componentDidUpdate() {
38
+ this.init();
39
+ }
40
+ init() {
41
+ const { editor } = this.props;
42
+ if (editor && !editor.isDestroyed && editor.options.element) {
43
+ if (editor.contentComponent) {
44
+ return;
45
+ }
46
+ const element = this.editorContentRef.current;
47
+ element.append(...editor.options.element.childNodes);
48
+ editor.setOptions({
49
+ element,
50
+ });
51
+ editor.contentComponent = this;
52
+ editor.createNodeViews();
53
+ this.initialized = true;
54
+ }
55
+ }
56
+ maybeFlushSync(fn) {
57
+ // Avoid calling flushSync until the editor is initialized.
58
+ // Initialization happens during the componentDidMount or componentDidUpdate
59
+ // lifecycle methods, and React doesn't allow calling flushSync from inside
60
+ // a lifecycle method.
61
+ if (this.initialized) {
62
+ flushSync(fn);
63
+ }
64
+ else {
65
+ fn();
66
+ }
67
+ }
68
+ setRenderer(id, renderer) {
69
+ this.maybeFlushSync(() => {
70
+ this.setState(({ renderers }) => ({
71
+ renderers: {
72
+ ...renderers,
73
+ [id]: renderer,
74
+ },
75
+ }));
76
+ });
77
+ }
78
+ removeRenderer(id) {
79
+ this.maybeFlushSync(() => {
80
+ this.setState(({ renderers }) => {
81
+ const nextRenderers = { ...renderers };
82
+ delete nextRenderers[id];
83
+ return { renderers: nextRenderers };
84
+ });
85
+ });
86
+ }
87
+ componentWillUnmount() {
88
+ const { editor } = this.props;
89
+ if (!editor) {
90
+ return;
91
+ }
92
+ this.initialized = false;
93
+ if (!editor.isDestroyed) {
94
+ editor.view.setProps({
95
+ nodeViews: {},
96
+ });
97
+ }
98
+ editor.contentComponent = null;
99
+ if (!editor.options.element.firstChild) {
100
+ return;
101
+ }
102
+ const newElement = document.createElement('div');
103
+ newElement.append(...editor.options.element.childNodes);
104
+ editor.setOptions({
105
+ element: newElement,
106
+ });
107
+ }
108
+ render() {
109
+ const { editor, innerRef, ...rest } = this.props;
110
+ return (React.createElement(React.Fragment, null,
111
+ React.createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
112
+ React.createElement(Portals, { renderers: this.state.renderers })));
113
+ }
114
+ }
115
+ // EditorContent should be re-created whenever the Editor instance changes
116
+ const EditorContentWithKey = forwardRef((props, ref) => {
117
+ const key = React.useMemo(() => {
118
+ return Math.floor(Math.random() * 0xFFFFFFFF).toString();
119
+ }, [props.editor]);
120
+ // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
121
+ return React.createElement(PureEditorContent, {
122
+ key,
123
+ innerRef: ref,
124
+ ...props,
125
+ });
126
+ });
127
127
  const EditorContent = React.memo(EditorContentWithKey);
128
128
 
129
- class Editor extends Editor$1 {
130
- constructor() {
131
- super(...arguments);
132
- this.contentComponent = null;
133
- }
129
+ class Editor extends Editor$1 {
130
+ constructor() {
131
+ super(...arguments);
132
+ this.contentComponent = null;
133
+ }
134
134
  }
135
135
 
136
- /**
137
- * This hook allows you to create an editor instance.
138
- * @param options The editor options
139
- * @param deps The dependencies to watch for changes
140
- * @returns The editor instance
141
- * @example const editor = useEditor({ extensions: [...] })
142
- */
143
- const useEditor = (options = {}, deps = []) => {
144
- const editorRef = useRef(null);
145
- const [, forceUpdate] = useState({});
146
- const { onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, onContentError, } = options;
147
- const onBeforeCreateRef = useRef(onBeforeCreate);
148
- const onBlurRef = useRef(onBlur);
149
- const onCreateRef = useRef(onCreate);
150
- const onDestroyRef = useRef(onDestroy);
151
- const onFocusRef = useRef(onFocus);
152
- const onSelectionUpdateRef = useRef(onSelectionUpdate);
153
- const onTransactionRef = useRef(onTransaction);
154
- const onUpdateRef = useRef(onUpdate);
155
- const onContentErrorRef = useRef(onContentError);
156
- // This effect will handle updating the editor instance
157
- // when the event handlers change.
158
- useEffect(() => {
159
- if (!editorRef.current) {
160
- return;
161
- }
162
- if (onBeforeCreate) {
163
- editorRef.current.off('beforeCreate', onBeforeCreateRef.current);
164
- editorRef.current.on('beforeCreate', onBeforeCreate);
165
- onBeforeCreateRef.current = onBeforeCreate;
166
- }
167
- if (onBlur) {
168
- editorRef.current.off('blur', onBlurRef.current);
169
- editorRef.current.on('blur', onBlur);
170
- onBlurRef.current = onBlur;
171
- }
172
- if (onCreate) {
173
- editorRef.current.off('create', onCreateRef.current);
174
- editorRef.current.on('create', onCreate);
175
- onCreateRef.current = onCreate;
176
- }
177
- if (onDestroy) {
178
- editorRef.current.off('destroy', onDestroyRef.current);
179
- editorRef.current.on('destroy', onDestroy);
180
- onDestroyRef.current = onDestroy;
181
- }
182
- if (onFocus) {
183
- editorRef.current.off('focus', onFocusRef.current);
184
- editorRef.current.on('focus', onFocus);
185
- onFocusRef.current = onFocus;
186
- }
187
- if (onSelectionUpdate) {
188
- editorRef.current.off('selectionUpdate', onSelectionUpdateRef.current);
189
- editorRef.current.on('selectionUpdate', onSelectionUpdate);
190
- onSelectionUpdateRef.current = onSelectionUpdate;
191
- }
192
- if (onTransaction) {
193
- editorRef.current.off('transaction', onTransactionRef.current);
194
- editorRef.current.on('transaction', onTransaction);
195
- onTransactionRef.current = onTransaction;
196
- }
197
- if (onUpdate) {
198
- editorRef.current.off('update', onUpdateRef.current);
199
- editorRef.current.on('update', onUpdate);
200
- onUpdateRef.current = onUpdate;
201
- }
202
- if (onContentError) {
203
- editorRef.current.off('contentError', onContentErrorRef.current);
204
- editorRef.current.on('contentError', onContentError);
205
- onContentErrorRef.current = onContentError;
206
- }
207
- }, [onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, editorRef.current]);
208
- useEffect(() => {
209
- let isMounted = true;
210
- const editor = new Editor(options);
211
- editorRef.current = editor;
212
- editorRef.current.on('transaction', () => {
213
- requestAnimationFrame(() => {
214
- requestAnimationFrame(() => {
215
- if (isMounted) {
216
- forceUpdate({});
217
- }
218
- });
219
- });
220
- });
221
- return () => {
222
- isMounted = false;
223
- editor.destroy();
224
- };
225
- }, deps);
226
- return editorRef.current;
136
+ /**
137
+ * This hook allows you to create an editor instance.
138
+ * @param options The editor options
139
+ * @param deps The dependencies to watch for changes
140
+ * @returns The editor instance
141
+ * @example const editor = useEditor({ extensions: [...] })
142
+ */
143
+ const useEditor = (options = {}, deps = []) => {
144
+ const editorRef = useRef(null);
145
+ const [, forceUpdate] = useState({});
146
+ const { onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, onContentError, } = options;
147
+ const onBeforeCreateRef = useRef(onBeforeCreate);
148
+ const onBlurRef = useRef(onBlur);
149
+ const onCreateRef = useRef(onCreate);
150
+ const onDestroyRef = useRef(onDestroy);
151
+ const onFocusRef = useRef(onFocus);
152
+ const onSelectionUpdateRef = useRef(onSelectionUpdate);
153
+ const onTransactionRef = useRef(onTransaction);
154
+ const onUpdateRef = useRef(onUpdate);
155
+ const onContentErrorRef = useRef(onContentError);
156
+ // This effect will handle updating the editor instance
157
+ // when the event handlers change.
158
+ useEffect(() => {
159
+ if (!editorRef.current) {
160
+ return;
161
+ }
162
+ if (onBeforeCreate) {
163
+ editorRef.current.off('beforeCreate', onBeforeCreateRef.current);
164
+ editorRef.current.on('beforeCreate', onBeforeCreate);
165
+ onBeforeCreateRef.current = onBeforeCreate;
166
+ }
167
+ if (onBlur) {
168
+ editorRef.current.off('blur', onBlurRef.current);
169
+ editorRef.current.on('blur', onBlur);
170
+ onBlurRef.current = onBlur;
171
+ }
172
+ if (onCreate) {
173
+ editorRef.current.off('create', onCreateRef.current);
174
+ editorRef.current.on('create', onCreate);
175
+ onCreateRef.current = onCreate;
176
+ }
177
+ if (onDestroy) {
178
+ editorRef.current.off('destroy', onDestroyRef.current);
179
+ editorRef.current.on('destroy', onDestroy);
180
+ onDestroyRef.current = onDestroy;
181
+ }
182
+ if (onFocus) {
183
+ editorRef.current.off('focus', onFocusRef.current);
184
+ editorRef.current.on('focus', onFocus);
185
+ onFocusRef.current = onFocus;
186
+ }
187
+ if (onSelectionUpdate) {
188
+ editorRef.current.off('selectionUpdate', onSelectionUpdateRef.current);
189
+ editorRef.current.on('selectionUpdate', onSelectionUpdate);
190
+ onSelectionUpdateRef.current = onSelectionUpdate;
191
+ }
192
+ if (onTransaction) {
193
+ editorRef.current.off('transaction', onTransactionRef.current);
194
+ editorRef.current.on('transaction', onTransaction);
195
+ onTransactionRef.current = onTransaction;
196
+ }
197
+ if (onUpdate) {
198
+ editorRef.current.off('update', onUpdateRef.current);
199
+ editorRef.current.on('update', onUpdate);
200
+ onUpdateRef.current = onUpdate;
201
+ }
202
+ if (onContentError) {
203
+ editorRef.current.off('contentError', onContentErrorRef.current);
204
+ editorRef.current.on('contentError', onContentError);
205
+ onContentErrorRef.current = onContentError;
206
+ }
207
+ }, [onBeforeCreate, onBlur, onCreate, onDestroy, onFocus, onSelectionUpdate, onTransaction, onUpdate, editorRef.current]);
208
+ useEffect(() => {
209
+ let isMounted = true;
210
+ const editor = new Editor(options);
211
+ editorRef.current = editor;
212
+ editorRef.current.on('transaction', () => {
213
+ requestAnimationFrame(() => {
214
+ requestAnimationFrame(() => {
215
+ if (isMounted) {
216
+ forceUpdate({});
217
+ }
218
+ });
219
+ });
220
+ });
221
+ return () => {
222
+ isMounted = false;
223
+ editor.destroy();
224
+ };
225
+ }, deps);
226
+ return editorRef.current;
227
227
  };
228
228
 
229
- const EditorContext = createContext({
230
- editor: null,
231
- });
232
- const EditorConsumer = EditorContext.Consumer;
233
- const useCurrentEditor = () => useContext(EditorContext);
234
- const EditorProvider = ({ children, slotAfter, slotBefore, ...editorOptions }) => {
235
- const editor = useEditor(editorOptions);
236
- if (!editor) {
237
- return null;
238
- }
239
- return (React.createElement(EditorContext.Provider, { value: { editor } },
240
- slotBefore,
241
- React.createElement(EditorConsumer, null, ({ editor: currentEditor }) => (React.createElement(EditorContent, { editor: currentEditor }))),
242
- children,
243
- slotAfter));
229
+ const EditorContext = createContext({
230
+ editor: null,
231
+ });
232
+ const EditorConsumer = EditorContext.Consumer;
233
+ const useCurrentEditor = () => useContext(EditorContext);
234
+ const EditorProvider = ({ children, slotAfter, slotBefore, ...editorOptions }) => {
235
+ const editor = useEditor(editorOptions);
236
+ if (!editor) {
237
+ return null;
238
+ }
239
+ return (React.createElement(EditorContext.Provider, { value: { editor } },
240
+ slotBefore,
241
+ React.createElement(EditorConsumer, null, ({ editor: currentEditor }) => (React.createElement(EditorContent, { editor: currentEditor }))),
242
+ children,
243
+ slotAfter));
244
244
  };
245
245
 
246
- const BubbleMenu = (props) => {
247
- const [element, setElement] = useState(null);
248
- const { editor: currentEditor } = useCurrentEditor();
249
- useEffect(() => {
250
- var _a;
251
- if (!element) {
252
- return;
253
- }
254
- if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
255
- return;
256
- }
257
- const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, updateDelay, shouldShow = null, } = props;
258
- const menuEditor = editor || currentEditor;
259
- if (!menuEditor) {
260
- console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.');
261
- return;
262
- }
263
- const plugin = BubbleMenuPlugin({
264
- updateDelay,
265
- editor: menuEditor,
266
- element,
267
- pluginKey,
268
- shouldShow,
269
- tippyOptions,
270
- });
271
- menuEditor.registerPlugin(plugin);
272
- return () => menuEditor.unregisterPlugin(pluginKey);
273
- }, [props.editor, currentEditor, element]);
274
- return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
246
+ const BubbleMenu = (props) => {
247
+ const [element, setElement] = useState(null);
248
+ const { editor: currentEditor } = useCurrentEditor();
249
+ useEffect(() => {
250
+ var _a;
251
+ if (!element) {
252
+ return;
253
+ }
254
+ if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
255
+ return;
256
+ }
257
+ const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, updateDelay, shouldShow = null, } = props;
258
+ const menuEditor = editor || currentEditor;
259
+ if (!menuEditor) {
260
+ console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.');
261
+ return;
262
+ }
263
+ const plugin = BubbleMenuPlugin({
264
+ updateDelay,
265
+ editor: menuEditor,
266
+ element,
267
+ pluginKey,
268
+ shouldShow,
269
+ tippyOptions,
270
+ });
271
+ menuEditor.registerPlugin(plugin);
272
+ return () => menuEditor.unregisterPlugin(pluginKey);
273
+ }, [props.editor, currentEditor, element]);
274
+ return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
275
275
  };
276
276
 
277
- const FloatingMenu = (props) => {
278
- const [element, setElement] = useState(null);
279
- const { editor: currentEditor } = useCurrentEditor();
280
- useEffect(() => {
281
- var _a;
282
- if (!element) {
283
- return;
284
- }
285
- if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
286
- return;
287
- }
288
- const { pluginKey = 'floatingMenu', editor, tippyOptions = {}, shouldShow = null, } = props;
289
- const menuEditor = editor || currentEditor;
290
- if (!menuEditor) {
291
- console.warn('FloatingMenu component is not rendered inside of an editor component or does not have editor prop.');
292
- return;
293
- }
294
- const plugin = FloatingMenuPlugin({
295
- pluginKey,
296
- editor: menuEditor,
297
- element,
298
- tippyOptions,
299
- shouldShow,
300
- });
301
- menuEditor.registerPlugin(plugin);
302
- return () => menuEditor.unregisterPlugin(pluginKey);
303
- }, [
304
- props.editor,
305
- currentEditor,
306
- element,
307
- ]);
308
- return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
277
+ const FloatingMenu = (props) => {
278
+ const [element, setElement] = useState(null);
279
+ const { editor: currentEditor } = useCurrentEditor();
280
+ useEffect(() => {
281
+ var _a;
282
+ if (!element) {
283
+ return;
284
+ }
285
+ if (((_a = props.editor) === null || _a === void 0 ? void 0 : _a.isDestroyed) || (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.isDestroyed)) {
286
+ return;
287
+ }
288
+ const { pluginKey = 'floatingMenu', editor, tippyOptions = {}, shouldShow = null, } = props;
289
+ const menuEditor = editor || currentEditor;
290
+ if (!menuEditor) {
291
+ console.warn('FloatingMenu component is not rendered inside of an editor component or does not have editor prop.');
292
+ return;
293
+ }
294
+ const plugin = FloatingMenuPlugin({
295
+ pluginKey,
296
+ editor: menuEditor,
297
+ element,
298
+ tippyOptions,
299
+ shouldShow,
300
+ });
301
+ menuEditor.registerPlugin(plugin);
302
+ return () => menuEditor.unregisterPlugin(pluginKey);
303
+ }, [
304
+ props.editor,
305
+ currentEditor,
306
+ element,
307
+ ]);
308
+ return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
309
309
  };
310
310
 
311
- const ReactNodeViewContext = createContext({
312
- onDragStart: undefined,
313
- });
311
+ const ReactNodeViewContext = createContext({
312
+ onDragStart: undefined,
313
+ });
314
314
  const useReactNodeView = () => useContext(ReactNodeViewContext);
315
315
 
316
- const NodeViewContent = props => {
317
- const Tag = props.as || 'div';
318
- const { nodeViewContentRef } = useReactNodeView();
319
- return (React.createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
320
- whiteSpace: 'pre-wrap',
321
- ...props.style,
322
- } }));
316
+ const NodeViewContent = props => {
317
+ const Tag = props.as || 'div';
318
+ const { nodeViewContentRef } = useReactNodeView();
319
+ return (React.createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
320
+ whiteSpace: 'pre-wrap',
321
+ ...props.style,
322
+ } }));
323
323
  };
324
324
 
325
- const NodeViewWrapper = React.forwardRef((props, ref) => {
326
- const { onDragStart } = useReactNodeView();
327
- const Tag = props.as || 'div';
328
- return (React.createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
329
- whiteSpace: 'normal',
330
- ...props.style,
331
- } }));
325
+ const NodeViewWrapper = React.forwardRef((props, ref) => {
326
+ const { onDragStart } = useReactNodeView();
327
+ const Tag = props.as || 'div';
328
+ return (React.createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
329
+ whiteSpace: 'normal',
330
+ ...props.style,
331
+ } }));
332
332
  });
333
333
 
334
- /**
335
- * Check if a component is a class component.
336
- * @param Component
337
- * @returns {boolean}
338
- */
339
- function isClassComponent(Component) {
340
- return !!(typeof Component === 'function'
341
- && Component.prototype
342
- && Component.prototype.isReactComponent);
343
- }
344
- /**
345
- * Check if a component is a forward ref component.
346
- * @param Component
347
- * @returns {boolean}
348
- */
349
- function isForwardRefComponent(Component) {
350
- var _a;
351
- return !!(typeof Component === 'object'
352
- && ((_a = Component.$$typeof) === null || _a === void 0 ? void 0 : _a.toString()) === 'Symbol(react.forward_ref)');
353
- }
354
- /**
355
- * The ReactRenderer class. It's responsible for rendering React components inside the editor.
356
- * @example
357
- * new ReactRenderer(MyComponent, {
358
- * editor,
359
- * props: {
360
- * foo: 'bar',
361
- * },
362
- * as: 'span',
363
- * })
364
- */
365
- class ReactRenderer {
366
- constructor(component, { editor, props = {}, as = 'div', className = '', attrs, }) {
367
- this.ref = null;
368
- this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString();
369
- this.component = component;
370
- this.editor = editor;
371
- this.props = props;
372
- this.element = document.createElement(as);
373
- this.element.classList.add('react-renderer');
374
- if (className) {
375
- this.element.classList.add(...className.split(' '));
376
- }
377
- if (attrs) {
378
- Object.keys(attrs).forEach(key => {
379
- this.element.setAttribute(key, attrs[key]);
380
- });
381
- }
382
- this.render();
383
- }
384
- render() {
385
- var _a, _b;
386
- const Component = this.component;
387
- const props = this.props;
388
- if (isClassComponent(Component) || isForwardRefComponent(Component)) {
389
- props.ref = (ref) => {
390
- this.ref = ref;
391
- };
392
- }
393
- this.reactElement = React.createElement(Component, { ...props });
394
- (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.setRenderer(this.id, this);
395
- }
396
- updateProps(props = {}) {
397
- this.props = {
398
- ...this.props,
399
- ...props,
400
- };
401
- this.render();
402
- }
403
- destroy() {
404
- var _a, _b;
405
- (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.removeRenderer(this.id);
406
- }
334
+ /**
335
+ * Check if a component is a class component.
336
+ * @param Component
337
+ * @returns {boolean}
338
+ */
339
+ function isClassComponent(Component) {
340
+ return !!(typeof Component === 'function'
341
+ && Component.prototype
342
+ && Component.prototype.isReactComponent);
343
+ }
344
+ /**
345
+ * Check if a component is a forward ref component.
346
+ * @param Component
347
+ * @returns {boolean}
348
+ */
349
+ function isForwardRefComponent(Component) {
350
+ var _a;
351
+ return !!(typeof Component === 'object'
352
+ && ((_a = Component.$$typeof) === null || _a === void 0 ? void 0 : _a.toString()) === 'Symbol(react.forward_ref)');
353
+ }
354
+ /**
355
+ * The ReactRenderer class. It's responsible for rendering React components inside the editor.
356
+ * @example
357
+ * new ReactRenderer(MyComponent, {
358
+ * editor,
359
+ * props: {
360
+ * foo: 'bar',
361
+ * },
362
+ * as: 'span',
363
+ * })
364
+ */
365
+ class ReactRenderer {
366
+ constructor(component, { editor, props = {}, as = 'div', className = '', attrs, }) {
367
+ this.ref = null;
368
+ this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString();
369
+ this.component = component;
370
+ this.editor = editor;
371
+ this.props = props;
372
+ this.element = document.createElement(as);
373
+ this.element.classList.add('react-renderer');
374
+ if (className) {
375
+ this.element.classList.add(...className.split(' '));
376
+ }
377
+ if (attrs) {
378
+ Object.keys(attrs).forEach(key => {
379
+ this.element.setAttribute(key, attrs[key]);
380
+ });
381
+ }
382
+ this.render();
383
+ }
384
+ render() {
385
+ var _a, _b;
386
+ const Component = this.component;
387
+ const props = this.props;
388
+ if (isClassComponent(Component) || isForwardRefComponent(Component)) {
389
+ props.ref = (ref) => {
390
+ this.ref = ref;
391
+ };
392
+ }
393
+ this.reactElement = React.createElement(Component, { ...props });
394
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.setRenderer(this.id, this);
395
+ }
396
+ updateProps(props = {}) {
397
+ this.props = {
398
+ ...this.props,
399
+ ...props,
400
+ };
401
+ this.render();
402
+ }
403
+ destroy() {
404
+ var _a, _b;
405
+ (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.removeRenderer(this.id);
406
+ }
407
407
  }
408
408
 
409
- class ReactNodeView extends NodeView {
410
- mount() {
411
- const props = {
412
- editor: this.editor,
413
- node: this.node,
414
- decorations: this.decorations,
415
- selected: false,
416
- extension: this.extension,
417
- getPos: () => this.getPos(),
418
- updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
419
- deleteNode: () => this.deleteNode(),
420
- };
421
- if (!this.component.displayName) {
422
- const capitalizeFirstChar = (string) => {
423
- return string.charAt(0).toUpperCase() + string.substring(1);
424
- };
425
- this.component.displayName = capitalizeFirstChar(this.extension.name);
426
- }
427
- const ReactNodeViewProvider = componentProps => {
428
- const Component = this.component;
429
- const onDragStart = this.onDragStart.bind(this);
430
- const nodeViewContentRef = element => {
431
- if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
432
- element.appendChild(this.contentDOMElement);
433
- }
434
- };
435
- return (React.createElement(React.Fragment, null,
436
- React.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
437
- React.createElement(Component, { ...componentProps }))));
438
- };
439
- ReactNodeViewProvider.displayName = 'ReactNodeView';
440
- if (this.node.isLeaf) {
441
- this.contentDOMElement = null;
442
- }
443
- else if (this.options.contentDOMElementTag) {
444
- this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
445
- }
446
- else {
447
- this.contentDOMElement = document.createElement(this.node.isInline ? 'span' : 'div');
448
- }
449
- if (this.contentDOMElement) {
450
- // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari
451
- // With this fix it seems to work fine
452
- // See: https://github.com/ueberdosis/tiptap/issues/1197
453
- this.contentDOMElement.style.whiteSpace = 'inherit';
454
- }
455
- let as = this.node.isInline ? 'span' : 'div';
456
- if (this.options.as) {
457
- as = this.options.as;
458
- }
459
- const { className = '' } = this.options;
460
- this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
461
- this.editor.on('selectionUpdate', this.handleSelectionUpdate);
462
- this.renderer = new ReactRenderer(ReactNodeViewProvider, {
463
- editor: this.editor,
464
- props,
465
- as,
466
- className: `node-${this.node.type.name} ${className}`.trim(),
467
- attrs: this.options.attrs,
468
- });
469
- }
470
- get dom() {
471
- var _a;
472
- if (this.renderer.element.firstElementChild
473
- && !((_a = this.renderer.element.firstElementChild) === null || _a === void 0 ? void 0 : _a.hasAttribute('data-node-view-wrapper'))) {
474
- throw Error('Please use the NodeViewWrapper component for your node view.');
475
- }
476
- return this.renderer.element;
477
- }
478
- get contentDOM() {
479
- if (this.node.isLeaf) {
480
- return null;
481
- }
482
- return this.contentDOMElement;
483
- }
484
- handleSelectionUpdate() {
485
- const { from, to } = this.editor.state.selection;
486
- if (from <= this.getPos() && to >= this.getPos() + this.node.nodeSize) {
487
- if (this.renderer.props.selected) {
488
- return;
489
- }
490
- this.selectNode();
491
- }
492
- else {
493
- if (!this.renderer.props.selected) {
494
- return;
495
- }
496
- this.deselectNode();
497
- }
498
- }
499
- update(node, decorations) {
500
- const updateProps = (props) => {
501
- this.renderer.updateProps(props);
502
- };
503
- if (node.type !== this.node.type) {
504
- return false;
505
- }
506
- if (typeof this.options.update === 'function') {
507
- const oldNode = this.node;
508
- const oldDecorations = this.decorations;
509
- this.node = node;
510
- this.decorations = decorations;
511
- return this.options.update({
512
- oldNode,
513
- oldDecorations,
514
- newNode: node,
515
- newDecorations: decorations,
516
- updateProps: () => updateProps({ node, decorations }),
517
- });
518
- }
519
- if (node === this.node && this.decorations === decorations) {
520
- return true;
521
- }
522
- this.node = node;
523
- this.decorations = decorations;
524
- updateProps({ node, decorations });
525
- return true;
526
- }
527
- selectNode() {
528
- this.renderer.updateProps({
529
- selected: true,
530
- });
531
- this.renderer.element.classList.add('ProseMirror-selectednode');
532
- }
533
- deselectNode() {
534
- this.renderer.updateProps({
535
- selected: false,
536
- });
537
- this.renderer.element.classList.remove('ProseMirror-selectednode');
538
- }
539
- destroy() {
540
- this.renderer.destroy();
541
- this.editor.off('selectionUpdate', this.handleSelectionUpdate);
542
- this.contentDOMElement = null;
543
- }
544
- }
545
- function ReactNodeViewRenderer(component, options) {
546
- return (props) => {
547
- // try to get the parent component
548
- // this is important for vue devtools to show the component hierarchy correctly
549
- // maybe it’s `undefined` because <editor-content> isn’t rendered yet
550
- if (!props.editor.contentComponent) {
551
- return {};
552
- }
553
- return new ReactNodeView(component, props, options);
554
- };
409
+ class ReactNodeView extends NodeView {
410
+ mount() {
411
+ const props = {
412
+ editor: this.editor,
413
+ node: this.node,
414
+ decorations: this.decorations,
415
+ selected: false,
416
+ extension: this.extension,
417
+ getPos: () => this.getPos(),
418
+ updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
419
+ deleteNode: () => this.deleteNode(),
420
+ };
421
+ if (!this.component.displayName) {
422
+ const capitalizeFirstChar = (string) => {
423
+ return string.charAt(0).toUpperCase() + string.substring(1);
424
+ };
425
+ this.component.displayName = capitalizeFirstChar(this.extension.name);
426
+ }
427
+ const ReactNodeViewProvider = componentProps => {
428
+ const Component = this.component;
429
+ const onDragStart = this.onDragStart.bind(this);
430
+ const nodeViewContentRef = element => {
431
+ if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
432
+ element.appendChild(this.contentDOMElement);
433
+ }
434
+ };
435
+ return (React.createElement(React.Fragment, null,
436
+ React.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
437
+ React.createElement(Component, { ...componentProps }))));
438
+ };
439
+ ReactNodeViewProvider.displayName = 'ReactNodeView';
440
+ if (this.node.isLeaf) {
441
+ this.contentDOMElement = null;
442
+ }
443
+ else if (this.options.contentDOMElementTag) {
444
+ this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
445
+ }
446
+ else {
447
+ this.contentDOMElement = document.createElement(this.node.isInline ? 'span' : 'div');
448
+ }
449
+ if (this.contentDOMElement) {
450
+ // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari
451
+ // With this fix it seems to work fine
452
+ // See: https://github.com/ueberdosis/tiptap/issues/1197
453
+ this.contentDOMElement.style.whiteSpace = 'inherit';
454
+ }
455
+ let as = this.node.isInline ? 'span' : 'div';
456
+ if (this.options.as) {
457
+ as = this.options.as;
458
+ }
459
+ const { className = '' } = this.options;
460
+ this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
461
+ this.editor.on('selectionUpdate', this.handleSelectionUpdate);
462
+ this.renderer = new ReactRenderer(ReactNodeViewProvider, {
463
+ editor: this.editor,
464
+ props,
465
+ as,
466
+ className: `node-${this.node.type.name} ${className}`.trim(),
467
+ attrs: this.options.attrs,
468
+ });
469
+ }
470
+ get dom() {
471
+ var _a;
472
+ if (this.renderer.element.firstElementChild
473
+ && !((_a = this.renderer.element.firstElementChild) === null || _a === void 0 ? void 0 : _a.hasAttribute('data-node-view-wrapper'))) {
474
+ throw Error('Please use the NodeViewWrapper component for your node view.');
475
+ }
476
+ return this.renderer.element;
477
+ }
478
+ get contentDOM() {
479
+ if (this.node.isLeaf) {
480
+ return null;
481
+ }
482
+ return this.contentDOMElement;
483
+ }
484
+ handleSelectionUpdate() {
485
+ const { from, to } = this.editor.state.selection;
486
+ if (from <= this.getPos() && to >= this.getPos() + this.node.nodeSize) {
487
+ if (this.renderer.props.selected) {
488
+ return;
489
+ }
490
+ this.selectNode();
491
+ }
492
+ else {
493
+ if (!this.renderer.props.selected) {
494
+ return;
495
+ }
496
+ this.deselectNode();
497
+ }
498
+ }
499
+ update(node, decorations) {
500
+ const updateProps = (props) => {
501
+ this.renderer.updateProps(props);
502
+ };
503
+ if (node.type !== this.node.type) {
504
+ return false;
505
+ }
506
+ if (typeof this.options.update === 'function') {
507
+ const oldNode = this.node;
508
+ const oldDecorations = this.decorations;
509
+ this.node = node;
510
+ this.decorations = decorations;
511
+ return this.options.update({
512
+ oldNode,
513
+ oldDecorations,
514
+ newNode: node,
515
+ newDecorations: decorations,
516
+ updateProps: () => updateProps({ node, decorations }),
517
+ });
518
+ }
519
+ if (node === this.node && this.decorations === decorations) {
520
+ return true;
521
+ }
522
+ this.node = node;
523
+ this.decorations = decorations;
524
+ updateProps({ node, decorations });
525
+ return true;
526
+ }
527
+ selectNode() {
528
+ this.renderer.updateProps({
529
+ selected: true,
530
+ });
531
+ this.renderer.element.classList.add('ProseMirror-selectednode');
532
+ }
533
+ deselectNode() {
534
+ this.renderer.updateProps({
535
+ selected: false,
536
+ });
537
+ this.renderer.element.classList.remove('ProseMirror-selectednode');
538
+ }
539
+ destroy() {
540
+ this.renderer.destroy();
541
+ this.editor.off('selectionUpdate', this.handleSelectionUpdate);
542
+ this.contentDOMElement = null;
543
+ }
544
+ }
545
+ function ReactNodeViewRenderer(component, options) {
546
+ return (props) => {
547
+ // try to get the parent component
548
+ // this is important for vue devtools to show the component hierarchy correctly
549
+ // maybe it’s `undefined` because <editor-content> isn’t rendered yet
550
+ if (!props.editor.contentComponent) {
551
+ return {};
552
+ }
553
+ return new ReactNodeView(component, props, options);
554
+ };
555
555
  }
556
556
 
557
557
  export { BubbleMenu, Editor, EditorConsumer, EditorContent, EditorContext, EditorProvider, FloatingMenu, NodeViewContent, NodeViewWrapper, PureEditorContent, ReactNodeViewContext, ReactNodeViewRenderer, ReactRenderer, useCurrentEditor, useEditor, useReactNodeView };