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

IgniteUI / igniteui-angular / 28358286454

29 Jun 2026 08:17AM UTC coverage: 90.127% (-0.05%) from 90.174%
28358286454

Pull #17246

github

web-flow
Merge 21687d939 into 07bdcd752
Pull Request #17246: fix(pivot-grid): fix date format based on the localization

14921 of 17392 branches covered (85.79%)

Branch coverage included in aggregate %.

29 of 32 new or added lines in 4 files covered. (90.63%)

735 existing lines in 76 files now uncovered.

29992 of 32441 relevant lines covered (92.45%)

34632.46 hits per line

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

95.77
/projects/igniteui-angular/list/src/list/list.component.ts
1
import { NgTemplateOutlet } from '@angular/common';
2
import {
3
  Component,
4
  ContentChild,
5
  ContentChildren,
6
  ElementRef,
7
  EventEmitter,
8
  forwardRef,
9
  HostBinding,
10
  Input,
11
  Output,
12
  QueryList,
13
  TemplateRef,
14
  ViewChild,
15
  Directive,
16
  booleanAttribute,
17
  inject,
18
  DestroyRef,
19
  ChangeDetectionStrategy
20
} from '@angular/core';
21

22

23

24
import { IgxListItemComponent } from './list-item.component';
25
import {
26
    IgxListBaseDirective,
27
    IgxDataLoadingTemplateDirective,
28
    IgxEmptyListTemplateDirective,
29
    IgxListPanState,
30
    IgxListItemLeftPanningTemplateDirective,
31
    IgxListItemRightPanningTemplateDirective
32
} from './list.common';
33
import { IBaseEventArgs } from 'igniteui-angular/core';
34
import { IListResourceStrings, ListResourceStringsEN } from 'igniteui-angular/core';
35
import { getCurrentResourceStrings, onResourceChangeHandle } from 'igniteui-angular/core';
36

37
let NEXT_ID = 0;
3✔
38

39
/**
40
 * Interface for the panStateChange igxList event arguments
41
 */
42
export interface IPanStateChangeEventArgs extends IBaseEventArgs {
43
    oldState: IgxListPanState;
44
    newState: IgxListPanState;
45
    item: IgxListItemComponent;
46
}
47

48
/**
49
 * Interface for the listItemClick igxList event arguments
50
 */
51
export interface IListItemClickEventArgs extends IBaseEventArgs {
52
    item: IgxListItemComponent;
53
    event: Event;
54
    direction: IgxListPanState;
55
}
56

57
/**
58
 * Interface for the listItemPanning igxList event arguments
59
 */
60
export interface IListItemPanningEventArgs extends IBaseEventArgs {
61
    item: IgxListItemComponent;
62
    direction: IgxListPanState;
63
    keepItem: boolean;
64
}
65

66
/**
67
 * igxListThumbnail is container for the List media
68
 * Use it to wrap anything you want to be used as a thumbnail.
69
 */
70
@Directive({
71
    selector: '[igxListThumbnail]',
72
    standalone: true
73
})
74
export class IgxListThumbnailDirective { }
3✔
75

76
/**
77
 * igxListAction is container for the List action
78
 * Use it to wrap anything you want to be used as a list action: icon, checkbox...
79
 */
80
@Directive({
81
    selector: '[igxListAction]',
82
    standalone: true
83
})
84
export class IgxListActionDirective { }
3✔
85

86
/**
87
 * igxListLine is container for the List text content
88
 * Use it to wrap anything you want to be used as a plane text.
89
 */
90
@Directive({
91
    selector: '[igxListLine]',
92
    standalone: true
93
})
94
export class IgxListLineDirective { }
3✔
95

96
/**
97
 * igxListLineTitle is a directive that add class to the target element
98
 * Use it to make anything to look like list Title.
99
 */
100
@Directive({
101
    selector: '[igxListLineTitle]',
102
    standalone: true
103
})
104
export class IgxListLineTitleDirective {
3✔
105
    @HostBinding('class.igx-list__item-line-title')
106
    public cssClass = 'igx-list__item-line-title';
5✔
107
}
108

109
/**
110
 * igxListLineSubTitle is a directive that add class to the target element
111
 * Use it to make anything to look like list Subtitle.
112
 */
113
@Directive({
114
    selector: '[igxListLineSubTitle]',
115
    standalone: true
116
})
117
export class IgxListLineSubTitleDirective {
3✔
118
    @HostBinding('class.igx-list__item-line-subtitle')
119
    public cssClass = 'igx-list__item-line-subtitle';
5✔
120
}
121

122
/**
123
 * Displays a collection of data items in a templatable list format
124
 *
125
 * @igxModule IgxListModule
126
 *
127
 * @igxTheme igx-list-theme
128
 *
129
 * @igxKeywords list, data
130
 *
131
 * @igxGroup Grids & Lists
132
 *
133
 * @remarks
134
 * The Ignite UI List displays rows of items and supports one or more header items as well as search and filtering
135
 * of list items. Each list item is completely templatable and will support any valid HTML or Angular component.
136
 *
137
 * @example
138
 * ```html
139
 * <igx-list>
140
 *   <igx-list-item isHeader="true">Contacts</igx-list-item>
141
 *   <igx-list-item *ngFor="let contact of contacts">
142
 *     <span class="name">{{ contact.name }}</span>
143
 *     <span class="phone">{{ contact.phone }}</span>
144
 *   </igx-list-item>
145
 * </igx-list>
146
 * ```
147
 */
148
@Component({
149
    selector: 'igx-list',
150
    templateUrl: 'list.component.html',
151
    providers: [{ provide: IgxListBaseDirective, useExisting: IgxListComponent }],
152
    changeDetection: ChangeDetectionStrategy.Eager,
153
    imports: [NgTemplateOutlet]
154
})
155
export class IgxListComponent extends IgxListBaseDirective {
3✔
156
    public element = inject(ElementRef);
892✔
157
    private destroyRef = inject(DestroyRef);
892✔
158

159
    /**
160
     * Returns a collection of all items and headers in the list.
161
     *
162
     * @example
163
     * ```typescript
164
     * let listChildren: QueryList = this.list.children;
165
     * ```
166
     */
167
    @ContentChildren(forwardRef(() => IgxListItemComponent), { descendants: true })
6✔
168
    public override children: QueryList<IgxListItemComponent>;
169

170
    /**
171
     * Sets/gets the empty list template.
172
     *
173
     * @remarks
174
     * This template is used by list in case there are no list items
175
     * defined and `isLoading` is set to `false`.
176
     *
177
     * @example
178
     * ```html
179
     * <igx-list>
180
     *   <ng-template igxEmptyList>
181
     *     <p class="empty">No contacts! :(</p>
182
     *   </ng-template>
183
     * </igx-list>
184
     * ```
185
     * ```typescript
186
     * let emptyTemplate = this.list.emptyListTemplate;
187
     * ```
188
     */
189
    @ContentChild(IgxEmptyListTemplateDirective, { read: IgxEmptyListTemplateDirective })
190
    public emptyListTemplate: IgxEmptyListTemplateDirective;
191

192
    /**
193
     * Sets/gets the list loading template.
194
     *
195
     * @remarks
196
     * This template is used by list in case there are no list items defined and `isLoading` is set to `true`.
197
     *
198
     * @example
199
     * ```html
200
     * <igx-list>
201
     *   <ng-template igxDataLoading>
202
     *     <p>Patience, we are currently loading your data...</p>
203
     *   </ng-template>
204
     * </igx-list>
205
     * ```
206
     * ```typescript
207
     * let loadingTemplate = this.list.dataLoadingTemplate;
208
     * ```
209
     */
210
    @ContentChild(IgxDataLoadingTemplateDirective, { read: IgxDataLoadingTemplateDirective })
211
    public dataLoadingTemplate: IgxDataLoadingTemplateDirective;
212

213
    /**
214
     * Sets/gets the template for left panning a list item.
215
     *
216
     * @remarks
217
     * Default value is `null`.
218
     *
219
     * @example
220
     * ```html
221
     * <igx-list [allowLeftPanning]="true">
222
     *   <ng-template igxListItemLeftPanning>
223
     *     <igx-icon>delete</igx-icon>Delete
224
     *   </ng-template>
225
     * </igx-list>
226
     * ```
227
     * ```typescript
228
     * let itemLeftPanTmpl = this.list.listItemLeftPanningTemplate;
229
     * ```
230
     */
231
    @ContentChild(IgxListItemLeftPanningTemplateDirective, { read: IgxListItemLeftPanningTemplateDirective })
232
    public override listItemLeftPanningTemplate: IgxListItemLeftPanningTemplateDirective;
233

234
    /**
235
     * Sets/gets the template for right panning a list item.
236
     *
237
     * @remarks
238
     * Default value is `null`.
239
     *
240
     * @example
241
     * ```html
242
     * <igx-list [allowRightPanning] = "true">
243
     *   <ng-template igxListItemRightPanning>
244
     *     <igx-icon>call</igx-icon>Dial
245
     *   </ng-template>
246
     * </igx-list>
247
     * ```
248
     * ```typescript
249
     * let itemRightPanTmpl = this.list.listItemRightPanningTemplate;
250
     * ```
251
     */
252
    @ContentChild(IgxListItemRightPanningTemplateDirective, { read: IgxListItemRightPanningTemplateDirective })
253
    public override listItemRightPanningTemplate: IgxListItemRightPanningTemplateDirective;
254

255
    /**
256
     * Provides a threshold after which the item's panning will be completed automatically.
257
     *
258
     * @remarks
259
     * By default this property is set to 0.5 which is 50% of the list item's width.
260
     *
261
     * @example
262
     * ```html
263
     * <igx-list [panEndTriggeringThreshold]="0.8"></igx-list>
264
     * ```
265
     */
266
    @Input()
267
    public override panEndTriggeringThreshold = 0.5;
892✔
268

269
    /**
270
     * Sets/gets the `id` of the list.
271
     *
272
     * @remarks
273
     * If not set, the `id` of the first list component will be `"igx-list-0"`.
274
     *
275
     * @example
276
     * ```html
277
     * <igx-list id="my-first-list"></igx-list>
278
     * ```
279
     * ```typescript
280
     * let listId = this.list.id;
281
     * ```
282
     */
283
    @HostBinding('attr.id')
284
    @Input()
285
    public id = `igx-list-${NEXT_ID++}`;
892✔
286

287
    /**
288
     * Sets/gets whether the left panning of an item is allowed.
289
     *
290
     * @remarks
291
     * Default value is `false`.
292
     *
293
     * @example
294
     * ```html
295
     * <igx-list [allowLeftPanning]="true"></igx-list>
296
     * ```
297
     * ```typescript
298
     * let isLeftPanningAllowed = this.list.allowLeftPanning;
299
     * ```
300
     */
301
    @Input({ transform: booleanAttribute })
302
    public override allowLeftPanning = false;
892✔
303

304
    /**
305
     * Sets/gets whether the right panning of an item is allowed.
306
     *
307
     * @remarks
308
     * Default value is `false`.
309
     *
310
     * @example
311
     * ```html
312
     * <igx-list [allowRightPanning]="true"></igx-list>
313
     * ```
314
     * ```typescript
315
     * let isRightPanningAllowed = this.list.allowRightPanning;
316
     * ```
317
     */
318
    @Input({ transform: booleanAttribute })
319
    public override allowRightPanning = false;
892✔
320

321
    /**
322
     * Sets/gets whether the list is currently loading data.
323
     *
324
     * @remarks
325
     * Set it to display the dataLoadingTemplate while data is being retrieved.
326
     * Default value is `false`.
327
     *
328
     * @example
329
     * ```html
330
     *  <igx-list [isLoading]="true"></igx-list>
331
     * ```
332
     * ```typescript
333
     * let isLoading = this.list.isLoading;
334
     * ```
335
     */
336
    @Input({ transform: booleanAttribute })
337
    public isLoading = false;
892✔
338

339
    /**
340
     * Event emitted when a left pan gesture is executed on a list item.
341
     *
342
     * @remarks
343
     * Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
344
     *
345
     * @example
346
     * ```html
347
     * <igx-list [allowLeftPanning]="true" (leftPan)="leftPan($event)"></igx-list>
348
     * ```
349
     */
350
    @Output()
351
    public override leftPan = new EventEmitter<IListItemPanningEventArgs>();
892✔
352

353
    /**
354
     * Event emitted when a right pan gesture is executed on a list item.
355
     *
356
     * @remarks
357
     * Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
358
     *
359
     * @example
360
     * ```html
361
     * <igx-list [allowRightPanning]="true" (rightPan)="rightPan($event)"></igx-list>
362
     * ```
363
     */
364
    @Output()
365
    public override rightPan = new EventEmitter<IListItemPanningEventArgs>();
892✔
366

367
    /**
368
     * Event emitted when a pan gesture is started.
369
     *
370
     * @remarks
371
     * Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
372
     *
373
     * @example
374
     * ```html
375
     * <igx-list (startPan)="startPan($event)"></igx-list>
376
     * ```
377
     */
378
    @Output()
379
    public override startPan = new EventEmitter<IListItemPanningEventArgs>();
892✔
380

381
    /**
382
     * Event emitted when a pan gesture is completed or canceled.
383
     *
384
     * @remarks
385
     * Provides a reference to an object of type `IListItemPanningEventArgs` as an event argument.
386
     *
387
     * @example
388
     * ```html
389
     * <igx-list (endPan)="endPan($event)"></igx-list>
390
     * ```
391
     */
392
    @Output()
393
    public override endPan = new EventEmitter<IListItemPanningEventArgs>();
892✔
394

395
    /**
396
     * Event emitted when a pan item is returned to its original position.
397
     *
398
     * @remarks
399
     * Provides a reference to an object of type list as an event argument.
400
     *
401
     * @example
402
     * ```html
403
     * <igx-list (resetPan)="resetPan($event)"></igx-list>
404
     * ```
405
     */
406
    @Output()
407
    public override resetPan = new EventEmitter<IgxListComponent>();
892✔
408

409
    /**
410
     *
411
     * Event emitted when a pan gesture is executed on a list item.
412
     *
413
     * @remarks
414
     * Provides references to the list item and list pan state as event arguments.
415
     *
416
     * @example
417
     * ```html
418
     * <igx-list (panStateChange)="panStateChange($event)"></igx-list>
419
     * ```
420
     */
421
    @Output()
422
    public override panStateChange = new EventEmitter<IPanStateChangeEventArgs>();
892✔
423

424
    /**
425
     * Event emitted when a list item is clicked.
426
     *
427
     * @remarks
428
     * Provides references to the list item and `Event` as event arguments.
429
     *
430
     * @example
431
     * ```html
432
     * <igx-list (itemClicked)="onItemClicked($event)"></igx-list>
433
     * ```
434
     */
435
    @Output()
436
    public override itemClicked = new EventEmitter<IListItemClickEventArgs>();
892✔
437

438
    /**
439
     * @hidden
440
     * @internal
441
     */
442
    @ViewChild('defaultEmptyList', { read: TemplateRef, static: true })
443
    protected defaultEmptyListTemplate: TemplateRef<any>;
444

445
    /**
446
     * @hidden
447
     * @internal
448
     */
449
    @ViewChild('defaultDataLoading', { read: TemplateRef, static: true })
450
    protected defaultDataLoadingTemplate: TemplateRef<any>;
451

452
    private _resourceStrings: IListResourceStrings = null;
892✔
453
    private _defaultResourceStrings = getCurrentResourceStrings(ListResourceStringsEN);
892✔
454

455
    /**
456
     * Sets the resource strings.
457
     * By default it uses EN resources.
458
     */
459
    @Input()
460
    public set resourceStrings(value: IListResourceStrings) {
UNCOV
461
        this._resourceStrings = Object.assign({}, this._resourceStrings, value);
×
462
    }
463

464
    /**
465
     * Returns the resource strings.
466
     */
467
    public get resourceStrings(): IListResourceStrings {
468
        return this._resourceStrings || this._defaultResourceStrings;
21✔
469
    }
470

471
    constructor() {
472
        super();
892✔
473
        onResourceChangeHandle(this.destroyRef, () => {
892✔
UNCOV
474
            this._defaultResourceStrings = getCurrentResourceStrings(ListResourceStringsEN, false);
×
475
        }, this);
476
    }
477

478
    /**
479
     * @hidden
480
     * @internal
481
     */
482
    protected get sortedChildren(): IgxListItemComponent[] {
483
        if (this.children !== undefined) {
91✔
484
            return this.children.toArray()
91✔
485
                .sort((a: IgxListItemComponent, b: IgxListItemComponent) => a.index - b.index);
332✔
486
        }
UNCOV
487
        return null;
×
488
    }
489

490
    private _role = 'list';
892✔
491

492
    /**
493
     * Gets/Sets the `role` attribute value.
494
     *
495
     * @example
496
     * ```typescript
497
     * let listRole =  this.list.role;
498
     * ```
499
     */
500
    @HostBinding('attr.role')
501
    @Input()
502
    public get role() {
503
        return this._role;
10,887✔
504
    }
505

506
    public set role(val: string) {
507
        this._role = val;
533✔
508
    }
509

510
    /**
511
     * Gets a boolean indicating if the list is empty.
512
     *
513
     * @example
514
     * ```typescript
515
     * let isEmpty =  this.list.isListEmpty;
516
     * ```
517
     */
518
    @HostBinding('class.igx-list--empty')
519
    public get isListEmpty(): boolean {
520
        return !this.children || this.children.length === 0;
21,786✔
521
    }
522

523
    /**
524
     * @hidden
525
     * @internal
526
     */
527
    @HostBinding('class.igx-list')
528
    public get cssClass(): boolean {
529
        return !this.isListEmpty;
10,893✔
530
    }
531

532
    /**
533
     * Gets the list `items` excluding the header ones.
534
     *
535
     * @example
536
     * ```typescript
537
     * let listItems: IgxListItemComponent[] = this.list.items;
538
     * ```
539
     */
540
    public get items(): IgxListItemComponent[] {
541
        const items: IgxListItemComponent[] = [];
96✔
542
        if (this.children !== undefined) {
96✔
543
            for (const child of this.sortedChildren) {
91✔
544
                if (!child.isHeader) {
327✔
545
                    items.push(child);
258✔
546
                }
547
            }
548
        }
549
        return items;
96✔
550
    }
551

552
    /**
553
     * Gets the header list `items`.
554
     *
555
     * @example
556
     * ```typescript
557
     * let listHeaders: IgxListItemComponent[] =  this.list.headers;
558
     * ```
559
     */
560
    public get headers(): IgxListItemComponent[] {
561
        const headers: IgxListItemComponent[] = [];
11✔
562
        if (this.children !== undefined) {
11✔
563
            for (const child of this.children.toArray()) {
9✔
564
                if (child.isHeader) {
38✔
565
                    headers.push(child);
11✔
566
                }
567
            }
568
        }
569
        return headers;
11✔
570
    }
571

572
    /**
573
     * Gets the `context` object of the template binding.
574
     *
575
     * @remarks
576
     * Gets the `context` object which represents the `template context` binding into the `list container`
577
     * by providing the `$implicit` declaration which is the list itself.
578
     *
579
     * @example
580
     * ```typescript
581
     * let listComponent =  this.list.context;
582
     * ```
583
     */
584
    public get context(): any {
585
        return {
7,259✔
586
            $implicit: this
587
        };
588
    }
589

590
    /**
591
     * Gets a `TemplateRef` to the currently used template.
592
     *
593
     * @example
594
     * ```typescript
595
     * let listTemplate = this.list.template;
596
     * ```
597
     */
598
    public get template(): TemplateRef<any> {
599
        if (this.isLoading) {
7,259✔
600
            return this.dataLoadingTemplate ? this.dataLoadingTemplate.template : this.defaultDataLoadingTemplate;
7,122✔
601
        } else {
602
            return this.emptyListTemplate ? this.emptyListTemplate.template : this.defaultEmptyListTemplate;
137✔
603
        }
604
    }
605
}
606

607
/**
608
 * @hidden
609
 */
610

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc