Skip to content

Commit 12994d6

Browse files
committed
feat(autocomplete): add md-autocomplete classes to overlay panel
Transfers any classes added to `md-autocomplete` to the resulting panel, allowing for easier styling similarly to `md-menu`. Fixes #4196.
1 parent 244c906 commit 12994d6

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
@@ -1482,6 +1482,25 @@ describe('MdAutocomplete', () => {
14821482
expect(placeholder.classList).not.toContain('mat-form-field-empty');
14831483
}));
14841484

1485+
it('should transfer the md-autocomplete classes to the panel element', fakeAsync(() => {
1486+
const fixture = TestBed.createComponent(SimpleAutocomplete);
1487+
fixture.detectChanges();
1488+
1489+
fixture.componentInstance.trigger.openPanel();
1490+
tick();
1491+
fixture.detectChanges();
1492+
1493+
const autocomplete = fixture.debugElement.nativeElement.querySelector('md-autocomplete');
1494+
const panel = overlayContainerElement.querySelector('.mat-autocomplete-panel')!;
1495+
1496+
expect(autocomplete.classList).not.toContain('class-one');
1497+
expect(autocomplete.classList).not.toContain('class-two');
1498+
1499+
expect(panel.classList).toContain('class-one');
1500+
expect(panel.classList).toContain('class-two');
1501+
}));
1502+
1503+
14851504
});
14861505

14871506
it('should have correct width when opened', () => {
@@ -1607,7 +1626,7 @@ describe('MdAutocomplete', () => {
16071626
<input mdInput placeholder="State" [mdAutocomplete]="auto" [formControl]="stateCtrl">
16081627
</md-form-field>
16091628
1610-
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn">
1629+
<md-autocomplete class="class-one class-two" #auto="mdAutocomplete" [displayWith]="displayFn">
16111630
<md-option *ngFor="let state of filteredStates" [value]="state">
16121631
<span> {{ state.code }}: {{ state.name }} </span>
16131632
</md-option>

src/lib/autocomplete/autocomplete.ts

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

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

82-
constructor(private _changeDetectorRef: ChangeDetectorRef) { }
95+
constructor(private _changeDetectorRef: ChangeDetectorRef, private _elementRef: ElementRef) { }
8396

8497
ngAfterContentInit() {
8598
this._keyManager = new ActiveDescendantKeyManager<MdOption>(this.options).withWrap();
@@ -104,6 +117,8 @@ export class MdAutocomplete implements AfterContentInit {
104117
_setVisibility(): void {
105118
Promise.resolve().then(() => {
106119
this.showPanel = !!this.options.length;
120+
this._classList['mat-autocomplete-visible'] = this.showPanel;
121+
this._classList['mat-autocomplete-hidden'] = !this.showPanel;
107122
this._changeDetectorRef.markForCheck();
108123
});
109124
}
@@ -113,14 +128,5 @@ export class MdAutocomplete implements AfterContentInit {
113128
const event = new MdAutocompleteSelectedEvent(this, option);
114129
this.optionSelected.emit(event);
115130
}
116-
117-
/** Sets a class on the panel based on whether it is visible. */
118-
_getClassList() {
119-
return {
120-
'mat-autocomplete-visible': this.showPanel,
121-
'mat-autocomplete-hidden': !this.showPanel
122-
};
123-
}
124-
125131
}
126132

0 commit comments

Comments
 (0)