diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index 7aea32ce1fb..c23c3a06965 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -1966,6 +1966,31 @@ describe('MatAutocomplete', () => { expect(panel.classList).toContain('class-two'); })); + it('should remove old classes when the panel class changes', fakeAsync(() => { + const fixture = createComponent(SimpleAutocomplete); + fixture.detectChanges(); + + fixture.componentInstance.trigger.openPanel(); + tick(); + fixture.detectChanges(); + + const classList = + overlayContainerElement.querySelector('.mat-autocomplete-panel')!.classList; + + expect(classList).toContain('mat-autocomplete-visible'); + expect(classList).toContain('class-one'); + expect(classList).toContain('class-two'); + + fixture.componentInstance.panelClass = 'class-three class-four'; + fixture.detectChanges(); + + expect(classList).not.toContain('class-one'); + expect(classList).not.toContain('class-two'); + expect(classList).toContain('mat-autocomplete-visible'); + expect(classList).toContain('class-three'); + expect(classList).toContain('class-four'); + })); + it('should reset correctly when closed programmatically', fakeAsync(() => { const scrolledSubject = new Subject(); const fixture = createComponent(SimpleAutocomplete, [ @@ -2307,7 +2332,7 @@ describe('MatAutocomplete', () => { [formControl]="stateCtrl"> - {{ state.code }}: {{ state.name }} @@ -2323,6 +2348,7 @@ class SimpleAutocomplete implements OnDestroy { width: number; disableRipple = false; autocompleteDisabled = false; + panelClass = 'class-one class-two'; openedSpy = jasmine.createSpy('autocomplete opened spy'); closedSpy = jasmine.createSpy('autocomplete closed spy'); @@ -2361,7 +2387,6 @@ class SimpleAutocomplete implements OnDestroy { ngOnDestroy() { this.valueSub.unsubscribe(); } - } @Component({ diff --git a/src/lib/autocomplete/autocomplete.ts b/src/lib/autocomplete/autocomplete.ts index bbd5a0ca1b2..b28380b36f2 100644 --- a/src/lib/autocomplete/autocomplete.ts +++ b/src/lib/autocomplete/autocomplete.ts @@ -153,9 +153,16 @@ export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterC @Input('class') set classList(value: string) { if (value && value.length) { - value.split(' ').forEach(className => this._classList[className.trim()] = true); - this._elementRef.nativeElement.className = ''; + this._classList = value.split(' ').reduce((classList, className) => { + classList[className.trim()] = true; + return classList; + }, {} as {[key: string]: boolean}); + } else { + this._classList = {}; } + + this._setVisibilityClasses(this._classList); + this._elementRef.nativeElement.className = ''; } _classList: {[key: string]: boolean} = {}; @@ -195,8 +202,7 @@ export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterC /** Panel should hide itself when the option list is empty. */ _setVisibility() { this.showPanel = !!this.options.length; - this._classList['mat-autocomplete-visible'] = this.showPanel; - this._classList['mat-autocomplete-hidden'] = !this.showPanel; + this._setVisibilityClasses(this._classList); this._changeDetectorRef.markForCheck(); } @@ -205,5 +211,11 @@ export class MatAutocomplete extends _MatAutocompleteMixinBase implements AfterC const event = new MatAutocompleteSelectedEvent(this, option); this.optionSelected.emit(event); } + + /** Sets the autocomplete visibility classes on a classlist based on the panel is visible. */ + private _setVisibilityClasses(classList: {[key: string]: boolean}) { + classList['mat-autocomplete-visible'] = this.showPanel; + classList['mat-autocomplete-hidden'] = !this.showPanel; + } }