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

atinc / ngx-tethys / ebc321d8-d8ed-4ed1-9e59-a5945729a8da

24 Aug 2023 02:49AM UTC coverage: 90.055% (-0.1%) from 90.181%
ebc321d8-d8ed-4ed1-9e59-a5945729a8da

Pull #2771

circleci

web-flow
feat(dropdown): update thyImmediateRender template remove div #INFR-9359 (#2794)

* feat(dropdown): update thyImmediateRender template remove div #INFR-9359

* feat(dropdown): update test

* feat(dropdown): update test

* build: code review

* build: code review
Pull Request #2771: feat: bump angular to 16.x

5104 of 6321 branches covered (80.75%)

Branch coverage included in aggregate %.

144 of 144 new or added lines in 15 files covered. (100.0%)

12897 of 13668 relevant lines covered (94.36%)

977.88 hits per line

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

79.03
/src/input/input-group.component.ts
1
import {
2
    Component,
3
    HostBinding,
4
    Input,
5
    ContentChild,
6
    TemplateRef,
7
    ViewEncapsulation,
8
    ChangeDetectionStrategy,
9
    AfterContentChecked,
10
    OnInit,
1✔
11
    OnDestroy,
12
    ChangeDetectorRef,
13
    NgZone
14
} from '@angular/core';
15
import { MixinBase, ThyTranslate, mixinUnsubscribe, useHostFocusControl } from 'ngx-tethys/core';
16
import { useHostRenderer } from '@tethys/cdk/dom';
17
import { ThyInputDirective } from './input.directive';
18
import { NgIf, NgTemplateOutlet } from '@angular/common';
19
import { takeUntil, throttleTime } from 'rxjs/operators';
20
import { Observable, of } from 'rxjs';
1✔
21
import { FocusOrigin } from '@angular/cdk/a11y';
22

8✔
23
export type InputGroupSize = 'sm' | 'lg' | 'md' | '';
24

25
const inputGroupSizeMap = {
8!
26
    sm: ['input-group-sm'],
8✔
27
    lg: ['input-group-lg'],
28
    md: ['input-group-md']
29
};
30

8✔
31
/**
32
 * 输入框分组
33
 * @name thy-input-group
8!
34
 * @order 20
8✔
35
 */
36
@Component({
37
    selector: 'thy-input-group',
38
    templateUrl: './input-group.component.html',
18✔
39
    changeDetection: ChangeDetectionStrategy.OnPush,
3✔
40
    encapsulation: ViewEncapsulation.None,
41
    host: {
42
        class: 'thy-input-group',
15✔
43
        '[class.form-control]': 'prefixTemplate || suffixTemplate',
44
        '[class.thy-input-group-with-prefix]': 'prefixTemplate',
45
        '[class.thy-input-group-with-suffix]': 'suffixTemplate',
46
        '[class.thy-input-group-with-textarea-suffix]': 'isTextareaSuffix',
30✔
47
        '[class.thy-input-group-with-scroll-bar]': 'isTextareaSuffix && hasScrollbar'
30✔
48
    },
30✔
49
    standalone: true,
30✔
50
    imports: [NgIf, NgTemplateOutlet]
30✔
51
})
30✔
52
export class ThyInputGroupComponent extends mixinUnsubscribe(MixinBase) implements OnInit, AfterContentChecked, OnDestroy {
30✔
53
    private hostRenderer = useHostRenderer();
54

55
    private hostFocusControl = useHostFocusControl();
30✔
56

2!
57
    public appendText: string;
2✔
58

59
    public prependText: string;
60

×
61
    public isTextareaSuffix: boolean;
62

63
    public hasScrollbar: boolean;
64

65
    @HostBinding('class.disabled') disabled = false;
45✔
66

45✔
67
    /**
45✔
68
     * 输入框上添加的后置文本
2✔
69
     */
70
    @Input()
71
    set thyAppendText(value: string) {
72
        this.appendText = value;
2✔
73
    }
2✔
74

75
    /**
76
     * 输入框上添加的后置文本多语言 Key
×
77
     */
×
78
    @Input()
×
79
    set thyAppendTextTranslateKey(value: string) {
×
80
        if (value) {
×
81
            this.appendText = this.thyTranslate.instant(value);
82
        }
83
    }
84

85
    /**
86
     * 输入框上添加的前置文本
87
     */
2!
88
    @Input()
89
    set thyPrependText(value: string) {
90
        this.prependText = value;
2✔
91
    }
×
92

93
    /**
2✔
94
     * 输入框上添加的前置文本多语言 Key
2✔
95
     */
2✔
96
    @Input()
97
    set thyPrependTextTranslateKey(value: string) {
98
        if (value) {
99
            this.prependText = this.thyTranslate.instant(value);
100
        }
30✔
101
    }
30✔
102

103
    /**
1✔
104
     * 输入框分组大小
105
     * @type 'sm' | 'lg' | 'md' | ''
106
     * @default ''
107
     */
108
    @Input()
1✔
109
    set thySize(size: InputGroupSize) {
110
        if (size && inputGroupSizeMap[size]) {
111
            this.hostRenderer.updateClass(inputGroupSizeMap[size]);
112
        } else {
113
            this.hostRenderer.updateClass([]);
114
        }
115
    }
116

117
    /**
118
     * 后置模板
119
     */
120
    @ContentChild('append') appendTemplate: TemplateRef<unknown>;
121

122
    /**
1✔
123
     * 前置模板
124
     */
125
    @ContentChild('prepend') prependTemplate: TemplateRef<unknown>;
126

127
    /**
128
     * 前缀
129
     */
130
    @ContentChild('prefix') prefixTemplate: TemplateRef<unknown>;
131

132
    /**
133
     * 后缀
134
     */
135
    @ContentChild('suffix') suffixTemplate: TemplateRef<unknown>;
136

137
    /**
138
     * @private
139
     */
140
    @ContentChild(ThyInputDirective) inputDirective: ThyInputDirective;
141

142
    constructor(private thyTranslate: ThyTranslate, private ngZone: NgZone, private cdr: ChangeDetectorRef) {
143
        super();
144
    }
145

146
    ngOnInit() {
147
        this.hostFocusControl.focusChanged = (origin: FocusOrigin) => {
148
            if (origin) {
149
                this.hostRenderer.addClass('form-control-active');
150
            } else {
151
                this.hostRenderer.removeClass('form-control-active');
152
            }
153
        };
154
    }
155

156
    ngAfterContentChecked(): void {
157
        this.disabled = !!this.inputDirective?.nativeElement?.hasAttribute('disabled');
158

159
        this.isTextareaSuffix = this.inputDirective?.nativeElement?.tagName === 'TEXTAREA';
160
        if (this.isTextareaSuffix) {
161
            this.determineHasScrollbar();
162
        }
163
    }
164

165
    private determineHasScrollbar() {
166
        this.ngZone.runOutsideAngular(() => {
167
            this.resizeObserver(this.inputDirective.nativeElement)
168
                .pipe(throttleTime(100), takeUntil(this.ngUnsubscribe$))
169
                .subscribe(() => {
170
                    const hasScrollbar = this.inputDirective.nativeElement.scrollHeight > this.inputDirective.nativeElement.clientHeight;
171
                    if (this.hasScrollbar !== hasScrollbar) {
172
                        this.ngZone.run(() => {
173
                            this.hasScrollbar = hasScrollbar;
174
                            this.cdr.detectChanges();
175
                        });
176
                    }
177
                });
178
        });
179
    }
180

181
    private resizeObserver(element: HTMLElement): Observable<ResizeObserverEntry[]> {
182
        return typeof ResizeObserver === 'undefined' || !ResizeObserver
183
            ? of(null)
184
            : new Observable(observer => {
185
                  const resize = new ResizeObserver((entries: ResizeObserverEntry[]) => {
186
                      observer.next(entries);
187
                  });
188
                  resize.observe(element);
189
                  return () => {
190
                      resize.disconnect();
191
                  };
192
              });
193
    }
194

195
    ngOnDestroy() {
196
        super.ngOnDestroy();
197
        this.hostFocusControl.destroy();
198
    }
199
}
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