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

atinc / ngx-tethys / #88

11 Aug 2025 06:37AM UTC coverage: 90.32% (+0.01%) from 90.309%
#88

push

web-flow
refactor(select): migrate to signal for select #TINFR-1767 (#3514)

5535 of 6815 branches covered (81.22%)

Branch coverage included in aggregate %.

57 of 58 new or added lines in 2 files covered. (98.28%)

19 existing lines in 2 files now uncovered.

13863 of 14662 relevant lines covered (94.55%)

902.81 hits per line

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

91.43
/src/select/native-select/native-select.component.ts
1
import { Component, forwardRef, OnInit, input, viewChild, model, signal } from '@angular/core';
2
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
3
import { TabIndexDisabledControlValueAccessorMixin } from 'ngx-tethys/core';
4
import { coerceBooleanProperty, elementMatchClosest } from 'ngx-tethys/util';
5
import { ElementRef } from '@angular/core';
6
import { useHostRenderer } from '@tethys/cdk/dom';
7
import { ThyIcon } from 'ngx-tethys/icon';
8
import { ThyInputDirective } from 'ngx-tethys/input';
9
import { SafeAny } from 'ngx-tethys/types';
10

11
export type InputSize = 'xs' | 'sm' | 'md' | 'lg' | '';
1✔
12

13
const noop = () => {};
14

15
/**
16
 * 下拉选择
17
 * @name thy-native-select
1✔
18
 * @order 20
19
 */
18✔
20
@Component({
9✔
21
    selector: 'thy-native-select',
22
    templateUrl: './native-select.component.html',
23
    providers: [
24
        {
19✔
25
            provide: NG_VALUE_ACCESSOR,
26
            useExisting: forwardRef(() => ThyNativeSelect),
27
            multi: true
10✔
28
        }
10✔
29
    ],
10✔
30
    imports: [ThyInputDirective, FormsModule, ThyIcon],
10✔
31
    host: {
10✔
32
        class: 'thy-select',
10✔
33
        '[attr.tabindex]': 'tabIndex',
10✔
34
        '(focus)': 'onFocus($event)',
10✔
35
        '(blur)': 'onBlur($event)'
36
    }
UNCOV
37
})
×
UNCOV
38
export class ThyNativeSelect extends TabIndexDisabledControlValueAccessorMixin implements ControlValueAccessor, OnInit {
×
39
    readonly selectElement = viewChild<ElementRef<any>>('select');
40

41
    readonly innerValue = model<SafeAny>(null);
9✔
42

9!
43
    readonly disabled = signal<boolean>(false);
9✔
44

45
    private hostRenderer = useHostRenderer();
46

2✔
47
    readonly thySize = input<InputSize>();
1✔
48

49
    readonly name = input<string>();
1✔
50

51
    readonly thyAllowClear = input(false, { transform: coerceBooleanProperty });
52

1✔
53
    writeValue(obj: any): void {
54
        if (obj !== this.innerValue()) {
55
            this.innerValue.set(obj);
1✔
56
        }
1✔
57
    }
1✔
58

59
    setDisabledState?(isDisabled: boolean): void {
1✔
60
        this.disabled.set(isDisabled);
1✔
61
    }
62

63
    constructor() {
64
        super();
65
    }
66

67
    ngModelChange() {
68
        this.onChangeFn(this.innerValue());
1✔
69
        this.onTouchedFn();
70
    }
71

72
    ngOnInit() {
73
        const size = this.thySize();
74
        const classes = size ? [`thy-select-${size}`] : [];
75
        this.hostRenderer.updateClass(classes);
10✔
76
    }
77

78
    onBlur(event: FocusEvent) {
79
        if (elementMatchClosest(event?.relatedTarget as HTMLElement, 'thy-native-select')) {
80
            return;
81
        }
82
        this.onTouchedFn();
83
    }
84

85
    onFocus(event?: Event) {
86
        this.selectElement().nativeElement.focus();
87
    }
88

89
    clearSelectValue(event: Event) {
90
        event.stopPropagation();
91
        this.innerValue.set('');
92
        this.onChangeFn(this.innerValue());
93
    }
94
}
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

© 2025 Coveralls, Inc