@tiptap/react 3.0.0-next.4 → 3.0.0-next.6

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
@@ -1,15 +1,11 @@
1
- // src/BubbleMenu.tsx
2
- import { BubbleMenuPlugin } from "@tiptap/extension-bubble-menu";
3
- import React3, { useEffect as useEffect3, useRef as useRef2 } from "react";
4
- import { createPortal } from "react-dom";
5
-
6
1
  // src/Context.tsx
7
- import React2, { createContext, useContext, useMemo } from "react";
2
+ import { createContext, useContext, useMemo } from "react";
8
3
 
9
4
  // src/EditorContent.tsx
10
5
  import React, { forwardRef } from "react";
11
6
  import ReactDOM from "react-dom";
12
7
  import { useSyncExternalStore } from "use-sync-external-store/shim";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
9
  var mergeRefs = (...refs) => {
14
10
  return (node) => {
15
11
  refs.forEach((ref) => {
@@ -28,7 +24,7 @@ var Portals = ({ contentComponent }) => {
28
24
  contentComponent.getSnapshot,
29
25
  contentComponent.getServerSnapshot
30
26
  );
31
- return /* @__PURE__ */ React.createElement(React.Fragment, null, Object.values(renderers));
27
+ return /* @__PURE__ */ jsx(Fragment, { children: Object.values(renderers) });
32
28
  };
33
29
  function getInstance() {
34
30
  const subscribers = /* @__PURE__ */ new Set();
@@ -118,6 +114,7 @@ var PureEditorContent = class extends React.Component {
118
114
  }
119
115
  }
120
116
  componentWillUnmount() {
117
+ var _a;
121
118
  const editor = this.props.editor;
122
119
  if (!editor) {
123
120
  return;
@@ -132,7 +129,7 @@ var PureEditorContent = class extends React.Component {
132
129
  this.unsubscribeToContentComponent();
133
130
  }
134
131
  editor.contentComponent = null;
135
- if (!editor.options.element.firstChild) {
132
+ if (!((_a = editor.options.element) == null ? void 0 : _a.firstChild)) {
136
133
  return;
137
134
  }
138
135
  const newElement = document.createElement("div");
@@ -143,7 +140,10 @@ var PureEditorContent = class extends React.Component {
143
140
  }
144
141
  render() {
145
142
  const { editor, innerRef, ...rest } = this.props;
146
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }), (editor == null ? void 0 : editor.contentComponent) && /* @__PURE__ */ React.createElement(Portals, { contentComponent: editor.contentComponent }));
143
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
144
+ /* @__PURE__ */ jsx("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
145
+ (editor == null ? void 0 : editor.contentComponent) && /* @__PURE__ */ jsx(Portals, { contentComponent: editor.contentComponent })
146
+ ] });
147
147
  }
148
148
  };
149
149
  var EditorContentWithKey = forwardRef(
@@ -248,7 +248,7 @@ function useEditorState(options) {
248
248
  var isDev = process.env.NODE_ENV !== "production";
249
249
  var isSSR = typeof window === "undefined";
250
250
  var isNext = isSSR || Boolean(typeof window !== "undefined" && window.next);
251
- var EditorInstanceManager = class {
251
+ var EditorInstanceManager = class _EditorInstanceManager {
252
252
  constructor(options) {
253
253
  /**
254
254
  * The current editor instance.
@@ -360,6 +360,10 @@ var EditorInstanceManager = class {
360
360
  onPaste: (...args) => {
361
361
  var _a, _b;
362
362
  return (_b = (_a = this.options.current).onPaste) == null ? void 0 : _b.call(_a, ...args);
363
+ },
364
+ onDelete: (...args) => {
365
+ var _a, _b;
366
+ return (_b = (_a = this.options.current).onDelete) == null ? void 0 : _b.call(_a, ...args);
363
367
  }
364
368
  };
365
369
  const editor = new Editor(optionsToApply);
@@ -386,6 +390,41 @@ var EditorInstanceManager = class {
386
390
  this.subscriptions.delete(onStoreChange);
387
391
  };
388
392
  }
393
+ static compareOptions(a, b) {
394
+ return Object.keys(a).every((key) => {
395
+ if ([
396
+ "onCreate",
397
+ "onBeforeCreate",
398
+ "onDestroy",
399
+ "onUpdate",
400
+ "onTransaction",
401
+ "onFocus",
402
+ "onBlur",
403
+ "onSelectionUpdate",
404
+ "onContentError",
405
+ "onDrop",
406
+ "onPaste"
407
+ ].includes(key)) {
408
+ return true;
409
+ }
410
+ if (key === "extensions" && a.extensions && b.extensions) {
411
+ if (a.extensions.length !== b.extensions.length) {
412
+ return false;
413
+ }
414
+ return a.extensions.every((extension, index) => {
415
+ var _a;
416
+ if (extension !== ((_a = b.extensions) == null ? void 0 : _a[index])) {
417
+ return false;
418
+ }
419
+ return true;
420
+ });
421
+ }
422
+ if (a[key] !== b[key]) {
423
+ return false;
424
+ }
425
+ return true;
426
+ });
427
+ }
389
428
  /**
390
429
  * On each render, we will create, update, or destroy the editor instance.
391
430
  * @param deps The dependencies to watch for changes
@@ -396,10 +435,12 @@ var EditorInstanceManager = class {
396
435
  this.isComponentMounted = true;
397
436
  clearTimeout(this.scheduledDestructionTimeout);
398
437
  if (this.editor && !this.editor.isDestroyed && deps.length === 0) {
399
- this.editor.setOptions({
400
- ...this.options.current,
401
- editable: this.editor.isEditable
402
- });
438
+ if (!_EditorInstanceManager.compareOptions(this.options.current, this.editor.options)) {
439
+ this.editor.setOptions({
440
+ ...this.options.current,
441
+ editable: this.editor.isEditable
442
+ });
443
+ }
403
444
  } else {
404
445
  this.refreshEditorInstance(deps);
405
446
  }
@@ -480,6 +521,7 @@ function useEditor(options = {}, deps = []) {
480
521
  }
481
522
 
482
523
  // src/Context.tsx
524
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
483
525
  var EditorContext = createContext({
484
526
  editor: null
485
527
  });
@@ -497,105 +539,14 @@ function EditorProvider({
497
539
  if (!editor) {
498
540
  return null;
499
541
  }
500
- 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);
542
+ return /* @__PURE__ */ jsxs2(EditorContext.Provider, { value: contextValue, children: [
543
+ slotBefore,
544
+ /* @__PURE__ */ jsx2(EditorConsumer, { children: ({ editor: currentEditor }) => /* @__PURE__ */ jsx2(EditorContent, { editor: currentEditor, ...editorContainerProps }) }),
545
+ children,
546
+ slotAfter
547
+ ] });
501
548
  }
502
549
 
503
- // src/BubbleMenu.tsx
504
- var BubbleMenu = React3.forwardRef(
505
- ({ pluginKey = "bubbleMenu", editor, updateDelay, resizeDelay, shouldShow = null, options, children, ...restProps }, ref) => {
506
- const menuEl = useRef2(document.createElement("div"));
507
- if (typeof ref === "function") {
508
- ref(menuEl.current);
509
- } else if (ref) {
510
- ref.current = menuEl.current;
511
- }
512
- const { editor: currentEditor } = useCurrentEditor();
513
- useEffect3(() => {
514
- const bubbleMenuElement = menuEl.current;
515
- bubbleMenuElement.style.visibility = "hidden";
516
- bubbleMenuElement.style.position = "absolute";
517
- if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
518
- return;
519
- }
520
- const attachToEditor = editor || currentEditor;
521
- if (!attachToEditor) {
522
- console.warn("BubbleMenu component is not rendered inside of an editor component or does not have editor prop.");
523
- return;
524
- }
525
- const plugin = BubbleMenuPlugin({
526
- updateDelay,
527
- resizeDelay,
528
- editor: attachToEditor,
529
- element: bubbleMenuElement,
530
- pluginKey,
531
- shouldShow,
532
- options
533
- });
534
- attachToEditor.registerPlugin(plugin);
535
- return () => {
536
- attachToEditor.unregisterPlugin(pluginKey);
537
- window.requestAnimationFrame(() => {
538
- if (bubbleMenuElement.parentNode) {
539
- bubbleMenuElement.parentNode.removeChild(bubbleMenuElement);
540
- }
541
- });
542
- };
543
- }, [editor, currentEditor]);
544
- return createPortal(/* @__PURE__ */ React3.createElement("div", { ...restProps }, children), menuEl.current);
545
- }
546
- );
547
-
548
- // src/FloatingMenu.tsx
549
- import { FloatingMenuPlugin } from "@tiptap/extension-floating-menu";
550
- import React4, { useEffect as useEffect4, useRef as useRef3 } from "react";
551
- import { createPortal as createPortal2 } from "react-dom";
552
- var FloatingMenu = React4.forwardRef(
553
- ({ pluginKey = "floatingMenu", editor, shouldShow = null, options, children, ...restProps }, ref) => {
554
- const menuEl = useRef3(document.createElement("div"));
555
- if (typeof ref === "function") {
556
- ref(menuEl.current);
557
- } else if (ref) {
558
- ref.current = menuEl.current;
559
- }
560
- const { editor: currentEditor } = useCurrentEditor();
561
- useEffect4(() => {
562
- const floatingMenuElement = menuEl.current;
563
- floatingMenuElement.style.visibility = "hidden";
564
- floatingMenuElement.style.position = "absolute";
565
- if ((editor == null ? void 0 : editor.isDestroyed) || (currentEditor == null ? void 0 : currentEditor.isDestroyed)) {
566
- return;
567
- }
568
- const attachToEditor = editor || currentEditor;
569
- if (!attachToEditor) {
570
- console.warn(
571
- "FloatingMenu component is not rendered inside of an editor component or does not have editor prop."
572
- );
573
- return;
574
- }
575
- const plugin = FloatingMenuPlugin({
576
- editor: attachToEditor,
577
- element: floatingMenuElement,
578
- pluginKey,
579
- shouldShow,
580
- options
581
- });
582
- attachToEditor.registerPlugin(plugin);
583
- return () => {
584
- attachToEditor.unregisterPlugin(pluginKey);
585
- window.requestAnimationFrame(() => {
586
- if (floatingMenuElement.parentNode) {
587
- floatingMenuElement.parentNode.removeChild(floatingMenuElement);
588
- }
589
- });
590
- };
591
- }, [editor, currentEditor]);
592
- return createPortal2(/* @__PURE__ */ React4.createElement("div", { ...restProps }, children), menuEl.current);
593
- }
594
- );
595
-
596
- // src/NodeViewContent.tsx
597
- import React5 from "react";
598
-
599
550
  // src/useReactNodeView.ts
600
551
  import { createContext as createContext2, createElement, useContext as useContext2 } from "react";
601
552
  var ReactNodeViewContext = createContext2({
@@ -611,6 +562,7 @@ var ReactNodeViewContentProvider = ({ children, content }) => {
611
562
  var useReactNodeView = () => useContext2(ReactNodeViewContext);
612
563
 
613
564
  // src/NodeViewContent.tsx
565
+ import { jsx as jsx3 } from "react/jsx-runtime";
614
566
  function NodeViewContent({
615
567
  as: Tag = "div",
616
568
  ...props
@@ -618,7 +570,7 @@ function NodeViewContent({
618
570
  const { nodeViewContentRef, nodeViewContentChildren } = useReactNodeView();
619
571
  return (
620
572
  // @ts-ignore
621
- /* @__PURE__ */ React5.createElement(
573
+ /* @__PURE__ */ jsx3(
622
574
  Tag,
623
575
  {
624
576
  ...props,
@@ -627,21 +579,22 @@ function NodeViewContent({
627
579
  style: {
628
580
  whiteSpace: "pre-wrap",
629
581
  ...props.style
630
- }
631
- },
632
- nodeViewContentChildren
582
+ },
583
+ children: nodeViewContentChildren
584
+ }
633
585
  )
634
586
  );
635
587
  }
636
588
 
637
589
  // src/NodeViewWrapper.tsx
638
- import React6 from "react";
639
- var NodeViewWrapper = React6.forwardRef((props, ref) => {
590
+ import React3 from "react";
591
+ import { jsx as jsx4 } from "react/jsx-runtime";
592
+ var NodeViewWrapper = React3.forwardRef((props, ref) => {
640
593
  const { onDragStart } = useReactNodeView();
641
594
  const Tag = props.as || "div";
642
595
  return (
643
596
  // @ts-ignore
644
- /* @__PURE__ */ React6.createElement(
597
+ /* @__PURE__ */ jsx4(
645
598
  Tag,
646
599
  {
647
600
  ...props,
@@ -657,16 +610,13 @@ var NodeViewWrapper = React6.forwardRef((props, ref) => {
657
610
  );
658
611
  });
659
612
 
660
- // src/ReactNodeViewRenderer.tsx
661
- import {
662
- getRenderedAttributes,
663
- NodeView
664
- } from "@tiptap/core";
665
- import React8 from "react";
613
+ // src/ReactMarkViewRenderer.tsx
614
+ import { MarkView } from "@tiptap/core";
615
+ import React4 from "react";
666
616
 
667
617
  // src/ReactRenderer.tsx
668
- import React7 from "react";
669
618
  import { flushSync } from "react-dom";
619
+ import { jsx as jsx5 } from "react/jsx-runtime";
670
620
  function isClassComponent(Component) {
671
621
  return !!(typeof Component === "function" && Component.prototype && Component.prototype.isReactComponent);
672
622
  }
@@ -710,7 +660,7 @@ var ReactRenderer = class {
710
660
  this.ref = ref;
711
661
  };
712
662
  }
713
- this.reactElement = /* @__PURE__ */ React7.createElement(Component, { ...props });
663
+ this.reactElement = /* @__PURE__ */ jsx5(Component, { ...props });
714
664
  (_a = editor == null ? void 0 : editor.contentComponent) == null ? void 0 : _a.setRenderer(this.id, this);
715
665
  }
716
666
  /**
@@ -741,7 +691,71 @@ var ReactRenderer = class {
741
691
  }
742
692
  };
743
693
 
694
+ // src/ReactMarkViewRenderer.tsx
695
+ import { jsx as jsx6 } from "react/jsx-runtime";
696
+ var ReactMarkViewContext = React4.createContext({
697
+ markViewContentRef: () => {
698
+ }
699
+ });
700
+ var MarkViewContent = (props) => {
701
+ const Tag = props.as || "span";
702
+ const { markViewContentRef } = React4.useContext(ReactMarkViewContext);
703
+ return (
704
+ // @ts-ignore
705
+ /* @__PURE__ */ jsx6(Tag, { ...props, ref: markViewContentRef, "data-mark-view-content": "" })
706
+ );
707
+ };
708
+ var ReactMarkView = class extends MarkView {
709
+ constructor(component, props, options) {
710
+ super(component, props, options);
711
+ this.didMountContentDomElement = false;
712
+ const { as = "span", attrs, className = "" } = options || {};
713
+ const componentProps = props;
714
+ this.contentDOMElement = document.createElement("span");
715
+ const markViewContentRef = (el) => {
716
+ if (el && this.contentDOMElement && el.firstChild !== this.contentDOMElement) {
717
+ el.appendChild(this.contentDOMElement);
718
+ this.didMountContentDomElement = true;
719
+ }
720
+ };
721
+ const context = {
722
+ markViewContentRef
723
+ };
724
+ const ReactMarkViewProvider = React4.memo((componentProps2) => {
725
+ return /* @__PURE__ */ jsx6(ReactMarkViewContext.Provider, { value: context, children: React4.createElement(component, componentProps2) });
726
+ });
727
+ ReactMarkViewProvider.displayName = "ReactNodeView";
728
+ this.renderer = new ReactRenderer(ReactMarkViewProvider, {
729
+ editor: props.editor,
730
+ props: componentProps,
731
+ as,
732
+ className: `mark-${props.mark.type.name} ${className}`.trim()
733
+ });
734
+ if (attrs) {
735
+ this.renderer.updateAttributes(attrs);
736
+ }
737
+ }
738
+ get dom() {
739
+ return this.renderer.element;
740
+ }
741
+ get contentDOM() {
742
+ if (!this.didMountContentDomElement) {
743
+ return null;
744
+ }
745
+ return this.contentDOMElement;
746
+ }
747
+ };
748
+ function ReactMarkViewRenderer(component, options = {}) {
749
+ return (props) => new ReactMarkView(component, props, options);
750
+ }
751
+
744
752
  // src/ReactNodeViewRenderer.tsx
753
+ import {
754
+ getRenderedAttributes,
755
+ NodeView
756
+ } from "@tiptap/core";
757
+ import React5 from "react";
758
+ import { jsx as jsx7 } from "react/jsx-runtime";
745
759
  var ReactNodeView = class extends NodeView {
746
760
  /**
747
761
  * Setup the React component.
@@ -775,8 +789,8 @@ var ReactNodeView = class extends NodeView {
775
789
  };
776
790
  const context = { onDragStart, nodeViewContentRef };
777
791
  const Component = this.component;
778
- const ReactNodeViewProvider = React8.memo((componentProps) => {
779
- return /* @__PURE__ */ React8.createElement(ReactNodeViewContext.Provider, { value: context }, React8.createElement(Component, componentProps));
792
+ const ReactNodeViewProvider = React5.memo((componentProps) => {
793
+ return /* @__PURE__ */ jsx7(ReactNodeViewContext.Provider, { value: context, children: React5.createElement(Component, componentProps) });
780
794
  });
781
795
  ReactNodeViewProvider.displayName = "ReactNodeView";
782
796
  if (this.node.isLeaf) {
@@ -796,13 +810,13 @@ var ReactNodeView = class extends NodeView {
796
810
  }
797
811
  const { className = "" } = this.options;
798
812
  this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
799
- this.editor.on("selectionUpdate", this.handleSelectionUpdate);
800
813
  this.renderer = new ReactRenderer(ReactNodeViewProvider, {
801
814
  editor: this.editor,
802
815
  props,
803
816
  as,
804
817
  className: `node-${this.node.type.name} ${className}`.trim()
805
818
  });
819
+ this.editor.on("selectionUpdate", this.handleSelectionUpdate);
806
820
  this.updateElementAttributes();
807
821
  }
808
822
  /**
@@ -946,15 +960,17 @@ function ReactNodeViewRenderer(component, options) {
946
960
  // src/index.ts
947
961
  export * from "@tiptap/core";
948
962
  export {
949
- BubbleMenu,
950
963
  EditorConsumer,
951
964
  EditorContent,
952
965
  EditorContext,
953
966
  EditorProvider,
954
- FloatingMenu,
967
+ MarkViewContent,
955
968
  NodeViewContent,
956
969
  NodeViewWrapper,
957
970
  PureEditorContent,
971
+ ReactMarkView,
972
+ ReactMarkViewContext,
973
+ ReactMarkViewRenderer,
958
974
  ReactNodeView,
959
975
  ReactNodeViewContentProvider,
960
976
  ReactNodeViewContext,