ipsos-components
Version:
Material Design components for Angular
146 lines (119 loc) • 4.58 kB
text/typescript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {
AfterContentInit,
Component,
ContentChildren,
ElementRef,
Input,
QueryList,
TemplateRef,
ViewChild,
ViewEncapsulation,
ChangeDetectorRef,
ChangeDetectionStrategy,
EventEmitter,
Output,
} from '@angular/core';
import {MatOption, MatOptgroup} from '@angular/material/core';
import {ActiveDescendantKeyManager} from '@angular/cdk/a11y';
/**
* Autocomplete IDs need to be unique across components, so this counter exists outside of
* the component definition.
*/
let _uniqueAutocompleteIdCounter = 0;
/** Event object that is emitted when an autocomplete option is selected */
export class MatAutocompleteSelectedEvent {
constructor(
/** Reference to the autocomplete panel that emitted the event. */
public source: MatAutocomplete,
/** Option that was selected. */
public option: MatOption) { }
}
export class MatAutocomplete implements AfterContentInit {
/** Manages active item in option list based on key events. */
_keyManager: ActiveDescendantKeyManager<MatOption>;
/** Whether the autocomplete panel should be visible, depending on option length. */
showPanel = false;
/** Whether the autocomplete panel is open. */
get isOpen(): boolean {
return this._isOpen && this.showPanel;
}
_isOpen: boolean = false;
/** @docs-private */
template: TemplateRef<any>;
/** Element for the panel containing the autocomplete options. */
panel: ElementRef;
/** @docs-private */
options: QueryList<MatOption>;
/** @docs-private */
optionGroups: QueryList<MatOptgroup>;
/** Function that maps an option's control value to its display value in the trigger. */
displayWith: ((value: any) => string) | null = null;
/** Event that is emitted whenever an option from the list is selected. */
optionSelected: EventEmitter<MatAutocompleteSelectedEvent> =
new EventEmitter<MatAutocompleteSelectedEvent>();
/**
* Takes classes set on the host mat-autocomplete element and applies them to the panel
* inside the overlay container to allow for easy styling.
*/
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, private _elementRef: ElementRef) { }
ngAfterContentInit() {
this._keyManager = new ActiveDescendantKeyManager<MatOption>(this.options).withWrap();
// Set the initial visibiity state.
this._setVisibility();
}
/**
* Sets the panel scrollTop. This allows us to manually scroll to display options
* above or below the fold, as they are not actually being focused when active.
*/
_setScrollTop(scrollTop: number): void {
if (this.panel) {
this.panel.nativeElement.scrollTop = scrollTop;
}
}
/** Returns the panel's scrollTop. */
_getScrollTop(): number {
return this.panel ? this.panel.nativeElement.scrollTop : 0;
}
/** 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._changeDetectorRef.markForCheck();
}
/** Emits the `select` event. */
_emitSelectEvent(option: MatOption): void {
const event = new MatAutocompleteSelectedEvent(this, option);
this.optionSelected.emit(event);
}
}