Skip to content

Commit 2dc4e70

Browse files
crisbetojelbourn
authored andcommitted
fix(autocomplete): panel width not being updated on window resize (#10629)
Fixes the width of the autocomplete panel not being recalculated when the viewport size changes.
1 parent 9c1f8a9 commit 2dc4e70

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
OverlayRef,
1515
PositionStrategy,
1616
ScrollStrategy,
17+
ViewportRuler,
1718
} from '@angular/cdk/overlay';
1819
import {TemplatePortal} from '@angular/cdk/portal';
1920
import {DOCUMENT} from '@angular/common';
@@ -122,6 +123,9 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
122123
/** The subscription for closing actions (some are bound to document). */
123124
private _closingActionsSubscription: Subscription;
124125

126+
/** Subscription to viewport size changes. */
127+
private _viewportSubscription = Subscription.EMPTY;
128+
125129
/** Stream of keyboard events that can close the panel. */
126130
private readonly _closeKeyEventStream = new Subject<void>();
127131

@@ -141,9 +145,12 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
141145
@Inject(MAT_AUTOCOMPLETE_SCROLL_STRATEGY) private _scrollStrategy,
142146
@Optional() private _dir: Directionality,
143147
@Optional() @Host() private _formField: MatFormField,
144-
@Optional() @Inject(DOCUMENT) private _document: any) {}
148+
@Optional() @Inject(DOCUMENT) private _document: any,
149+
// @deletion-target 7.0.0 Make `_viewportRuler` required.
150+
private _viewportRuler?: ViewportRuler) {}
145151

146152
ngOnDestroy() {
153+
this._viewportSubscription.unsubscribe();
147154
this._componentDestroyed = true;
148155
this._destroyPanel();
149156
this._closeKeyEventStream.complete();
@@ -482,6 +489,14 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
482489
if (!this._overlayRef) {
483490
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
484491
this._overlayRef = this._overlay.create(this._getOverlayConfig());
492+
493+
if (this._viewportRuler) {
494+
this._viewportSubscription = this._viewportRuler.change().subscribe(() => {
495+
if (this.panelOpen && this._overlayRef) {
496+
this._overlayRef.updateSize({width: this._getHostWidth()});
497+
}
498+
});
499+
}
485500
} else {
486501
/** Update the panel width, in case the host width has changed */
487502
this._overlayRef.updateSize({width: this._getHostWidth()});

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,6 +1838,28 @@ describe('MatAutocomplete', () => {
18381838
expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(500);
18391839
});
18401840

1841+
it('should update the panel width if the window is resized', fakeAsync(() => {
1842+
const widthFixture = createComponent(SimpleAutocomplete);
1843+
1844+
widthFixture.componentInstance.width = 300;
1845+
widthFixture.detectChanges();
1846+
1847+
widthFixture.componentInstance.trigger.openPanel();
1848+
widthFixture.detectChanges();
1849+
1850+
const overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
1851+
1852+
expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(300);
1853+
1854+
widthFixture.componentInstance.width = 400;
1855+
widthFixture.detectChanges();
1856+
1857+
dispatchFakeEvent(window, 'resize');
1858+
tick(20);
1859+
1860+
expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(400);
1861+
}));
1862+
18411863
it('should show the panel when the options are initialized later within a component with ' +
18421864
'OnPush change detection', fakeAsync(() => {
18431865
let fixture = createComponent(AutocompleteWithOnPushDelay);

0 commit comments

Comments
 (0)