Skip to content

Commit 1b414c8

Browse files
fix: Formatting toolbar opening on drop (#944)
* WIP fix for formatting toolbar appearing on drop * Re-added focus event handling for formatting toolbar * Removed focus handler
1 parent 2064dfc commit 1b414c8

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,45 @@ export class FormattingToolbarView implements PluginView {
5858
pmView.dom.addEventListener("mouseup", this.viewMouseupHandler);
5959
pmView.dom.addEventListener("dragstart", this.dragHandler);
6060
pmView.dom.addEventListener("dragover", this.dragHandler);
61+
pmView.dom.addEventListener("blur", this.blurHandler);
6162

6263
// Setting capture=true ensures that any parent container of the editor that
6364
// gets scrolled will trigger the scroll event. Scroll events do not bubble
6465
// and so won't propagate to the document by default.
6566
pmView.root.addEventListener("scroll", this.scrollHandler, true);
6667
}
6768

69+
blurHandler = (event: FocusEvent) => {
70+
if (this.preventHide) {
71+
this.preventHide = false;
72+
73+
return;
74+
}
75+
76+
const editorWrapper = this.pmView.dom.parentElement!;
77+
78+
// Checks if the focus is moving to an element outside the editor. If it is,
79+
// the toolbar is hidden.
80+
if (
81+
// An element is clicked.
82+
event &&
83+
event.relatedTarget &&
84+
// Element is inside the editor.
85+
(editorWrapper === (event.relatedTarget as Node) ||
86+
editorWrapper.contains(event.relatedTarget as Node) ||
87+
(event.relatedTarget as HTMLElement).matches(
88+
".bn-ui-container, .bn-ui-container *"
89+
))
90+
) {
91+
return;
92+
}
93+
94+
if (this.state?.show) {
95+
this.state.show = false;
96+
this.emitUpdate();
97+
}
98+
};
99+
68100
viewMousedownHandler = () => {
69101
this.preventShow = true;
70102
};
@@ -90,6 +122,10 @@ export class FormattingToolbarView implements PluginView {
90122
};
91123

92124
update(view: EditorView, oldState?: EditorState) {
125+
// Delays the update to handle edge case with drag and drop, where the view
126+
// is blurred asynchronously and happens only after the state update.
127+
// Wrapping in a setTimeout gives enough time to wait for the blur event to
128+
// occur before updating the toolbar.
93129
const { state, composing } = view;
94130
const { doc, selection } = state;
95131
const isSame =
@@ -146,6 +182,7 @@ export class FormattingToolbarView implements PluginView {
146182
this.pmView.dom.removeEventListener("mouseup", this.viewMouseupHandler);
147183
this.pmView.dom.removeEventListener("dragstart", this.dragHandler);
148184
this.pmView.dom.removeEventListener("dragover", this.dragHandler);
185+
this.pmView.dom.removeEventListener("blur", this.blurHandler);
149186

150187
this.pmView.root.removeEventListener("scroll", this.scrollHandler, true);
151188
}

0 commit comments

Comments
 (0)