feat: add optional to support top and left slick dots (#16186) (#16225)

* add optional to support top and left slick dots

* update carousel snapshot

* Update doc, add placement demo

* update carousel placement demo snapshots

* rename dots placement to position

* update vertical as deprecated

* rename dotsPosition to dotPosition

* refine code

* add warning testcase for vertical

* remove unused warning

* update expression

* Additional test case for dotPosition
This commit is contained in:
Eden Wang 2019-04-29 17:24:06 +08:00 committed by zombieJ
parent 6e6e1ecadc
commit 19f0ca4a2f
11 changed files with 556 additions and 253 deletions

View File

@ -180,7 +180,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
@ -396,7 +396,7 @@ exports[`renders ./components/carousel/demo/basic.md correctly 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
@ -522,7 +522,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
@ -558,12 +558,95 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
</div>
`;
exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
<div
class="ant-carousel ant-carousel-vertical"
>
exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
<div>
<div
class="slick-slider slick-vertical slick-initialized"
class="ant-radio-group ant-radio-group-outline"
style="margin-bottom:8px"
>
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
>
<span
class="ant-radio-button ant-radio-button-checked"
>
<input
checked=""
class="ant-radio-button-input"
type="radio"
value="top"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Top
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="bottom"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Bottom
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="left"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Left
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="right"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Right
</span>
</label>
</div>
<div
class="ant-carousel"
>
<div
class="slick-slider slick-initialized"
dir="ltr"
>
<div
@ -738,7 +821,7 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-top"
style="display:block"
>
<li
@ -771,5 +854,6 @@ exports[`renders ./components/carousel/demo/vertical.md correctly 1`] = `
</li>
</ul>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,137 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Carousel should works for dotPosition bottom 1`] = `
<div
class="ant-carousel"
>
<div
class="slick-slider slick-initialized"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Carousel should works for dotPosition left 1`] = `
<div
class="ant-carousel ant-carousel-vertical"
>
<div
class="slick-slider slick-vertical slick-initialized"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Carousel should works for dotPosition right 1`] = `
<div
class="ant-carousel ant-carousel-vertical"
>
<div
class="slick-slider slick-vertical slick-initialized"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`Carousel should works for dotPosition top 1`] = `
<div
class="ant-carousel"
>
<div
class="slick-slider slick-initialized"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -78,4 +78,31 @@ describe('Carousel', () => {
expect(spy).toHaveBeenCalled();
expect(spy2).toHaveBeenCalledWith('resize', onWindowResized);
});
describe('should works for dotPosition', () => {
['left', 'right', 'top', 'bottom'].forEach(dotPosition => {
it(dotPosition, () => {
const wrapper = mount(
<Carousel dotPosition={dotPosition}>
<div />
</Carousel>,
);
jest.runAllTimers();
expect(wrapper.render()).toMatchSnapshot();
});
});
});
it('warning', () => {
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(
<Carousel vertical>
<div />
</Carousel>,
);
expect(warnSpy).toHaveBeenCalledWith(
'Warning: [antd: Carousel] `vertical` is deprecated, please use `dotPosition` instead.',
);
warnSpy.mockRestore();
});
});

View File

@ -1,5 +1,5 @@
---
order: 2
order: 3
title:
zh-CN: 渐显
en-US: Fade in

View File

@ -0,0 +1,63 @@
---
order: 2
title:
zh-CN: 位置
en-US: Position
---
## zh-CN
位置有 4 个方向。
## en-US
There are 4 position options available.
````jsx
import { Carousel, Radio } from 'antd';
class PositionCarouselDemo extends React.Component {
state = {
dotPosition: 'top',
};
handlePositionChange = ({ target: { value: dotPosition } }) => this.setState({ dotPosition });
render() {
const { dotPosition } = this.state;
return (
<div>
<Radio.Group onChange={this.handlePositionChange} value={dotPosition} style={{ marginBottom: 8 }}>
<Radio.Button value="top">Top</Radio.Button>
<Radio.Button value="bottom">Bottom</Radio.Button>
<Radio.Button value="left">Left</Radio.Button>
<Radio.Button value="right">Right</Radio.Button>
</Radio.Group>
<Carousel dotPosition={dotPosition}>
<div><h3>1</h3></div>
<div><h3>2</h3></div>
<div><h3>3</h3></div>
<div><h3>4</h3></div>
</Carousel>
</div>
);
}
}
ReactDOM.render(<PositionCarouselDemo />, mountNode);
````
````css
/* For demo */
.ant-carousel .slick-slide {
text-align: center;
height: 160px;
line-height: 160px;
background: #364d79;
overflow: hidden;
}
.ant-carousel .slick-slide h3 {
color: #fff;
}
````

View File

@ -1,43 +0,0 @@
---
order: 1
title:
zh-CN: 垂直
en-US: Vertical
---
## zh-CN
垂直显示。
## en-US
Vertical pagination.
````jsx
import { Carousel } from 'antd';
ReactDOM.render(
<Carousel vertical>
<div><h3>1</h3></div>
<div><h3>2</h3></div>
<div><h3>3</h3></div>
<div><h3>4</h3></div>
</Carousel>,
mountNode
);
````
````css
/* For demo */
.ant-carousel .slick-slide {
text-align: center;
height: 160px;
line-height: 160px;
background: #364d79;
overflow: hidden;
}
.ant-carousel .slick-slide h3 {
color: #fff;
}
````

View File

@ -14,15 +14,15 @@ A carousel component. Scales with its container.
## 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` |
| 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) | - | |
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | bottom | 3.17.0 |
| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` | |
| easing | Transition interpolation function name | string | `linear` | |
| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |
## Methods

View File

@ -2,6 +2,7 @@ import * as React from 'react';
import debounce from 'lodash/debounce';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { Settings } from 'react-slick';
import warning from '../_util/warning';
// matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82
@ -23,12 +24,15 @@ if (typeof window !== 'undefined') {
const SlickCarousel = require('react-slick').default;
export type CarouselEffect = 'scrollx' | 'fade';
export type DotPosition = 'top' | 'bottom' | 'left' | 'right';
// Carousel
export interface CarouselProps extends Settings {
effect?: CarouselEffect;
style?: React.CSSProperties;
prefixCls?: string;
slickGoTo?: number;
dotPosition?: DotPosition;
}
export default class Carousel extends React.Component<CarouselProps, {}> {
@ -47,6 +51,14 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
this.onWindowResized = debounce(this.onWindowResized, 500, {
leading: false,
});
if ('vertical' in this.props) {
warning(
!this.props.vertical,
'Carousel',
'`vertical` is deprecated, please use `dotPosition` instead.',
);
}
}
componentDidMount() {
@ -90,6 +102,15 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
this.slick.slickGoTo(slide, dontAnimate);
}
getDotPosition(): DotPosition {
if (this.props.dotPosition) {
return this.props.dotPosition;
} else if ('vertical' in this.props) {
return this.props.vertical ? 'right' : 'bottom';
}
return 'bottom';
}
renderCarousel = ({ getPrefixCls }: ConfigConsumerProps) => {
const props = {
...this.props,
@ -100,6 +121,10 @@ export default class Carousel extends React.Component<CarouselProps, {}> {
}
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'}`;
if (props.vertical) {
className = `${className} ${className}-vertical`;
}

View File

@ -15,15 +15,15 @@ subtitle: 走马灯
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| afterChange | 切换面板的回调 | function(current) | 无 |
| autoplay | 是否自动切换 | boolean | false |
| beforeChange | 切换面板的回调 | function(from, to) | 无 |
| dots | 是否显示面板指示点 | boolean | true |
| 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 | 3.17.0 |
| dots | 是否显示面板指示点 | boolean | true | |
| easing | 动画效果 | string | linear | |
| effect | 动画效果函数,可取 scrollx, fade | string | scrollx | |
## 方法

View File

@ -146,7 +146,6 @@
// Dots
.slick-dots {
position: absolute;
bottom: 12px;
display: block;
width: 100%;
height: @carousel-dot-height;
@ -154,6 +153,12 @@
padding: 0;
text-align: center;
list-style: none;
&-bottom {
bottom: 12px;
}
&-top {
top: 12px;
}
li {
position: relative;
display: inline-block;
@ -196,11 +201,16 @@
.@{ant-prefix}-carousel-vertical {
.slick-dots {
top: 50%;
right: 12px;
bottom: auto;
width: @carousel-dot-height;
height: auto;
transform: translateY(-50%);
&-left {
left: 12px;
}
&-right {
right: 12px;
}
li {
margin: 0 2px;
vertical-align: baseline;

View File

@ -5517,7 +5517,7 @@ exports[`ConfigProvider components Carousel configProvider 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
@ -5647,7 +5647,7 @@ exports[`ConfigProvider components Carousel normal 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
@ -5777,7 +5777,7 @@ exports[`ConfigProvider components Carousel prefixCls 1`] = `
</div>
</div>
<ul
class="slick-dots"
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li