From 5134c6257317cc7ba28cd5610191d1468ee1ac77 Mon Sep 17 00:00:00 2001 From: Dominik Biedebach Date: Mon, 27 Mar 2023 10:38:22 +0200 Subject: [PATCH 1/4] fix(bubble-menu): use correct children of node view renderers for clientRect --- packages/extension-bubble-menu/src/bubble-menu-plugin.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/extension-bubble-menu/src/bubble-menu-plugin.ts b/packages/extension-bubble-menu/src/bubble-menu-plugin.ts index f297f43aca1..827669d3aa3 100644 --- a/packages/extension-bubble-menu/src/bubble-menu-plugin.ts +++ b/packages/extension-bubble-menu/src/bubble-menu-plugin.ts @@ -201,7 +201,13 @@ export class BubbleMenuView { this.tippyOptions?.getReferenceClientRect || (() => { if (isNodeSelection(state.selection)) { - const node = view.nodeDOM(from) as HTMLElement + let node = view.nodeDOM(from) as HTMLElement + + const nodeViewWrapper = node.querySelector('[data-node-view-wrapper]') + + if (nodeViewWrapper) { + node = nodeViewWrapper.firstChild as HTMLElement + } if (node) { return node.getBoundingClientRect() From cb1aa869278120f8183df5ba151c60256a19a090 Mon Sep 17 00:00:00 2001 From: Dominik Biedebach Date: Mon, 27 Mar 2023 10:48:28 +0200 Subject: [PATCH 2/4] fix(bubble-menu): remove lodash --- package-lock.json | 24 ++++--------------- packages/extension-bubble-menu/package.json | 4 +--- .../src/bubble-menu-plugin.ts | 20 ++++++++++++---- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 29e34bb29db..09a178bf415 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6564,12 +6564,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", - "dev": true - }, "node_modules/@types/minimatch": { "version": "3.0.5", "dev": true, @@ -13328,7 +13322,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -19345,12 +19340,10 @@ "version": "2.0.0-beta.220", "license": "MIT", "dependencies": { - "lodash": "^4.17.21", "tippy.js": "^6.3.7" }, "devDependencies": { - "@tiptap/pm": "^2.0.0-beta.220", - "@types/lodash": "^4.14.191" + "@tiptap/pm": "^2.0.0-beta.220" }, "funding": { "type": "github", @@ -24496,8 +24489,6 @@ "version": "file:packages/extension-bubble-menu", "requires": { "@tiptap/pm": "^2.0.0-beta.220", - "@types/lodash": "^4.14.191", - "lodash": "^4.17.21", "tippy.js": "^6.3.7" } }, @@ -24917,12 +24908,6 @@ "version": "0.0.29", "dev": true }, - "@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", - "dev": true - }, "@types/minimatch": { "version": "3.0.5", "dev": true @@ -29258,7 +29243,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.debounce": { "version": "4.0.8", diff --git a/packages/extension-bubble-menu/package.json b/packages/extension-bubble-menu/package.json index b15eda3e8ab..1df36675b94 100644 --- a/packages/extension-bubble-menu/package.json +++ b/packages/extension-bubble-menu/package.json @@ -33,7 +33,6 @@ "@tiptap/pm": "^2.0.0-beta.209" }, "dependencies": { - "lodash": "^4.17.21", "tippy.js": "^6.3.7" }, "repository": { @@ -43,8 +42,7 @@ }, "sideEffects": false, "devDependencies": { - "@tiptap/pm": "^2.0.0-beta.220", - "@types/lodash": "^4.14.191" + "@tiptap/pm": "^2.0.0-beta.220" }, "scripts": { "clean": "rm -rf dist", diff --git a/packages/extension-bubble-menu/src/bubble-menu-plugin.ts b/packages/extension-bubble-menu/src/bubble-menu-plugin.ts index 827669d3aa3..14f6074a719 100644 --- a/packages/extension-bubble-menu/src/bubble-menu-plugin.ts +++ b/packages/extension-bubble-menu/src/bubble-menu-plugin.ts @@ -3,7 +3,6 @@ import { } from '@tiptap/core' import { EditorState, Plugin, PluginKey } from '@tiptap/pm/state' import { EditorView } from '@tiptap/pm/view' -import debounce from 'lodash/debounce' import tippy, { Instance, Props } from 'tippy.js' export interface BubbleMenuPluginProps { @@ -43,6 +42,8 @@ export class BubbleMenuView { public updateDelay: number + private updateDebounceTimer: number | undefined + public shouldShow: Exclude = ({ view, state, @@ -159,10 +160,21 @@ export class BubbleMenuView { const hasValidSelection = state.selection.$from.pos !== state.selection.$to.pos if (this.updateDelay > 0 && hasValidSelection) { - debounce(this.updateHandler, this.updateDelay)(view, oldState) - } else { - this.updateHandler(view, oldState) + this.handleDebouncedUpdate(view, oldState) + return } + + this.updateHandler(view, oldState) + } + + handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => { + if (this.updateDebounceTimer) { + clearTimeout(this.updateDebounceTimer) + } + + this.updateDebounceTimer = window.setTimeout(() => { + this.updateHandler(view, oldState) + }, this.updateDelay) } updateHandler = (view: EditorView, oldState?: EditorState) => { From 1503c24f4f51eb21681e3d219b6013aea5c474f2 Mon Sep 17 00:00:00 2001 From: Dominik Biedebach Date: Mon, 27 Mar 2023 10:51:25 +0200 Subject: [PATCH 3/4] fix(bubble-menu): support vue node views --- .../src/Extensions/BubbleMenu/React/index.jsx | 55 ++++++++++++++++++- .../src/bubble-menu-plugin.ts | 2 +- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/demos/src/Extensions/BubbleMenu/React/index.jsx b/demos/src/Extensions/BubbleMenu/React/index.jsx index 3fe7675b969..4daaa6ed9d5 100644 --- a/demos/src/Extensions/BubbleMenu/React/index.jsx +++ b/demos/src/Extensions/BubbleMenu/React/index.jsx @@ -1,18 +1,69 @@ import './styles.scss' -import { BubbleMenu, EditorContent, useEditor } from '@tiptap/react' +import { + BubbleMenu, EditorContent, Node, NodeViewWrapper, ReactNodeViewRenderer, useEditor, +} from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import React, { useEffect } from 'react' +const CustomNodeView = () => { + return ( + +
This is my node view!
+
+ ) +} + +const CustomNodeViewNode = Node.create({ + name: 'customNodeView', + + group: 'block', + + content: 'inline*', + + selectable: true, + + defining: true, + + atom: true, + + isolating: true, + + renderHTML() { + return ['div', { class: 'custom-node-view' }, 0] + }, + + parseHTML() { + return [ + { + tag: 'div.custom-node-view', + }, + ] + }, + + addNodeView() { + return ReactNodeViewRenderer(CustomNodeView) + }, +}) + export default () => { const editor = useEditor({ extensions: [ StarterKit, + CustomNodeViewNode, ], content: ` +
+

+ Hey, try to select some text here. There will popup a menu for selecting some inline styles. Remember: you have full control about content and styling of this menu. +

+
+

Hey, try to select some text here. There will popup a menu for selecting some inline styles. Remember: you have full control about content and styling of this menu.

+
+
`, }) @@ -30,7 +81,7 @@ export default () => { setIsEditable(!isEditable)} /> Editable - {editor && + {editor &&