Skip to content

Commit 6176677

Browse files
authored
refactor(carousel): select index overload, change detail, suppress slides (#1457)
1 parent 1d24359 commit 6176677

File tree

3 files changed

+61
-11
lines changed

3 files changed

+61
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [Unreleased]
8+
### Added
9+
- Carousel component select method overload accepting index [#1457](https://github.com/IgniteUI/igniteui-webcomponents/issues/1457)
10+
711
## [5.1.1] - 2024-10-28
812
### Fixed
913
- Library - internal import path for styles and public exports for themes

src/components/carousel/carousel.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,21 @@ describe('Carousel', () => {
429429
animation = await carousel.select(slides[2]);
430430
expect(animation).to.be.true;
431431
expect(carousel.current).to.equal(2);
432+
433+
// select current slide by index
434+
animation = await carousel.select(2);
435+
expect(animation).to.be.false;
436+
expect(carousel.current).to.equal(2);
437+
438+
// select invalid slide by index
439+
animation = await carousel.select(3);
440+
expect(animation).to.be.false;
441+
expect(carousel.current).to.equal(2);
442+
443+
// select fist slide by index
444+
animation = await carousel.select(0);
445+
expect(animation).to.be.true;
446+
expect(carousel.current).to.equal(0);
432447
});
433448
});
434449

@@ -505,6 +520,7 @@ describe('Carousel', () => {
505520
describe('Interactions', () => {
506521
describe('Click', () => {
507522
it('should change slide when clicking next button', async () => {
523+
const eventSpy = spy(carousel, 'emitEvent');
508524
expect(carousel.current).to.equal(0);
509525
expect(defaultIndicators[0].active).to.be.true;
510526

@@ -514,9 +530,11 @@ describe('Carousel', () => {
514530
expect(carousel.current).to.equal(1);
515531
expect(defaultIndicators[0].active).to.be.false;
516532
expect(defaultIndicators[1].active).to.be.true;
533+
expect(eventSpy.firstCall).calledWith('igcSlideChanged', { detail: 1 });
517534
});
518535

519536
it('should change slide when clicking previous button', async () => {
537+
const eventSpy = spy(carousel, 'emitEvent');
520538
expect(carousel.current).to.equal(0);
521539
expect(defaultIndicators[0].active).to.be.true;
522540

@@ -526,9 +544,11 @@ describe('Carousel', () => {
526544
expect(carousel.current).to.equal(2);
527545
expect(defaultIndicators[0].active).to.be.false;
528546
expect(defaultIndicators[2].active).to.be.true;
547+
expect(eventSpy.firstCall).calledWith('igcSlideChanged', { detail: 2 });
529548
});
530549

531550
it('should change slide when clicking indicators', async () => {
551+
const eventSpy = spy(carousel, 'emitEvent');
532552
expect(carousel.current).to.equal(0);
533553
expect(defaultIndicators[0].active).to.be.true;
534554

@@ -539,6 +559,7 @@ describe('Carousel', () => {
539559
expect(carousel.current).to.equal(1);
540560
expect(defaultIndicators[0].active).to.be.false;
541561
expect(defaultIndicators[1].active).to.be.true;
562+
expect(eventSpy.firstCall).calledWith('igcSlideChanged', { detail: 1 });
542563

543564
// select first slide
544565
simulateClick(defaultIndicators[0]);
@@ -547,6 +568,9 @@ describe('Carousel', () => {
547568
expect(carousel.current).to.equal(0);
548569
expect(defaultIndicators[0].active).to.be.true;
549570
expect(defaultIndicators[1].active).to.be.false;
571+
expect(eventSpy.secondCall).calledWith('igcSlideChanged', {
572+
detail: 0,
573+
});
550574
});
551575
});
552576

src/components/carousel/carousel.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import { all } from './themes/container.js';
5252
import { styles as shared } from './themes/shared/carousel.common.css.js';
5353

5454
export interface IgcCarouselComponentEventMap {
55-
igcSlideChanged: CustomEvent<void>;
55+
igcSlideChanged: CustomEvent<number>;
5656
igcPlaying: CustomEvent<void>;
5757
igcPaused: CustomEvent<void>;
5858
}
@@ -243,7 +243,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
243243
* @attr interval
244244
*/
245245
@property({ type: Number, reflect: false })
246-
public interval!: number;
246+
public interval: number | undefined;
247247

248248
/**
249249
* Controls the maximum indicator controls (dots) that can be shown. Default value is `10`.
@@ -263,6 +263,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
263263
@property({ attribute: 'animation-type' })
264264
public animationType: 'slide' | 'fade' | 'none' = 'slide';
265265

266+
/* blazorSuppress */
266267
/**
267268
* The slides of the carousel.
268269
*/
@@ -505,7 +506,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
505506
}
506507

507508
await callback.call(this);
508-
this.emitEvent('igcSlideChanged');
509+
this.emitEvent('igcSlideChanged', { detail: this.current });
509510

510511
if (this.interval) {
511512
this.restartInterval();
@@ -553,7 +554,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
553554
this._lastInterval = setInterval(() => {
554555
if (this.isPlaying && this.total) {
555556
this.next();
556-
this.emitEvent('igcSlideChanged');
557+
this.emitEvent('igcSlideChanged', { detail: this.current });
557558
} else {
558559
this.pause();
559560
}
@@ -606,7 +607,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
606607
}
607608

608609
/**
609-
* Switches to the next slide running any animations and returns if the operation was a success.
610+
* Switches to the next slide, runs any animations, and returns if the operation was successful.
610611
*/
611612
public async next(): Promise<boolean> {
612613
if (this.disableLoop && this.nextIndex === 0) {
@@ -618,7 +619,7 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
618619
}
619620

620621
/**
621-
* Switches to the previous slide running any animations and returns if the operation was a success.
622+
* Switches to the previous slide, runs any animations, and returns if the operation was successful.
622623
*/
623624
public async prev(): Promise<boolean> {
624625
if (this.disableLoop && this.prevIndex === this.total - 1) {
@@ -629,20 +630,41 @@ export default class IgcCarouselComponent extends EventEmitterMixin<
629630
return await this.select(this.slides[this.prevIndex], 'prev');
630631
}
631632

633+
/* blazorSuppress */
632634
/**
633-
* Switches the passed in slide running any animations and returns if the operation was a success.
635+
* Switches to the passed-in slide, runs any animations, and returns if the operation was successful.
634636
*/
635637
public async select(
636638
slide: IgcCarouselSlideComponent,
637-
direction?: 'next' | 'prev'
639+
animationDirection?: 'next' | 'prev'
640+
): Promise<boolean>;
641+
/**
642+
* Switches to slide by index, runs any animations, and returns if the operation was successful.
643+
*/
644+
public async select(
645+
index: number,
646+
animationDirection?: 'next' | 'prev'
647+
): Promise<boolean>;
648+
public async select(
649+
slideOrIndex: IgcCarouselSlideComponent | number,
650+
animationDirection?: 'next' | 'prev'
638651
): Promise<boolean> {
639-
const index = this.slides.indexOf(slide);
652+
let index: number;
653+
let slide: IgcCarouselSlideComponent | undefined;
654+
655+
if (typeof slideOrIndex === 'number') {
656+
index = slideOrIndex;
657+
slide = this.slides.at(index);
658+
} else {
659+
slide = slideOrIndex;
660+
index = this.slides.indexOf(slide);
661+
}
640662

641-
if (index === this.current || index === -1) {
663+
if (index === this.current || index === -1 || !slide) {
642664
return false;
643665
}
644666

645-
const dir = direction ?? (index > this.current ? 'next' : 'prev');
667+
const dir = animationDirection ?? (index > this.current ? 'next' : 'prev');
646668

647669
await this.animateSlides(slide, this._activeSlide, dir);
648670
return true;

0 commit comments

Comments
 (0)