From 453feb0779d3b7ba97a53470a6bdae5022a8c93f Mon Sep 17 00:00:00 2001 From: Joy Serquina Date: Tue, 4 Jun 2024 20:25:31 +0000 Subject: [PATCH] fix(material/autocomplete): autocomplete panel top cut off in mobile landscape Fixes Angular Components autocomplete so that when the panel is open in mobile landscape that it does not cut off at the top and the panel resizes/adjusts according to the viewport. Updates the previous fix to avoid subscribing to handsetLandscapeSubscription as a side effect. Fixes b/284148377 --- .../autocomplete/autocomplete-trigger.ts | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index d3aa777808a7..efee88306410 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -140,7 +140,6 @@ export class MatAutocompleteTrigger private _scrollStrategy: () => ScrollStrategy; private _keydownSubscription: Subscription | null; private _outsideClickSubscription: Subscription | null; - private _handsetLandscapeBreakpointSubscription: Subscription | null; /** Old value of the native input. Used to work around issues with the `input` event on IE. */ private _previousValue: string | number | null; @@ -163,6 +162,10 @@ export class MatAutocompleteTrigger /** Subscription to viewport size changes. */ private _viewportSubscription = Subscription.EMPTY; + /** Implements BreakpointObserver to be used to detect handset landscape */ + private _breakpointObserver = inject(BreakpointObserver); + private _handsetLandscapeSubscription = Subscription.EMPTY; + /** * Whether the autocomplete can open the next time it is focused. Used to prevent a focused, * closed autocomplete from being reopened if the user switches to another browser tab and then @@ -284,7 +287,7 @@ export class MatAutocompleteTrigger window.removeEventListener('blur', this._windowBlurHandler); } - this._handsetLandscapeBreakpointSubscription?.unsubscribe(); + this._handsetLandscapeSubscription.unsubscribe(); this._viewportSubscription.unsubscribe(); this._componentDestroyed = true; this._destroyPanel(); @@ -792,6 +795,23 @@ export class MatAutocompleteTrigger overlayRef.updateSize({width: this._getPanelWidth()}); } }); + // Subscribe to the breakpoint events stream to detect when screen is in + // handsetLandscape. + this._handsetLandscapeSubscription = this._breakpointObserver + .observe(Breakpoints.HandsetLandscape) + .subscribe(result => { + const isHandsetLandscape = result.matches; + // Check if result.matches Breakpoints.HandsetLandscape. Apply HandsetLandscape + // settings to prevent overlay cutoff in that breakpoint. Fixes b/284148377 + if (isHandsetLandscape) { + this._positionStrategy + .withFlexibleDimensions(true) + .withGrowAfterOpen(true) + .withViewportMargin(8); + } else { + this._positionStrategy.withGrowAfterOpen(false); + } + }); } else { // Update the trigger, panel width and direction, in case anything has changed. this._positionStrategy.setOrigin(this._getConnectedElement()); @@ -882,9 +902,6 @@ export class MatAutocompleteTrigger }); } - /** Implements BreakpointObserver to be used to detect handset landscape */ - private _breakpointObserver = inject(BreakpointObserver); - private _getOverlayPosition(): PositionStrategy { // Set default Overlay Position const strategy = this._overlay @@ -893,24 +910,6 @@ export class MatAutocompleteTrigger .withFlexibleDimensions(false) .withPush(false); - if (!this._handsetLandscapeBreakpointSubscription) { - // Subscribe to the breakpoint events stream to detect when screen is in - // handsetLandscape. Only subscribe if/when this panel is open. - // BreakpointObserver only returns screen size or isMatched/matches boolean. - this._handsetLandscapeBreakpointSubscription = this._breakpointObserver - .observe(Breakpoints.HandsetLandscape) - .subscribe(result => { - // Check breakpoint if being viewed in HandsetLandscape via subscription (if not null) - const isHandsetLandscape = result.matches; - // Apply HandsetLandscape settings to prevent overlay cutoff in that breakpoint - // Fixes b/284148377 - if (isHandsetLandscape) { - strategy.withFlexibleDimensions(true).withGrowAfterOpen(true).withViewportMargin(8); - } - return; - }); - } - this._setStrategyPositions(strategy); this._positionStrategy = strategy; return strategy;