Merge pull request #3921 from blue-squirrel/feat-carousel-event-action

feat: Carousel轮播图组件事件&动作补充
This commit is contained in:
hsm-lv 2022-03-31 19:29:22 +08:00 committed by GitHub
commit 6cf77d0585
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 7 deletions

View File

@ -2,7 +2,7 @@ import React = require('react');
import {render, fireEvent} from '@testing-library/react';
import '../../src/themes/default';
import {render as amisRender} from '../../src/index';
import {makeEnv} from '../helper';
import {makeEnv, wait} from '../helper';
test('Renderer:carousel', async () => {
const {container} = render(
@ -44,5 +44,6 @@ test('Renderer:carousel', async () => {
const rightArrow = document.querySelector('div.cxd-Carousel-rightArrow');
fireEvent.click(rightArrow as HTMLDivElement);
await wait(500);
expect(container).toMatchSnapshot();
});

View File

@ -1149,6 +1149,7 @@ test('Renderer:Page initApi reload by Dialog action', async () => {
await wait(1000);
expect(container).toMatchSnapshot();
await wait(1000);
expect(fetcher).toHaveBeenCalledTimes(2);
});

View File

@ -717,6 +717,7 @@ test('Renderer:Wizard send data', async () => {
website: 'http://amis.baidu.com'
}
});
await wait(1000);
expect(container).toMatchSnapshot();
});

View File

@ -10,7 +10,7 @@ exports[`Renderer:carousel 1`] = `
class="cxd-Carousel-container"
>
<div
class="cxd-Carousel-item fade in"
class="cxd-Carousel-item fade out"
>
<div
class="cxd-Image cxd-Image--original cxd-Carousel-image"
@ -35,6 +35,19 @@ exports[`Renderer:carousel 1`] = `
</div>
</div>
</div>
<div
class="cxd-Carousel-item fade in"
>
<span
class="cxd-Html"
>
<div
style="width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;"
>
carousel data
</div>
</span>
</div>
<div
class="cxd-Carousel-item fade out"
>
@ -56,10 +69,10 @@ exports[`Renderer:carousel 1`] = `
class="cxd-Carousel-dotsControl"
>
<span
class="cxd-Carousel-dot is-active"
class="cxd-Carousel-dot"
/>
<span
class="cxd-Carousel-dot"
class="cxd-Carousel-dot is-active"
/>
<span
class="cxd-Carousel-dot"

View File

@ -127,6 +127,20 @@ itemSchema: {
| animation | `string` | fade | 切换动画效果,默认`fade`,另有`slide`模式 |
| thumbMode | `string` | `"cover" \| "contain"` | 图片默认缩放模式 |
## 事件表
| 事件名称 | 事件参数 | 说明 |
|-------------------|------------------------------------------------|----------------------|
| change | `activeIndex: number` 激活图片的索引 <br> `prevIndex: number` 上一张图片的索引 | 轮播图切换时触发 |
## 动作表
| 动作名称 | 动作配置 | 说明 |
|-------------------|-------------------------|------------------------|
| next | - | 下一张 |
| prev | - | 上一张 |
| goto-image | `activeIndex: number` 切换图片的索引 | 切换轮播图 |
- `type` 请设置成 `carousel`
- `className` 外层 Dom 的类名
- `options` 轮播面板数据,默认`[]`,支持以下模式

View File

@ -13,6 +13,7 @@ import {
isArrayChildrenModified,
getPropValue
} from '../utils/helper';
import {Action} from '../types';
import {Icon} from '../components/icons';
import {BaseSchema, SchemaCollection, SchemaName, SchemaTpl} from '../Schema';
import Html from '../components/Html';
@ -191,6 +192,17 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
this.clearAutoTimeout();
}
doAction(action: Action, data: object, throwErrors: boolean): any {
const actionType = action?.actionType as string;
if (!!~['next', 'prev'].indexOf(actionType)) {
this.autoSlide(actionType);
}
else if (actionType === 'goto-image') {
this.changeSlide((data as any).activeIndex);
}
}
@autobind
prepareAutoSlide() {
if (this.state.options.length < 2) {
@ -230,9 +242,9 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
}
@autobind
transitFramesTowards(direction: string, nextAnimation: string) {
async transitFramesTowards(direction: string, nextAnimation: string) {
let {current} = this.state;
let prevIndex = current;
switch (direction) {
case 'left':
current = this.getFrameId('next');
@ -242,6 +254,18 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
break;
}
const {dispatchEvent, data} = this.props;
const rendererEvent = await dispatchEvent(
'change',
createObject(data, {
activeIndex: current,
prevIndex
})
);
if (rendererEvent?.prevented) {
return;
}
this.setState({
current,
nextAnimation
@ -279,7 +303,21 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
}
@autobind
changeSlide(index: number) {
async changeSlide(index: number) {
const {current} = this.state;
const {dispatchEvent, data} = this.props;
const rendererEvent = await dispatchEvent(
'change',
createObject(data, {
activeIndex: index,
prevIndex: current
})
);
if (rendererEvent?.prevented) {
return;
}
this.setState({
current: index
});

View File

@ -107,6 +107,7 @@ export interface Action extends Button {
| 'clear-and-submit'
| 'toast'
| 'goto-step'
| 'goto-image'
| 'expand'
| 'collapse'
| 'step-submit'