• 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

10.0
/projects/igniteui-angular/progressbar/src/progressbar/progressbar.component.ts
1
import { NgClass, NgTemplateOutlet } from '@angular/common';
2
import {
3
    Component,
4
    ElementRef,
5
    EventEmitter,
6
    HostBinding,
7
    Input,
8
    Output,
9
    Renderer2,
10
    ViewChild,
11
    ContentChild,
12
    AfterContentInit,
13
    Directive,
14
    booleanAttribute,
15
    inject,
16
    ChangeDetectorRef,
17
    NgZone,
18
} from '@angular/core';
19
import {
20
    IgxProgressBarTextTemplateDirective,
21
    IgxProgressBarGradientDirective,
22
} from './progressbar.common';
23
import { IBaseEventArgs } from 'igniteui-angular/core';
24
const ONE_PERCENT = 0.01;
3✔
25
const MIN_VALUE = 0;
3✔
26

27
export const IgxTextAlign = {
3✔
28
    START: 'start',
29
    CENTER: 'center',
30
    END: 'end'
31
} as const;
32
export type IgxTextAlign = (typeof IgxTextAlign)[keyof typeof IgxTextAlign];
33

34
export const IgxProgressType = {
3✔
35
    ERROR: 'error',
36
    INFO: 'info',
37
    WARNING: 'warning',
38
    SUCCESS: 'success'
39
} as const;
40
export type IgxProgressType = (typeof IgxProgressType)[keyof typeof IgxProgressType];
41

42
export interface IChangeProgressEventArgs extends IBaseEventArgs {
43
    previousValue: number;
44
    currentValue: number;
45
}
46
export const valueInRange = (value: number, max: number, min = 0): number => Math.max(Math.min(value, max), min);
3!
47

48
/**
49
 * @hidden
50
 */
51
@Directive()
52
export abstract class BaseProgressDirective {
3✔
53
    /**
54
     * An event, which is triggered after progress is changed.
55
     * ```typescript
56
     * public progressChange(event) {
57
     *     alert("Progress made!");
58
     * }
59
     *  //...
60
     * ```
61
     * ```html
62
     * <igx-circular-bar (progressChanged)="progressChange($event)"></igx-circular-bar>
63
     * <igx-linear-bar (progressChanged)="progressChange($event)"></igx-linear-bar>
64
     * ```
65
     */
66
    @Output()
UNCOV
67
    public progressChanged = new EventEmitter<IChangeProgressEventArgs>();
×
68

69
    /**
70
     * Sets/Gets progressbar animation duration. By default, it is 2000ms.
71
     * ```html
72
     * <igx-linear-bar [animationDuration]="3000"></igx-linear-bar>
73
     * <igx-circular-bar [animationDuration]="3000"></igx-linear-bar>
74
     * ```
75
     */
76
    @Input()
UNCOV
77
    public animationDuration = 2000;
×
78

UNCOV
79
    protected _contentInit = false;
×
UNCOV
80
    protected _indeterminate = false;
×
81
    protected _text: string;
UNCOV
82
    protected _max = 100;
×
UNCOV
83
    protected _value = MIN_VALUE;
×
UNCOV
84
    protected _animate = true;
×
85
    protected _step: number;
UNCOV
86
    protected _fraction = 0;
×
UNCOV
87
    protected _integer = 0;
×
UNCOV
88
    protected _cdr = inject(ChangeDetectorRef);
×
UNCOV
89
    protected _zone = inject(NgZone);
×
90

91
    /**
92
     * Sets progressbar in indeterminate. By default, it is set to false.
93
     * ```html
94
     * <igx-linear-bar [indeterminate]="true"></igx-linear-bar>
95
     * <igx-circular-bar [indeterminate]="true"></igx-circular-bar>
96
     * ```
97
     */
98
    @Input({ transform: booleanAttribute })
99
    public set indeterminate(isIndeterminate: boolean) {
UNCOV
100
        this._indeterminate = isIndeterminate;
×
UNCOV
101
        this._resetCounterValues(this._indeterminate); // Use the helper for indeterminate condition
×
102
    }
103

104
    /**
105
     * Gets the current state of the progress bar:
106
     * - `true` if in the indeterminate state (no progress value displayed),
107
     * - `false` if the progress bar shows the actual progress.
108
     *
109
     * ```typescript
110
     * const isIndeterminate = progressBar.indeterminate;
111
     * ```
112
    */
113
    public get indeterminate(): boolean {
UNCOV
114
        return this._indeterminate;
×
115
    }
116

117
    /**
118
     * Returns the value which update the progress indicator of the `progress bar`.
119
     * ```typescript
120
     * @ViewChild("MyProgressBar")
121
     * public progressBar: IgxLinearProgressBarComponent | IgxCircularBarComponent;
122
     * public stepValue(event) {
123
     *     let step = this.progressBar.step;
124
     *     alert(step);
125
     * }
126
     * ```
127
     */
128
    @Input()
129
    public get step(): number {
UNCOV
130
        if (this._step) {
×
UNCOV
131
            return this._step;
×
132
        }
UNCOV
133
        return this._max * ONE_PERCENT;
×
134
    }
135

136
    /**
137
     * Sets the value by which progress indicator is updated. By default, it is 1.
138
     * ```html
139
     * <igx-linear-bar [step]="1"></igx-linear-bar>
140
     * <igx-circular-bar [step]="1"></igx-circular-bar>
141
     * ```
142
     */
143
    public set step(val: number) {
UNCOV
144
        const step = Number(val);
×
UNCOV
145
        if (step > this.max) {
×
UNCOV
146
            return;
×
147
        }
148

UNCOV
149
        this._step = step;
×
150
    }
151

152

153
    /**
154
     * Set a custom text. This will hide the counter value.
155
     * ```html
156
     * <igx-circular-bar text="my text"></igx-circular-bar>
157
     * ```
158
     */
159
    @Input()
160
    public set text(value: string) {
UNCOV
161
        this._text = value;
×
UNCOV
162
        this._resetCounterValues(!!this._text); // Use the helper for text condition
×
163
    }
164

165
    /**
166
     * Gets a custom text.
167
     * ```typescript
168
     * let text = this.circularBar.text;
169
     * ```
170
     */
171
    public get text(): string {
UNCOV
172
        return this._text;
×
173
    }
174

175
    /**
176
     * Animating the progress. By default, it is set to true.
177
     * ```html
178
     * <igx-linear-bar [animate]="false"></igx-linear-bar>
179
     * <igx-circular-bar [animate]="false"></igx-circular-bar>
180
     * ```
181
     */
182
    @Input({ transform: booleanAttribute })
183
    public set animate(animate: boolean) {
UNCOV
184
        this._animate = animate;
×
185
    }
186

187
    /**
188
     * Returns whether the `progress bar` has animation true/false.
189
     * ```typescript
190
     * @ViewChild("MyProgressBar")
191
     * public progressBar: IgxLinearProgressBarComponent | IgxCircularBarComponent;
192
     * public animationStatus(event) {
193
     *     let animationStatus = this.progressBar.animate;
194
     *     alert(animationStatus);
195
     * }
196
     * ```
197
     */
198
    public get animate(): boolean {
UNCOV
199
        return this._animate;
×
200
    }
201

202
    /**
203
     * Set maximum value that can be passed. By default it is set to 100.
204
     * ```html
205
     * <igx-linear-bar [max]="200"></igx-linear-bar>
206
     * <igx-circular-bar [max]="200"></igx-circular-bar>
207
     * ```
208
     */
209
    @HostBinding('attr.aria-valuemax')
210
    @Input()
211
    public set max(maxNum: number) {
212
        // Ignore invalid or unchanged max
UNCOV
213
        if (maxNum < MIN_VALUE || this._max === maxNum) {
×
UNCOV
214
            return;
×
215
        }
216

UNCOV
217
        this._max = maxNum;
×
218

219
        // Revalidate current value
UNCOV
220
        this._value = valueInRange(this._value, this._max);
×
221

222
        // Refresh CSS variables
UNCOV
223
        this._updateProgressValues();
×
224
    }
225

226
    /**
227
     * Returns the maximum progress value of the `progress bar`.
228
     * ```typescript
229
     * @ViewChild("MyProgressBar")
230
     * public progressBar: IgxLinearProgressBarComponent | IgxCircularBarComponent;
231
     * public maxValue(event) {
232
     *     let max = this.progressBar.max;
233
     *     alert(max);
234
     * }
235
     * ```
236
     */
237
    public get max() {
UNCOV
238
        return this._max;
×
239
    }
240

241
    @HostBinding('style.--_progress-integer')
242
    private get progressInteger() {
UNCOV
243
        return this._integer.toString();
×
244
    }
245

246
    @HostBinding('style.--_progress-fraction')
247
    private get progressFraction() {
UNCOV
248
        return this._fraction.toString();
×
249
    }
250

251
    @HostBinding('style.--_progress-whole')
252
    private get progressWhole() {
UNCOV
253
        return this.valueInPercent.toFixed(2);
×
254
    }
255

256
    @HostBinding('style.--_transition-duration')
257
    private get transitionDuration() {
UNCOV
258
        return `${this.animationDuration}ms`;
×
259
    }
260

261
    /**
262
     * @hidden
263
     */
264
    protected get hasFraction(): boolean {
UNCOV
265
        const percentage = this.valueInPercent;
×
UNCOV
266
        const integerPart = Math.floor(percentage);
×
UNCOV
267
        const fractionalPart = percentage - integerPart;
×
268

UNCOV
269
        return fractionalPart > 0;
×
270
    }
271

272
    /**
273
     * Returns the `IgxLinearProgressBarComponent`/`IgxCircularProgressBarComponent` value in percentage.
274
     * ```typescript
275
     * @ViewChild("MyProgressBar")
276
     * public progressBar: IgxLinearProgressBarComponent / IgxCircularProgressBarComponent
277
     * public valuePercent(event){
278
     *     let percentValue = this.progressBar.valueInPercent;
279
     *     alert(percentValue);
280
     * }
281
     * ```
282
     */
283
    public get valueInPercent(): number {
UNCOV
284
        const result = this.max > 0 ? (this._value / this.max) * 100 : 0;
×
UNCOV
285
        return Math.round(result * 100) / 100; // Round to two decimal places
×
286
    }
287

288
    /**
289
     * Returns value that indicates the current `IgxLinearProgressBarComponent`/`IgxCircularProgressBarComponent` position.
290
     * ```typescript
291
     * @ViewChild("MyProgressBar")
292
     * public progressBar: IgxLinearProgressBarComponent / IgxCircularProgressBarComponent;
293
     * public getValue(event) {
294
     *     let value = this.progressBar.value;
295
     *     alert(value);
296
     * }
297
     * ```
298
     */
299
    @HostBinding('attr.aria-valuenow')
300
    @Input()
301
    public get value(): number {
UNCOV
302
        return this._value;
×
303
    }
304

305
    /**
306
     * @hidden
307
     */
308
    protected _updateProgressValues(): void {
UNCOV
309
        const percentage = this.valueInPercent;
×
UNCOV
310
        const integerPart = Math.floor(percentage);
×
UNCOV
311
        const fractionalPart = Math.round((percentage % 1) * 100);
×
312

UNCOV
313
        this._integer = integerPart;
×
UNCOV
314
        this._fraction = fractionalPart;
×
315
    }
316

317
    private _resetCounterValues(condition: boolean) {
UNCOV
318
        if (condition) {
×
UNCOV
319
            this._integer = 0;
×
UNCOV
320
            this._fraction = 0;
×
321
        } else {
UNCOV
322
            this._zone.runOutsideAngular(() => {
×
UNCOV
323
                setTimeout(() => {
×
UNCOV
324
                    this._updateProgressValues();
×
UNCOV
325
                    this._cdr.markForCheck();
×
326
                });
327
            });
328
        }
329
    }
330

331
    /**
332
     * Set value that indicates the current `IgxLinearProgressBarComponent / IgxCircularProgressBarComponent` position.
333
     * ```html
334
     * <igx-linear-bar [value]="50"></igx-linear-bar>
335
     * <igx-circular-bar [value]="50"></igx-circular-bar>
336
     * ```
337
     */
338
    public set value(val) {
UNCOV
339
        const valInRange = valueInRange(val, this.max); // Ensure value is in range
×
340

341
        // Avoid redundant updates
UNCOV
342
        if (isNaN(valInRange) || this._value === valInRange) {
×
UNCOV
343
            return;
×
344
        }
345

UNCOV
346
        const previousValue = this._value;
×
347

348
        // Update internal value
UNCOV
349
        this._value = valInRange;
×
350

UNCOV
351
        this._zone.runOutsideAngular(() => {
×
UNCOV
352
            setTimeout(() => {
×
UNCOV
353
                this._updateProgressValues();
×
UNCOV
354
                this._cdr.markForCheck();
×
355
            });
356
        });
357

358
        // Emit the progressChanged event
UNCOV
359
        this.progressChanged.emit({
×
360
            previousValue,
361
            currentValue: this._value,
362
        });
363
    }
364
}
365
let NEXT_LINEAR_ID = 0;
3✔
366
let NEXT_CIRCULAR_ID = 0;
3✔
367
let NEXT_GRADIENT_ID = 0;
3✔
368
@Component({
369
    selector: 'igx-linear-bar',
370
    templateUrl: 'templates/linear-bar.component.html',
371
    imports: [NgClass]
372
})
373
export class IgxLinearProgressBarComponent extends BaseProgressDirective implements AfterContentInit {
3✔
374
    @HostBinding('attr.aria-valuemin')
UNCOV
375
    public valueMin = 0;
×
376

377
    @HostBinding('class.igx-linear-bar')
UNCOV
378
    public cssClass = 'igx-linear-bar';
×
379

380
    /**
381
     * Set `IgxLinearProgressBarComponent` to have striped style. By default it is set to false.
382
     * ```html
383
     * <igx-linear-bar [striped]="true" [max]="200" [value]="50"></igx-linear-bar>
384
     * ```
385
     */
386
    @HostBinding('class.igx-linear-bar--striped')
387
    @Input({ transform: booleanAttribute })
UNCOV
388
    public striped = false;
×
389

390
    /**
391
     * @hidden
392
     * ```
393
     */
394
    @HostBinding('class.igx-linear-bar--indeterminate')
395
    public get isIndeterminate() {
UNCOV
396
        return this.indeterminate;
×
397
    }
398

399
    /**
400
     * Sets the value of the `role` attribute. If not provided it will be automatically set to `progressbar`.
401
     * ```html
402
     * <igx-linear-bar role="progressbar"></igx-linear-bar>
403
     * ```
404
     */
405
    @HostBinding('attr.role')
406
    @Input()
UNCOV
407
    public role = 'progressbar';
×
408

409
    /**
410
     * Sets the value of `id` attribute. If not provided it will be automatically generated.
411
     * ```html
412
     * <igx-linear-bar [id]="'igx-linear-bar-55'" [striped]="true" [max]="200" [value]="50"></igx-linear-bar>
413
     * ```
414
     */
415
    @HostBinding('attr.id')
416
    @Input()
UNCOV
417
    public id = `igx-linear-bar-${NEXT_LINEAR_ID++}`;
×
418

419
    /**
420
     * @hidden
421
     */
422
    @HostBinding('class.igx-linear-bar--animation-none')
423
    public get disableAnimationClass(): boolean {
UNCOV
424
        return !this._animate;
×
425
    }
426

427
    /**
428
     * @hidden
429
     */
430
    @HostBinding('class.igx-linear-bar--hide-counter')
431
    public get hasText(): boolean {
UNCOV
432
        return !!this.text;
×
433
    }
434

435
    /**
436
     * Set the position that defines where the text is aligned.
437
     * Possible options - `IgxTextAlign.START` (default), `IgxTextAlign.CENTER`, `IgxTextAlign.END`.
438
     * ```typescript
439
     * public positionCenter: IgxTextAlign;
440
     * public ngOnInit() {
441
     *     this.positionCenter = IgxTextAlign.CENTER;
442
     * }
443
     *  //...
444
     * ```
445
     *  ```html
446
     * <igx-linear-bar [textAlign]="positionCenter"></igx-linear-bar>
447
     * ```
448
     */
449
    @Input()
UNCOV
450
    public textAlign: IgxTextAlign = IgxTextAlign.START;
×
451

452
    /**
453
     * Set the text to be visible. By default, it is set to true.
454
     * ```html
455
     *  <igx-linear-bar [textVisibility]="false"></igx-linear-bar>
456
     * ```
457
     */
458
    @Input({ transform: booleanAttribute })
UNCOV
459
    public textVisibility = true;
×
460

461
    /**
462
     * Set the position that defines if the text should be aligned above the progress line. By default, is set to false.
463
     * ```html
464
     *  <igx-linear-bar [textTop]="true"></igx-linear-bar>
465
     * ```
466
     */
467
    @Input({ transform: booleanAttribute })
UNCOV
468
    public textTop = false;
×
469

470
    /**
471
     * Set type of the `IgxLinearProgressBarComponent`. Possible options - `default`, `success`, `info`, `warning`, and `error`.
472
     * ```html
473
     * <igx-linear-bar [type]="'error'"></igx-linear-bar>
474
     * ```
475
     */
476
    @Input()
UNCOV
477
    public type = 'default';
×
478

479
    /**
480
     * @hidden
481
     */
482
    @HostBinding('class.igx-linear-bar--danger')
483
    public get error() {
UNCOV
484
        return this.type === IgxProgressType.ERROR;
×
485
    }
486

487
    /**
488
     * @hidden
489
     */
490
    @HostBinding('class.igx-linear-bar--info')
491
    public get info() {
UNCOV
492
        return this.type === IgxProgressType.INFO;
×
493
    }
494

495
    /**
496
     * @hidden
497
     */
498
    @HostBinding('class.igx-linear-bar--warning')
499
    public get warning() {
UNCOV
500
        return this.type === IgxProgressType.WARNING;
×
501
    }
502

503
    /**
504
     * @hidden
505
     */
506
    @HostBinding('class.igx-linear-bar--success')
507
    public get success() {
UNCOV
508
        return this.type === IgxProgressType.SUCCESS;
×
509
    }
510

511
    public ngAfterContentInit() {
UNCOV
512
        this._contentInit = true;
×
513
    }
514
}
515

516
@Component({
517
    selector: 'igx-circular-bar',
518
    templateUrl: 'templates/circular-bar.component.html',
519
    imports: [NgTemplateOutlet, NgClass]
520
})
521
export class IgxCircularProgressBarComponent extends BaseProgressDirective implements AfterContentInit {
3✔
UNCOV
522
    private renderer = inject(Renderer2);
×
523

524
    /**
525
     * @hidden
526
     */
527
    @HostBinding('class.igx-circular-bar')
UNCOV
528
    public cssClass = 'igx-circular-bar';
×
529

530
    /**
531
     * Sets the value of `id` attribute. If not provided it will be automatically generated.
532
     * ```html
533
     * <igx-circular-bar [id]="'igx-circular-bar-55'"></igx-circular-bar>
534
     * ```
535
     */
536
    @HostBinding('attr.id')
537
    @Input()
UNCOV
538
    public id = `igx-circular-bar-${NEXT_CIRCULAR_ID++}`;
×
539

540
    /**
541
     * @hidden
542
     */
543
    @HostBinding('class.igx-circular-bar--indeterminate')
544
    public get isIndeterminate() {
UNCOV
545
        return this.indeterminate;
×
546
    }
547

548
    /**
549
     * @hidden
550
     */
551
    @HostBinding('class.igx-circular-bar--animation-none')
552
    public get disableAnimationClass(): boolean {
UNCOV
553
        return !this._animate;
×
554
    }
555

556
    /**
557
     * @hidden
558
     */
559
    @HostBinding('class.igx-circular-bar--hide-counter')
560
    public get hasText(): boolean {
UNCOV
561
        return !!this.text;
×
562
    }
563

564
    /**
565
     * Sets the text visibility. By default, it is set to true.
566
     * ```html
567
     * <igx-circular-bar [textVisibility]="false"></igx-circular-bar>
568
     * ```
569
     */
570
    @Input({ transform: booleanAttribute })
UNCOV
571
    public textVisibility = true;
×
572

573
    @ContentChild(IgxProgressBarTextTemplateDirective, { read: IgxProgressBarTextTemplateDirective })
574
    public textTemplate: IgxProgressBarTextTemplateDirective;
575

576
    @ContentChild(IgxProgressBarGradientDirective, { read: IgxProgressBarGradientDirective })
577
    public gradientTemplate: IgxProgressBarGradientDirective;
578

579
    @ViewChild('circle', { static: true })
580
    private _svgCircle: ElementRef;
581

582
    /**
583
     * @hidden
584
     */
UNCOV
585
    public gradientId = `igx-circular-gradient-${NEXT_GRADIENT_ID++}`;
×
586

587
    /**
588
     * @hidden
589
     */
590
    public get context(): any {
UNCOV
591
        return {
×
592
            $implicit: { value: this.value, valueInPercent: this.valueInPercent, max: this.max }
593
        };
594
    }
595

596
    /**
597
     * @hidden
598
     */
599
    public get textContent(): string {
UNCOV
600
        return this.text;
×
601
    }
602

603
    /**
604
     * Set type of the `IgxCircularProgressBarComponent`. Possible options - `default`, `success`, `info`, `warning`, and `error`.
605
     * ```html
606
     * <igx-circular-bar [type]="'error'"></igx-circular-bar>
607
     * ```
608
     */
609
    @Input()
UNCOV
610
    public type = 'default';
×
611

612
    /**
613
     * @hidden
614
     */
615
    @HostBinding('class.igx-circular-bar--danger')
616
    public get error() {
UNCOV
617
        return this.type === IgxProgressType.ERROR;
×
618
    }
619

620
    /**
621
     * @hidden
622
     */
623
    @HostBinding('class.igx-circular-bar--info')
624
    public get info() {
UNCOV
625
        return this.type === IgxProgressType.INFO;
×
626
    }
627

628
    /**
629
     * @hidden
630
     */
631
    @HostBinding('class.igx-circular-bar--warning')
632
    public get warning() {
UNCOV
633
        return this.type === IgxProgressType.WARNING;
×
634
    }
635

636
    /**
637
     * @hidden
638
     */
639
    @HostBinding('class.igx-circular-bar--success')
640
    public get success() {
UNCOV
641
        return this.type === IgxProgressType.SUCCESS;
×
642
    }
643

644
    /**
645
     * @hidden
646
     */
647
    @HostBinding('style.stroke')
648
    public get strokeStyle() {
UNCOV
649
        return this.type === 'default' ? `url(#${this.gradientId})` : 'none';
×
650
    }
651

652
    public ngAfterContentInit() {
UNCOV
653
        this._contentInit = true;
×
654
    }
655

656
}
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