• 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

89.78
/projects/igniteui-angular/src/lib/chips/chip.component.ts
1
import {
2
    Component,
3
    ChangeDetectorRef,
4
    EventEmitter,
5
    ElementRef,
6
    HostBinding,
7
    HostListener,
8
    Input,
9
    Output,
10
    ViewChild,
11
    Renderer2,
12
    TemplateRef,
2✔
13
    Inject,
14
    Optional,
15
    OnDestroy
16
} from '@angular/core';
17
import { IDisplayDensityOptions, DisplayDensityToken, DisplayDensity, DisplayDensityBase } from '../core/density';
18
import { IgxDragDirective, IDragBaseEventArgs, IDragStartEventArgs, IDropBaseEventArgs, IDropDroppedEventArgs, IgxDropDirective } from '../directives/drag-drop/drag-drop.directive';
19
import { IBaseEventArgs, mkenum } from '../core/utils';
2✔
20
import { ChipResourceStringsEN, IChipResourceStrings } from '../core/i18n/chip-resources';
21
import { Subject } from 'rxjs';
22
import { IgxIconComponent } from '../icon/icon.component';
23
import { NgClass, NgTemplateOutlet, NgIf } from '@angular/common';
24
import { getCurrentResourceStrings } from '../core/i18n/resources';
25

26
export const IgxChipTypeVariant = mkenum({
27
    PRIMARY: 'primary',
28
    INFO: 'info',
29
    SUCCESS: 'success',
30
    WARNING: 'warning',
31
    DANGER: 'danger'
32
});
33

34
export interface IBaseChipEventArgs extends IBaseEventArgs {
35
    originalEvent: IDragBaseEventArgs | IDropBaseEventArgs | KeyboardEvent | MouseEvent | TouchEvent;
36
    owner: IgxChipComponent;
37
}
38

39
export interface IChipClickEventArgs extends IBaseChipEventArgs {
40
    cancel: boolean;
41
}
42

43
export interface IChipKeyDownEventArgs extends IBaseChipEventArgs {
2✔
44
    originalEvent: KeyboardEvent;
45
    cancel: boolean;
3,677✔
46
}
47

48
export interface IChipEnterDragAreaEventArgs extends IBaseChipEventArgs {
61,112✔
49
    dragChip: IgxChipComponent;
29,829✔
50
}
51

31,283✔
52
export interface IChipSelectEventArgs extends IBaseChipEventArgs {
53
    cancel: boolean;
54
    selected: boolean;
487✔
55
}
56

57
let CHIP_ID = 0;
58

59
/**
60
 * Chip is compact visual component that displays information in an obround.
61
 *
62
 * @igxModule IgxChipsModule
63
 *
64
 * @igxTheme igx-chip-theme
65
 *
66
 * @igxKeywords chip
67
 *
68
 * @igxGroup display
69
 *
102,505✔
70
 * @remarks
71
 * The Ignite UI Chip can be templated, deleted, and selected.
72
 * Multiple chips can be reordered and visually connected to each other.
1✔
73
 * Chips reside in a container called chips area which is responsible for managing the interactions between the chips.
74
 *
75
 * @example
76
 * ```html
77
 * <igx-chip class="chipStyle" [id]="901" [draggable]="true" [removable]="true" (remove)="chipRemoved($event)">
78
 *    <igx-avatar class="chip-avatar-resized" igxPrefix></igx-avatar>
79
 * </igx-chip>
80
 * ```
81
 */
82
@Component({
83
    selector: 'igx-chip',
84
    templateUrl: 'chip.component.html',
85
    standalone: true,
86
    imports: [IgxDropDirective, IgxDragDirective, NgClass, NgTemplateOutlet, NgIf, IgxIconComponent]
87
})
1✔
88
export class IgxChipComponent extends DisplayDensityBase implements OnDestroy {
89

90
    /**
×
91
     * Sets/gets the variant of the chip.
92
     *
93
     * @remarks
94
     * Allowed values are `primary`, `info`, `success`, `warning`, `danger`.
95
     * Providing an invalid value won't change the chip.
96
     *
12,849✔
97
     * @example
98
     * ```html
99
     * <igx-chip [variant]="success"></igx-chip>
48,726✔
100
     * ```
101
     */
102
    @Input()
48,726✔
103
    public variant: string | typeof IgxChipTypeVariant;
104
    /**
105
     * An @Input property that sets the value of `id` attribute. If not provided it will be automatically generated.
48,726✔
106
     *
107
     * @example
108
     * ```html
48,726✔
109
     * <igx-chip [id]="'igx-chip-1'"></igx-chip>
110
     * ```
111
     */
48,726✔
112
    @HostBinding('attr.id')
113
    @Input()
114
    public id = `igx-chip-${CHIP_ID++}`;
48,726✔
115

116
    /**
117
     * Returns the `role` attribute of the chip.
118
     *
119
     * @example
120
     * ```typescript
121
     * let chipRole = this.chip.role;
12,386!
122
     * ```
12,386✔
123
     */
124
    @HostBinding('attr.role')
125
    public role = 'option';
126

127
    /**
128
     * An @Input property that sets the value of `tabindex` attribute. If not provided it will use the element's tabindex if set.
129
     *
130
     * @example
463✔
131
     * ```html
132
     * <igx-chip [id]="'igx-chip-1'" [tabIndex]="1"></igx-chip>
133
     * ```
134
     */
135
    @HostBinding('attr.tabIndex')
136
    @Input()
137
    public set tabIndex(value: number) {
48,734✔
138
        this._tabIndex = value;
139
    }
973✔
140

141
    public get tabIndex() {
142
        if (this._tabIndex !== null) {
143
            return this._tabIndex;
28,236✔
144
        }
145
        return !this.disabled ? 0 : null;
146
    }
147

148
    /**
19,525✔
149
     * An @Input property that stores data related to the chip.
150
     *
151
     * @example
152
     * ```html
153
     * <igx-chip [data]="{ value: 'Country' }"></igx-chip>
154
     * ```
155
     */
10,615✔
156
    @Input()
157
    public data: any;
158

5,845✔
159
    /**
5,845✔
160
     * An @Input property that defines if the `IgxChipComponent` can be dragged in order to change it's position.
5,845✔
161
     * By default it is set to false.
5,845✔
162
     *
5,845✔
163
     * @example
5,845✔
164
     * ```html
5,845✔
165
     * <igx-chip [id]="'igx-chip-1'" [draggable]="true"></igx-chip>
5,845✔
166
     * ```
5,845✔
167
     */
5,845✔
168
    @Input()
5,845✔
169
    public draggable = false;
5,845✔
170

5,845✔
171
    /**
5,845✔
172
     * An @Input property that enables/disables the draggable element animation when the element is released.
5,845✔
173
     * By default it's set to true.
5,845✔
174
     *
5,845✔
175
     * @example
5,845✔
176
     * ```html
5,845✔
177
     * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [animateOnRelease]="false"></igx-chip>
5,845✔
178
     * ```
5,845✔
179
     */
5,845✔
180
    @Input()
5,845✔
181
    public animateOnRelease = true;
5,845✔
182

5,845✔
183
    /**
5,845✔
184
     * An @Input property that enables/disables the hiding of the base element that has been dragged.
5,845✔
185
     * By default it's set to true.
186
     *
187
     * @example
188
     * ```html
189
     * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [hideBaseOnDrag]="false"></igx-chip>
5,845✔
190
     * ```
191
     */
192
    @Input()
193
    public hideBaseOnDrag = true;
194

5,845✔
195
    /**
5,845✔
196
     * An @Input property that defines if the `IgxChipComponent` should render remove button and throw remove events.
5,845✔
197
     * By default it is set to false.
5,845✔
198
     *
5,845✔
199
     * @example
5,845✔
200
     * ```html
201
     * <igx-chip [id]="'igx-chip-1'" [draggable]="true" [removable]="true"></igx-chip>
202
     * ```
10✔
203
     */
204
    @Input()
205
    public removable = false;
206

207
    /**
208
     * An @Input property that overrides the default icon that the chip applies to the remove button.
209
     *
463✔
210
     * @example
463✔
211
     * ```html
212
     * <igx-chip [id]="chip.id" [removable]="true" [removeIcon]="iconTemplate"></igx-chip>
213
     * <ng-template #iconTemplate><igx-icon>delete</igx-icon></ng-template>
214
     * ```
215
     */
216
    @Input()
×
217
    public removeIcon: TemplateRef<any>;
218

×
219
    /**
220
     * An @Input property that defines if the `IgxChipComponent` can be selected on click or through navigation,
221
     * By default it is set to false.
222
     *
223
     * @example
224
     * ```html
225
     * <igx-chip [id]="chip.id" [draggable]="true" [removable]="true" [selectable]="true"></igx-chip>
226
     * ```
227
     */
228
    @Input()
229
    public selectable = false;
21✔
230

231
    /**
232
     * An @Input property that overrides the default icon that the chip applies when it is selected.
233
     *
234
     * @example
21✔
235
     * ```html
21!
236
     * <igx-chip [id]="chip.id" [selectable]="true" [selectIcon]="iconTemplate"></igx-chip>
×
237
     * <ng-template #iconTemplate><igx-icon>done_outline</igx-icon></ng-template>
238
     * ```
21✔
239
     */
3✔
240
    @Input()
241
    public selectIcon: TemplateRef<any>;
242

243
    /**
244
     * @hidden
21✔
245
     * @internal
5✔
246
     */
247
    @Input()
21!
248
    public class = '';
21✔
249

250
    /**
251
     * An @Input property that defines if the `IgxChipComponent` is disabled. When disabled it restricts user interactions
252
     * like focusing on click or tab, selection on click or Space, dragging.
253
     * By default it is set to false.
254
     *
255
     * @example
256
     * ```html
3!
257
     * <igx-chip [id]="chip.id" [disabled]="true"></igx-chip>
3✔
258
     * ```
259
     */
260
    @HostBinding('class.igx-chip--disabled')
261
    @Input()
3✔
262
    public disabled = false;
3✔
263

264
    /**
265
     * Sets the `IgxChipComponent` selected state.
266
     *
2✔
267
     * @example
268
     * ```html
269
     * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [selected]="true">
270
     * ```
271
     *
272
     * Two-way data binding:
273
     * ```html
25✔
274
     * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" [(selected)]="model.isSelected">
275
     * ```
276
     */
277
    @HostBinding('attr.aria-selected')
278
    @Input()
279
    public set selected(newValue: boolean) {
280
        this.changeSelection(newValue);
281
    }
282

283
    /**
284
     * Returns if the `IgxChipComponent` is selected.
×
285
     *
286
     * @example
287
     * ```typescript
288
     * @ViewChild('myChip')
289
     * public chip: IgxChipComponent;
290
     * selectedChip(){
291
     *     let selectedChip = this.chip.selected;
×
292
     * }
×
293
     * ```
294
     */
×
295
    public get selected() {
296
        return this._selected;
297
    }
298

299
    /**
300
     * @hidden
301
     * @internal
302
     */
303
    @Output()
10✔
304
    public selectedChange = new EventEmitter<boolean>();
305

306
    /**
307
     * An @Input property that sets the `IgxChipComponent` background color.
10✔
308
     * The `color` property supports string, rgb, hex.
309
     *
310
     * @example
311
     * ```html
312
     * <igx-chip #myChip [id]="'igx-chip-1'" [color]="'#ff0000'"></igx-chip>
313
     * ```
314
     */
3!
315
    @Input()
×
316
    public set color(newColor) {
317
        this.chipArea.nativeElement.style.backgroundColor = newColor;
318
    }
319

320
    /**
321
     * Returns the background color of the `IgxChipComponent`.
322
     *
323
     * @example
324
     * ```typescript
3✔
325
     * @ViewChild('myChip')
326
     * public chip: IgxChipComponent;
327
     * ngAfterViewInit(){
328
     *     let chipColor = this.chip.color;
3!
329
     * }
×
330
     * ```
331
     */
332
    public get color() {
333
        return this.chipArea.nativeElement.style.backgroundColor;
334
    }
335

336
    /**
337
     * An accessor that sets the resource strings.
8✔
338
     * By default it uses EN resources.
339
     */
340
    @Input()
341
    public set resourceStrings(value: IChipResourceStrings) {
342
        this._resourceStrings = Object.assign({}, this._resourceStrings, value);
343
    }
344

3✔
345
    /**
346
     * An accessor that returns the resource strings.
347
     */
348
    public get resourceStrings(): IChipResourceStrings {
349
        return this._resourceStrings;
350
    }
351

4✔
352
    /**
353
     * Emits an event when the `IgxChipComponent` moving starts.
354
     * Returns the moving `IgxChipComponent`.
355
     *
356
     * @example
4✔
357
     * ```html
4✔
358
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (moveStart)="moveStarted($event)">
2✔
359
     * ```
360
     */
361
    @Output()
362
    public moveStart = new EventEmitter<IBaseChipEventArgs>();
363

364
    /**
365
     * Emits an event when the `IgxChipComponent` moving ends.
366
     * Returns the moved `IgxChipComponent`.
367
     *
368
     * @example
369
     * ```html
7!
370
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (moveEnd)="moveEnded($event)">
×
371
     * ```
372
     */
7✔
373
    @Output()
374
    public moveEnd = new EventEmitter<IBaseChipEventArgs>();
375

376
    /**
377
     * Emits an event when the `IgxChipComponent` is removed.
7✔
378
     * Returns the removed `IgxChipComponent`.
379
     *
380
     * @example
381
     * ```html
382
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (remove)="remove($event)">
383
     * ```
384
     */
5!
385
    @Output()
×
386
    public remove = new EventEmitter<IBaseChipEventArgs>();
387

5✔
388
    /**
389
     * Emits an event when the `IgxChipComponent` is clicked.
390
     * Returns the clicked `IgxChipComponent`, whether the event should be canceled.
391
     *
392
     * @example
5✔
393
     * ```html
394
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (click)="chipClick($event)">
395
     * ```
396
     */
397
    @Output()
398
    public chipClick = new EventEmitter<IChipClickEventArgs>();
399

400
    /**
4✔
401
     * Emits event when the `IgxChipComponent` is selected/deselected.
4!
402
     * Returns the selected chip reference, whether the event should be canceled, what is the next selection state and
×
403
     * when the event is triggered by interaction `originalEvent` is provided, otherwise `originalEvent` is `null`.
404
     *
4✔
405
     * @example
406
     * ```html
407
     * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (selectedChanging)="chipSelect($event)">
408
     * ```
409
     */
4✔
410
    @Output()
411
    public selectedChanging = new EventEmitter<IChipSelectEventArgs>();
412

413
    /**
414
     * Emits event when the `IgxChipComponent` is selected/deselected and any related animations and transitions also end.
415
     *
416
     * @example
7!
417
     * ```html
×
418
     * <igx-chip #myChip [id]="'igx-chip-1'" [selectable]="true" (selectedChanged)="chipSelectEnd($event)">
419
     * ```
7✔
420
     */
421
    @Output()
422
    public selectedChanged = new EventEmitter<IBaseChipEventArgs>();
423

424
    /**
7✔
425
     * Emits an event when the `IgxChipComponent` keyboard navigation is being used.
426
     * Returns the focused/selected `IgxChipComponent`, whether the event should be canceled,
427
     * if the `alt`, `shift` or `control` key is pressed and the pressed key name.
487✔
428
     *
494✔
429
     * @example
430
     * ```html
431
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (keyDown)="chipKeyDown($event)">
432
     * ```
433
     */
434
    @Output()
494✔
435
    public keyDown = new EventEmitter<IChipKeyDownEventArgs>();
147✔
436

147✔
437
    /**
147!
438
     * Emits an event when the `IgxChipComponent` has entered the `IgxChipsAreaComponent`.
147✔
439
     * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as  well as
147✔
440
     * the original drop event arguments.
147✔
441
     *
147✔
442
     * @example
443
     * ```html
444
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragEnter)="chipEnter($event)">
445
     * ```
446
     */
447
    @Output()
347✔
448
    public dragEnter = new EventEmitter<IChipEnterDragAreaEventArgs>();
57✔
449

57!
450
    /**
57✔
451
     * Emits an event when the `IgxChipComponent` has left the `IgxChipsAreaComponent`.
57✔
452
     * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as  well as
57✔
453
     * the original drop event arguments.
57✔
454
     *
455
     * @example
456
     * ```html
457
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragLeave)="chipLeave($event)">
458
     * ```
459
     */
460
    @Output()
461
    public dragLeave = new EventEmitter<IChipEnterDragAreaEventArgs>();
5,841✔
462

5,841✔
463
    /**
464
     * Emits an event when the `IgxChipComponent` is over the `IgxChipsAreaComponent`.
2✔
465
     * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as  well as
466
     * the original drop event arguments.
467
     *
468
     * @example
469
     * ```html
470
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragOver)="chipOver($event)">
2✔
471
     * ```
472
     */
473
     @Output()
474
     public dragOver = new EventEmitter<IChipEnterDragAreaEventArgs>();
475

476
    /**
477
     * Emits an event when the `IgxChipComponent` has been dropped in the `IgxChipsAreaComponent`.
478
     * Returns the target `IgxChipComponent`, the drag `IgxChipComponent`, as  well as
479
     * the original drop event arguments.
480
     *
481
     * @example
482
     * ```html
483
     * <igx-chip #myChip [id]="'igx-chip-1'" [draggable]="true" (dragDrop)="chipLeave($event)">
484
     * ```
485
     */
486
    @Output()
487
    public dragDrop = new EventEmitter<IChipEnterDragAreaEventArgs>();
488

489
    @HostBinding('class.igx-chip')
490
    protected defaultClass = 'igx-chip';
491

492
    @HostBinding('class.igx-chip--primary')
493
    protected get isPrimary() {
494
        return this.variant === IgxChipTypeVariant.PRIMARY;
495
    }
496

497
    @HostBinding('class.igx-chip--info')
498
    protected get isInfo() {
499
        return this.variant === IgxChipTypeVariant.INFO;
500
    }
501

502
    @HostBinding('class.igx-chip--success')
503
    protected get isSuccess() {
504
        return this.variant === IgxChipTypeVariant.SUCCESS;
505
    }
506

507
    @HostBinding('class.igx-chip--warning')
508
    protected get isWarning() {
509
        return this.variant === IgxChipTypeVariant.WARNING;
510
    }
511

512
    @HostBinding('class.igx-chip--danger')
513
    protected get isDanger() {
514
        return this.variant === IgxChipTypeVariant.DANGER;
2✔
515
    }
516

517
    /**
518
     * @hidden
519
     * @internal
520
     */
521
    @HostBinding('style.--component-size')
522
    public get componentSize(): string {
523
        return this.getComponentSizeStyles();
524
    }
525

526
    /**
527
     * Property that contains a reference to the `IgxDragDirective` the `IgxChipComponent` uses for dragging behavior.
528
     *
529
     * @example
530
     * ```html
531
     * <igx-chip [id]="chip.id" [draggable]="true"></igx-chip>
532
     * ```
533
     * ```typescript
534
     * onMoveStart(event: IBaseChipEventArgs){
535
     *     let dragDirective = event.owner.dragDirective;
536
     * }
537
     * ```
538
     */
539
    @ViewChild('chipArea', { read: IgxDragDirective, static: true })
540
    public dragDirective: IgxDragDirective;
541

542
    /**
543
     * @hidden
544
     * @internal
545
     */
546
    @ViewChild('chipArea', { read: ElementRef, static: true })
547
    public chipArea: ElementRef;
548

549
    /**
550
     * @hidden
551
     * @internal
552
     */
553
    @ViewChild('defaultRemoveIcon', { read: TemplateRef, static: true })
554
    public defaultRemoveIcon: TemplateRef<any>;
555

556
    /**
557
     * @hidden
558
     * @internal
559
     */
560
    @ViewChild('defaultSelectIcon', { read: TemplateRef, static: true })
561
    public defaultSelectIcon: TemplateRef<any>;
562

563
    /**
564
     * @hidden
565
     * @internal
566
     */
567
    public get removeButtonTemplate() {
568
        if(!this.disabled) {
569
            return this.removeIcon || this.defaultRemoveIcon;
570
        }
571
    }
572

573
    /**
574
     * @hidden
575
     * @internal
576
     */
577
    public get selectIconTemplate() {
578
        return this.selectIcon || this.defaultSelectIcon;
579
    }
580

581
    /**
582
     * @hidden
583
     * @internal
584
     */
585
    public get ghostStyles() {
586
        switch(this.displayDensity) {
587
            case DisplayDensity.compact:
588
                return {
589
                    '--component-size': 'var(--ig-size, var(--ig-size-small))',
590
                };
591
            case DisplayDensity.cosy:
592
                return {
593
                    '--component-size': 'var(--ig-size, var(--ig-size-medium))',
594
                };
595
            case DisplayDensity.comfortable:
596
            default:
597
                return {
598
                    '--component-size': 'var(--ig-size, var(--ig-size-large))',
599
                };
600
        }
601
    }
602

603
    /** @hidden @internal */
604
    public get nativeElement() {
605
        return this.ref.nativeElement;
606
    }
607

608
    /**
609
     * @hidden
610
     * @internal
611
     */
612
    public hideBaseElement = false;
613

614
    /**
615
     * @hidden
616
     * @internal
617
     */
618
    public destroy$ = new Subject();
619

620
    protected _tabIndex = null;
621
    protected _selected = false;
622
    protected _selectedItemClass = 'igx-chip__item--selected';
623
    protected _movedWhileRemoving = false;
624
    private _resourceStrings = getCurrentResourceStrings(ChipResourceStringsEN);
625

626
    constructor(public cdr: ChangeDetectorRef, private ref: ElementRef<HTMLElement>, private renderer: Renderer2,
627
        @Optional() @Inject(DisplayDensityToken) protected _displayDensityOptions: IDisplayDensityOptions) {
628
        super(_displayDensityOptions, ref);
629
    }
630

631
    /**
632
     * @hidden
633
     * @internal
634
     */
635
    @HostListener('keydown', ['$event'])
636
    public keyEvent(event: KeyboardEvent) {
637
        this.onChipKeyDown(event);
638
    }
639

640
    /**
641
     * @hidden
642
     * @internal
643
     */
644
    public selectClass(condition: boolean): any {
645
        const SELECT_CLASS = 'igx-chip__select';
646

647
        return {
648
            [SELECT_CLASS]: condition,
649
            [`${SELECT_CLASS}--hidden`]: !condition
650
        };
651
    }
652

653
    public onSelectTransitionDone(event) {
654
        if (event.target.tagName) {
655
            // Trigger onSelectionDone on when `width` property is changed and the target is valid element(not comment).
656
            this.selectedChanged.emit({
657
                owner: this,
658
                originalEvent: event
659
            });
660
        }
661
    }
662

663
    /**
664
     * @hidden
665
     * @internal
666
     */
667
    public onChipKeyDown(event: KeyboardEvent) {
668
        const keyDownArgs: IChipKeyDownEventArgs = {
669
            originalEvent: event,
670
            owner: this,
671
            cancel: false
672
        };
673

674
        this.keyDown.emit(keyDownArgs);
675
        if (keyDownArgs.cancel) {
676
            return;
677
        }
678

679
        if ((event.key === 'Delete' || event.key === 'Del') && this.removable) {
680
            this.remove.emit({
681
                originalEvent: event,
682
                owner: this
683
            });
684
        }
685

686
        if ((event.key === ' ' || event.key === 'Spacebar') && this.selectable && !this.disabled) {
687
            this.changeSelection(!this.selected, event);
688
        }
689

690
        if (event.key !== 'Tab') {
691
            event.preventDefault();
692
        }
693
    }
694

695
    /**
696
     * @hidden
697
     * @internal
698
     */
699
    public onRemoveBtnKeyDown(event: KeyboardEvent) {
700
        if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') {
701
            this.remove.emit({
702
                originalEvent: event,
703
                owner: this
704
            });
705

706
            event.preventDefault();
707
            event.stopPropagation();
708
        }
709
    }
710

711
    public onRemoveMouseDown(event: PointerEvent | MouseEvent) {
712
        event.stopPropagation();
713
    }
714

715
    /**
716
     * @hidden
717
     * @internal
718
     */
719
    public onRemoveClick(event: MouseEvent | TouchEvent) {
720
        this.remove.emit({
721
            originalEvent: event,
722
            owner: this
723
        });
724
    }
725

726
    /**
727
     * @hidden
728
     * @internal
729
     */
730
    public onRemoveTouchMove() {
731
        // We don't remove chip if user starting touch interacting on the remove button moves the chip
732
        this._movedWhileRemoving = true;
733
    }
734

735
    /**
736
     * @hidden
737
     * @internal
738
     */
739
    public onRemoveTouchEnd(event: TouchEvent) {
740
        if (!this._movedWhileRemoving) {
741
            this.onRemoveClick(event);
742
        }
743
        this._movedWhileRemoving = false;
744
    }
745

746
    /**
747
     * @hidden
748
     * @internal
749
     */
750
    // -----------------------------
751
    // Start chip igxDrag behavior
752
    public onChipDragStart(event: IDragStartEventArgs) {
753
        this.moveStart.emit({
754
            originalEvent: event,
755
            owner: this
756
        });
757
        event.cancel = !this.draggable || this.disabled;
758
    }
759

760
    /**
761
     * @hidden
762
     * @internal
763
     */
764
    public onChipDragEnd() {
765
        if (this.animateOnRelease) {
766
            this.dragDirective.transitionToOrigin();
767
        }
768
    }
769

770
    /**
771
     * @hidden
772
     * @internal
773
     */
774
    public onChipMoveEnd(event: IDragBaseEventArgs) {
775
        // moveEnd is triggered after return animation has finished. This happen when we drag and release the chip.
776
        this.moveEnd.emit({
777
            originalEvent: event,
778
            owner: this
779
        });
780

781
        if (this.selected) {
782
            this.chipArea.nativeElement.focus();
783
        }
784
    }
785

786
    /**
787
     * @hidden
788
     * @internal
789
     */
790
    public onChipGhostCreate() {
791
        this.hideBaseElement = this.hideBaseOnDrag;
792
    }
793

794
    /**
795
     * @hidden
796
     * @internal
797
     */
798
    public onChipGhostDestroy() {
799
        this.hideBaseElement = false;
800
    }
801

802
    /**
803
     * @hidden
804
     * @internal
805
     */
806
    public onChipDragClicked(event: IDragBaseEventArgs) {
807
        const clickEventArgs: IChipClickEventArgs = {
808
            originalEvent: event,
809
            owner: this,
810
            cancel: false
811
        };
812
        this.chipClick.emit(clickEventArgs);
813

814
        if (!clickEventArgs.cancel && this.selectable && !this.disabled) {
815
            this.changeSelection(!this.selected, event);
816
        }
817
    }
818
    // End chip igxDrag behavior
819

820
    /**
821
     * @hidden
822
     * @internal
823
     */
824
    // -----------------------------
825
    // Start chip igxDrop behavior
826
    public onChipDragEnterHandler(event: IDropBaseEventArgs) {
827
        if (this.dragDirective === event.drag) {
828
            return;
829
        }
830

831
        const eventArgs: IChipEnterDragAreaEventArgs = {
832
            owner: this,
833
            dragChip: event.drag.data?.chip,
834
            originalEvent: event
835
        };
836
        this.dragEnter.emit(eventArgs);
837
    }
838

839
    /**
840
     * @hidden
841
     * @internal
842
     */
843
    public onChipDragLeaveHandler(event: IDropBaseEventArgs) {
844
        if (this.dragDirective === event.drag) {
845
            return;
846
        }
847

848
        const eventArgs: IChipEnterDragAreaEventArgs = {
849
            owner: this,
850
            dragChip: event.drag.data?.chip,
851
            originalEvent: event
852
        };
853
        this.dragLeave.emit(eventArgs);
854
    }
855

856
    /**
857
     * @hidden
858
     * @internal
859
     */
860
    public onChipDrop(event: IDropDroppedEventArgs) {
861
        // Cancel the default drop logic
862
        event.cancel = true;
863
        if (this.dragDirective === event.drag) {
864
            return;
865
        }
866

867
        const eventArgs: IChipEnterDragAreaEventArgs = {
868
            owner: this,
869
            dragChip: event.drag.data?.chip,
870
            originalEvent: event
871
        };
872
        this.dragDrop.emit(eventArgs);
873
    }
874

875
    /**
876
     * @hidden
877
     * @internal
878
     */
879
    public onChipOverHandler(event: IDropBaseEventArgs) {
880
        if (this.dragDirective === event.drag) {
881
            return;
882
        }
883

884
        const eventArgs: IChipEnterDragAreaEventArgs = {
885
            owner: this,
886
            dragChip: event.drag.data?.chip,
887
            originalEvent: event
888
        };
889
        this.dragOver.emit(eventArgs);
890
    }
891
    // End chip igxDrop behavior
892

893
    protected changeSelection(newValue: boolean, srcEvent = null) {
894
        const onSelectArgs: IChipSelectEventArgs = {
895
            originalEvent: srcEvent,
896
            owner: this,
897
            selected: false,
898
            cancel: false
899
        };
900

901
        if (newValue && !this._selected) {
902
            onSelectArgs.selected = true;
903
            this.selectedChanging.emit(onSelectArgs);
904

905
            if (!onSelectArgs.cancel) {
906
                this.renderer.addClass(this.chipArea.nativeElement, this._selectedItemClass);
907
                this._selected = newValue;
908
                this.selectedChange.emit(this._selected);
909
                this.selectedChanged.emit({
910
                    owner: this,
911
                    originalEvent: srcEvent
912
                });
913
            }
914
        } else if (!newValue && this._selected) {
915
            this.selectedChanging.emit(onSelectArgs);
916

917
            if (!onSelectArgs.cancel) {
918
                this.renderer.removeClass(this.chipArea.nativeElement, this._selectedItemClass);
919
                this._selected = newValue;
920
                this.selectedChange.emit(this._selected);
921
                this.selectedChanged.emit({
922
                    owner: this,
923
                    originalEvent: srcEvent
924
                });
925
            }
926
        }
927
    }
928

929
    public ngOnDestroy(): void {
930
        this.destroy$.next();
931
        this.destroy$.complete();
932
    }
933
}
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