diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 5217d48597d..398829627c6 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -529,13 +529,13 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { if (this._viewportRuler) { this._viewportSubscription = this._viewportRuler.change().subscribe(() => { if (this.panelOpen && this._overlayRef) { - this._overlayRef.updateSize({width: this._getHostWidth()}); + this._overlayRef.updateSize({width: this._getPanelWidth()}); } }); } } else { // Update the panel width and direction, in case anything has changed. - this._overlayRef.updateSize({width: this._getHostWidth()}); + this._overlayRef.updateSize({width: this._getPanelWidth()}); } if (this._overlayRef && !this._overlayRef.hasAttached()) { @@ -559,7 +559,7 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { return new OverlayConfig({ positionStrategy: this._getOverlayPosition(), scrollStrategy: this._scrollStrategy(), - width: this._getHostWidth(), + width: this._getPanelWidth(), direction: this._dir }); } @@ -585,6 +585,10 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy { return this._formField ? this._formField.getConnectedOverlayOrigin() : this._element; } + private _getPanelWidth(): number | string { + return this.autocomplete.panelWidth || this._getHostWidth(); + } + /** Returns the width of the input element, so the panel width can match it. */ private _getHostWidth(): number { return this._getConnectedElement().nativeElement.getBoundingClientRect().width; diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index eee9f95a03c..b8df3f0e9fb 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -1931,6 +1931,50 @@ describe('MatAutocomplete', () => { expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(400); })); + it('should have panel width match host width by default', () => { + const widthFixture = createComponent(SimpleAutocomplete); + + widthFixture.componentInstance.width = 300; + widthFixture.detectChanges(); + + widthFixture.componentInstance.trigger.openPanel(); + widthFixture.detectChanges(); + + const overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(300); + }); + + it('should have panel width set to string value', () => { + const widthFixture = createComponent(SimpleAutocomplete); + + widthFixture.componentInstance.width = 300; + widthFixture.detectChanges(); + + widthFixture.componentInstance.trigger.autocomplete.panelWidth = 'auto'; + widthFixture.componentInstance.trigger.openPanel(); + widthFixture.detectChanges(); + + const overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.width).toBe('auto'); + }); + + it('should have panel width set to number value', () => { + const widthFixture = createComponent(SimpleAutocomplete); + + widthFixture.componentInstance.width = 300; + widthFixture.detectChanges(); + + widthFixture.componentInstance.trigger.autocomplete.panelWidth = 400; + widthFixture.componentInstance.trigger.openPanel(); + widthFixture.detectChanges(); + + const overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(400); + }); + it('should show the panel when the options are initialized later within a component with ' + 'OnPush change detection', fakeAsync(() => { let fixture = createComponent(AutocompleteWithOnPushDelay); diff --git a/src/lib/autocomplete/autocomplete.ts b/src/lib/autocomplete/autocomplete.ts index 38894866c8e..fb79a51face 100644 --- a/src/lib/autocomplete/autocomplete.ts +++ b/src/lib/autocomplete/autocomplete.ts @@ -126,6 +126,11 @@ export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterC } private _autoActiveFirstOption: boolean; + /** + * Specify the width of the autocomplete panel. Can be any CSS sizing value, otherwise it will + * match the width of its host. + */ + @Input() panelWidth: string | number; /** Event that is emitted whenever an option from the list is selected. */ @Output() readonly optionSelected: EventEmitter =