diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 7be99c44f356..9bb71cba4655 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -523,13 +523,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()) { @@ -553,7 +553,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 }); } @@ -579,6 +579,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 7d1240b602f4..58c9c6d9ea25 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -1922,6 +1922,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 38894866c8ef..fb79a51face1 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 =