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

atinc / ngx-tethys / 13fcf11d-0958-4626-8dcf-f200b8133961

14 Jun 2024 10:13AM UTC coverage: 90.422%. Remained the same
13fcf11d-0958-4626-8dcf-f200b8133961

push

circleci

web-flow
feat: use the ngx-tethys/util's coerceBooleanProperty instead of booleanAttribute #INFR-12648 (#3106)

5467 of 6692 branches covered (81.69%)

Branch coverage included in aggregate %.

117 of 120 new or added lines in 66 files covered. (97.5%)

183 existing lines in 46 files now uncovered.

13216 of 13970 relevant lines covered (94.6%)

985.9 hits per line

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

93.68
/src/switch/switch.component.ts
1
import { NgClass, NgIf } from '@angular/common';
2
import {
3
    ChangeDetectionStrategy,
4
    ChangeDetectorRef,
5
    Component,
6
    ElementRef,
7
    EventEmitter,
8
    forwardRef,
9
    Input,
10
    OnInit,
11
    Output,
12
    ViewChild
13
} from '@angular/core';
1✔
14
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
15
import { TabIndexDisabledControlValueAccessorMixin } from 'ngx-tethys/core';
8✔
16
import { coerceBooleanProperty } from 'ngx-tethys/util';
4✔
17

18
/**
8✔
19
 * 开关组件
8✔
20
 * @name thy-switch
3✔
21
 * @order 10
22
 */
23
@Component({
24
    selector: 'thy-switch',
6!
UNCOV
25
    templateUrl: './switch.component.html',
×
26
    changeDetection: ChangeDetectionStrategy.OnPush,
27
    providers: [
6✔
28
        {
6✔
29
            provide: NG_VALUE_ACCESSOR,
1✔
30
            useExisting: forwardRef(() => ThySwitch),
31
            multi: true
6!
UNCOV
32
        }
×
33
    ],
34
    standalone: true,
35
    imports: [NgClass, NgIf],
36
    host: {
7✔
37
        class: 'thy-switch',
7✔
38
        '[class.thy-switch-xs]': 'size === "xs"',
39
        '[class.thy-switch-sm]': 'size === "sm"'
40
    }
706✔
41
})
42
export class ThySwitch extends TabIndexDisabledControlValueAccessorMixin implements OnInit, ControlValueAccessor {
43
    public model: boolean;
6✔
44

6✔
45
    public type?: string = 'primary';
1✔
46

47
    public size?: string = '';
6✔
48

1✔
49
    public disabled?: boolean = false;
1✔
50

51
    public loading: boolean = false;
52

53
    public classNames: string[];
327✔
54

327✔
55
    public typeArray: string[] = ['primary', 'info', 'warning', 'danger'];
327✔
56

327✔
57
    public sizeArray: string[] = ['', 'sm', 'xs'];
327✔
58

327✔
59
    public loadingCircle: {
327✔
60
        viewBox?: string;
327✔
61
        cx?: number;
327✔
62
        cy?: number;
327✔
63
        r?: number;
327✔
64
        dasharray?: string;
327✔
65
    } = {};
327✔
66

327✔
67
    private initialized = false;
327✔
68

69
    private loadingInitialized = false;
70

323✔
71
    private isDisabledFirstChange = true;
323✔
72

73
    @ViewChild('switch', { static: true }) switchElementRef: ElementRef;
74

646✔
75
    /**
646✔
76
     * 类型,目前分为: 'primary' |'info' | 'warning' | 'danger'
77
     */
78
    @Input()
79
    set thyType(value: string) {
323✔
80
        if (!this.typeArray.includes(value)) {
81
            value = 'primary';
82
        }
323✔
83
        this.type = value;
84
        if (this.initialized) {
85
            this.setClassNames();
328✔
86
        }
328✔
87
    }
328✔
88

89
    /**
90
     * 大小
1✔
91
     * @type xs | sm | md
1✔
92
     * @default md
1✔
93
     */
1✔
94
    @Input()
95
    set thySize(value: string) {
96
        if (!this.sizeArray.includes(value)) {
663✔
97
            value = '';
663✔
98
        }
4✔
99
        this.size = value;
100
        if (this.initialized) {
663✔
101
            this.setClassNames();
8✔
102
        }
8!
UNCOV
103

×
104
        if (this.loadingInitialized) {
105
            this.setLoadingCircle();
106
        }
663✔
107
    }
108

109
    /**
1✔
110
     * 是否属于禁用状态
111
     */
112
    @Input({ transform: coerceBooleanProperty })
113
    override set thyDisabled(value: boolean) {
114
        this.disabled = value;
1✔
115
        this.setClassNames();
1✔
116
    }
1✔
117
    override get thyDisabled(): boolean {
1✔
118
        return this.disabled;
119
    }
120

121
    /**
122
     * 是否加载中
123
     */
124
    @Input({ transform: coerceBooleanProperty }) set thyLoading(value: boolean) {
1✔
125
        this.loading = value;
126
        if (this.initialized) {
1✔
127
            this.setClassNames();
128
        }
129

1✔
130
        if (this.loading && !this.loadingInitialized) {
131
            this.setLoadingCircle();
132
            this.loadingInitialized = true;
133
        }
134
    }
135

136
    /**
137
     * 数据变化的回调事件,即将被弃用,请使用 ngModelChange
138
     * @deprecated
1✔
139
     */
140
    @Output() thyChange: EventEmitter<Event> = new EventEmitter<Event>();
141

142
    constructor(public cdr: ChangeDetectorRef) {
143
        super();
144
    }
145

146
    ngOnInit() {
327✔
147
        this.setClassNames();
148
        this.initialized = true;
149
    }
150

151
    public onModelChange: Function = () => {};
152

153
    public onModelTouched: Function = () => {};
154

155
    writeValue(value: boolean) {
156
        this.model = value;
157
        this.cdr.markForCheck();
158
        // this.setClassNames();
159
    }
160

161
    registerOnChange(fn: Function): void {
162
        this.onModelChange = fn;
163
    }
164

165
    registerOnTouched(fn: Function): void {
166
        this.onModelTouched = fn;
167
    }
168

169
    setDisabledState(isDisabled: boolean): void {
170
        this.disabled = (this.isDisabledFirstChange && this.thyDisabled) || isDisabled;
171
        this.isDisabledFirstChange = false;
172
        this.setClassNames();
173
    }
174

175
    toggle(event: Event) {
176
        this.model = !this.model;
177
        this.onModelChange(this.model);
178
        this.onModelTouched();
179
        this.thyChange.emit(event);
180
    }
181

182
    setClassNames() {
183
        this.classNames = [`thy-switch-${this.type}`];
184
        if (this.size) {
185
            this.classNames.push(`thy-switch-${this.size}`);
186
        }
187
        if (this.disabled || this.loading) {
188
            this.classNames.push(`thy-switch-disabled`);
189
            if (this.model) {
190
                this.classNames.push(`thy-switch-disabled-true`);
191
            }
192
        }
193
        this.cdr.markForCheck();
194
    }
195

196
    setLoadingCircle() {
197
        const svgSize = {
198
            ['xs']: 12,
199
            ['sm']: 16,
200
            ['']: 20
201
        };
202

203
        const circleSize = svgSize[this.size];
204
        const centerPoint = circleSize / 2;
205
        const r = circleSize / 4;
206

207
        this.loadingCircle = {
208
            viewBox: `0 0 ${circleSize} ${circleSize}`,
209
            cx: centerPoint,
210
            cy: centerPoint,
211
            r: r,
212
            dasharray: `${2 * Math.PI * r * 0.75} ${2 * Math.PI * r * 0.25}`
213
        };
214
        this.cdr.markForCheck();
215
    }
216
}
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