@tiptap/react 3.0.0-next.1 → 3.0.0-next.2

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.
package/dist/index.js CHANGED
@@ -4,7 +4,11 @@ import React3, { useEffect as useEffect3, useRef as useRef2 } from "react";
4
4
  import { createPortal } from "react-dom";
5
5
 
6
6
  // src/Context.tsx
7
- import React2, { createContext, useContext } from "react";
7
+ import React2, {
8
+ createContext,
9
+ useContext,
10
+ useMemo
11
+ } from "react";
8
12
 
9
13
  // src/EditorContent.tsx
10
14
  import React, {
@@ -174,8 +178,15 @@ import {
174
178
  import { useSyncExternalStore as useSyncExternalStore2 } from "use-sync-external-store/shim";
175
179
 
176
180
  // src/useEditorState.ts
177
- import { useDebugValue, useEffect, useState } from "react";
181
+ import deepEqual from "fast-deep-equal/es6/react";
182
+ import {
183
+ useDebugValue,
184
+ useEffect,
185
+ useLayoutEffect,
186
+ useState
187
+ } from "react";
178
188
  import { useSyncExternalStoreWithSelector } from "use-sync-external-store/shim/with-selector";
189
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
179
190
  var EditorStateManager = class {
180
191
  constructor(initialEditor) {
181
192
  this.transactionNumber = 0;
@@ -234,17 +245,18 @@ var EditorStateManager = class {
234
245
  }
235
246
  };
236
247
  function useEditorState(options) {
237
- const [editorInstance] = useState(() => new EditorStateManager(options.editor));
248
+ var _a;
249
+ const [editorStateManager] = useState(() => new EditorStateManager(options.editor));
238
250
  const selectedState = useSyncExternalStoreWithSelector(
239
- editorInstance.subscribe,
240
- editorInstance.getSnapshot,
241
- editorInstance.getServerSnapshot,
251
+ editorStateManager.subscribe,
252
+ editorStateManager.getSnapshot,
253
+ editorStateManager.getServerSnapshot,
242
254
  options.selector,
243
- options.equalityFn
255
+ (_a = options.equalityFn) != null ? _a : deepEqual
244
256
  );
245
- useEffect(() => {
246
- return editorInstance.watch(options.editor);
247
- }, [options.editor, editorInstance]);
257
+ useIsomorphicLayoutEffect(() => {
258
+ return editorStateManager.watch(options.editor);
259
+ }, [options.editor, editorStateManager]);
248
260
  useDebugValue(selectedState);
249
261
  return selectedState;
250
262
  }
@@ -279,6 +291,7 @@ var EditorInstanceManager = class {
279
291
  this.options = options;
280
292
  this.subscriptions = /* @__PURE__ */ new Set();
281
293
  this.setEditor(this.getInitialEditor());
294
+ this.scheduleDestroy();
282
295
  this.getEditor = this.getEditor.bind(this);
283
296
  this.getServerSnapshot = this.getServerSnapshot.bind(this);
284
297
  this.subscribe = this.subscribe.bind(this);
@@ -356,6 +369,14 @@ var EditorInstanceManager = class {
356
369
  onContentError: (...args) => {
357
370
  var _a, _b;
358
371
  return (_b = (_a = this.options.current).onContentError) == null ? void 0 : _b.call(_a, ...args);
372
+ },
373
+ onDrop: (...args) => {
374
+ var _a, _b;
375
+ return (_b = (_a = this.options.current).onDrop) == null ? void 0 : _b.call(_a, ...args);
376
+ },
377
+ onPaste: (...args) => {
378
+ var _a, _b;
379
+ return (_b = (_a = this.options.current).onPaste) == null ? void 0 : _b.call(_a, ...args);
359
380
  }
360
381
  };
361
382
  const editor = new Editor(optionsToApply);
@@ -392,7 +413,10 @@ var EditorInstanceManager = class {
392
413
  this.isComponentMounted = true;
393
414
  clearTimeout(this.scheduledDestructionTimeout);
394
415
  if (this.editor && !this.editor.isDestroyed && deps.length === 0) {
395
- this.editor.setOptions(this.options.current);
416
+ this.editor.setOptions({
417
+ ...this.options.current,
418
+ editable: this.editor.isEditable
419
+ });
396
420
  } else {
397
421
  this.refreshEditorInstance(deps);
398
422
  }
@@ -443,7 +467,7 @@ var EditorInstanceManager = class {
443
467
  this.setEditor(null);
444
468
  }
445
469
  }
446
- }, 0);
470
+ }, 1);
447
471
  }
448
472
  };
449
473
  function useEditor(options = {}, deps = []) {
@@ -460,7 +484,7 @@ function useEditor(options = {}, deps = []) {
460
484
  useEditorState({
461
485
  editor,
462
486
  selector: ({ transactionNumber }) => {
463
- if (options.shouldRerenderOnTransaction === false) {
487
+ if (options.shouldRerenderOnTransaction === false || options.shouldRerenderOnTransaction === void 0) {
464
488
  return null;
465
489
  }
466
490
  if (options.immediatelyRender && transactionNumber === 0) {
@@ -482,118 +506,143 @@ function EditorProvider({
482
506
  children,
483
507
  slotAfter,
484
508
  slotBefore,
509
+ editorContainerProps = {},
485
510
  ...editorOptions
486
511
  }) {
487
512
  const editor = useEditor(editorOptions);
513
+ const contextValue = useMemo(() => ({ editor }), [editor]);
488
514
  if (!editor) {
489
515
  return null;
490
516
  }
491
- return /* @__PURE__ */ React2.createElement(EditorContext.Provider, { value: { editor } }, slotBefore, /* @__PURE__ */ React2.createElement(EditorConsumer, null, ({ editor: currentEditor }) => /* @__PURE__ */ React2.createElement(EditorContent, { editor: currentEditor })), children, slotAfter);
517
+ return /* @__PURE__ */ React2.createElement(EditorContext.Provider, { value: contextValue }, slotBefore, /* @__PURE__ */ React2.createElement(EditorConsumer, null, ({ editor: currentEditor }) => /* @__PURE__ */ React2.createElement(EditorContent, { editor: currentEditor, ...editorContainerProps })), children, slotAfter);
492
518
  }
493
519
 
494
520
  // src/BubbleMenu.tsx
495
- var BubbleMenu = (props) => {
496
- const menuEl = useRef2(document.createElement("div"));
497
- const { editor: currentEditor } = useCurrentEditor();
498
- useEffect3(() => {
499
- var _a;
500
- menuEl.current.style.visibility = "hidden";
501
- menuEl.current.style.position = "absolute";
502
- if (((_a = props.editor) == null ? void 0 : _a.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
503
- return;
504
- }
505
- const {
506
- pluginKey = "bubbleMenu",
507
- editor,
508
- updateDelay,
509
- resizeDelay,
510
- shouldShow = null
511
- } = props;
512
- const menuEditor = editor || currentEditor;
513
- if (!menuEditor) {
514
- console.warn("BubbleMenu component is not rendered inside of an editor component or does not have editor prop.");
515
- return;
516
- }
517
- const plugin = BubbleMenuPlugin({
518
- updateDelay,
519
- resizeDelay,
520
- editor: menuEditor,
521
- element: menuEl.current,
522
- pluginKey,
523
- shouldShow,
524
- options: props.options
525
- });
526
- menuEditor.registerPlugin(plugin);
527
- return () => {
528
- menuEditor.unregisterPlugin(pluginKey);
529
- window.requestAnimationFrame(() => {
530
- if (menuEl.current.parentNode) {
531
- menuEl.current.parentNode.removeChild(menuEl.current);
532
- }
521
+ var BubbleMenu = React3.forwardRef(
522
+ ({
523
+ pluginKey = "bubbleMenu",
524
+ editor,
525
+ updateDelay,
526
+ resizeDelay,
527
+ shouldShow = null,
528
+ options,
529
+ children,
530
+ ...restProps
531
+ }, ref) => {
532
+ const menuEl = useRef2(document.createElement("div"));
533
+ if (typeof ref === "function") {
534
+ ref(menuEl.current);
535
+ } else if (ref) {
536
+ ref.current = menuEl.current;
537
+ }
538
+ const { editor: currentEditor } = useCurrentEditor();
539
+ useEffect3(() => {
540
+ const bubbleMenuElement = menuEl.current;
541
+ bubbleMenuElement.style.visibility = "hidden";
542
+ bubbleMenuElement.style.position = "absolute";
543
+ if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
544
+ return;
545
+ }
546
+ const attachToEditor = editor || currentEditor;
547
+ if (!attachToEditor) {
548
+ console.warn(
549
+ "BubbleMenu component is not rendered inside of an editor component or does not have editor prop."
550
+ );
551
+ return;
552
+ }
553
+ const plugin = BubbleMenuPlugin({
554
+ updateDelay,
555
+ resizeDelay,
556
+ editor: attachToEditor,
557
+ element: bubbleMenuElement,
558
+ pluginKey,
559
+ shouldShow,
560
+ options
533
561
  });
534
- };
535
- }, [props.editor, currentEditor]);
536
- const portal = createPortal(
537
- /* @__PURE__ */ React3.createElement("div", { className: props.className }, props.children),
538
- menuEl.current
539
- );
540
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, portal);
541
- };
562
+ attachToEditor.registerPlugin(plugin);
563
+ return () => {
564
+ attachToEditor.unregisterPlugin(pluginKey);
565
+ window.requestAnimationFrame(() => {
566
+ if (bubbleMenuElement.parentNode) {
567
+ bubbleMenuElement.parentNode.removeChild(bubbleMenuElement);
568
+ }
569
+ });
570
+ };
571
+ }, [editor, currentEditor]);
572
+ return createPortal(
573
+ /* @__PURE__ */ React3.createElement(
574
+ "div",
575
+ {
576
+ ...restProps
577
+ },
578
+ children
579
+ ),
580
+ menuEl.current
581
+ );
582
+ }
583
+ );
542
584
 
543
585
  // src/FloatingMenu.tsx
544
586
  import { FloatingMenuPlugin } from "@tiptap/extension-floating-menu";
545
- import React4, {
546
- useEffect as useEffect4,
547
- useRef as useRef3
548
- } from "react";
587
+ import React4, { useEffect as useEffect4, useRef as useRef3 } from "react";
549
588
  import { createPortal as createPortal2 } from "react-dom";
550
- var FloatingMenu = (props) => {
589
+ var FloatingMenu = React4.forwardRef(({
590
+ pluginKey = "floatingMenu",
591
+ editor,
592
+ shouldShow = null,
593
+ options,
594
+ children,
595
+ ...restProps
596
+ }, ref) => {
551
597
  const menuEl = useRef3(document.createElement("div"));
598
+ if (typeof ref === "function") {
599
+ ref(menuEl.current);
600
+ } else if (ref) {
601
+ ref.current = menuEl.current;
602
+ }
552
603
  const { editor: currentEditor } = useCurrentEditor();
553
604
  useEffect4(() => {
554
- var _a;
555
- menuEl.current.style.visibility = "hidden";
556
- menuEl.current.style.position = "absolute";
557
- if (((_a = props.editor) == null ? void 0 : _a.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
605
+ const floatingMenuElement = menuEl.current;
606
+ floatingMenuElement.style.visibility = "hidden";
607
+ floatingMenuElement.style.position = "absolute";
608
+ if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
558
609
  return;
559
610
  }
560
- const {
561
- pluginKey = "floatingMenu",
562
- editor,
563
- options,
564
- shouldShow = null
565
- } = props;
566
- const menuEditor = editor || currentEditor;
567
- if (!menuEditor) {
568
- console.warn("FloatingMenu component is not rendered inside of an editor component or does not have editor prop.");
611
+ const attachToEditor = editor || currentEditor;
612
+ if (!attachToEditor) {
613
+ console.warn(
614
+ "FloatingMenu component is not rendered inside of an editor component or does not have editor prop."
615
+ );
569
616
  return;
570
617
  }
571
618
  const plugin = FloatingMenuPlugin({
619
+ editor: attachToEditor,
620
+ element: floatingMenuElement,
572
621
  pluginKey,
573
- editor: menuEditor,
574
- element: menuEl.current,
575
- options,
576
- shouldShow
622
+ shouldShow,
623
+ options
577
624
  });
578
- menuEditor.registerPlugin(plugin);
625
+ attachToEditor.registerPlugin(plugin);
579
626
  return () => {
580
- menuEditor.unregisterPlugin(pluginKey);
627
+ attachToEditor.unregisterPlugin(pluginKey);
581
628
  window.requestAnimationFrame(() => {
582
- if (menuEl.current.parentNode) {
583
- menuEl.current.parentNode.removeChild(menuEl.current);
629
+ if (floatingMenuElement.parentNode) {
630
+ floatingMenuElement.parentNode.removeChild(floatingMenuElement);
584
631
  }
585
632
  });
586
633
  };
587
- }, [
588
- props.editor,
589
- currentEditor
590
- ]);
591
- const portal = createPortal2(
592
- /* @__PURE__ */ React4.createElement("div", { className: props.className }, props.children),
634
+ }, [editor, currentEditor]);
635
+ return createPortal2(
636
+ /* @__PURE__ */ React4.createElement(
637
+ "div",
638
+ {
639
+ ...restProps
640
+ },
641
+ children
642
+ ),
593
643
  menuEl.current
594
644
  );
595
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, portal);
596
- };
645
+ });
597
646
 
598
647
  // src/NodeViewContent.tsx
599
648
  import React5 from "react";
@@ -651,6 +700,7 @@ var NodeViewWrapper = React6.forwardRef((props, ref) => {
651
700
 
652
701
  // src/ReactNodeViewRenderer.tsx
653
702
  import {
703
+ getRenderedAttributes,
654
704
  NodeView
655
705
  } from "@tiptap/core";
656
706
  import React8 from "react";
@@ -666,12 +716,14 @@ function isForwardRefComponent(Component) {
666
716
  return !!(typeof Component === "object" && ((_a = Component.$$typeof) == null ? void 0 : _a.toString()) === "Symbol(react.forward_ref)");
667
717
  }
668
718
  var ReactRenderer = class {
719
+ /**
720
+ * Immediately creates element and renders the provided React component.
721
+ */
669
722
  constructor(component, {
670
723
  editor,
671
724
  props = {},
672
725
  as = "div",
673
- className = "",
674
- attrs
726
+ className = ""
675
727
  }) {
676
728
  this.ref = null;
677
729
  this.id = Math.floor(Math.random() * 4294967295).toString();
@@ -683,11 +735,6 @@ var ReactRenderer = class {
683
735
  if (className) {
684
736
  this.element.classList.add(...className.split(" "));
685
737
  }
686
- if (attrs) {
687
- Object.keys(attrs).forEach((key) => {
688
- this.element.setAttribute(key, attrs[key]);
689
- });
690
- }
691
738
  if (this.editor.isInitialized) {
692
739
  flushSync(() => {
693
740
  this.render();
@@ -696,6 +743,9 @@ var ReactRenderer = class {
696
743
  this.render();
697
744
  }
698
745
  }
746
+ /**
747
+ * Render the React component.
748
+ */
699
749
  render() {
700
750
  var _a;
701
751
  const Component = this.component;
@@ -706,9 +756,12 @@ var ReactRenderer = class {
706
756
  this.ref = ref;
707
757
  };
708
758
  }
709
- this.reactElement = React7.createElement(Component, props);
759
+ this.reactElement = /* @__PURE__ */ React7.createElement(Component, { ...props });
710
760
  (_a = editor == null ? void 0 : editor.contentComponent) == null ? void 0 : _a.setRenderer(this.id, this);
711
761
  }
762
+ /**
763
+ * Re-renders the React component with new props.
764
+ */
712
765
  updateProps(props = {}) {
713
766
  this.props = {
714
767
  ...this.props,
@@ -716,22 +769,40 @@ var ReactRenderer = class {
716
769
  };
717
770
  this.render();
718
771
  }
772
+ /**
773
+ * Destroy the React component.
774
+ */
719
775
  destroy() {
720
776
  var _a;
721
777
  const editor = this.editor;
722
778
  (_a = editor == null ? void 0 : editor.contentComponent) == null ? void 0 : _a.removeRenderer(this.id);
723
779
  }
780
+ /**
781
+ * Update the attributes of the element that holds the React component.
782
+ */
783
+ updateAttributes(attributes) {
784
+ Object.keys(attributes).forEach((key) => {
785
+ this.element.setAttribute(key, attributes[key]);
786
+ });
787
+ }
724
788
  };
725
789
 
726
790
  // src/ReactNodeViewRenderer.tsx
727
791
  var ReactNodeView = class extends NodeView {
792
+ /**
793
+ * Setup the React component.
794
+ * Called on initialization.
795
+ */
728
796
  mount() {
729
797
  const props = {
730
798
  editor: this.editor,
731
799
  node: this.node,
732
800
  decorations: this.decorations,
801
+ innerDecorations: this.innerDecorations,
802
+ view: this.view,
733
803
  selected: false,
734
804
  extension: this.extension,
805
+ HTMLAttributes: this.HTMLAttributes,
735
806
  getPos: () => this.getPos(),
736
807
  updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
737
808
  deleteNode: () => this.deleteNode()
@@ -750,9 +821,11 @@ var ReactNodeView = class extends NodeView {
750
821
  };
751
822
  const context = { onDragStart, nodeViewContentRef };
752
823
  const Component = this.component;
753
- const ReactNodeViewProvider = React8.memo((componentProps) => {
754
- return /* @__PURE__ */ React8.createElement(ReactNodeViewContext.Provider, { value: context }, React8.createElement(Component, componentProps));
755
- });
824
+ const ReactNodeViewProvider = React8.memo(
825
+ (componentProps) => {
826
+ return /* @__PURE__ */ React8.createElement(ReactNodeViewContext.Provider, { value: context }, React8.createElement(Component, componentProps));
827
+ }
828
+ );
756
829
  ReactNodeViewProvider.displayName = "ReactNodeView";
757
830
  if (this.node.isLeaf) {
758
831
  this.contentDOMElement = null;
@@ -762,6 +835,7 @@ var ReactNodeView = class extends NodeView {
762
835
  this.contentDOMElement = document.createElement(this.node.isInline ? "span" : "div");
763
836
  }
764
837
  if (this.contentDOMElement) {
838
+ this.contentDOMElement.dataset.nodeViewContentReact = "";
765
839
  this.contentDOMElement.style.whiteSpace = "inherit";
766
840
  }
767
841
  let as = this.node.isInline ? "span" : "div";
@@ -775,10 +849,14 @@ var ReactNodeView = class extends NodeView {
775
849
  editor: this.editor,
776
850
  props,
777
851
  as,
778
- className: `node-${this.node.type.name} ${className}`.trim(),
779
- attrs: this.options.attrs
852
+ className: `node-${this.node.type.name} ${className}`.trim()
780
853
  });
854
+ this.updateElementAttributes();
781
855
  }
856
+ /**
857
+ * Return the DOM element.
858
+ * This is the element that will be used to display the node view.
859
+ */
782
860
  get dom() {
783
861
  var _a;
784
862
  if (this.renderer.element.firstElementChild && !((_a = this.renderer.element.firstElementChild) == null ? void 0 : _a.hasAttribute("data-node-view-wrapper"))) {
@@ -786,15 +864,27 @@ var ReactNodeView = class extends NodeView {
786
864
  }
787
865
  return this.renderer.element;
788
866
  }
867
+ /**
868
+ * Return the content DOM element.
869
+ * This is the element that will be used to display the rich-text content of the node.
870
+ */
789
871
  get contentDOM() {
790
872
  if (this.node.isLeaf) {
791
873
  return null;
792
874
  }
793
875
  return this.contentDOMElement;
794
876
  }
877
+ /**
878
+ * On editor selection update, check if the node is selected.
879
+ * If it is, call `selectNode`, otherwise call `deselectNode`.
880
+ */
795
881
  handleSelectionUpdate() {
796
882
  const { from, to } = this.editor.state.selection;
797
- if (from <= this.getPos() && to >= this.getPos() + this.node.nodeSize) {
883
+ const pos = this.getPos();
884
+ if (typeof pos !== "number") {
885
+ return;
886
+ }
887
+ if (from <= pos && to >= pos + this.node.nodeSize) {
798
888
  if (this.renderer.props.selected) {
799
889
  return;
800
890
  }
@@ -806,9 +896,16 @@ var ReactNodeView = class extends NodeView {
806
896
  this.deselectNode();
807
897
  }
808
898
  }
809
- update(node, decorations) {
810
- const updateProps = (props) => {
899
+ /**
900
+ * On update, update the React component.
901
+ * To prevent unnecessary updates, the `update` option can be used.
902
+ */
903
+ update(node, decorations, innerDecorations) {
904
+ const rerenderComponent = (props) => {
811
905
  this.renderer.updateProps(props);
906
+ if (typeof this.options.attrs === "function") {
907
+ this.updateElementAttributes();
908
+ }
812
909
  };
813
910
  if (node.type !== this.node.type) {
814
911
  return false;
@@ -816,41 +913,74 @@ var ReactNodeView = class extends NodeView {
816
913
  if (typeof this.options.update === "function") {
817
914
  const oldNode = this.node;
818
915
  const oldDecorations = this.decorations;
916
+ const oldInnerDecorations = this.innerDecorations;
819
917
  this.node = node;
820
918
  this.decorations = decorations;
919
+ this.innerDecorations = innerDecorations;
821
920
  return this.options.update({
822
921
  oldNode,
823
922
  oldDecorations,
824
923
  newNode: node,
825
924
  newDecorations: decorations,
826
- updateProps: () => updateProps({ node, decorations })
925
+ oldInnerDecorations,
926
+ innerDecorations,
927
+ updateProps: () => rerenderComponent({ node, decorations, innerDecorations })
827
928
  });
828
929
  }
829
- if (node === this.node && this.decorations === decorations) {
930
+ if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
830
931
  return true;
831
932
  }
832
933
  this.node = node;
833
934
  this.decorations = decorations;
834
- updateProps({ node, decorations });
935
+ this.innerDecorations = innerDecorations;
936
+ rerenderComponent({ node, decorations, innerDecorations });
835
937
  return true;
836
938
  }
939
+ /**
940
+ * Select the node.
941
+ * Add the `selected` prop and the `ProseMirror-selectednode` class.
942
+ */
837
943
  selectNode() {
838
944
  this.renderer.updateProps({
839
945
  selected: true
840
946
  });
841
947
  this.renderer.element.classList.add("ProseMirror-selectednode");
842
948
  }
949
+ /**
950
+ * Deselect the node.
951
+ * Remove the `selected` prop and the `ProseMirror-selectednode` class.
952
+ */
843
953
  deselectNode() {
844
954
  this.renderer.updateProps({
845
955
  selected: false
846
956
  });
847
957
  this.renderer.element.classList.remove("ProseMirror-selectednode");
848
958
  }
959
+ /**
960
+ * Destroy the React component instance.
961
+ */
849
962
  destroy() {
850
963
  this.renderer.destroy();
851
964
  this.editor.off("selectionUpdate", this.handleSelectionUpdate);
852
965
  this.contentDOMElement = null;
853
966
  }
967
+ /**
968
+ * Update the attributes of the top-level element that holds the React component.
969
+ * Applying the attributes defined in the `attrs` option.
970
+ */
971
+ updateElementAttributes() {
972
+ if (this.options.attrs) {
973
+ let attrsObj = {};
974
+ if (typeof this.options.attrs === "function") {
975
+ const extensionAttributes = this.editor.extensionManager.attributes;
976
+ const HTMLAttributes2 = getRenderedAttributes(this.node, extensionAttributes);
977
+ attrsObj = this.options.attrs({ node: this.node, HTMLAttributes: HTMLAttributes2 });
978
+ } else {
979
+ attrsObj = this.options.attrs;
980
+ }
981
+ this.renderer.updateAttributes(attrsObj);
982
+ }
983
+ }
854
984
  };
855
985
  function ReactNodeViewRenderer(component, options) {
856
986
  return (props) => {
@@ -873,6 +1003,7 @@ export {
873
1003
  NodeViewContent,
874
1004
  NodeViewWrapper,
875
1005
  PureEditorContent,
1006
+ ReactNodeView,
876
1007
  ReactNodeViewContext,
877
1008
  ReactNodeViewRenderer,
878
1009
  ReactRenderer,