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) {
+
+
+
+
+
+
Transition
+
This carousel has fade transition.
+
+
+ }
+
+}
+
+
+
+
+
+
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.
*