diff --git a/packages/editor/src/extensions/embed/embed.ts b/packages/editor/src/extensions/embed/embed.ts
index ee061e965..4490ec51c 100644
--- a/packages/editor/src/extensions/embed/embed.ts
+++ b/packages/editor/src/extensions/embed/embed.ts
@@ -18,6 +18,7 @@ along with this program. If not, see .
*/
import { Node, mergeAttributes } from "@tiptap/core";
+import { hasSameAttributes } from "../../utils/prosemirror";
import { createSelectionBasedNodeView } from "../react";
import { TextDirections } from "../text-direction";
import { EmbedComponent } from "./component";
@@ -100,7 +101,9 @@ export const EmbedNode = Node.create({
},
addNodeView() {
- return createSelectionBasedNodeView(EmbedComponent);
+ return createSelectionBasedNodeView(EmbedComponent, {
+ shouldUpdate: (prev, next) => !hasSameAttributes(prev.attrs, next.attrs)
+ });
},
addCommands() {
diff --git a/packages/editor/src/extensions/image/image.ts b/packages/editor/src/extensions/image/image.ts
index ca5373224..4981d151c 100644
--- a/packages/editor/src/extensions/image/image.ts
+++ b/packages/editor/src/extensions/image/image.ts
@@ -23,6 +23,7 @@ import {
mergeAttributes,
findChildren
} from "@tiptap/core";
+import { hasSameAttributes } from "../../utils/prosemirror";
import { Attachment, getDataAttribute } from "../attachment";
import { createSelectionBasedNodeView } from "../react";
import { TextDirections } from "../text-direction";
@@ -133,7 +134,9 @@ export const ImageNode = Node.create({
},
addNodeView() {
- return createSelectionBasedNodeView(ImageComponent);
+ return createSelectionBasedNodeView(ImageComponent, {
+ shouldUpdate: (prev, next) => !hasSameAttributes(prev.attrs, next.attrs)
+ });
},
addCommands() {
diff --git a/packages/editor/src/extensions/table/component.tsx b/packages/editor/src/extensions/table/component.tsx
index 5e8cce151..e87b850ae 100644
--- a/packages/editor/src/extensions/table/component.tsx
+++ b/packages/editor/src/extensions/table/component.tsx
@@ -35,7 +35,10 @@ import {
} from "../../toolbar/tools/table";
import { getToolDefinition } from "../../toolbar/tool-definitions";
import { getPosition } from "../../utils/position";
-import { findSelectedDOMNode } from "../../utils/prosemirror";
+import {
+ findSelectedDOMNode,
+ hasSameAttributes
+} from "../../utils/prosemirror";
import { DesktopOnly } from "../../components/responsive";
import { TextDirections } from "../text-direction";
@@ -59,12 +62,12 @@ export function TableComponent(props: SelectionBasedReactNodeViewProps) {
<>
>
@@ -98,7 +101,10 @@ export function TableNodeView(editor: Editor) {
{
component: TableComponent,
shouldUpdate: (prev, next) => {
- return prev.type === next.type;
+ return (
+ !hasSameAttributes(prev.attrs, next.attrs) ||
+ prev.childCount !== next.childCount
+ );
},
contentDOMFactory: () => {
const dom = document.createElement("tbody");
@@ -119,7 +125,7 @@ export function TableNodeView(editor: Editor) {
type TableToolbarProps = {
editor: Editor;
- table?: HTMLTableElement;
+ table?: React.MutableRefObject;
textDirection: TextDirections;
};
@@ -127,12 +133,11 @@ function TableRowToolbar(props: TableToolbarProps) {
const { editor, textDirection } = props;
const rowToolsRef = useRef(null);
- useEffect(
- () => {
+ useEffect(() => {
+ function onSelectionUpdate() {
if (!rowToolsRef.current) {
return;
}
-
const currentRow = findSelectedDOMNode(editor, ["tableRow"]);
if (!currentRow) return;
@@ -151,10 +156,13 @@ function TableRowToolbar(props: TableToolbarProps) {
rowToolsRef.current.style.left = `${pos.left}px`;
rowToolsRef.current.style.right = `unset`;
}
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [editor.state.selection, textDirection]
- );
+ }
+
+ editor.current?.on("selectionUpdate", onSelectionUpdate);
+ return () => {
+ editor.current?.off("selectionUpdate", onSelectionUpdate);
+ };
+ }, [textDirection]);
return (
(null);
- useEffect(
- () => {
- if (!columnToolsRef.current || !table) {
+
+ useEffect(() => {
+ function onSelectionUpdate() {
+ if (!columnToolsRef.current || !table?.current) {
return;
}
@@ -209,16 +218,19 @@ function TableColumnToolbar(props: TableToolbarProps) {
location: "top",
align: "center",
target: currentCell as HTMLElement,
- yAnchor: table,
+ yAnchor: table.current,
yOffset: 2
});
columnToolsRef.current.style.left = `${pos.left}px`;
columnToolsRef.current.style.top = `${pos.top}px`;
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [editor.state.selection, table]
- );
+ }
+
+ editor.current?.on("selectionUpdate", onSelectionUpdate);
+ return () => {
+ editor.current?.off("selectionUpdate", onSelectionUpdate);
+ };
+ }, []);
return (
{
+ return (
+ !hasSameAttributes(prev.attrs, next.attrs) ||
+ prev.childCount !== next.childCount
+ );
}
});
},
diff --git a/packages/editor/src/extensions/web-clip/web-clip.ts b/packages/editor/src/extensions/web-clip/web-clip.ts
index a003ff64f..203051306 100644
--- a/packages/editor/src/extensions/web-clip/web-clip.ts
+++ b/packages/editor/src/extensions/web-clip/web-clip.ts
@@ -18,6 +18,7 @@ along with this program. If not, see .
*/
import { Node, mergeAttributes, findChildren } from "@tiptap/core";
+import { hasSameAttributes } from "../../utils/prosemirror";
import { getDataAttribute } from "../attachment";
import { createSelectionBasedNodeView } from "../react";
import { WebClipComponent } from "./component";
@@ -108,7 +109,9 @@ export const WebClipNode = Node.create({
},
addNodeView() {
- return createSelectionBasedNodeView(WebClipComponent);
+ return createSelectionBasedNodeView(WebClipComponent, {
+ shouldUpdate: (prev, next) => !hasSameAttributes(prev.attrs, next.attrs)
+ });
},
addCommands() {
diff --git a/packages/editor/src/utils/prosemirror.ts b/packages/editor/src/utils/prosemirror.ts
index c6f3d04ea..fbd7b743d 100644
--- a/packages/editor/src/utils/prosemirror.ts
+++ b/packages/editor/src/utils/prosemirror.ts
@@ -28,10 +28,20 @@ import {
Node as ProsemirrorNode,
Mark,
NodeType,
- ResolvedPos
+ ResolvedPos,
+ Attrs
} from "prosemirror-model";
import { EditorState, Selection } from "prosemirror-state";
+export function hasSameAttributes(prev: Attrs, next: Attrs) {
+ for (const key in prev) {
+ const prevValue = prev[key];
+ const nextValue = next[key];
+ if (prevValue !== nextValue) return false;
+ }
+ return true;
+}
+
export type NodeWithOffset = {
node?: ProsemirrorNode;
from: number;