Skip to content

Commit f8cd790

Browse files
crisbetoandrewseguin
authored andcommitted
feat(autocomplete): add md-autocomplete classes to overlay panel (#7176)
Transfers any classes added to `md-autocomplete` to the resulting panel, allowing for easier styling similarly to `md-menu`. Fixes #4196.
1 parent 2d350a0 commit f8cd790

File tree

3 files changed

+37
-12
lines changed

3 files changed

+37
-12
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ng-template>
2-
<div class="mat-autocomplete-panel" role="listbox" [id]="id" [ngClass]="_getClassList()" #panel>
2+
<div class="mat-autocomplete-panel" role="listbox" [id]="id" [ngClass]="_classList" #panel>
33
<ng-content></ng-content>
44
</div>
55
</ng-template>

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,25 @@ describe('MatAutocomplete', () => {
15211521
expect(placeholder.classList).not.toContain('mat-form-field-empty');
15221522
}));
15231523

1524+
it('should transfer the mat-autocomplete classes to the panel element', fakeAsync(() => {
1525+
const fixture = TestBed.createComponent(SimpleAutocomplete);
1526+
fixture.detectChanges();
1527+
1528+
fixture.componentInstance.trigger.openPanel();
1529+
tick();
1530+
fixture.detectChanges();
1531+
1532+
const autocomplete = fixture.debugElement.nativeElement.querySelector('mat-autocomplete');
1533+
const panel = overlayContainerElement.querySelector('.mat-autocomplete-panel')!;
1534+
1535+
expect(autocomplete.classList).not.toContain('class-one');
1536+
expect(autocomplete.classList).not.toContain('class-two');
1537+
1538+
expect(panel.classList).toContain('class-one');
1539+
expect(panel.classList).toContain('class-two');
1540+
}));
1541+
1542+
15241543
});
15251544

15261545
it('should have correct width when opened', () => {
@@ -1646,7 +1665,7 @@ describe('MatAutocomplete', () => {
16461665
<input matInput placeholder="State" [matAutocomplete]="auto" [formControl]="stateCtrl">
16471666
</mat-form-field>
16481667
1649-
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
1668+
<mat-autocomplete class="class-one class-two" #auto="matAutocomplete" [displayWith]="displayFn">
16501669
<mat-option *ngFor="let state of filteredStates" [value]="state">
16511670
<span> {{ state.code }}: {{ state.name }} </span>
16521671
</mat-option>

src/lib/autocomplete/autocomplete.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,23 @@ export class MatAutocomplete implements AfterContentInit {
7777
@Output() optionSelected: EventEmitter<MatAutocompleteSelectedEvent> =
7878
new EventEmitter<MatAutocompleteSelectedEvent>();
7979

80+
/**
81+
* Takes classes set on the host md-autocomplete element and applies them to the panel
82+
* inside the overlay container to allow for easy styling.
83+
*/
84+
@Input('class')
85+
set classList(classList: string) {
86+
if (classList && classList.length) {
87+
classList.split(' ').forEach(className => this._classList[className.trim()] = true);
88+
this._elementRef.nativeElement.className = '';
89+
}
90+
}
91+
_classList: {[key: string]: boolean} = {};
92+
8093
/** Unique ID to be used by autocomplete trigger's "aria-owns" property. */
8194
id: string = `mat-autocomplete-${_uniqueAutocompleteIdCounter++}`;
8295

83-
constructor(private _changeDetectorRef: ChangeDetectorRef) { }
96+
constructor(private _changeDetectorRef: ChangeDetectorRef, private _elementRef: ElementRef) { }
8497

8598
ngAfterContentInit() {
8699
this._keyManager = new ActiveDescendantKeyManager<MatOption>(this.options).withWrap();
@@ -105,6 +118,8 @@ export class MatAutocomplete implements AfterContentInit {
105118
_setVisibility(): void {
106119
Promise.resolve().then(() => {
107120
this.showPanel = !!this.options.length;
121+
this._classList['mat-autocomplete-visible'] = this.showPanel;
122+
this._classList['mat-autocomplete-hidden'] = !this.showPanel;
108123
this._changeDetectorRef.markForCheck();
109124
});
110125
}
@@ -114,14 +129,5 @@ export class MatAutocomplete implements AfterContentInit {
114129
const event = new MatAutocompleteSelectedEvent(this, option);
115130
this.optionSelected.emit(event);
116131
}
117-
118-
/** Sets a class on the panel based on whether it is visible. */
119-
_getClassList() {
120-
return {
121-
'mat-autocomplete-visible': this.showPanel,
122-
'mat-autocomplete-hidden': !this.showPanel
123-
};
124-
}
125-
126132
}
127133

0 commit comments

Comments
 (0)