From 72cab105103538db5207a0dfd8d11ede929c6b49 Mon Sep 17 00:00:00 2001 From: Bastien Date: Wed, 6 Dec 2023 15:16:40 +0100 Subject: [PATCH] feat(carousel): add fade input --- .../components/carousel/carousel.routes.ts | 10 +++++++- .../demos/transition/carousel-transition.html | 23 +++++++++++++++++++ .../demos/transition/carousel-transition.ts | 14 +++++++++++ src/carousel/carousel-config.spec.ts | 1 + src/carousel/carousel-config.ts | 1 + src/carousel/carousel.spec.ts | 23 +++++++++++++++++++ src/carousel/carousel.ts | 9 ++++++++ 7 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 demo/src/app/components/carousel/demos/transition/carousel-transition.html create mode 100644 demo/src/app/components/carousel/demos/transition/carousel-transition.ts diff --git a/demo/src/app/components/carousel/carousel.routes.ts b/demo/src/app/components/carousel/carousel.routes.ts index 8dfd367576..99dcf1ff08 100644 --- a/demo/src/app/components/carousel/carousel.routes.ts +++ b/demo/src/app/components/carousel/carousel.routes.ts @@ -4,6 +4,7 @@ import { DemoListComponent } from '../../shared/examples-page/demo-list.componen import { NgbdCarouselBasic } from './demos/basic/carousel-basic'; import { NgbdCarouselConfig } from './demos/config/carousel-config'; import { NgbdCarouselNavigation } from './demos/navigation/carousel-navigation'; +import { NgbdCarouselTransition } from './demos/transition/carousel-transition'; import { NgbdCarouselPause } from './demos/pause/carousel-pause'; import { Routes } from '@angular/router'; @@ -17,11 +18,18 @@ const DEMOS = [ }, { fragment: 'navigation', - title: 'Navigation arrows and indicators', + title: 'Navigation arrows andindicators', type: NgbdCarouselNavigation, code: 'carousel/demos/navigation/carousel-navigation.ts', markup: 'carousel/demos/navigation/carousel-navigation.html', }, + { + fragment: 'transition', + title: 'Fade transition', + type: NgbdCarouselTransition, + code: 'carousel/demos/navigation/carousel-transition.ts', + markup: 'carousel/demos/navigation/carousel-transition.html', + }, { fragment: 'pause', title: 'Pause/cycle', diff --git a/demo/src/app/components/carousel/demos/transition/carousel-transition.html b/demo/src/app/components/carousel/demos/transition/carousel-transition.html new file mode 100644 index 0000000000..a4285c92ba --- /dev/null +++ b/demo/src/app/components/carousel/demos/transition/carousel-transition.html @@ -0,0 +1,23 @@ +@if (images) { + + @for (image of images; track image) { + +
+ Random slide +
+ +
+ } +
+} + +
+ +
+ +
diff --git a/demo/src/app/components/carousel/demos/transition/carousel-transition.ts b/demo/src/app/components/carousel/demos/transition/carousel-transition.ts new file mode 100644 index 0000000000..0ad5acfce4 --- /dev/null +++ b/demo/src/app/components/carousel/demos/transition/carousel-transition.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { NgbCarouselConfig, NgbCarouselModule } from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'ngbd-carousel-transition', + standalone: true, + imports: [NgbCarouselModule], + templateUrl: './carousel-transition.html', + providers: [NgbCarouselConfig], // add NgbCarouselConfig to the component providers +}) +export class NgbdCarouselTransition { + fade = true; + images = [1055, 194, 368].map((n) => `https://picsum.photos/id/${n}/900/500`); +} diff --git a/src/carousel/carousel-config.spec.ts b/src/carousel/carousel-config.spec.ts index 5237a8fe8f..f34570c9e9 100644 --- a/src/carousel/carousel-config.spec.ts +++ b/src/carousel/carousel-config.spec.ts @@ -11,5 +11,6 @@ describe('ngb-carousel-config', () => { expect(config.pauseOnHover).toBe(true); expect(config.showNavigationIndicators).toBe(true); expect(config.showNavigationArrows).toBe(true); + expect(config.fade).toBe(false); }); }); diff --git a/src/carousel/carousel-config.ts b/src/carousel/carousel-config.ts index 26d562ae0f..2c29474fae 100644 --- a/src/carousel/carousel-config.ts +++ b/src/carousel/carousel-config.ts @@ -19,6 +19,7 @@ export class NgbCarouselConfig { pauseOnFocus = true; showNavigationArrows = true; showNavigationIndicators = true; + fade = false; get animation(): boolean { return this._animation ?? this._ngbConfig.animation; diff --git a/src/carousel/carousel.spec.ts b/src/carousel/carousel.spec.ts index 09e48b5026..d6994751d5 100644 --- a/src/carousel/carousel.spec.ts +++ b/src/carousel/carousel.spec.ts @@ -53,6 +53,7 @@ describe('ngb-carousel', () => { expect(carousel.pauseOnFocus).toBe(defaultConfig.pauseOnFocus); expect(carousel.showNavigationIndicators).toBe(defaultConfig.showNavigationIndicators); expect(carousel.showNavigationArrows).toBe(defaultConfig.showNavigationArrows); + expect(carousel.fade).toBe(defaultConfig.fade); }); it('should render slides and navigation indicators', fakeAsync(() => { @@ -889,6 +890,23 @@ describe('ngb-carousel', () => { discardPeriodicTasks(); })); + it('should have fade transition to the flags', fakeAsync(() => { + const html = ` + + foo + + `; + const fixture = createTestComponent(html); + + expect(fixture.nativeElement.querySelector('ngb-carousel').className).toBe('carousel slide'); + + fixture.componentInstance.fade = true; + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('ngb-carousel').className).toBe('carousel slide carousel-fade'); + + discardPeriodicTasks(); + })); + describe('Custom config', () => { let config: NgbCarouselConfig; @@ -901,6 +919,7 @@ describe('ngb-carousel', () => { config.pauseOnFocus = false; config.showNavigationIndicators = true; config.showNavigationArrows = true; + config.fade = false; })); it('should initialize inputs with provided config', () => { @@ -915,6 +934,7 @@ describe('ngb-carousel', () => { expect(carousel.pauseOnFocus).toBe(config.pauseOnFocus); expect(carousel.showNavigationIndicators).toBe(config.showNavigationIndicators); expect(carousel.showNavigationArrows).toBe(config.showNavigationArrows); + expect(carousel.fade).toBe(config.fade); }); }); @@ -927,6 +947,7 @@ describe('ngb-carousel', () => { config.pauseOnFocus = false; config.showNavigationIndicators = true; config.showNavigationArrows = true; + config.fade = false; const carousel = TestBed.createComponent(NgbCarousel).componentInstance; expect(carousel.interval).toBe(config.interval); @@ -936,6 +957,7 @@ describe('ngb-carousel', () => { expect(carousel.pauseOnFocus).toBe(config.pauseOnFocus); expect(carousel.showNavigationIndicators).toBe(config.showNavigationIndicators); expect(carousel.showNavigationArrows).toBe(config.showNavigationArrows); + expect(carousel.fade).toBe(config.fade); }); }); @@ -1156,6 +1178,7 @@ class TestComponent { pauseOnHover = true; showNavigationArrows = true; showNavigationIndicators = true; + fade = false; slides = ['a', 'b']; carouselSlideCallBack = (event: NgbSlideEvent) => {}; carouselSingleSlideCallBack = (event: NgbSingleSlideEvent, id: string) => {}; diff --git a/src/carousel/carousel.ts b/src/carousel/carousel.ts index 2ac92dd6b7..eb17901779 100644 --- a/src/carousel/carousel.ts +++ b/src/carousel/carousel.ts @@ -2,6 +2,7 @@ import { AfterContentChecked, AfterContentInit, AfterViewInit, + booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -73,6 +74,7 @@ export class NgbSlide { encapsulation: ViewEncapsulation.None, host: { class: 'carousel slide', + '[class.carousel-fade]': 'fade', '[style.display]': '"block"', tabIndex: '0', '(keydown.arrowLeft)': 'keyboard && arrowLeft()', @@ -233,6 +235,13 @@ export class NgbCarousel implements AfterContentChecked, AfterContentInit, After */ @Input() showNavigationIndicators = this._config.showNavigationIndicators; + /** + * If `true`, the animation of the slides will be a fade transition instead of a slide. + * + * @since 16.1.0 + */ + @Input({ transform: booleanAttribute }) fade = this._config.fade; + /** * An event emitted just before the slide transition starts. *