From 2b80dbf58368743b20349c007160f7a1b560f9a6 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 29 Jun 2018 19:43:58 +0200 Subject: [PATCH] fix(autocomplete): reposition the panel when the amount of options changes (#4469) --- src/lib/autocomplete/autocomplete-trigger.ts | 5 +++ src/lib/autocomplete/autocomplete.spec.ts | 33 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 398829627c6..6116754b087 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -453,6 +453,11 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { switchMap(() => { this._resetActiveItem(); this.autocomplete._setVisibility(); + + if (this.panelOpen) { + this._overlayRef!.updatePosition(); + } + return this.panelClosingActions; }), // when the first closing event occurs... diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index b8df3f0e9fb..8bd6d3521b1 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -1606,6 +1606,39 @@ describe('MatAutocomplete', () => { subscription!.unsubscribe(); })); + it('should reposition the panel when the amount of options changes', fakeAsync(() => { + let formField = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement; + let inputReference = formField.querySelector('.mat-form-field-flex'); + let input = inputReference.querySelector('input'); + + formField.style.bottom = '100px'; + formField.style.position = 'fixed'; + + typeInElement('Cali', input); + fixture.detectChanges(); + tick(); + zone.simulateZoneExit(); + fixture.detectChanges(); + + const inputBottom = inputReference.getBoundingClientRect().bottom; + const panel = overlayContainerElement.querySelector('.mat-autocomplete-panel')!; + const panelTop = panel.getBoundingClientRect().top; + + expect(Math.floor(inputBottom)).toBe(Math.floor(panelTop), + `Expected panel top to match input bottom when there is only one option.`); + + typeInElement('', input); + fixture.detectChanges(); + tick(); + fixture.detectChanges(); + + const inputTop = inputReference.getBoundingClientRect().top; + const panelBottom = panel.getBoundingClientRect().bottom; + + expect(Math.floor(inputTop)).toBe(Math.floor(panelBottom), + `Expected panel switch to the above position if the options no longer fit.`); + })); + }); describe('panel closing', () => {