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

IgniteUI / igniteui-angular / 23353730325

20 Mar 2026 05:03PM UTC coverage: 9.784% (-79.5%) from 89.264%
23353730325

Pull #17069

github

web-flow
Merge cfa7e86d1 into a4dc50177
Pull Request #17069: fix(IgxGrid): Do not apply width constraint to groups.

921 of 16963 branches covered (5.43%)

Branch coverage included in aggregate %.

1 of 3 new or added lines in 1 file covered. (33.33%)

25213 existing lines in 340 files now uncovered.

3842 of 31721 relevant lines covered (12.11%)

6.13 hits per line

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

3.74
/projects/igniteui-angular/carousel/src/carousel/carousel-base.ts
1
import { AnimationReferenceMetadata, useAnimation } from '@angular/animations';
2
import { ChangeDetectorRef, Directive, EventEmitter, inject, OnDestroy } from '@angular/core';
3
import { IgxAngularAnimationService } from 'igniteui-angular/core';
4
import { AnimationPlayer, AnimationService } from 'igniteui-angular/core';
5
import { fadeIn, slideInLeft } from 'igniteui-angular/animations';
6
import { CarouselAnimationType } from './enums';
7

8
export enum CarouselAnimationDirection { NONE, NEXT, PREV }
3✔
9

10
export interface CarouselAnimationSettings {
11
    enterAnimation: AnimationReferenceMetadata;
12
    leaveAnimation: AnimationReferenceMetadata;
13
}
14

15
/** @hidden */
16
export interface IgxSlideComponentBase {
17
    direction: CarouselAnimationDirection;
18
    previous: boolean;
19
}
20

21
/** @hidden */
22
@Directive()
23
export abstract class IgxCarouselComponentBase implements OnDestroy {
3✔
UNCOV
24
    private animationService = inject<AnimationService>(IgxAngularAnimationService);
×
UNCOV
25
    protected cdr = inject(ChangeDetectorRef);
×
26

27
    /** @hidden */
UNCOV
28
    public animationType: CarouselAnimationType = CarouselAnimationType.slide;
×
29

30
    /** @hidden @internal */
UNCOV
31
    public enterAnimationDone = new EventEmitter();
×
32
    /** @hidden @internal */
UNCOV
33
    public leaveAnimationDone = new EventEmitter();
×
34

35
    /** @hidden */
36
    protected currentItem: IgxSlideComponentBase;
37
    /** @hidden */
38
    protected previousItem: IgxSlideComponentBase;
39
    /** @hidden */
40
    protected enterAnimationPlayer?: AnimationPlayer;
41
    /** @hidden */
42
    protected leaveAnimationPlayer?: AnimationPlayer;
43
    /** @hidden */
UNCOV
44
    protected defaultAnimationDuration = 320;
×
45
    /** @hidden */
UNCOV
46
    protected animationPosition = 0;
×
47
    /** @hidden */
UNCOV
48
    protected newDuration = 0;
×
49
    /** @hidden */
UNCOV
50
    protected vertical = false;
×
51

52
    public ngOnDestroy(): void {
UNCOV
53
        if (this.enterAnimationPlayer) {
×
UNCOV
54
            this.enterAnimationPlayer.destroy();
×
UNCOV
55
            this.enterAnimationPlayer = null;
×
56
        }
UNCOV
57
        if (this.leaveAnimationPlayer) {
×
UNCOV
58
            this.leaveAnimationPlayer.destroy();
×
UNCOV
59
            this.leaveAnimationPlayer = null;
×
60
        }
61
    }
62

63
    /** @hidden */
64
    protected triggerAnimations() {
UNCOV
65
        if (this.animationType !== CarouselAnimationType.none) {
×
UNCOV
66
            if (this.animationStarted(this.leaveAnimationPlayer) || this.animationStarted(this.enterAnimationPlayer)) {
×
UNCOV
67
                requestAnimationFrame(() => {
×
UNCOV
68
                    this.resetAnimations();
×
UNCOV
69
                    this.playAnimations();
×
70
                });
71
            } else {
UNCOV
72
                this.playAnimations();
×
73
            }
74
        }
75
    }
76

77
    /** @hidden */
78
    protected animationStarted(animation: AnimationPlayer): boolean {
UNCOV
79
        return animation && animation.hasStarted();
×
80
    }
81

82
    /** @hidden */
83
    protected playAnimations() {
UNCOV
84
        this.playLeaveAnimation();
×
UNCOV
85
        this.playEnterAnimation();
×
86
    }
87

88
    private resetAnimations() {
UNCOV
89
        if (this.animationStarted(this.leaveAnimationPlayer)) {
×
90
            this.leaveAnimationPlayer.reset();
×
91
            this.leaveAnimationDone.emit();
×
92
        }
93

UNCOV
94
        if (this.animationStarted(this.enterAnimationPlayer)) {
×
95
            this.enterAnimationPlayer.reset();
×
96
            this.enterAnimationDone.emit();
×
97
            this.cdr.markForCheck();
×
98
        }
99
    }
100

101
    private getAnimation(): CarouselAnimationSettings {
102
        let duration;
UNCOV
103
        if (this.newDuration) {
×
104
            duration = this.animationPosition ? this.animationPosition * this.newDuration : this.newDuration;
×
105
        } else {
UNCOV
106
            duration = this.animationPosition ? this.animationPosition * this.defaultAnimationDuration : this.defaultAnimationDuration;
×
107
        }
108

UNCOV
109
        const trans = this.animationPosition ? this.animationPosition * 100 : 100;
×
UNCOV
110
        switch (this.animationType) {
×
111
            case CarouselAnimationType.slide:
UNCOV
112
                return {
×
113
                    enterAnimation: useAnimation(slideInLeft,
114
                        {
115
                            params: {
116
                                delay: '0s',
117
                                duration: `${duration}ms`,
118
                                endOpacity: 1,
119
                                startOpacity: 1,
120
                                fromPosition: `${this.vertical ? 'translateY' : 'translateX'}(${this.currentItem.direction === 1 ? trans : -trans}%)`,
×
121
                                toPosition: `${this.vertical ? 'translateY(0%)' : 'translateX(0%)'}`
×
122
                            }
123
                        }),
124
                    leaveAnimation: useAnimation(slideInLeft,
125
                        {
126
                            params: {
127
                                delay: '0s',
128
                                duration: `${duration}ms`,
129
                                endOpacity: 1,
130
                                startOpacity: 1,
131
                                fromPosition: `${this.vertical ? 'translateY(0%)' : 'translateX(0%)'}`,
×
132
                                toPosition: `${this.vertical ? 'translateY' : 'translateX'}(${this.currentItem.direction === 1 ? -trans : trans}%)`,
×
133
                            }
134
                        })
135
                };
136
            case CarouselAnimationType.fade:
UNCOV
137
                return {
×
138
                    enterAnimation: useAnimation(fadeIn,
139
                        { params: { duration: `${duration}ms`, startOpacity: `${this.animationPosition}` } }),
140
                    leaveAnimation: null
141
                };
142
        }
UNCOV
143
        return {
×
144
            enterAnimation: null,
145
            leaveAnimation: null
146
        };
147
    }
148

149
    private playEnterAnimation() {
UNCOV
150
        const animation = this.getAnimation().enterAnimation;
×
UNCOV
151
        if (!animation) {
×
UNCOV
152
            return;
×
153
        }
154

UNCOV
155
        this.enterAnimationPlayer = this.animationService.buildAnimation(animation, this.getCurrentElement());
×
UNCOV
156
        this.enterAnimationPlayer.animationEnd.subscribe(() => {
×
157
            // TODO: animation may never end. Find better way to clean up the player
UNCOV
158
            if (this.enterAnimationPlayer) {
×
UNCOV
159
                this.enterAnimationPlayer.destroy();
×
UNCOV
160
                this.enterAnimationPlayer = null;
×
161
            }
UNCOV
162
            this.animationPosition = 0;
×
UNCOV
163
            this.newDuration = 0;
×
UNCOV
164
            this.previousItem.previous = false;
×
UNCOV
165
            this.enterAnimationDone.emit();
×
UNCOV
166
            this.cdr.markForCheck();
×
167
        });
UNCOV
168
        this.previousItem.previous = true;
×
UNCOV
169
        this.enterAnimationPlayer.play();
×
170
    }
171

172
    private playLeaveAnimation() {
UNCOV
173
        const animation = this.getAnimation().leaveAnimation;
×
UNCOV
174
        if (!animation) {
×
UNCOV
175
            return;
×
176
        }
177

UNCOV
178
        this.leaveAnimationPlayer = this.animationService.buildAnimation(animation, this.getPreviousElement());
×
UNCOV
179
        this.leaveAnimationPlayer.animationEnd.subscribe(() => {
×
180
            // TODO: animation may never end. Find better way to clean up the player
UNCOV
181
            if (this.leaveAnimationPlayer) {
×
UNCOV
182
                this.leaveAnimationPlayer.destroy();
×
UNCOV
183
                this.leaveAnimationPlayer = null;
×
184
            }
UNCOV
185
            this.animationPosition = 0;
×
UNCOV
186
            this.newDuration = 0;
×
UNCOV
187
            this.leaveAnimationDone.emit();
×
188
        });
UNCOV
189
        this.leaveAnimationPlayer.play();
×
190
    }
191

192
    protected abstract getPreviousElement(): HTMLElement;
193

194
    protected abstract getCurrentElement(): HTMLElement;
195
}
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