-
Notifications
You must be signed in to change notification settings - Fork 6.7k
/
autocomplete.ts
104 lines (86 loc) · 2.88 KB
/
autocomplete.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* @license
* Copyright Google Inc. 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,
} from '@angular/core';
import {MdOption} from '../core';
import {ActiveDescendantKeyManager} from '../core/a11y/activedescendant-key-manager';
/**
* Autocomplete IDs need to be unique across components, so this counter exists outside of
* the component definition.
*/
let _uniqueAutocompleteIdCounter = 0;
@Component({
moduleId: module.id,
selector: 'md-autocomplete, mat-autocomplete',
templateUrl: 'autocomplete.html',
styleUrls: ['autocomplete.css'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'mdAutocomplete',
host: {
'class': 'mat-autocomplete'
}
})
export class MdAutocomplete implements AfterContentInit {
/** Manages active item in option list based on key events. */
_keyManager: ActiveDescendantKeyManager;
/** Whether the autocomplete panel should be visible, depending on option length. */
showPanel = false;
/** @docs-private */
@ViewChild(TemplateRef) template: TemplateRef<any>;
/** Element for the panel containing the autocomplete options. */
@ViewChild('panel') panel: ElementRef;
/** @docs-private */
@ContentChildren(MdOption) options: QueryList<MdOption>;
/** Function that maps an option's control value to its display value in the trigger. */
@Input() displayWith: ((value: any) => string) | null = null;
/** Unique ID to be used by autocomplete trigger's "aria-owns" property. */
id: string = `md-autocomplete-${_uniqueAutocompleteIdCounter++}`;
constructor(private _changeDetectorRef: ChangeDetectorRef) { }
ngAfterContentInit() {
this._keyManager = new ActiveDescendantKeyManager(this.options).withWrap();
}
/**
* 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() {
Promise.resolve().then(() => {
this.showPanel = !!this.options.length;
this._changeDetectorRef.markForCheck();
});
}
/** Sets a class on the panel based on whether it is visible. */
_getClassList() {
return {
'mat-autocomplete-visible': this.showPanel,
'mat-autocomplete-hidden': !this.showPanel
};
}
}