Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(carousel): add fade input #4646

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion demo/src/app/components/carousel/carousel.routes.ts
Expand Up @@ -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';

Expand All @@ -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',
Expand Down
@@ -0,0 +1,23 @@
@if (images) {
<ngb-carousel [fade]="fade">
@for (image of images; track image) {
<ng-template ngbSlide>
<div class="picsum-img-wrapper">
<img [src]="image" alt="Random slide" />
</div>
<div class="carousel-caption">
<h3>Transition</h3>
<p>This carousel has fade transition.</p>
</div>
</ng-template>
}
</ngb-carousel>
}

<hr />

<div class="btn-group" role="group" aria-label="Carousel toggle transition">
<button type="button" (click)="fade = !fade" class="btn btn-outline-secondary btn-sm">
Toggle fade transitions
</button>
</div>
@@ -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`);
}
1 change: 1 addition & 0 deletions src/carousel/carousel-config.spec.ts
Expand Up @@ -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);
});
});
1 change: 1 addition & 0 deletions src/carousel/carousel-config.ts
Expand Up @@ -19,6 +19,7 @@ export class NgbCarouselConfig {
pauseOnFocus = true;
showNavigationArrows = true;
showNavigationIndicators = true;
fade = false;

get animation(): boolean {
return this._animation ?? this._ngbConfig.animation;
Expand Down
23 changes: 23 additions & 0 deletions src/carousel/carousel.spec.ts
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -889,6 +890,23 @@ describe('ngb-carousel', () => {
discardPeriodicTasks();
}));

it('should have fade transition to the flags', fakeAsync(() => {
const html = `
<ngb-carousel [fade]="fade">
<ng-template ngbSlide>foo</ng-template>
</ngb-carousel>
`;
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;

Expand All @@ -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', () => {
Expand All @@ -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);
});
});

Expand All @@ -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);
Expand All @@ -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);
});
});

Expand Down Expand Up @@ -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) => {};
Expand Down
9 changes: 9 additions & 0 deletions src/carousel/carousel.ts
Expand Up @@ -2,6 +2,7 @@ import {
AfterContentChecked,
AfterContentInit,
AfterViewInit,
booleanAttribute,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Expand Down Expand Up @@ -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()',
Expand Down Expand Up @@ -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.
*
Expand Down