diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index aa872fc467..5b86a5aaa4 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -154,6 +154,10 @@ export class BlockNoteEditor { return this._tiptapEditor.view.dom as HTMLDivElement; } + public isFocused() { + return this._tiptapEditor.view.hasFocus(); + } + public focus() { this._tiptapEditor.view.focus(); } diff --git a/packages/core/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts b/packages/core/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts index 51d7b823d8..b076f00dd8 100644 --- a/packages/core/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +++ b/packages/core/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts @@ -375,11 +375,45 @@ export class BlockMenuView { return; } - // Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of - // the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box. + // Editor itself may have padding or other styling which affects + // size/position, so we get the boundingRect of the first child (i.e. the + // blockGroup that wraps all blocks in the editor) for more accurate side + // menu placement. const editorBoundingBox = ( this.ttEditor.view.dom.firstChild! as HTMLElement ).getBoundingClientRect(); + // We want the full area of the editor to check if the cursor is hovering + // above it though. + const editorOuterBoundingBox = + this.ttEditor.view.dom.getBoundingClientRect(); + const cursorWithinEditor = + event.clientX >= editorOuterBoundingBox.left && + event.clientX <= editorOuterBoundingBox.right && + event.clientY >= editorOuterBoundingBox.top && + event.clientY <= editorOuterBoundingBox.bottom; + + // Doesn't update if the mouse hovers an element that's over the editor but + // isn't a part of it or the side menu. + if ( + // Cursor is within the editor area + cursorWithinEditor && + // An element is hovered + event && + event.target && + // Element is outside the editor + this.ttEditor.view.dom !== event.target && + !this.ttEditor.view.dom.contains(event.target as HTMLElement) && + // Element is outside the side menu + this.blockMenu.element !== event.target && + !this.blockMenu.element?.contains(event.target as HTMLElement) + ) { + if (this.menuOpen) { + this.menuOpen = false; + this.blockMenu.hide(); + } + + return; + } this.horizontalPosAnchor = editorBoundingBox.x;