Skip to content

Commit

Permalink
feat(autocomplete): add md-autocomplete classes to overlay panel
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 angular#4196.
  • Loading branch information
crisbeto committed Sep 19, 2017
1 parent 244c906 commit 12994d6
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 @@ -1482,6 +1482,25 @@ describe('MdAutocomplete', () => {
expect(placeholder.classList).not.toContain('mat-form-field-empty');
}));

it('should transfer the md-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('md-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 @@ -1607,7 +1626,7 @@ describe('MdAutocomplete', () => {
<input mdInput placeholder="State" [mdAutocomplete]="auto" [formControl]="stateCtrl">
</md-form-field>
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn">
<md-autocomplete class="class-one class-two" #auto="mdAutocomplete" [displayWith]="displayFn">
<md-option *ngFor="let state of filteredStates" [value]="state">
<span> {{ state.code }}: {{ state.name }} </span>
</md-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 @@ -76,10 +76,23 @@ export class MdAutocomplete implements AfterContentInit {
@Output() optionSelected: EventEmitter<MdAutocompleteSelectedEvent> =
new EventEmitter<MdAutocompleteSelectedEvent>();

/**
* 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 = `md-autocomplete-${_uniqueAutocompleteIdCounter++}`;

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

ngAfterContentInit() {
this._keyManager = new ActiveDescendantKeyManager<MdOption>(this.options).withWrap();
Expand All @@ -104,6 +117,8 @@ export class MdAutocomplete 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 @@ -113,14 +128,5 @@ export class MdAutocomplete implements AfterContentInit {
const event = new MdAutocompleteSelectedEvent(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 12994d6

Please sign in to comment.