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

IgniteUI / igniteui-angular / 6653488239

26 Oct 2023 11:33AM UTC coverage: 92.101% (-0.1%) from 92.206%
6653488239

push

github

web-flow
Merge pull request #13451 from IgniteUI/bundle-test-extended

refactor(i18n, util): tree shaking i18n

15273 of 17962 branches covered (0.0%)

45 of 45 new or added lines in 24 files covered. (100.0%)

26410 of 28675 relevant lines covered (92.1%)

30213.01 hits per line

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

92.54
/projects/igniteui-angular/src/lib/input-group/input-group.component.ts
1
import { DOCUMENT, NgIf, NgTemplateOutlet, NgClass, NgSwitch, NgSwitchCase, NgSwitchDefault } from '@angular/common';
2
import {
3
    AfterViewChecked, ChangeDetectorRef, Component,
4
    ContentChild,
5
    ContentChildren,
6
    ElementRef,
7
    HostBinding,
8
    HostListener, Inject, Input,
9
    OnDestroy, Optional, QueryList
10
} from '@angular/core';
11
import { Subject, Subscription } from 'rxjs';
12
import {
13
    DisplayDensityBase, DisplayDensityToken, IDisplayDensityOptions
14
} from '../core/density';
15
import { IInputResourceStrings, InputResourceStringsEN } from '../core/i18n/input-resources';
16
import { mkenum, PlatformUtil } from '../core/utils';
17
import { IgxButtonDirective } from '../directives/button/button.directive';
18
import { IgxHintDirective } from '../directives/hint/hint.directive';
19
import {
2✔
20
    IgxInputDirective,
21
    IgxInputState
22
} from '../directives/input/input.directive';
23
import { IgxPrefixDirective } from '../directives/prefix/prefix.directive';
24
import { IgxSuffixDirective } from '../directives/suffix/suffix.directive';
25

2✔
26
import { IgxInputGroupBase } from './input-group.common';
27
import { IgxInputGroupType, IGX_INPUT_GROUP_TYPE } from './inputGroupType';
×
28
import { IgxIconComponent } from '../icon/icon.component';
29
import { getCurrentResourceStrings } from '../core/i18n/resources';
30

31
const IgxInputGroupTheme = mkenum({
32
    Material: 'material',
33
    Fluent: 'fluent',
35✔
34
    Bootstrap: 'bootstrap',
35
    IndigoDesign: 'indigo-design'
36
});
22,560✔
37

38
/**
39
 * Determines the Input Group theme.
22,560✔
40
 */
41
export type IgxInputGroupTheme = (typeof IgxInputGroupTheme)[keyof typeof IgxInputGroupTheme];
42

22,630✔
43
@Component({
44
    selector: 'igx-input-group',
45
    templateUrl: 'input-group.component.html',
22,560✔
46
    providers: [{ provide: IgxInputGroupBase, useExisting: IgxInputGroupComponent }],
47
    standalone: true,
48
    imports: [NgIf, NgTemplateOutlet, IgxPrefixDirective, IgxButtonDirective, NgClass, IgxSuffixDirective, IgxIconComponent, NgSwitch, NgSwitchCase, NgSwitchDefault]
22,560✔
49
})
50
export class IgxInputGroupComponent extends DisplayDensityBase implements IgxInputGroupBase, AfterViewChecked, OnDestroy {
51
    /**
1,457✔
52
     * Sets the resource strings.
53
     * By default it uses EN resources.
54
     */
55
   @Input()
56
   public set resourceStrings(value: IInputResourceStrings) {
57
       this._resourceStrings = Object.assign({}, this._resourceStrings, value);
58
   }
59

60
    /**
61
     * Returns the resource strings.
62
     */
63
    public get resourceStrings(): IInputResourceStrings {
64
        return this._resourceStrings;
65
    }
141,744✔
66

67
    /**
68
     * Property that enables/disables the auto-generated class of the `IgxInputGroupComponent`.
99✔
69
     * By default applied the class is applied.
70
     * ```typescript
71
     *  @ViewChild("MyInputGroup")
72
     *  public inputGroup: IgxInputGroupComponent;
73
     *  ngAfterViewInit(){
74
     *  this.inputGroup.defaultClass = false;
75
     * ```
76
     * }
77
     */
78
    @HostBinding('class.igx-input-group')
79
    public defaultClass = true;
80

81
    /** @hidden */
36,322✔
82
    @HostBinding('class.igx-input-group--placeholder')
83
    public hasPlaceholder = false;
84

2,260✔
85
    /** @hidden */
2,260✔
86
    @HostBinding('class.igx-input-group--required')
2,260✔
87
    public isRequired = false;
2,260✔
88

2,260✔
89
    /** @hidden */
2,260✔
90
    @HostBinding('class.igx-input-group--focused')
2,260✔
91
    public isFocused = false;
2,260✔
92

2,260✔
93
    /**
2,260✔
94
     * @hidden @internal
2,260✔
95
     * When truthy, disables the `IgxInputGroupComponent`.
2,260✔
96
     * Controlled by the underlying `IgxInputDirective`.
2,260✔
97
     * ```html
2,260✔
98
     * <igx-input-group [disabled]="true"></igx-input-group>
2,260✔
99
     * ```
2,260✔
100
     */
2,260✔
101
    @HostBinding('class.igx-input-group--disabled')
2,260✔
102
    public disabled = false;
5,480✔
103

5,480✔
104
    /**
105
     * Prevents automatically focusing the input when clicking on other elements in the input group (e.g. prefix or suffix).
106
     *
107
     * @remarks Automatic focus causes software keyboard to show on mobile devices.
132✔
108
     *
109
     * @example
110
     * ```html
84✔
111
     * <igx-input-group [suppressInputAutofocus]="true"></igx-input-group>
112
     * ```
113
     */
114
    @Input()
11✔
115
    public suppressInputAutofocus = false;
1✔
116

117
    /** @hidden */
118
    @HostBinding('class.igx-input-group--warning')
119
    public hasWarning = false;
120

2✔
121
    /** @hidden */
122
    @ContentChildren(IgxHintDirective, { read: IgxHintDirective })
123
    protected hints: QueryList<IgxHintDirective>;
124

125
    @ContentChildren(IgxPrefixDirective, { read: IgxPrefixDirective, descendants: true })
126
    protected _prefixes: QueryList<IgxPrefixDirective>;
127

128
    @ContentChildren(IgxSuffixDirective, { read: IgxSuffixDirective, descendants: true })
129
    protected _suffixes: QueryList<IgxSuffixDirective>;
130

131
    /** @hidden */
132
    @ContentChild(IgxInputDirective, { read: IgxInputDirective, static: true })
133
    protected input: IgxInputDirective;
×
134

135
    private _type: IgxInputGroupType = null;
136
    private _filled = false;
22,560✔
137
    private _theme: IgxInputGroupTheme;
138
    private _theme$ = new Subject();
139
    private _subscription: Subscription;
140
    private _resourceStrings = getCurrentResourceStrings(InputResourceStringsEN);
404✔
141

142
    /** @hidden */
143
    @HostBinding('class.igx-input-group--valid')
22,560✔
144
    public get validClass(): boolean {
145
        return this.input.valid === IgxInputState.VALID;
146
    }
147

30✔
148
    /** @hidden */
149
    @HostBinding('class.igx-input-group--invalid')
150
    public get invalidClass(): boolean {
151
        return this.input.valid === IgxInputState.INVALID;
152
    }
153

154
    /** @hidden */
155
    @HostBinding('class.igx-input-group--filled')
156
    public get isFilled() {
157
        return this._filled || (this.input && this.input.value);
158
    }
159

160
    /** @hidden @internal */
28,040✔
161
    @HostBinding('style.--component-size')
162
    public get componentSize() {
163
        return this.getComponentSizeStyles();
164
    }
165

166
    /** @hidden */
167
    @HostBinding('class.igx-input-group--textarea-group')
168
    public get textAreaClass(): boolean {
169
        return this.input.isTextArea;
170
    }
171

172
    /**
173
     * An @Input property that sets how the input will be styled.
174
     * Allowed values of type IgxInputGroupType.
45✔
175
     * ```html
176
     * <igx-input-group [type]="'search'">
177
     * ```
50,610✔
178
     */
179
    @Input('type')
180
    public set type(value: IgxInputGroupType) {
181
        this._type = value;
×
182
    }
183

184
    /**
185
     * Returns the type of the `IgxInputGroupComponent`. How the input is styled.
2✔
186
     * The default is `line`.
187
     * ```typescript
188
     * @ViewChild("MyInputGroup")
133,597✔
189
     * public inputGroup: IgxInputGroupComponent;
190
     * ngAfterViewInit(){
191
     *    let inputType = this.inputGroup.type;
192
     * }
70✔
193
     * ```
194
     */
195
    public get type() {
22,570✔
196
        return this._type || this._inputGroupType || 'line';
197
    }
198

22,560✔
199
    /**
200
     * Sets the theme of the input.
201
     * Allowed values of type IgxInputGroupTheme.
22,560✔
202
     * ```typescript
203
     * @ViewChild("MyInputGroup")
204
     * public inputGroup: IgxInputGroupComponent;
22,560✔
205
     * ngAfterViewInit() {
206
     *  let inputTheme = 'fluent';
207
     * }
22,570✔
208
     */
209
    @Input()
210
    public set theme(value: IgxInputGroupTheme) {
211
        this._theme = value;
×
212
    }
213

214
    /**
215
     * Returns the theme of the input.
×
216
     * The returned value is of type IgxInputGroupType.
217
     * ```typescript
218
     * @ViewChild("MyInputGroup")
219
     * public inputGroup: IgxInputGroupComponent;
17,408✔
220
     * ngAfterViewInit() {
9,320✔
221
     *  let inputTheme = this.inputGroup.theme;
222
     * }
223
     */
224
    public get theme(): IgxInputGroupTheme {
9,320✔
225
        return this._theme;
9,155✔
226
    }
9,155✔
227

9,155✔
228
    constructor(
229
        public element: ElementRef<HTMLElement>,
230
        @Optional()
231
        @Inject(DisplayDensityToken)
232
        _displayDensityOptions: IDisplayDensityOptions,
233
        @Optional()
234
        @Inject(IGX_INPUT_GROUP_TYPE)
2,238✔
235
        private _inputGroupType: IgxInputGroupType,
236
        @Inject(DOCUMENT)
4✔
237
        private document: any,
238
        private platform: PlatformUtil,
239
        private cdr: ChangeDetectorRef
240
    ) {
241
        super(_displayDensityOptions, element);
242

243
        this._subscription = this._theme$.asObservable().subscribe(value => {
244
            this._theme = value as IgxInputGroupTheme;
2✔
245
            this.cdr.detectChanges();
246
        });
247
    }
248

249
    /** @hidden */
250
    @HostListener('click', ['$event'])
251
    public onClick(event: MouseEvent) {
252
        if (
253
            !this.isFocused &&
254
            event.target !== this.input.nativeElement &&
255
            !this.suppressInputAutofocus
256
        ) {
257
            this.input.focus();
258
        }
259
    }
260

261
    /** @hidden */
262
    @HostListener('pointerdown', ['$event'])
263
    public onPointerDown(event: PointerEvent) {
264
        if (this.isFocused && event.target !== this.input.nativeElement) {
265
            event.preventDefault();
266
        }
267
    }
268

269
    /** @hidden @internal */
270
    public hintClickHandler(event: MouseEvent) {
271
        event.stopPropagation();
272
    }
273

274
    /**
275
     * Returns whether the `IgxInputGroupComponent` has hints.
276
     * ```typescript
277
     * @ViewChild("MyInputGroup")
2✔
278
     * public inputGroup: IgxInputGroupComponent;
279
     * ngAfterViewInit(){
280
     *    let inputHints = this.inputGroup.hasHints;
281
     * }
282
     * ```
283
     */
284
    public get hasHints() {
285
        return this.hints.length > 0;
286
    }
287

288
    /** @hidden @internal */
289
    @HostBinding('class.igx-input-group--prefixed')
290
    public get hasPrefixes() {
291
        return this._prefixes.length > 0 || this.isFileType;
292
    }
293

294
    /** @hidden @internal */
295
    public set prefixes(items: QueryList<IgxPrefixDirective>) {
296
        this._prefixes = items;
297
    }
298

299
    /** @hidden @internal */
300
    @HostBinding('class.igx-input-group--suffixed')
301
    public get hasSuffixes() {
302
        return this._suffixes.length > 0 || this.isFileType && this.isFilled;
303
    }
304

305
    /** @hidden @internal */
306
    public set suffixes(items: QueryList<IgxPrefixDirective>) {
307
        this._suffixes = items;
308
    }
309

310
    /**
311
     * Returns whether the `IgxInputGroupComponent` has border.
312
     * ```typescript
313
     * @ViewChild("MyInputGroup")
314
     * public inputGroup: IgxInputGroupComponent;
315
     * ngAfterViewInit(){
316
     *    let inputBorder = this.inputGroup.hasBorder;
317
     * }
318
     * ```
319
     */
320
    public get hasBorder() {
321
        return (
322
            (this.type === 'line' || this.type === 'box') &&
323
            this._theme === 'material'
324
        );
325
    }
326

327
    /**
328
     * Returns whether the `IgxInputGroupComponent` type is line.
329
     * ```typescript
330
     * @ViewChild("MyInputGroup1")
331
     * public inputGroup: IgxInputGroupComponent;
332
     * ngAfterViewInit(){
333
     *    let isTypeLine = this.inputGroup.isTypeLine;
334
     * }
335
     * ```
336
     */
337
    public get isTypeLine(): boolean {
338
        return this.type === 'line' && this._theme === 'material';
339
    }
340

341
    /**
342
     * Returns whether the `IgxInputGroupComponent` type is box.
343
     * ```typescript
344
     * @ViewChild("MyInputGroup1")
345
     * public inputGroup: IgxInputGroupComponent;
346
     * ngAfterViewInit(){
347
     *    let isTypeBox = this.inputGroup.isTypeBox;
348
     * }
349
     * ```
350
     */
351
    @HostBinding('class.igx-input-group--box')
352
    public get isTypeBox() {
353
        return this.type === 'box' && this._theme === 'material';
354
    }
355

356
    /** @hidden @internal */
357
    public uploadButtonHandler() {
358
        this.input.nativeElement.click();
359
    }
360

361
    /** @hidden @internal */
362
    public clearValueHandler() {
363
        this.input.clear();
364
    }
365

366
    /** @hidden @internal */
367
    @HostBinding('class.igx-input-group--file')
368
    public get isFileType() {
369
        return this.input.type === 'file';
370
    }
371

372
    /** @hidden @internal */
373
    public get fileNames() {
374
        return this.input.fileNames || this._resourceStrings.igx_input_file_placeholder;
375
    }
376

377
    /**
378
     * Returns whether the `IgxInputGroupComponent` type is border.
379
     * ```typescript
380
     * @ViewChild("MyInputGroup1")
381
     * public inputGroup: IgxInputGroupComponent;
382
     * ngAfterViewInit(){
383
     *    let isTypeBorder = this.inputGroup.isTypeBorder;
384
     * }
385
     * ```
386
     */
387
    @HostBinding('class.igx-input-group--border')
388
    public get isTypeBorder() {
389
        return this.type === 'border' && this._theme === 'material';
390
    }
391

392
    /**
393
     * Returns true if the `IgxInputGroupComponent` theme is Fluent.
394
     * ```typescript
395
     * @ViewChild("MyInputGroup1")
396
     * public inputGroup: IgxInputGroupComponent;
397
     * ngAfterViewInit(){
398
     *    let isTypeFluent = this.inputGroup.isTypeFluent;
399
     * }
400
     * ```
401
     */
402
    @HostBinding('class.igx-input-group--fluent')
403
    public get isTypeFluent() {
404
        return this._theme === 'fluent';
405
    }
406

407
    /**
408
     * Returns true if the `IgxInputGroupComponent` theme is Bootstrap.
409
     * ```typescript
410
     * @ViewChild("MyInputGroup1")
411
     * public inputGroup: IgxInputGroupComponent;
412
     * ngAfterViewInit(){
413
     *    let isTypeBootstrap = this.inputGroup.isTypeBootstrap;
414
     * }
415
     * ```
416
     */
417
    @HostBinding('class.igx-input-group--bootstrap')
418
    public get isTypeBootstrap() {
419
        return this._theme === 'bootstrap';
420
    }
421

422
    /**
423
     * Returns true if the `IgxInputGroupComponent` theme is Indigo.
424
     * ```typescript
425
     * @ViewChild("MyInputGroup1")
426
     * public inputGroup: IgxInputGroupComponent;
427
     * ngAfterViewInit(){
428
     *    let isTypeIndigo = this.inputGroup.isTypeIndigo;
429
     * }
430
     * ```
431
     */
432
    @HostBinding('class.igx-input-group--indigo')
433
    public get isTypeIndigo() {
434
        return this._theme === 'indigo-design';
435
    }
436

437
    /**
438
     * Returns whether the `IgxInputGroupComponent` type is search.
439
     * ```typescript
440
     * @ViewChild("MyInputGroup1")
441
     * public inputGroup: IgxInputGroupComponent;
442
     * ngAfterViewInit(){
443
     *    let isTypeSearch = this.inputGroup.isTypeSearch;
444
     * }
445
     * ```
446
     */
447
    @HostBinding('class.igx-input-group--search')
448
    public get isTypeSearch() {
449
        return this.type === 'search';
450
    }
451

452
    /** @hidden */
453
    public get filled() {
454
        return this._filled;
455
    }
456

457
    /** @hidden */
458
    public set filled(val) {
459
        this._filled = val;
460
    }
461

462
    /** @hidden @internal */
463
    public ngAfterViewChecked() {
464
        if (!this._theme) {
465
            const cssProp = this.document.defaultView
466
                .getComputedStyle(this.element.nativeElement)
467
                .getPropertyValue('--theme')
468
                .trim();
469

470
            if(cssProp !== '') {
471
                Promise.resolve().then(() => {
472
                    this._theme$.next(cssProp);
473
                    this.cdr.markForCheck();
474
                });
475
            }
476
        }
477
    }
478

479
    /** @hidden @internal */
480
    public ngOnDestroy() {
481
        this._subscription.unsubscribe();
482
    }
483
}
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