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

IgniteUI / igniteui-angular / 13331632524

14 Feb 2025 02:51PM CUT coverage: 22.015% (-69.6%) from 91.622%
13331632524

Pull #15372

github

web-flow
Merge d52d57714 into bcb78ae0a
Pull Request #15372: chore(*): test ci passing

1990 of 15592 branches covered (12.76%)

431 of 964 new or added lines in 18 files covered. (44.71%)

19956 existing lines in 307 files now uncovered.

6452 of 29307 relevant lines covered (22.02%)

249.17 hits per line

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

3.23
/projects/igniteui-angular/src/lib/carousel/carousel-base.ts
1
import { AnimationReferenceMetadata, useAnimation } from '@angular/animations';
2
import { ChangeDetectorRef, EventEmitter, Inject, InjectionToken } from '@angular/core';
3
import { IgxAngularAnimationService } from '../services/animation/angular-animation-service';
4
import { AnimationPlayer, AnimationService } from '../services/animation/animation';
5
import { fadeIn, slideInLeft } from 'igniteui-angular/animations';
6
import { CarouselAnimationType, CarouselIndicatorsOrientation } from './enums';
7

8
export enum Direction { NONE, NEXT, PREV }
2✔
9

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

15
export interface ICarouselComponentBase {
16
    id: string;
17
    role: string;
18
    cssClass: string;
19
    loop: boolean;
20
    pause: boolean;
21
    navigation: boolean;
22
    indicators: boolean;
23
    vertical: boolean;
24
    keyboardSupport: boolean;
25
    gesturesSupport: boolean;
26
    maximumIndicatorsCount: number;
27
    indicatorsOrientation: CarouselIndicatorsOrientation;
28
    animationType: CarouselAnimationType;
29
    total: number;
30
    current: number;
31
    interval: number;
32
    slideChanged: EventEmitter<any>;
33
    slideAdded: EventEmitter<any>;
34
    slideRemoved: EventEmitter<any>;
35
    carouselPaused: EventEmitter<any>;
36
    carouselPlaying: EventEmitter<any>;
37
    next(): void;
38
    prev(): void;
39
    play(): void;
40
    stop(): void
41
}
42

43
/** @hidden */
44
export const IGX_CAROUSEL_COMPONENT = /*@__PURE__*/new InjectionToken<ICarouselComponentBase>('IgxCarouselToken');
2✔
45

46
/** @hidden */
47
export interface IgxSlideComponentBase {
48
    direction: Direction;
49
    previous: boolean;
50
}
51

52
/** @hidden */
53
export abstract class IgxCarouselComponentBase {
54
    /** @hidden */
UNCOV
55
    public animationType: CarouselAnimationType = CarouselAnimationType.slide;
×
56

57
    /** @hidden @internal */
UNCOV
58
    public enterAnimationDone = new EventEmitter();
×
59
    /** @hidden @internal */
UNCOV
60
    public leaveAnimationDone = new EventEmitter();
×
61

62
    /** @hidden */
63
    protected currentItem: IgxSlideComponentBase;
64
    /** @hidden */
65
    protected previousItem: IgxSlideComponentBase;
66
    /** @hidden */
67
    protected enterAnimationPlayer?: AnimationPlayer;
68
    /** @hidden */
69
    protected leaveAnimationPlayer?: AnimationPlayer;
70
    /** @hidden */
UNCOV
71
    protected defaultAnimationDuration = 320;
×
72
    /** @hidden */
UNCOV
73
    protected animationPosition = 0;
×
74
    /** @hidden */
UNCOV
75
    protected newDuration = 0;
×
76
    /** @hidden */
UNCOV
77
    protected vertical = false;
×
78

79
    constructor(
UNCOV
80
        @Inject(IgxAngularAnimationService) private animationService: AnimationService,
×
UNCOV
81
        protected cdr: ChangeDetectorRef) {
×
82
    }
83

84
    /** @hidden */
85
    protected triggerAnimations() {
UNCOV
86
        if (this.animationType !== CarouselAnimationType.none) {
×
UNCOV
87
            if (this.animationStarted(this.leaveAnimationPlayer) || this.animationStarted(this.enterAnimationPlayer)) {
×
UNCOV
88
                requestAnimationFrame(() => {
×
UNCOV
89
                    this.resetAnimations();
×
UNCOV
90
                    this.playAnimations();
×
91
                });
92
            } else {
UNCOV
93
                this.playAnimations();
×
94
            }
95
        }
96
    }
97

98
    /** @hidden */
99
    protected animationStarted(animation: AnimationPlayer): boolean {
UNCOV
100
        return animation && animation.hasStarted();
×
101
    }
102

103
    /** @hidden */
104
    protected playAnimations() {
UNCOV
105
        this.playLeaveAnimation();
×
UNCOV
106
        this.playEnterAnimation();
×
107
    }
108

109
    private resetAnimations() {
UNCOV
110
        if (this.animationStarted(this.leaveAnimationPlayer)) {
×
111
            this.leaveAnimationPlayer.reset();
×
112
            this.leaveAnimationDone.emit();
×
113
        }
114

UNCOV
115
        if (this.animationStarted(this.enterAnimationPlayer)) {
×
116
            this.enterAnimationPlayer.reset();
×
117
            this.enterAnimationDone.emit();
×
118
            this.cdr.markForCheck();
×
119
        }
120
    }
121

122
    private getAnimation(): CarouselAnimationSettings {
123
        let duration;
UNCOV
124
        if (this.newDuration) {
×
125
            duration = this.animationPosition ? this.animationPosition * this.newDuration : this.newDuration;
×
126
        } else {
UNCOV
127
            duration = this.animationPosition ? this.animationPosition * this.defaultAnimationDuration : this.defaultAnimationDuration;
×
128
        }
129

UNCOV
130
        const trans = this.animationPosition ? this.animationPosition * 100 : 100;
×
UNCOV
131
        switch (this.animationType) {
×
132
            case CarouselAnimationType.slide:
UNCOV
133
                return {
×
134
                    enterAnimation: useAnimation(slideInLeft,
135
                        {
136
                            params: {
137
                                delay: '0s',
138
                                duration: `${duration}ms`,
139
                                endOpacity: 1,
140
                                startOpacity: 1,
141
                                fromPosition: `${this.vertical ? 'translateY' : 'translateX'}(${this.currentItem.direction === 1 ? trans : -trans}%)`,
×
142
                                toPosition: `${this.vertical ? 'translateY(0%)' : 'translateX(0%)'}`
×
143
                            }
144
                        }),
145
                    leaveAnimation: useAnimation(slideInLeft,
146
                        {
147
                            params: {
148
                                delay: '0s',
149
                                duration: `${duration}ms`,
150
                                endOpacity: 1,
151
                                startOpacity: 1,
152
                                fromPosition: `${this.vertical ? 'translateY(0%)' : 'translateX(0%)'}`,
×
153
                                toPosition: `${this.vertical ? 'translateY' : 'translateX'}(${this.currentItem.direction === 1 ? -trans : trans}%)`,
×
154
                            }
155
                        })
156
                };
157
            case CarouselAnimationType.fade:
UNCOV
158
                return {
×
159
                    enterAnimation: useAnimation(fadeIn,
160
                        { params: { duration: `${duration}ms`, startOpacity: `${this.animationPosition}` } }),
161
                    leaveAnimation: null
162
                };
163
        }
UNCOV
164
        return {
×
165
            enterAnimation: null,
166
            leaveAnimation: null
167
        };
168
    }
169

170
    private playEnterAnimation() {
UNCOV
171
        const animation = this.getAnimation().enterAnimation;
×
UNCOV
172
        if (!animation) {
×
UNCOV
173
            return;
×
174
        }
175

UNCOV
176
        this.enterAnimationPlayer = this.animationService.buildAnimation(animation, this.getCurrentElement());
×
UNCOV
177
        this.enterAnimationPlayer.animationEnd.subscribe(() => {
×
178
            // TODO: animation may never end. Find better way to clean up the player
UNCOV
179
            if (this.enterAnimationPlayer) {
×
UNCOV
180
                this.enterAnimationPlayer.reset();
×
UNCOV
181
                this.enterAnimationPlayer = null;
×
182
            }
UNCOV
183
            this.animationPosition = 0;
×
UNCOV
184
            this.newDuration = 0;
×
UNCOV
185
            this.previousItem.previous = false;
×
UNCOV
186
            this.enterAnimationDone.emit();
×
UNCOV
187
            this.cdr.markForCheck();
×
188
        });
UNCOV
189
        this.previousItem.previous = true;
×
UNCOV
190
        this.enterAnimationPlayer.play();
×
191
    }
192

193
    private playLeaveAnimation() {
UNCOV
194
        const animation = this.getAnimation().leaveAnimation;
×
UNCOV
195
        if (!animation) {
×
UNCOV
196
            return;
×
197
        }
198

UNCOV
199
        this.leaveAnimationPlayer = this.animationService.buildAnimation(animation, this.getPreviousElement());
×
UNCOV
200
        this.leaveAnimationPlayer.animationEnd.subscribe(() => {
×
201
            // TODO: animation may never end. Find better way to clean up the player
UNCOV
202
            if (this.leaveAnimationPlayer) {
×
UNCOV
203
                this.leaveAnimationPlayer.reset();
×
UNCOV
204
                this.leaveAnimationPlayer = null;
×
205
            }
UNCOV
206
            this.animationPosition = 0;
×
UNCOV
207
            this.newDuration = 0;
×
UNCOV
208
            this.leaveAnimationDone.emit();
×
209
        });
UNCOV
210
        this.leaveAnimationPlayer.play();
×
211
    }
212

213
    protected abstract getPreviousElement(): HTMLElement;
214

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

© 2025 Coveralls, Inc