Skip to content

Commit

Permalink
feat(module: carousel): nzLoop to prevent the carousel to go in a l…
Browse files Browse the repository at this point in the history
…oop (#7693)

* feat(module: carousel): `nzLoop` to prevent the carousel to go in a loop

* ci(module: carousel): improve test coverage
  • Loading branch information
1wkk committed Nov 7, 2022
1 parent bec3b42 commit e3103f0
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 2 deletions.
15 changes: 13 additions & 2 deletions components/carousel/carousel.component.ts
Expand Up @@ -127,6 +127,7 @@ export class NzCarouselComponent implements AfterContentInit, AfterViewInit, OnD
@Input() @WithConfig() @InputBoolean() nzAutoPlay: boolean = false;
@Input() @WithConfig() @InputNumber() nzAutoPlaySpeed: number = 3000;
@Input() @InputNumber() nzTransitionSpeed = 500;
@Input() @WithConfig() nzLoop: boolean = true;

/**
* this property is passed directly to an NzCarouselBaseStrategy
Expand Down Expand Up @@ -300,7 +301,12 @@ export class NzCarouselComponent implements AfterContentInit, AfterViewInit, OnD
}

goTo(index: number): void {
if (this.carouselContents && this.carouselContents.length && !this.isTransiting) {
if (
this.carouselContents &&
this.carouselContents.length &&
!this.isTransiting &&
(this.nzLoop || (index >= 0 && index < this.carouselContents.length))
) {
const length = this.carouselContents.length;
const from = this.activeIndex;
const to = (index + length) % length;
Expand Down Expand Up @@ -386,7 +392,12 @@ export class NzCarouselComponent implements AfterContentInit, AfterViewInit, OnD
const xDelta = this.pointerDelta ? this.pointerDelta.x : 0;

// Switch to another slide if delta is bigger than third of the width.
if (Math.abs(xDelta) > this.gestureRect!.width / 3) {
if (
Math.abs(xDelta) > this.gestureRect!.width / 3 &&
(this.nzLoop ||
(xDelta <= 0 && this.activeIndex + 1 < this.carouselContents.length) ||
(xDelta > 0 && this.activeIndex > 0))
) {
this.goTo(xDelta > 0 ? this.activeIndex - 1 : this.activeIndex + 1);
} else {
this.goTo(this.activeIndex);
Expand Down
31 changes: 31 additions & 0 deletions components/carousel/carousel.spec.ts
Expand Up @@ -220,6 +220,35 @@ describe('carousel', () => {
tickMilliseconds(fixture, 700);
expect(carouselContents[1].nativeElement.classList).toContain('slick-active');
}));

it('should disable loop work', fakeAsync(() => {
testComponent.loop = false;
fixture.detectChanges();
swipe(testComponent.nzCarouselComponent, -10);
tickMilliseconds(fixture, 700);
expect(carouselContents[0].nativeElement.classList).toContain('slick-active');
swipe(testComponent.nzCarouselComponent, -1000);
tickMilliseconds(fixture, 700);
expect(carouselContents[0].nativeElement.classList).toContain('slick-active');

testComponent.loop = true;
fixture.detectChanges();
swipe(testComponent.nzCarouselComponent, -1000);
tickMilliseconds(fixture, 700);
expect(carouselContents[3].nativeElement.classList).toContain('slick-active');
swipe(testComponent.nzCarouselComponent, 1000);
tickMilliseconds(fixture, 700);
expect(carouselContents[0].nativeElement.classList).toContain('slick-active');

testComponent.loop = false;
testComponent.autoPlay = true;
testComponent.autoPlaySpeed = 1000;
fixture.detectChanges();
tick(10000);
expect(carouselContents[3].nativeElement.classList).toContain('slick-active');
tick(1000 + 10);
expect(carouselContents[3].nativeElement.classList).toContain('slick-active');
}));
});

describe('strategies', () => {
Expand Down Expand Up @@ -406,6 +435,7 @@ function swipe(carousel: NzCarouselComponent, distance: number): void {
[nzDotRender]="dotRender"
[nzAutoPlay]="autoPlay"
[nzAutoPlaySpeed]="autoPlaySpeed"
[nzLoop]="loop"
(nzAfterChange)="afterChange($event)"
(nzBeforeChange)="beforeChange($event)"
>
Expand All @@ -426,6 +456,7 @@ export class NzTestCarouselBasicComponent {
array = [1, 2, 3, 4];
autoPlay = false;
autoPlaySpeed = 3000;
loop = true;
afterChange = jasmine.createSpy('afterChange callback');
beforeChange = jasmine.createSpy('beforeChange callback');
}
Expand Down
14 changes: 14 additions & 0 deletions components/carousel/demo/loop.md
@@ -0,0 +1,14 @@
---
order: 5
title:
zh-CN: 循环
en-US: Loop
---

## zh-CN

防止轮播进入循环

## en-US

Prevent the carousel to go in a loop
34 changes: 34 additions & 0 deletions components/carousel/demo/loop.ts
@@ -0,0 +1,34 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-carousel-loop',
template: `
<nz-carousel nzAutoPlay [nzEffect]="effect" [nzLoop]="false">
<div nz-carousel-content *ngFor="let index of array">
<h3>{{ index }}</h3>
</div>
</nz-carousel>
`,
styles: [
`
[nz-carousel-content] {
text-align: center;
height: 160px;
line-height: 160px;
background: #364d79;
color: #fff;
overflow: hidden;
}
h3 {
color: #fff;
margin-bottom: 0;
user-select: none;
}
`
]
})
export class NzDemoCarouselLoopComponent {
array = [1, 2, 3, 4];
effect = 'scrollx';
}
1 change: 1 addition & 0 deletions components/carousel/doc/index.en-US.md
Expand Up @@ -30,6 +30,7 @@ import { NzCarouselModule } from 'ng-zorro-antd/carousel';
| `[nzDots]` | Whether to show the dots at the bottom of the gallery | `boolean` | `true` ||
| `[nzEffect]` | Transition effect | `'scrollx'\|'fade'` | `'scrollx'` ||
| `[nzEnableSwipe]` | Whether to support swipe gesture | `boolean` | `true` ||
| `[nzLoop]` | Whether to enable the carousel to go in a loop | `boolean` | `true` ||
| `(nzAfterChange)` | Callback function called after the current index changes | `EventEmitter<number>` | - |
| `(nzBeforeChange)` | Callback function called before the current index changes | `EventEmitter{ from: number; to: number }>` | - |

Expand Down
1 change: 1 addition & 0 deletions components/carousel/doc/index.zh-CN.md
Expand Up @@ -31,6 +31,7 @@ import { NzCarouselModule } from 'ng-zorro-antd/carousel';
| `[nzDots]` | 是否显示面板指示点 | `boolean` | `true` ||
| `[nzEffect]` | 动画效果函数,可取 `scrollx`, `fade` | `'scrollx'\|'fade'`|`'scrollx'` ||
| `[nzEnableSwipe]` | 是否支持手势划动切换 | `boolean` | `true` ||
| `[nzLoop]` | 是否支持循环 | `boolean` | `true` ||
| `(nzAfterChange)` | 切换面板的回调 | `EventEmitter<number>` | - |
| `(nzBeforeChange)` | 切换面板的回调 | `EventEmitter<{ from: number; to: number }>` | - |

Expand Down
1 change: 1 addition & 0 deletions components/core/config/config.ts
Expand Up @@ -160,6 +160,7 @@ export interface CarouselConfig {
nzEffect?: 'scrollx' | 'fade' | string;
nzEnableSwipe?: boolean;
nzVertical?: boolean;
nzLoop?: boolean;
}

export interface CascaderConfig {
Expand Down
7 changes: 7 additions & 0 deletions components/core/util/text-mesure.spec.ts
@@ -0,0 +1,7 @@
import { pxToNumber } from './text-measure';

describe('pxToNumber', () => {
it('should return 0 when value is null', () => {
expect(pxToNumber(null)).toBe(0);
});
});

0 comments on commit e3103f0

Please sign in to comment.