fix(autocomplete): remove old classes when classlist has changed (#15185)

Currently we have some logic that syncs the classes between the autocomplete host element and the panel, however this logic doesn't account for classes being removed.

Fixes #15179.
This commit is contained in:
Kristiyan Kostadinov
2019-02-22 16:10:34 +01:00
committed by Jeremy Elbourn
parent a115b3a0dc
commit 413fe33c73
2 changed files with 43 additions and 6 deletions
+27 -2
View File
@@ -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">
</mat-form-field>
<mat-autocomplete class="class-one class-two" #auto="matAutocomplete" [displayWith]="displayFn"
<mat-autocomplete [class]="panelClass" #auto="matAutocomplete" [displayWith]="displayFn"
[disableRipple]="disableRipple" (opened)="openedSpy()" (closed)="closedSpy()">
<mat-option *ngFor="let state of filteredStates" [value]="state">
<span>{{ state.code }}: {{ state.name }}</span>
@@ -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({
+16 -4
View File
@@ -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;
}
}