• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kolkov / angular-editor / 382

pending completion
382

Pull #524

travis-ci-com

web-flow
Merge 361cfc425 into 7f4b3cd24
Pull Request #524: Spacebar should also select.

22 of 191 branches covered (11.52%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

109 of 479 relevant lines covered (22.76%)

2.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.48
/projects/angular-editor/src/lib/ae-select/ae-select.component.ts
1
import {
2
  Attribute,
3
  Component,
4
  ElementRef,
5
  EventEmitter,
6
  forwardRef, HostBinding,
7
  HostListener,
8
  Input,
9
  OnInit,
10
  Output,
11
  Renderer2,
12
  ViewChild,
13
  ViewEncapsulation
14
} from '@angular/core';
15
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
16
import {isDefined} from '../utils';
17

18
export interface SelectOption {
19
  label: string;
20
  value: string;
21
}
22

23
@Component({
24
  selector: 'ae-select',
25
  templateUrl: './ae-select.component.html',
26
  styleUrls: ['./ae-select.component.scss'],
27
  encapsulation: ViewEncapsulation.None,
28
  providers: [
29
    {
30
      provide: NG_VALUE_ACCESSOR,
31
      useExisting: forwardRef(() => AeSelectComponent),
6✔
32
      multi: true,
33
    }
34
  ]
35
})
36
export class AeSelectComponent implements OnInit, ControlValueAccessor {
1✔
37
  @Input() options: SelectOption[] = [];
14✔
38
  // eslint-disable-next-line @angular-eslint/no-input-rename
39
  @Input('hidden') isHidden: boolean;
40

41
  selectedOption: SelectOption;
42
  disabled = false;
14✔
43
  optionId = 0;
14✔
44

45
  get label(): string {
46
    return this.selectedOption && this.selectedOption.hasOwnProperty('label') ? this.selectedOption.label : 'Select';
32✔
47
  }
48

49
  opened = false;
14✔
50

51
  get value(): string {
52
    return this.selectedOption.value;
96✔
53
  }
54

55
  @HostBinding('style.display') hidden = 'inline-block';
14✔
56

57
  // eslint-disable-next-line @angular-eslint/no-output-native, @angular-eslint/no-output-rename
58
  @Output('change') changeEvent = new EventEmitter();
14✔
59

60
  @ViewChild('labelButton', {static: true}) labelButton: ElementRef;
61

62
  constructor(private elRef: ElementRef,
14✔
63
              private r: Renderer2,
14✔
64
  ) {}
65

66
  ngOnInit() {
67
    this.selectedOption = this.options[0];
17✔
68
    if (isDefined(this.isHidden) && this.isHidden) {
17✔
69
      this.hide();
1✔
70
    }
71
  }
72

73
  hide() {
74
    this.hidden = 'none';
1✔
75
  }
76

77
  optionSelect(option: SelectOption, event: MouseEvent) {
78
    event.stopPropagation();
1✔
79
    this.setValue(option.value);
1✔
80
    this.onChange(this.selectedOption.value);
1✔
81
    this.changeEvent.emit(this.selectedOption.value);
1✔
82
    this.onTouched();
1✔
83
    this.opened = false;
1✔
84
  }
85

86
  toggleOpen(event: MouseEvent) {
87
    // event.stopPropagation();
88
    if (this.disabled) {
×
89
      return;
×
90
    }
91
    this.opened = !this.opened;
×
92
  }
93

94
  @HostListener('document:click', ['$event'])
95
  onClick($event: MouseEvent) {
96
    if (!this.elRef.nativeElement.contains($event.target)) {
×
97
      this.close();
×
98
    }
99
  }
100

101
  close() {
102
    this.opened = false;
×
103
  }
104

105
  get isOpen(): boolean {
106
    return this.opened;
32✔
107
  }
108

109
  writeValue(value) {
110
    if (!value || typeof value !== 'string') {
12✔
111
      return;
6✔
112
    }
113
    this.setValue(value);
6✔
114
  }
115

116
  setValue(value) {
117
    let index = 0;
6✔
118
    const selectedEl = this.options.find((el, i) => {
6✔
119
      index = i;
32✔
120
      return el.value === value;
32✔
121
    });
122
    if (selectedEl) {
6✔
123
      this.selectedOption = selectedEl;
6✔
124
      this.optionId = index;
6✔
125
    }
126
  }
127

128
  onChange: any = () => {
14✔
129
  }
130
  onTouched: any = () => {
14✔
131
  }
132

133
  registerOnChange(fn) {
134
    this.onChange = fn;
6✔
135
  }
136

137
  registerOnTouched(fn) {
138
    this.onTouched = fn;
6✔
139
  }
140

141
  setDisabledState(isDisabled: boolean): void {
142
    this.labelButton.nativeElement.disabled = isDisabled;
×
143
    const div = this.labelButton.nativeElement;
×
144
    const action = isDisabled ? 'addClass' : 'removeClass';
×
145
    this.r[action](div, 'disabled');
×
146
    this.disabled = isDisabled;
×
147
  }
148

149
  @HostListener('keydown', ['$event'])
150
  handleKeyDown($event: KeyboardEvent) {
151
    if (!this.opened) {
×
152
      return;
×
153
    }
154
    // console.log($event.key);
155
    // if (KeyCode[$event.key]) {
156
    switch ($event.key) {
×
157
      case 'ArrowDown':
158
        this._handleArrowDown($event);
×
159
        break;
×
160
      case 'ArrowUp':
161
        this._handleArrowUp($event);
×
162
        break;
×
163
      case 'Space':
164
        this._handleSpace($event);
×
165
        break;
×
166
      case 'Enter':
167
        this._handleEnter($event);
×
168
        break;
×
169
      case 'Tab':
170
        this._handleTab($event);
×
171
        break;
×
172
      case 'Escape':
173
        this.close();
×
174
        $event.preventDefault();
×
175
        break;
×
176
      case 'Backspace':
177
        this._handleBackspace();
×
178
        break;
×
179
    }
180
    // } else if ($event.key && $event.key.length === 1) {
181
    // this._keyPress$.next($event.key.toLocaleLowerCase());
182
    // }
183
  }
184

185
  _handleArrowDown($event) {
186
    if (this.optionId < this.options.length - 1) {
×
187
      this.optionId++;
×
188
    }
189
  }
190

191
  _handleArrowUp($event) {
192
    if (this.optionId >= 1) {
×
193
      this.optionId--;
×
194
    }
195
  }
196

197
  _handleSpace($event) {
198
    this.optionSelect(this.options[this.optionId], $event);
×
199
  }
200

201
  _handleEnter($event) {
202
    this.optionSelect(this.options[this.optionId], $event);
×
203
  }
204

205
  _handleTab($event) {
206

207
  }
208

209
  _handleBackspace() {
210

211
  }
212
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc