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

atinc / ngx-tethys / 9ed7e4e8-d8b9-4d4b-8b2f-b7bd9ead723a

pending completion
9ed7e4e8-d8b9-4d4b-8b2f-b7bd9ead723a

push

circleci

minlovehua
feat(input): thy-textarea

5105 of 6323 branches covered (80.74%)

Branch coverage included in aggregate %.

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

12916 of 13699 relevant lines covered (94.28%)

961.66 hits per line

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

32.65
/src/input/textarea/textarea.component.ts
1
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewChild, forwardRef } from '@angular/core';
2
import { ThyInputDirective, ThyInputSize } from '../input.directive';
3
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
4
import {
5
    AbstractControlValueAccessor,
6
    Constructor,
7
    InputBoolean,
8
    InputNumber,
9
    ThyCanDisable,
10
    ThyHasTabIndex,
11
    ThyInitialized,
12
    ThyUnsubscribe,
1✔
13
    mixinDisabled,
14
    mixinInitialized,
15
    mixinTabIndex,
16
    mixinUnsubscribe
17
} from 'ngx-tethys/core';
18
import { Subject } from 'rxjs';
1✔
19
import { filter, switchMap, takeUntil, tap } from 'rxjs/operators';
20
import { NgIf } from '@angular/common';
×
21
import { CdkTextareaAutosize, TextFieldModule } from '@angular/cdk/text-field';
×
22

×
23
const _MixinBase: Constructor<ThyHasTabIndex> &
×
24
    Constructor<ThyInitialized> &
×
25
    Constructor<ThyCanDisable> &
×
26
    Constructor<ThyUnsubscribe> &
×
27
    typeof AbstractControlValueAccessor = mixinInitialized(mixinTabIndex(mixinDisabled(mixinUnsubscribe(AbstractControlValueAccessor))));
×
28

×
29
/**
×
30
 * 文本域组件
×
31
 * @name thy-textarea
×
32
 * @order 50
×
33
 */
×
34
@Component({
35
    selector: 'thy-textarea',
36
    templateUrl: './textarea.component.html',
37
    host: {
×
38
        class: 'thy-textarea'
×
39
    },
40
    changeDetection: ChangeDetectionStrategy.OnPush,
41
    providers: [
×
42
        {
43
            provide: NG_VALUE_ACCESSOR,
44
            useExisting: forwardRef(() => ThyTextareaComponent),
×
45
            multi: true
×
46
        }
47
    ],
×
48
    standalone: true,
×
49
    imports: [NgIf, FormsModule, TextFieldModule, ThyInputDirective]
50
})
51
export class ThyTextareaComponent extends _MixinBase implements ControlValueAccessor, OnInit {
52
    @ViewChild(ThyInputDirective, { static: true }) inputDirective: ThyInputDirective;
53

×
54
    @ViewChild('autoSize', { static: true }) autoSize: CdkTextareaAutosize;
55

×
56
    // 待定:参数的命名是加thy前缀?还是和textarea保持完全一致的拼写?
57

×
58
    /**
59
     * 文本域的 name 属性
×
60
     */
×
61
    @Input() name = '';
62

63
    /**
64
     * 文本域的 placeholder
1✔
65
     */
66
    @Input() placeholder = '';
67

1✔
68
    /**
69
     * 最大字符长度
70
     */
71
    @Input() @InputNumber() maxlength: number;
72

73
    /**
74
     * 最小字符长度
75
     */
76
    @Input() @InputNumber() minlength: number;
77

78
    /**
79
     * 文本域的最大长度
80
     */
81
    @Input() @InputNumber() rows: number = 3;
82

83
    /**
84
     * 文本域的可视宽度
85
     */
86
    @Input() @InputNumber() cols: number;
1✔
87

88
    /**
89
     * 文本域最小支持行数
90
     */
1✔
91
    @Input() @InputNumber() minRows: number;
92

93
    /**
94
     * 文本域最大支持行数
1✔
95
     */
96
    @Input() @InputNumber() maxRows: number;
97

98
    /**
1✔
99
     * 是否只读
100
     */
101
    @Input() @InputBoolean() readonly = false;
102

1✔
103
    /**
104
     * 是否自动聚焦
105
     */
106
    @Input() @InputBoolean() thyAutofocus = false;
1✔
107

108
    /**
109
     * 是否自动调整高度
110
     */
1✔
111
    @Input() @InputBoolean() thyAutosize = false;
112

113
    /**
114
     * 自动调整高度的最小行数
1✔
115
     */
116
    @Input() @InputNumber() thyAutosizeMinRows = 1;
117

118
    /**
1✔
119
     * 自动调整高度的最大行数
120
     */
121
    @Input() @InputNumber() thyAutosizeMaxRows = 10;
122

1✔
123
    /**
124
     * 输入框大小
125
     * @type 'xs' | 'sm' | 'md' | 'lg' | ''
126
     */
1✔
127
    @Input() thySize: ThyInputSize;
128

129
    inputLength = 0;
130

1✔
131
    thyInput$ = new Subject<ThyInputDirective>();
132

133
    textareaValue: string;
134

135
    disabled: boolean;
136

137
    constructor(private changeDetectorRef: ChangeDetectorRef) {
138
        super();
139

140
        if (this.maxlength) {
141
            this.setup();
×
142
        }
143
    }
144

145
    writeValue(value: any): void {
146
        this.textareaValue = value;
147
        this.changeDetectorRef.markForCheck();
148
    }
149

150
    setDisabledState?(isDisabled: boolean): void {
151
        this.disabled = isDisabled;
152
    }
153

154
    ngOnInit(): void {
155
        if (this.maxlength) {
156
            this.thyInput$.next(this.inputDirective);
157
        }
158

159
        setTimeout(() => {
160
            this.autoSize.resizeToFitContent(true);
161
        }, 0);
162
    }
163

164
    textareaModelChange(value: string) {}
165

166
    setup() {
167
        this.thyInput$
168
            .pipe(
169
                filter(input => {
170
                    return !!input;
171
                }),
172
                takeUntil(this.ngUnsubscribe$),
173
                switchMap(input => {
174
                    return input.ngControl?.valueChanges;
175
                }),
176
                tap(value => {
177
                    this.inputLength = value?.length || 0;
178
                    this.changeDetectorRef.markForCheck();
179
                }),
180
                takeUntil(this.ngUnsubscribe$)
181
            )
182
            .subscribe();
183
    }
184
}
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