-
-
`;
diff --git a/components/carousel/__tests__/__snapshots__/index.test.js.snap b/components/carousel/__tests__/__snapshots__/index.test.js.snap
new file mode 100644
index 000000000..fed7985b7
--- /dev/null
+++ b/components/carousel/__tests__/__snapshots__/index.test.js.snap
@@ -0,0 +1,65 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Carousel should works for dotPosition bottom 1`] = `
+
+`;
+
+exports[`Carousel should works for dotPosition left 1`] = `
+
+`;
+
+exports[`Carousel should works for dotPosition right 1`] = `
+
+`;
+
+exports[`Carousel should works for dotPosition top 1`] = `
+
+`;
diff --git a/components/carousel/__tests__/index.test.js b/components/carousel/__tests__/index.test.js
index 2b39209cf..a14652f38 100644
--- a/components/carousel/__tests__/index.test.js
+++ b/components/carousel/__tests__/index.test.js
@@ -1,14 +1,23 @@
import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
import Carousel from '..';
+import mountTest from '../../../tests/shared/mountTest';
describe('Carousel', () => {
+ mountTest(Carousel);
+ // beforeEach(() => {
+ // jest.useFakeTimers();
+ // });
+
+ // afterEach(() => {
+ // jest.useRealTimers();
+ // });
it('should has innerSlider', () => {
const props = {
slots: {
default: '
',
},
- sync: true,
+ sync: false,
};
const wrapper = mount(Carousel, props);
const { innerSlider, $refs } = wrapper.vm;
@@ -22,7 +31,7 @@ describe('Carousel', () => {
slots: {
default: '
1
2
3
',
},
- sync: true,
+ sync: false,
};
const wrapper = mount(Carousel, props);
const { prev, next, goTo } = wrapper.vm;
@@ -56,14 +65,14 @@ describe('Carousel', () => {
slots: {
default: '
1
2
3
',
},
- sync: true,
+ sync: false,
};
const wrapper = mount(Carousel, props);
const spy = jest.spyOn(wrapper.vm.$refs.slick.innerSlider, 'handleAutoPlay');
window.resizeTo(1000);
- expect(spy).not.toBeCalled();
+ expect(spy).not.toHaveBeenCalled();
await new Promise(resolve => setTimeout(resolve, 1000));
- expect(spy).toBeCalled();
+ expect(spy).toHaveBeenCalled();
});
it('cancel resize listener when unmount', async () => {
@@ -74,14 +83,48 @@ describe('Carousel', () => {
slots: {
default: '
1
2
3
',
},
- sync: true,
+ sync: false,
};
const wrapper = mount(Carousel, props);
const { onWindowResized } = wrapper.vm;
const spy = jest.spyOn(wrapper.vm.onWindowResized, 'cancel');
const spy2 = jest.spyOn(window, 'removeEventListener');
wrapper.destroy();
- expect(spy).toBeCalled();
- expect(spy2).toBeCalledWith('resize', onWindowResized);
+ expect(spy).toHaveBeenCalled();
+ expect(spy2).toHaveBeenCalledWith('resize', onWindowResized);
+ });
+
+ describe('should works for dotPosition', () => {
+ ['left', 'right', 'top', 'bottom'].forEach(dotPosition => {
+ it(dotPosition, () => {
+ const wrapper = mount({
+ render() {
+ return (
+
+
+
+ );
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+ });
+ });
+
+ it('warning', () => {
+ const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount({
+ render() {
+ return (
+
+
+
+ );
+ },
+ });
+ expect(warnSpy).toHaveBeenCalledWith(
+ 'Warning: [antdv: Carousel] `vertical` is deprecated, please use `dotPosition` instead.',
+ );
+ warnSpy.mockRestore();
});
});
diff --git a/components/carousel/demo/index.vue b/components/carousel/demo/index.vue
index 61a6245cc..510018eb0 100644
--- a/components/carousel/demo/index.vue
+++ b/components/carousel/demo/index.vue
@@ -2,7 +2,7 @@
import Basic from './basic';
import Fade from './fade';
import Autoplay from './autoplay';
-import Vertical from './vertical';
+import Position from './position';
import CustomPaging from './customPaging';
import CustomArrows from './customArrows';
@@ -42,7 +42,7 @@ export default {
-
+
diff --git a/components/carousel/demo/position.md b/components/carousel/demo/position.md
new file mode 100644
index 000000000..1c7bdb8cb
--- /dev/null
+++ b/components/carousel/demo/position.md
@@ -0,0 +1,54 @@
+
+#### 位置
+位置有 4 个方向。
+
+
+
+#### Position
+There are 4 position options available.
+
+
+```tpl
+
+
+
+ Top
+ Bottom
+ Left
+ Right
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+```
diff --git a/components/carousel/demo/vertical.md b/components/carousel/demo/vertical.md
deleted file mode 100644
index 6d866c700..000000000
--- a/components/carousel/demo/vertical.md
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#### 垂直
-垂直显示。
-
-
-
-#### Vertical
-Vertical pagination.
-
-
-```tpl
-
-
- 1
- 2
- 3
- 4
-
-
-
-
-```
diff --git a/components/carousel/index.en-US.md b/components/carousel/index.en-US.md
index 2495904f2..ec54998ca 100644
--- a/components/carousel/index.en-US.md
+++ b/components/carousel/index.en-US.md
@@ -1,22 +1,18 @@
## API
-| Property | Description | Type | Default |
-| --- | --- | --- | --- |
-| afterChange | Callback function called after the current index changes | function(current) | - |
-| autoplay | Whether to scroll automatically | boolean | `false` |
-| beforeChange | Callback function called before the current index changes | function(from, to) | - |
-| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` |
-| dotsClass | Class name of the dots | string | `slick-dots` |
-| easing | Transition interpolation function name | string | `linear` |
-| effect | Transition effect | `scrollx` \| `fade` | `scrollx` |
-| vertical | Whether to use a vertical display | boolean | `false` |
+| Property | Description | Type | Default | Version |
+| --- | --- | --- | --- | --- |
+| afterChange | Callback function called after the current index changes | function(current) | - | |
+| autoplay | Whether to scroll automatically | boolean | `false` | |
+| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
+| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` | |
+| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | bottom | 1.5.0 |
+| dotsClass | Class name of the dots | string | `slick-dots` | |
+| easing | Transition interpolation function name | string | `linear` | |
+| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |
## Methods
-| Name | Description |
-| --- | --- |
-| goTo(slideNumber, dontAnimate) | Go to slide index, if dontAnimate=true, it happens without animation |
-| next() | Change current slide to next slide |
-| prev() | Change current slide to previous slide |
+| Name | Description | Version | | --- | --- | --- | Version | | goTo(slideNumber, dontAnimate) | Go to slide index, if dontAnimate=true, it happens without animation | | | next() | Change current slide to next slide | | | prev() | Change current slide to previous slide | |
For more info on the parameters, refer to the [vc-slick props](https://github.com/vueComponent/ant-design-vue/blob/master/components/vc-slick/src/default-props.js#L3)
diff --git a/components/carousel/index.jsx b/components/carousel/index.jsx
index 3a8c003e8..60b42f87e 100644
--- a/components/carousel/index.jsx
+++ b/components/carousel/index.jsx
@@ -1,6 +1,6 @@
import PropTypes from '../_util/vue-types';
import debounce from 'lodash/debounce';
-import {
+import hasProp, {
initDefaultProps,
getComponentFromProp,
filterEmpty,
@@ -8,6 +8,7 @@ import {
} from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
import Base from '../base';
+import warning from '../_util/warning';
// matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82
@@ -20,7 +21,8 @@ if (typeof window !== 'undefined') {
removeListener() {},
};
};
- window.matchMedia = window.matchMedia || matchMediaPolyfill;
+ // ref: https://github.com/ant-design/ant-design/issues/18774
+ if (!window.matchMedia) window.matchMedia = matchMediaPolyfill;
}
// Use require over import (will be lifted up)
// make sure matchMedia polyfill run before require('vc-slick')
@@ -71,6 +73,7 @@ export const CarouselProps = {
useCSS: PropTypes.bool,
slickGoTo: PropTypes.number,
responsive: PropTypes.array,
+ dotPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
};
const Carousel = {
@@ -91,6 +94,13 @@ const Carousel = {
},
mounted() {
+ if (hasProp(this, 'vertical')) {
+ warning(
+ !this.vertical,
+ 'Carousel',
+ '`vertical` is deprecated, please use `dotPosition` instead.',
+ );
+ }
const { autoplay } = this;
if (autoplay) {
window.addEventListener('resize', this.onWindowResized);
@@ -98,7 +108,6 @@ const Carousel = {
// https://github.com/ant-design/ant-design/issues/7191
this.innerSlider = this.$refs.slick && this.$refs.slick.innerSlider;
},
-
beforeDestroy() {
const { autoplay } = this;
if (autoplay) {
@@ -107,6 +116,15 @@ const Carousel = {
}
},
methods: {
+ getDotPosition() {
+ if (this.dotPosition) {
+ return this.dotPosition;
+ }
+ if (hasProp(this, 'vertical')) {
+ return this.vertical ? 'right' : 'bottom';
+ }
+ return 'bottom';
+ },
onWindowResized() {
// Fix https://github.com/ant-design/ant-design/issues/2550
const { autoplay } = this;
@@ -134,9 +152,7 @@ const Carousel = {
},
render() {
- const props = {
- ...this.$props,
- };
+ const props = { ...this.$props };
const { $slots } = this;
if (props.effect === 'fade') {
@@ -145,7 +161,10 @@ const Carousel = {
const getPrefixCls = this.configProvider.getPrefixCls;
let className = getPrefixCls('carousel', props.prefixCls);
-
+ const dotsClass = 'slick-dots';
+ const dotPosition = this.getDotPosition();
+ props.vertical = dotPosition === 'left' || dotPosition === 'right';
+ props.dotsClass = `${dotsClass} ${dotsClass}-${dotPosition || 'bottom'} ${props.dotsClass}`;
if (props.vertical) {
className = `${className} ${className}-vertical`;
}
@@ -158,11 +177,11 @@ const Carousel = {
on: getListeners(this),
scopedSlots: this.$scopedSlots,
};
-
+ const children = filterEmpty($slots.default);
return (
- {filterEmpty($slots.default)}
+ {children}
);
diff --git a/components/carousel/index.zh-CN.md b/components/carousel/index.zh-CN.md
index af34cb73b..add985487 100644
--- a/components/carousel/index.zh-CN.md
+++ b/components/carousel/index.zh-CN.md
@@ -1,22 +1,22 @@
## API
-| 参数 | 说明 | 类型 | 默认值 |
-| ------------ | -------------------------------- | ------------------ | ------------ |
-| afterChange | 切换面板的回调 | function(current) | 无 |
-| autoplay | 是否自动切换 | boolean | false |
-| beforeChange | 切换面板的回调 | function(from, to) | 无 |
-| dots | 是否显示面板指示点 | boolean | true |
-| dotsClass | 面板指示点类名 | string | `slick-dots` |
-| easing | 动画效果 | string | linear |
-| effect | 动画效果函数,可取 scrollx, fade | string | scrollx |
-| vertical | 垂直显示 | boolean | false |
+| 参数 | 说明 | 类型 | 默认值 | 版本 |
+| --- | --- | --- | --- | --- |
+| afterChange | 切换面板的回调 | function(current) | 无 | |
+| autoplay | 是否自动切换 | boolean | false | |
+| beforeChange | 切换面板的回调 | function(from, to) | 无 | |
+| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | bottom | 1.5.0 |
+| dots | 是否显示面板指示点 | boolean | true | |
+| dotsClass | 面板指示点类名 | string | `slick-dots` | |
+| easing | 动画效果 | string | linear | |
+| effect | 动画效果函数,可取 scrollx, fade | string | scrollx | |
## 方法
-| 名称 | 描述 |
-| ------------------------------ | ------------------------------------------------- |
-| goTo(slideNumber, dontAnimate) | 切换到指定面板, dontAnimate = true 时,不使用动画 |
-| next() | 切换到下一面板 |
-| prev() | 切换到上一面板 |
+| 名称 | 描述 | 版本 |
+| ------------------------------ | ------------------------------------------------- | ---- |
+| goTo(slideNumber, dontAnimate) | 切换到指定面板, dontAnimate = true 时,不使用动画 | |
+| next() | 切换到下一面板 | |
+| prev() | 切换到上一面板 | |
更多参数可参考:[vc-slick props](https://github.com/vueComponent/ant-design-vue/blob/master/components/vc-slick/src/default-props.js#L3)
diff --git a/types/carousel.d.ts b/types/carousel.d.ts
index 3b37e8307..a79b90d7e 100644
--- a/types/carousel.d.ts
+++ b/types/carousel.d.ts
@@ -4,6 +4,7 @@
import { AntdComponent } from './component';
+export type DotPosition = 'top' | 'bottom' | 'left' | 'right';
export interface Settings {
accessibility?: boolean;
adaptiveHeight?: boolean;
@@ -12,7 +13,6 @@ export interface Settings {
autoplay?: boolean;
centerMode?: boolean;
centerPadding?: string;
- className?: string;
cssEase?: string;
dotsClass?: string;
dots?: boolean;
@@ -44,12 +44,13 @@ export interface Settings {
vertical?: boolean;
verticalSwiping?: boolean;
waitForAnimate?: boolean;
+ dotPosition?: DotPosition;
}
export interface ResponsiveObject {
breakpoint: number;
settings: 'unslick' | Settings;
}
-export declare class Carousel extends AntdComponent {
+export declare class Carousel extends Settings, AntdComponent {
/**
* Callback function called after the current index changes
* @type Function