forked from NG-ZORRO/ng-zorro-antd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
select-search.component.ts
122 lines (109 loc) · 3.59 KB
/
select-search.component.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { FocusMonitor } from '@angular/cdk/a11y';
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
Output,
Renderer2,
SimpleChanges,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { COMPOSITION_BUFFER_MODE } from '@angular/forms';
@Component({
selector: 'nz-select-search',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<input
#inputElement
[attr.id]="nzId"
autocomplete="off"
class="ant-select-selection-search-input"
[ngModel]="value"
[attr.autofocus]="autofocus ? 'autofocus' : null"
[disabled]="disabled"
[style.opacity]="showInput ? null : 0"
(ngModelChange)="onValueChange($event)"
(compositionstart)="setCompositionState(true)"
(compositionend)="setCompositionState(false)"
/>
<span #mirrorElement *ngIf="mirrorSync" class="ant-select-selection-search-mirror"></span>
`,
host: { class: 'ant-select-selection-search' },
providers: [{ provide: COMPOSITION_BUFFER_MODE, useValue: false }]
})
export class NzSelectSearchComponent implements AfterViewInit, OnChanges {
@Input() nzId: string | null = null;
@Input() disabled = false;
@Input() mirrorSync = false;
@Input() showInput = true;
@Input() focusTrigger = false;
@Input() value = '';
@Input() autofocus = false;
@Output() readonly valueChange = new EventEmitter<string>();
@Output() readonly isComposingChange = new EventEmitter<boolean>();
@ViewChild('inputElement', { static: true }) inputElement!: ElementRef;
@ViewChild('mirrorElement', { static: false }) mirrorElement?: ElementRef;
setCompositionState(isComposing: boolean): void {
this.isComposingChange.next(isComposing);
}
onValueChange(value: string): void {
this.value = value;
this.valueChange.next(value);
if (this.mirrorSync) {
this.syncMirrorWidth();
}
}
clearInputValue(): void {
const inputDOM = this.inputElement.nativeElement;
inputDOM.value = '';
this.onValueChange('');
}
syncMirrorWidth(): void {
const mirrorDOM = this.mirrorElement!.nativeElement;
const hostDOM = this.elementRef.nativeElement;
const inputDOM = this.inputElement.nativeElement;
this.renderer.removeStyle(hostDOM, 'width');
this.renderer.setProperty(mirrorDOM, 'textContent', `${inputDOM.value}\u00a0`);
this.renderer.setStyle(hostDOM, 'width', `${mirrorDOM.scrollWidth}px`);
}
focus(): void {
this.focusMonitor.focusVia(this.inputElement, 'keyboard');
}
blur(): void {
this.inputElement.nativeElement.blur();
}
constructor(private elementRef: ElementRef, private renderer: Renderer2, private focusMonitor: FocusMonitor) {}
ngOnChanges(changes: SimpleChanges): void {
const inputDOM = this.inputElement.nativeElement;
const { focusTrigger, showInput } = changes;
if (showInput) {
if (this.showInput) {
this.renderer.removeAttribute(inputDOM, 'readonly');
} else {
this.renderer.setAttribute(inputDOM, 'readonly', 'readonly');
}
}
// IE11 cannot input value if focused before removing readonly
if (focusTrigger && focusTrigger.currentValue === true && focusTrigger.previousValue === false) {
inputDOM.focus();
}
}
ngAfterViewInit(): void {
if (this.mirrorSync) {
this.syncMirrorWidth();
}
if (this.autofocus) {
this.focus();
}
}
}