From e45471d6f4cd6a431d500e8a7d22837ef0caf37f Mon Sep 17 00:00:00 2001 From: Aaron Dodson Date: Mon, 14 Apr 2025 13:56:46 -0700 Subject: [PATCH] fix: Fix menu scrolling. (#8881) --- core/css.ts | 7 +++---- core/field_dropdown.ts | 20 +++++++++----------- core/menu.ts | 5 ++--- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/core/css.ts b/core/css.ts index 0502edbf1..6ca262f3b 100644 --- a/core/css.ts +++ b/core/css.ts @@ -124,9 +124,6 @@ let content = ` .blocklyDropDownContent { max-height: 300px; /* @todo: spec for maximum height. */ - overflow: auto; - overflow-x: hidden; - position: relative; } .blocklyDropDownArrow { @@ -416,7 +413,9 @@ input[type=number] { border: inherit; /* Compatibility with gapi, reset from goog-menu */ font: normal 13px "Helvetica Neue", Helvetica, sans-serif; outline: none; - position: relative; /* Compatibility with gapi, reset from goog-menu */ + overflow-y: auto; + overflow-x: hidden; + max-height: 100%; z-index: 20000; /* Arbitrary, but some apps depend on it... */ } diff --git a/core/field_dropdown.ts b/core/field_dropdown.ts index 525dbf01b..23a8a3f7d 100644 --- a/core/field_dropdown.ts +++ b/core/field_dropdown.ts @@ -30,7 +30,6 @@ import {Coordinate} from './utils/coordinate.js'; import * as dom from './utils/dom.js'; import * as parsing from './utils/parsing.js'; import * as utilsString from './utils/string.js'; -import * as style from './utils/style.js'; import {Svg} from './utils/svg.js'; /** @@ -276,16 +275,18 @@ export class FieldDropdown extends Field { throw new UnattachedFieldError(); } this.dropdownCreate(); + if (!this.menu_) return; + if (e && typeof e.clientX === 'number') { - this.menu_!.openingCoords = new Coordinate(e.clientX, e.clientY); + this.menu_.openingCoords = new Coordinate(e.clientX, e.clientY); } else { - this.menu_!.openingCoords = null; + this.menu_.openingCoords = null; } // Remove any pre-existing elements in the dropdown. dropDownDiv.clearContent(); // Element gets created in render. - const menuElement = this.menu_!.render(dropDownDiv.getContentDiv()); + const menuElement = this.menu_.render(dropDownDiv.getContentDiv()); dom.addClass(menuElement, 'blocklyDropdownMenu'); if (this.getConstants()!.FIELD_DROPDOWN_COLOURED_DIV) { @@ -296,18 +297,15 @@ export class FieldDropdown extends Field { dropDownDiv.showPositionedByField(this, this.dropdownDispose_.bind(this)); + dropDownDiv.getContentDiv().style.height = `${this.menu_.getSize().height}px`; + // Focusing needs to be handled after the menu is rendered and positioned. // Otherwise it will cause a page scroll to get the misplaced menu in // view. See issue #1329. - this.menu_!.focus(); + this.menu_.focus(); if (this.selectedMenuItem) { - this.menu_!.setHighlighted(this.selectedMenuItem); - style.scrollIntoContainerView( - this.selectedMenuItem.getElement()!, - dropDownDiv.getContentDiv(), - true, - ); + this.menu_.setHighlighted(this.selectedMenuItem); } this.applyColour(); diff --git a/core/menu.ts b/core/menu.ts index 664d3872d..13fd0866f 100644 --- a/core/menu.ts +++ b/core/menu.ts @@ -258,11 +258,10 @@ export class Menu { // Bring the highlighted item into view. This has no effect if the menu is // not scrollable. const menuElement = this.getElement(); - const scrollingParent = menuElement?.parentElement; const menuItemElement = item.getElement(); - if (!scrollingParent || !menuItemElement) return; + if (!menuElement || !menuItemElement) return; - style.scrollIntoContainerView(menuItemElement, scrollingParent); + style.scrollIntoContainerView(menuItemElement, menuElement); aria.setState(menuElement, aria.State.ACTIVEDESCENDANT, item.getId()); } }