Skip to content

Commit

Permalink
feat(autocomplete): add md-autocomplete classes to overlay panel (#7176)
Browse files Browse the repository at this point in the history
Transfers any classes added to `md-autocomplete` to the resulting panel, allowing for easier styling similarly to `md-menu`.

Fixes #4196.
  • Loading branch information
crisbeto authored and andrewseguin committed Sep 29, 2017
1 parent 2d350a0 commit f8cd790
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/lib/autocomplete/autocomplete.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ng-template>
<div class="mat-autocomplete-panel" role="listbox" [id]="id" [ngClass]="_getClassList()" #panel>
<div class="mat-autocomplete-panel" role="listbox" [id]="id" [ngClass]="_classList" #panel>
<ng-content></ng-content>
</div>
</ng-template>
21 changes: 20 additions & 1 deletion src/lib/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,25 @@ describe('MatAutocomplete', () => {
expect(placeholder.classList).not.toContain('mat-form-field-empty');
}));

it('should transfer the mat-autocomplete classes to the panel element', fakeAsync(() => {
const fixture = TestBed.createComponent(SimpleAutocomplete);
fixture.detectChanges();

fixture.componentInstance.trigger.openPanel();
tick();
fixture.detectChanges();

const autocomplete = fixture.debugElement.nativeElement.querySelector('mat-autocomplete');
const panel = overlayContainerElement.querySelector('.mat-autocomplete-panel')!;

expect(autocomplete.classList).not.toContain('class-one');
expect(autocomplete.classList).not.toContain('class-two');

expect(panel.classList).toContain('class-one');
expect(panel.classList).toContain('class-two');
}));


});

it('should have correct width when opened', () => {
Expand Down Expand Up @@ -1646,7 +1665,7 @@ describe('MatAutocomplete', () => {
<input matInput placeholder="State" [matAutocomplete]="auto" [formControl]="stateCtrl">
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-autocomplete class="class-one class-two" #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let state of filteredStates" [value]="state">
<span> {{ state.code }}: {{ state.name }} </span>
</mat-option>
Expand Down
26 changes: 16 additions & 10 deletions src/lib/autocomplete/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,23 @@ export class MatAutocomplete implements AfterContentInit {
@Output() optionSelected: EventEmitter<MatAutocompleteSelectedEvent> =
new EventEmitter<MatAutocompleteSelectedEvent>();

/**
* Takes classes set on the host md-autocomplete element and applies them to the panel
* inside the overlay container to allow for easy styling.
*/
@Input('class')
set classList(classList: string) {
if (classList && classList.length) {
classList.split(' ').forEach(className => this._classList[className.trim()] = true);
this._elementRef.nativeElement.className = '';
}
}
_classList: {[key: string]: boolean} = {};

/** Unique ID to be used by autocomplete trigger's "aria-owns" property. */
id: string = `mat-autocomplete-${_uniqueAutocompleteIdCounter++}`;

constructor(private _changeDetectorRef: ChangeDetectorRef) { }
constructor(private _changeDetectorRef: ChangeDetectorRef, private _elementRef: ElementRef) { }

ngAfterContentInit() {
this._keyManager = new ActiveDescendantKeyManager<MatOption>(this.options).withWrap();
Expand All @@ -105,6 +118,8 @@ export class MatAutocomplete implements AfterContentInit {
_setVisibility(): void {
Promise.resolve().then(() => {
this.showPanel = !!this.options.length;
this._classList['mat-autocomplete-visible'] = this.showPanel;
this._classList['mat-autocomplete-hidden'] = !this.showPanel;
this._changeDetectorRef.markForCheck();
});
}
Expand All @@ -114,14 +129,5 @@ export class MatAutocomplete implements AfterContentInit {
const event = new MatAutocompleteSelectedEvent(this, option);
this.optionSelected.emit(event);
}

/** Sets a class on the panel based on whether it is visible. */
_getClassList() {
return {
'mat-autocomplete-visible': this.showPanel,
'mat-autocomplete-hidden': !this.showPanel
};
}

}

0 comments on commit f8cd790

Please sign in to comment.