Skip to content

Commit 432110a

Browse files
fix: UI element position on scroll (#769)
* Fixed UI element position on scroll & minor fix for side menu * Added comments * Made add block button no longer freeze side menu
1 parent 2e26ead commit 432110a

File tree

6 files changed

+46
-27
lines changed

6 files changed

+46
-27
lines changed

packages/core/src/extensions/FilePanel/FilePanelPlugin.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
4242
};
4343

4444
pmView.dom.addEventListener("mousedown", this.mouseDownHandler);
45-
4645
pmView.dom.addEventListener("dragstart", this.dragstartHandler);
4746

48-
document.addEventListener("scroll", this.scrollHandler);
47+
// Setting capture=true ensures that any parent container of the editor that
48+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
49+
// and so won't propagate to the document by default.
50+
document.addEventListener("scroll", this.scrollHandler, true);
4951
}
5052

5153
mouseDownHandler = () => {
@@ -119,7 +121,7 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
119121

120122
this.pmView.dom.removeEventListener("dragstart", this.dragstartHandler);
121123

122-
document.removeEventListener("scroll", this.scrollHandler);
124+
document.removeEventListener("scroll", this.scrollHandler, true);
123125
}
124126
}
125127

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ export class FormattingToolbarView implements PluginView {
6060
pmView.dom.addEventListener("dragstart", this.dragHandler);
6161
pmView.dom.addEventListener("dragover", this.dragHandler);
6262

63-
document.addEventListener("scroll", this.scrollHandler);
63+
// Setting capture=true ensures that any parent container of the editor that
64+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
65+
// and so won't propagate to the document by default.
66+
document.addEventListener("scroll", this.scrollHandler, true);
6467
}
6568

6669
viewMousedownHandler = () => {
@@ -150,7 +153,7 @@ export class FormattingToolbarView implements PluginView {
150153
this.pmView.dom.removeEventListener("dragstart", this.dragHandler);
151154
this.pmView.dom.removeEventListener("dragover", this.dragHandler);
152155

153-
document.removeEventListener("scroll", this.scrollHandler);
156+
document.removeEventListener("scroll", this.scrollHandler, true);
154157
}
155158

156159
closeMenu = () => {

packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ class LinkToolbarView implements PluginView {
6262

6363
this.pmView.dom.addEventListener("mouseover", this.mouseOverHandler);
6464
document.addEventListener("click", this.clickHandler, true);
65-
document.addEventListener("scroll", this.scrollHandler);
65+
66+
// Setting capture=true ensures that any parent container of the editor that
67+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
68+
// and so won't propagate to the document by default.
69+
document.addEventListener("scroll", this.scrollHandler, true);
6670
}
6771

6872
mouseOverHandler = (event: MouseEvent) => {
@@ -267,7 +271,7 @@ class LinkToolbarView implements PluginView {
267271

268272
destroy() {
269273
this.pmView.dom.removeEventListener("mouseover", this.mouseOverHandler);
270-
document.removeEventListener("scroll", this.scrollHandler);
274+
document.removeEventListener("scroll", this.scrollHandler, true);
271275
document.removeEventListener("click", this.clickHandler, true);
272276
}
273277
}

packages/core/src/extensions/SideMenu/SideMenuPlugin.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ export class SideMenuView<
252252
S extends StyleSchema
253253
> implements PluginView
254254
{
255-
private state?: SideMenuState<BSchema, I, S>;
256-
private readonly emitUpdate: (state: SideMenuState<BSchema, I, S>) => void;
255+
public state?: SideMenuState<BSchema, I, S>;
256+
public readonly emitUpdate: (state: SideMenuState<BSchema, I, S>) => void;
257257

258258
private needUpdate = false;
259259
private mousePos: { x: number; y: number } | undefined;
@@ -296,13 +296,15 @@ export class SideMenuView<
296296
// Shows or updates menu position whenever the cursor moves, if the menu isn't frozen.
297297
document.body.addEventListener("mousemove", this.onMouseMove, true);
298298

299-
// Makes menu scroll with the page.
300-
document.addEventListener("scroll", this.onScroll);
301-
302-
// Unfreezes the menu whenever the user clicks anywhere.
303-
document.body.addEventListener("mousedown", this.onMouseDown, true);
299+
// Unfreezes the menu whenever the user clicks.
300+
this.pmView.dom.addEventListener("mousedown", this.onMouseDown);
304301
// Hides and unfreezes the menu whenever the user presses a key.
305302
document.body.addEventListener("keydown", this.onKeyDown, true);
303+
304+
// Setting capture=true ensures that any parent container of the editor that
305+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
306+
// and so won't propagate to the document by default.
307+
document.addEventListener("scroll", this.onScroll, true);
306308
}
307309

308310
updateState = () => {
@@ -456,12 +458,12 @@ export class SideMenuView<
456458
}
457459
};
458460

459-
onMouseDown = (_event: MouseEvent) => {
460-
if (this.state && !this.state.show) {
461-
this.state.show = true;
461+
onMouseDown = () => {
462+
if (this.state && this.state.show && this.menuFrozen) {
463+
this.menuFrozen = false;
464+
this.state.show = false;
462465
this.emitUpdate(this.state);
463466
}
464-
this.menuFrozen = false;
465467
};
466468

467469
onMouseMove = (event: MouseEvent) => {
@@ -552,8 +554,8 @@ export class SideMenuView<
552554
document.body.removeEventListener("dragover", this.onDragOver);
553555
this.pmView.dom.removeEventListener("dragstart", this.onDragStart);
554556
document.body.removeEventListener("drop", this.onDrop, true);
555-
document.removeEventListener("scroll", this.onScroll);
556-
document.body.removeEventListener("mousedown", this.onMouseDown, true);
557+
document.removeEventListener("scroll", this.onScroll, true);
558+
this.pmView.dom.removeEventListener("mousedown", this.onMouseDown);
557559
document.body.removeEventListener("keydown", this.onKeyDown, true);
558560
}
559561

@@ -563,8 +565,6 @@ export class SideMenuView<
563565
this.emitUpdate(this.state);
564566
}
565567

566-
this.menuFrozen = true;
567-
568568
const blockContent = this.hoveredBlock!.firstChild! as HTMLElement;
569569
const blockContentBoundingBox = blockContent.getBoundingClientRect();
570570

@@ -674,5 +674,9 @@ export class SideMenuProsemirrorPlugin<
674674
* attached to the same block regardless of which block is hovered by the
675675
* mouse cursor.
676676
*/
677-
unfreezeMenu = () => (this.view!.menuFrozen = false);
677+
unfreezeMenu = () => {
678+
this.view!.menuFrozen = false;
679+
this.view!.state!.show = false;
680+
this.view!.emitUpdate(this.view!.state!);
681+
};
678682
}

packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class SuggestionMenuView<
3737
emitUpdate(menuName, this.state);
3838
};
3939

40-
document.addEventListener("scroll", this.handleScroll);
40+
// Setting capture=true ensures that any parent container of the editor that
41+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
42+
// and so won't propagate to the document by default.
43+
document.addEventListener("scroll", this.handleScroll, true);
4144
}
4245

4346
handleScroll = () => {
@@ -92,7 +95,7 @@ class SuggestionMenuView<
9295
}
9396

9497
destroy() {
95-
document.removeEventListener("scroll", this.handleScroll);
98+
document.removeEventListener("scroll", this.handleScroll, true);
9699
}
97100

98101
closeMenu = () => {

packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ export class TableHandlesView<
119119
document.addEventListener("dragover", this.dragOverHandler);
120120
document.addEventListener("drop", this.dropHandler);
121121

122-
document.addEventListener("scroll", this.scrollHandler);
122+
// Setting capture=true ensures that any parent container of the editor that
123+
// gets scrolled will trigger the scroll event. Scroll events do not bubble
124+
// and so won't propagate to the document by default.
125+
document.addEventListener("scroll", this.scrollHandler, true);
123126
}
124127

125128
mouseMoveHandler = (event: MouseEvent) => {
@@ -361,7 +364,7 @@ export class TableHandlesView<
361364
document.removeEventListener("dragover", this.dragOverHandler);
362365
document.removeEventListener("drop", this.dropHandler);
363366

364-
document.removeEventListener("scroll", this.scrollHandler);
367+
document.removeEventListener("scroll", this.scrollHandler, true);
365368
}
366369
}
367370

0 commit comments

Comments
 (0)