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

IgniteUI / igniteui-angular / 20960087204

13 Jan 2026 02:19PM UTC coverage: 12.713% (-78.8%) from 91.5%
20960087204

Pull #16746

github

web-flow
Merge 9afce6e5d into a967f087e
Pull Request #16746: fix(csv): export summaries - master

1008 of 16803 branches covered (6.0%)

19 of 23 new or added lines in 2 files covered. (82.61%)

24693 existing lines in 336 files now uncovered.

3985 of 31345 relevant lines covered (12.71%)

2.49 hits per line

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

1.37
/projects/igniteui-angular/input-group/src/input-group/input-group.component.ts
1
import { NgTemplateOutlet } from '@angular/common';
2
import {
3
    ChangeDetectorRef,
4
    Component,
5
    ContentChild,
6
    ContentChildren,
7
    DestroyRef,
8
    ElementRef,
9
    HostBinding,
10
    HostListener, Input,
11
    QueryList, booleanAttribute,
12
    inject,
13
    DOCUMENT,
14
    AfterContentChecked
15
} from '@angular/core';
16
import { IInputResourceStrings, InputResourceStringsEN } from 'igniteui-angular/core';
17
import { PlatformUtil, getComponentTheme } from 'igniteui-angular/core';
18
import { IgxButtonDirective } from 'igniteui-angular/directives';
19
import { IgxHintDirective } from './directives-hint/hint.directive';
20
import {
21
    IgxInputDirective,
22
    IgxInputState
23
} from './directives-input/input.directive';
24
import { IgxPrefixDirective } from './directives-prefix/prefix.directive';
25
import { IgxSuffixDirective } from './directives-suffix/suffix.directive';
26

27
import { IgxInputGroupBase } from './input-group.common';
28
import { IgxInputGroupType, IGX_INPUT_GROUP_TYPE } from './inputGroupType';
29
import { IgxIconComponent } from 'igniteui-angular/icon';
30
import { getCurrentResourceStrings, onResourceChangeHandle } from 'igniteui-angular/core';
31
import { IgxTheme, THEME_TOKEN, ThemeToken } from 'igniteui-angular/core';
32

33
@Component({
34
    selector: 'igx-input-group',
35
    templateUrl: 'input-group.component.html',
36
    providers: [{ provide: IgxInputGroupBase, useExisting: IgxInputGroupComponent }],
37
    imports: [NgTemplateOutlet, IgxPrefixDirective, IgxButtonDirective, IgxSuffixDirective, IgxIconComponent]
38
})
39
export class IgxInputGroupComponent implements IgxInputGroupBase, AfterContentChecked {
3✔
UNCOV
40
    public element = inject<ElementRef<HTMLElement>>(ElementRef);
×
UNCOV
41
    private _inputGroupType = inject<IgxInputGroupType>(IGX_INPUT_GROUP_TYPE, { optional: true });
×
UNCOV
42
    private document = inject(DOCUMENT);
×
UNCOV
43
    private platform = inject(PlatformUtil);
×
UNCOV
44
    private cdr = inject(ChangeDetectorRef);
×
UNCOV
45
    private themeToken = inject<ThemeToken>(THEME_TOKEN);
×
46

47
    /**
48
     * Sets the resource strings.
49
     * By default it uses EN resources.
50
     */
51
    @Input()
52
    public set resourceStrings(value: IInputResourceStrings) {
53
        this._resourceStrings = Object.assign({}, this._resourceStrings, value);
×
54
    }
55

56
    /**
57
     * Returns the resource strings.
58
     */
59
    public get resourceStrings(): IInputResourceStrings {
UNCOV
60
        return this._resourceStrings || this._defaultResourceStrings;
×
61
    }
62

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

77
    /** @hidden */
78
    @HostBinding('class.igx-input-group--placeholder')
UNCOV
79
    public hasPlaceholder = false;
×
80

81
    /** @hidden */
82
    @HostBinding('class.igx-input-group--required')
UNCOV
83
    public isRequired = false;
×
84

85
    /** @hidden */
86
    @HostBinding('class.igx-input-group--focused')
UNCOV
87
    public isFocused = false;
×
88

89
    /**
90
     * @hidden @internal
91
     * When truthy, disables the `IgxInputGroupComponent`.
92
     * Controlled by the underlying `IgxInputDirective`.
93
     * ```html
94
     * <igx-input-group [disabled]="true"></igx-input-group>
95
     * ```
96
     */
97
    @HostBinding('class.igx-input-group--disabled')
UNCOV
98
    public disabled = false;
×
99

100
    /**
101
     * Prevents automatically focusing the input when clicking on other elements in the input group (e.g. prefix or suffix).
102
     *
103
     * @remarks Automatic focus causes software keyboard to show on mobile devices.
104
     *
105
     * @example
106
     * ```html
107
     * <igx-input-group [suppressInputAutofocus]="true"></igx-input-group>
108
     * ```
109
     */
110
    @Input({ transform: booleanAttribute })
UNCOV
111
    public suppressInputAutofocus = false;
×
112

113
    /** @hidden */
114
    @HostBinding('class.igx-input-group--warning')
UNCOV
115
    public hasWarning = false;
×
116

117
    /** @hidden */
118
    @ContentChildren(IgxHintDirective, { read: IgxHintDirective })
119
    protected hints: QueryList<IgxHintDirective>;
120

121
    @ContentChildren(IgxPrefixDirective, { read: IgxPrefixDirective, descendants: true })
122
    protected _prefixes: QueryList<IgxPrefixDirective>;
123

124
    @ContentChildren(IgxSuffixDirective, { read: IgxSuffixDirective, descendants: true })
125
    protected _suffixes: QueryList<IgxSuffixDirective>;
126

127
    /** @hidden */
128
    @ContentChild(IgxInputDirective, { read: IgxInputDirective, static: true })
129
    protected input: IgxInputDirective;
130

UNCOV
131
    private _destroyRef = inject(DestroyRef);
×
UNCOV
132
    private _type: IgxInputGroupType = null;
×
UNCOV
133
    private _filled = false;
×
134
    private _theme: IgxTheme;
UNCOV
135
    private _resourceStrings: IInputResourceStrings = null;
×
UNCOV
136
    private _defaultResourceStrings = getCurrentResourceStrings(InputResourceStringsEN);
×
137
    private _readOnly: undefined | boolean;
138

139
    /** @hidden @internal */
140
    @HostBinding('class.igx-input-group--readonly')
141
    public get readOnly(): boolean {
UNCOV
142
        return this._readOnly ?? (this.input?.nativeElement.readOnly || false);
×
143
    }
144

145
    /** @hidden @internal */
146
    public set readOnly(value: boolean) {
UNCOV
147
        this._readOnly = value;
×
148
    }
149

150
    /** @hidden */
151
    @HostBinding('class.igx-input-group--valid')
152
    public get validClass(): boolean {
UNCOV
153
        return this.input.valid === IgxInputState.VALID;
×
154
    }
155

156
    /** @hidden */
157
    @HostBinding('class.igx-input-group--invalid')
158
    public get invalidClass(): boolean {
UNCOV
159
        return this.input.valid === IgxInputState.INVALID;
×
160
    }
161

162
    /** @hidden */
163
    @HostBinding('class.igx-input-group--filled')
164
    public get isFilled() {
UNCOV
165
        return this._filled || (this.input && this.input.value);
×
166
    }
167

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

174
    /**
175
     * Sets how the input will be styled.
176
     * Allowed values of type IgxInputGroupType.
177
     * ```html
178
     * <igx-input-group [type]="'search'">
179
     * ```
180
     */
181
    @Input()
182
    public set type(value: IgxInputGroupType) {
UNCOV
183
        this._type = value;
×
184
    }
185

186
    /**
187
     * Returns the type of the `IgxInputGroupComponent`. How the input is styled.
188
     * The default is `line`.
189
     * ```typescript
190
     * @ViewChild("MyInputGroup")
191
     * public inputGroup: IgxInputGroupComponent;
192
     * ngAfterViewInit(){
193
     *    let inputType = this.inputGroup.type;
194
     * }
195
     * ```
196
     */
197
    public get type() {
UNCOV
198
        return this._type || this._inputGroupType || 'line';
×
199
    }
200

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

216
    /**
217
     * Returns the theme of the input.
218
     * The returned value is of type IgxInputGroupType.
219
     * ```typescript
220
     * @ViewChild("MyInputGroup")
221
     * public inputGroup: IgxInputGroupComponent;
222
     * ngAfterViewInit() {
223
     *  let inputTheme = this.inputGroup.theme;
224
     * }
225
     */
226
    public get theme(): IgxTheme {
UNCOV
227
        return this._theme;
×
228
    }
229

230
    constructor() {
UNCOV
231
        this._theme = this.themeToken.theme;
×
UNCOV
232
        const themeChange = this.themeToken.onChange((theme) => {
×
UNCOV
233
            if (this._theme !== theme) {
×
234
                this._theme = theme;
×
235
                this.cdr.detectChanges();
×
236
            }
237
        });
UNCOV
238
        this._destroyRef.onDestroy(() => themeChange.unsubscribe());
×
UNCOV
239
        onResourceChangeHandle(this._destroyRef, () => {
×
UNCOV
240
            this._defaultResourceStrings = getCurrentResourceStrings(InputResourceStringsEN, false);
×
241
        }, this);
242
    }
243

244
    /** @hidden */
245
    @HostListener('click', ['$event'])
246
    public onClick(event: MouseEvent) {
UNCOV
247
        if (
×
248
            !this.isFocused &&
×
249
            event.target !== this.input.nativeElement &&
250
            !this.suppressInputAutofocus
251
        ) {
UNCOV
252
            this.input.focus();
×
253
        }
254
    }
255

256
    /** @hidden */
257
    @HostListener('pointerdown', ['$event'])
258
    public onPointerDown(event: PointerEvent) {
UNCOV
259
        if (this.isFocused && event.target !== this.input.nativeElement) {
×
UNCOV
260
            event.preventDefault();
×
261
        }
262
    }
263

264
    /** @hidden @internal */
265
    public hintClickHandler(event: MouseEvent) {
UNCOV
266
        event.stopPropagation();
×
267
    }
268

269
    /**
270
     * Returns whether the `IgxInputGroupComponent` has hints.
271
     * ```typescript
272
     * @ViewChild("MyInputGroup")
273
     * public inputGroup: IgxInputGroupComponent;
274
     * ngAfterViewInit(){
275
     *    let inputHints = this.inputGroup.hasHints;
276
     * }
277
     * ```
278
     */
279
    public get hasHints() {
280
        return this.hints.length > 0;
×
281
    }
282

283
    /** @hidden @internal */
284
    @HostBinding('class.igx-input-group--prefixed')
285
    public get hasPrefixes() {
UNCOV
286
        return this._prefixes.length > 0;
×
287
    }
288

289
    /** @hidden @internal */
290
    public set prefixes(items: QueryList<IgxPrefixDirective>) {
UNCOV
291
        this._prefixes = items;
×
292
    }
293

294
    /** @hidden @internal */
295
    @HostBinding('class.igx-input-group--suffixed')
296
    public get hasSuffixes() {
UNCOV
297
        return this._suffixes.length > 0 || this.isFileType && this.isFilled;
×
298
    }
299

300
    /** @hidden @internal */
301
    public set suffixes(items: QueryList<IgxSuffixDirective>) {
UNCOV
302
        this._suffixes = items;
×
303
    }
304

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

322
    /**
323
     * Returns whether the `IgxInputGroupComponent` type is line.
324
     * ```typescript
325
     * @ViewChild("MyInputGroup1")
326
     * public inputGroup: IgxInputGroupComponent;
327
     * ngAfterViewInit(){
328
     *    let isTypeLine = this.inputGroup.isTypeLine;
329
     * }
330
     * ```
331
     */
332
    public get isTypeLine(): boolean {
UNCOV
333
        return this.type === 'line' && this._theme === 'material';
×
334
    }
335

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

351
    /** @hidden @internal */
352
    public clearValueHandler() {
UNCOV
353
        this.input.clear();
×
354
    }
355

356
    /** @hidden @internal */
357
    @HostBinding('class.igx-input-group--file')
358
    public get isFileType() {
UNCOV
359
        return this.input.type === 'file';
×
360
    }
361

362
    /** @hidden @internal */
363
    @HostBinding('class.igx-file-input')
364
    public get isFileInput() {
UNCOV
365
        return this.input.type === 'file';
×
366
    }
367

368
    /** @hidden @internal */
369
    @HostBinding('class.igx-file-input--filled')
370
    public get isFileInputFilled() {
UNCOV
371
        return this.isFileType && this.isFilled;
×
372
    }
373

374
    /** @hidden @internal */
375
    @HostBinding('class.igx-file-input--focused')
376
    public get isFileInputFocused() {
UNCOV
377
        return this.isFileType && this.isFocused;
×
378
    }
379

380
    /** @hidden @internal */
381
    @HostBinding('class.igx-file-input--disabled')
382
    public get isFileInputDisabled() {
UNCOV
383
        return this.isFileType && this.disabled;
×
384
    }
385

386
    /** @hidden @internal */
387
    public get fileNames() {
UNCOV
388
        return this.input.fileNames || this.resourceStrings.igx_input_file_placeholder;
×
389
    }
390

391
    /**
392
     * Returns whether the `IgxInputGroupComponent` type is border.
393
     * ```typescript
394
     * @ViewChild("MyInputGroup1")
395
     * public inputGroup: IgxInputGroupComponent;
396
     * ngAfterViewInit(){
397
     *    let isTypeBorder = this.inputGroup.isTypeBorder;
398
     * }
399
     * ```
400
     */
401
    @HostBinding('class.igx-input-group--border')
402
    public get isTypeBorder() {
UNCOV
403
        return this.type === 'border' && this._theme === 'material';
×
404
    }
405

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

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

436
    /**
437
     * Returns true if the `IgxInputGroupComponent` theme is Indigo.
438
     * ```typescript
439
     * @ViewChild("MyInputGroup1")
440
     * public inputGroup: IgxInputGroupComponent;
441
     * ngAfterViewInit(){
442
     *    let isTypeIndigo = this.inputGroup.isTypeIndigo;
443
     * }
444
     * ```
445
     */
446
    @HostBinding('class.igx-input-group--indigo')
447
    public get isTypeIndigo() {
UNCOV
448
        return this._theme === 'indigo';
×
449
    }
450

451
    /**
452
     * Returns whether the `IgxInputGroupComponent` type is search.
453
     * ```typescript
454
     * @ViewChild("MyInputGroup1")
455
     * public inputGroup: IgxInputGroupComponent;
456
     * ngAfterViewInit(){
457
     *    let isTypeSearch = this.inputGroup.isTypeSearch;
458
     * }
459
     * ```
460
     */
461
    @HostBinding('class.igx-input-group--search')
462
    public get isTypeSearch() {
UNCOV
463
        if(!this.isFileType && !this.input.isTextArea) {
×
UNCOV
464
            return this.type === 'search';
×
465
        }
466
    }
467

468
    /** @hidden */
469
    public get filled() {
470
        return this._filled;
×
471
    }
472

473
    /** @hidden */
474
    public set filled(val) {
475
        this._filled = val;
×
476
    }
477

478
    private setComponentTheme() {
UNCOV
479
        if (!this.themeToken.preferToken) {
×
UNCOV
480
            const theme = getComponentTheme(this.element.nativeElement);
×
481

UNCOV
482
            if (theme && theme !== this._theme) {
×
483
                this.theme = theme;
×
484
                this.cdr.markForCheck();
×
485
            }
486
        }
487
    }
488

489
    /** @hidden @internal */
490
    public ngAfterContentChecked() {
UNCOV
491
        this.setComponentTheme();
×
492
    }
493
}
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