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

atinc / ngx-tethys / #55

30 Jul 2025 07:08AM UTC coverage: 9.866% (-80.4%) from 90.297%
#55

push

why520crazy
feat(empty): add setMessage for update display text #TINFR-2616

92 of 6794 branches covered (1.35%)

Branch coverage included in aggregate %.

2014 of 14552 relevant lines covered (13.84%)

6.15 hits per line

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

12.73
/src/input/input.component.ts
1
import { take } from 'rxjs/operators';
2

3
import { NgTemplateOutlet } from '@angular/common';
4
import {
5
    Component,
6
    ElementRef,
7
    forwardRef,
8
    NgZone,
9
    OnInit,
10
    TemplateRef,
11
    ViewEncapsulation,
12
    inject,
1✔
13
    input,
14
    effect,
×
15
    signal,
16
    output,
17
    contentChild
1✔
18
} from '@angular/core';
1✔
19
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
20
import { ThyIcon } from 'ngx-tethys/icon';
21
import { ThyAutofocusDirective } from 'ngx-tethys/shared';
22
import { ThyInputDirective, ThyInputSize } from './input.directive';
23
import { coerceBooleanProperty } from 'ngx-tethys/util';
24

1✔
25
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
26
    provide: NG_VALUE_ACCESSOR,
×
27
    useExisting: forwardRef(() => ThyInput),
×
28
    multi: true
×
29
};
×
30

×
31
const noop = () => {};
×
32

×
33
const password = 'password';
×
34

×
35
/**
×
36
 * 内部集成输入框组件,建议 thy-input-group 和 thyInput 组合使用
×
37
 * @name thy-input
×
38
 * @order 50
×
39
 */
×
40
@Component({
×
41
    selector: 'thy-input',
×
42
    templateUrl: './input.component.html',
×
43
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR],
×
44
    encapsulation: ViewEncapsulation.None,
×
45
    host: {
×
46
        class: 'thy-input form-control',
×
47
        '[class.form-control-active]': 'focused()',
×
48
        '[class.disabled]': 'disabled()'
×
49
    },
50
    imports: [NgTemplateOutlet, ThyInputDirective, ThyAutofocusDirective, FormsModule, ThyIcon]
51
})
52
export class ThyInput implements ControlValueAccessor, OnInit {
×
53
    private ngZone = inject(NgZone);
×
54
    private elementRef = inject(ElementRef);
55

56
    /**
57
     * Placeholder
×
58
     */
59
    readonly placeholder = input('');
60

×
61
    /**
62
     * 输入框大小
63
     * @type 'xs' | 'sm' | 'md' | 'default' | 'lg'
×
64
     * @default default
65
     */
66
    readonly thySize = input<ThyInputSize>();
×
67

68
    /**
69
     * 是否自动聚焦
×
70
     */
71
    readonly thyAutofocus = input(false, { transform: coerceBooleanProperty });
72

×
73
    /**
×
74
     * 输入框类型
×
75
     * @type 'number' | 'input'
76
     */
77
    readonly thyType = input<string>();
×
78

×
79
    /**
×
80
     * @deprecated please use thyType
81
     */
×
82
    readonly _type = input<string>(undefined, { alias: 'type' });
×
83

×
84
    /**
85
     * 输入 Label 文本
86
     */
×
87
    readonly thyLabelText = input<string>(undefined);
88

89
    /**
×
90
     * 是否只读
91
     */
1✔
92
    readonly readonly = input(false, { transform: coerceBooleanProperty });
1✔
93

94
    /**
95
     * focus 聚焦事件
96
     */
97
    readonly focus = output<Event>();
98

99
    /**
100
     * blur 失焦事件
101
     */
102
    readonly blur = output<Event>();
103

104
    /**
105
     * 后置模板
106
     */
1✔
107
    readonly appendTemplate = contentChild<TemplateRef<any>>('append');
108

109
    /**
110
     * 前置模板
111
     */
112
    readonly prependTemplate = contentChild<TemplateRef<any>>('prepend');
113

114
    public type = signal<string>(undefined);
115

116
    public value = signal('');
117

118
    public showLabel = signal(false);
119

120
    public focused = signal(false);
121

122
    public disabled = signal(false);
123

124
    private onTouchedCallback: () => void = noop;
125

126
    private onChangeCallback: (_: any) => void = noop;
127

128
    public isPasswordType = signal(false);
129

130
    constructor() {
131
        effect(() => {
132
            this.type.set(this.thyType() || this._type());
133
        });
134
    }
135

136
    ngOnInit() {
137
        this.ngZone.onStable.pipe(take(1)).subscribe(() => {
138
            this.isPasswordType.set(this.isPassword(this.type()));
139
        });
140
    }
141

142
    writeValue(value: any): void {
143
        this.value.set(value);
144
    }
145

146
    registerOnChange(fn: any): void {
147
        this.onChangeCallback = fn;
148
    }
149

150
    registerOnTouched(fn: any): void {
151
        this.onTouchedCallback = fn;
152
    }
153

154
    setDisabledState?(isDisabled: boolean): void {
155
        this.disabled.set(isDisabled);
156
    }
157

158
    onModelChange() {
159
        this.onChangeCallback(this.value());
160
    }
161

162
    onInputFocus(event: Event) {
163
        this.focused.set(true);
164
        this.showLabel.set(true);
165
        this.focus.emit(event);
166
    }
167

168
    onInputBlur(event: Event) {
169
        this.onTouchedCallback();
170
        if (this.elementRef.nativeElement.onblur) {
171
            this.elementRef.nativeElement.onblur(event);
172
        }
173
        this.focused.set(false);
174
        this.showLabel.set(false);
175
        this.blur.emit(event);
176
    }
177

178
    isPassword(value: string) {
179
        return value === password;
180
    }
181

182
    togglePasswordType() {
183
        this.type.set(this.isPassword(this.type()) ? 'text' : 'password');
184
    }
185
}
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