Skip to content

Commit

Permalink
feat(Slider): support rtl
Browse files Browse the repository at this point in the history
  • Loading branch information
youluna committed Dec 5, 2018
1 parent f65fe78 commit c7416ab
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/slider/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
outline: 0;
transition: all .3s cubic-bezier(.86, 0, .07, 1);

[dir="rtl"] & {
#{$slick-prefix}[dir="rtl"] & {
float: right;
}

Expand Down
1 change: 1 addition & 0 deletions src/slider/slick/arrow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const {noop} = func;
export default class Arrow extends Component {
static propTypes = {
prefix: PropTypes.string,
rtl: PropTypes.bool,
type: PropTypes.oneOf(['prev', 'next']).isRequired,
centerMode: PropTypes.bool,
currentSlide: PropTypes.number,
Expand Down
11 changes: 9 additions & 2 deletions src/slider/slick/dots.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class Dots extends React.Component {
}

render () {
const {prefix, slideCount, slidesToScroll, currentSlide, dotsClass, dotsDirection, dotsRender, triggerType} = this.props;
const {prefix, slideCount, slidesToScroll, currentSlide, dotsClass, dotsDirection, dotsRender, triggerType, rtl} = this.props;

const dotsClazz = classNames(`${prefix}slick-dots`, dotsDirection, dotsClass);
const dotCount = Math.ceil(slideCount / slidesToScroll);
Expand All @@ -58,12 +58,19 @@ export default class Dots extends React.Component {
[(triggerType.toLowerCase() === 'hover') ? 'onMouseEnter' : 'onClick']: this.handleChangeSlide.bind(this, dotOptions)
};

let docIndex = i;
let currentSlideIndex = i;
if (rtl) {
docIndex = dotCount - 1 - i;
currentSlideIndex = dotCount - 1 - currentSlide;
}

children.push(
<li key={i} className={itemClazz}>
{
(dotsRender instanceof Function) ?
<span {...handleProp}>
{dotsRender(i, currentSlide)}
{dotsRender(docIndex, currentSlideIndex)}
</span> :
<button {...handleProp} />
}
Expand Down
2 changes: 2 additions & 0 deletions src/slider/slick/inner-slider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ class InnerSlider extends React.Component {
if (dots === true && slideCount > slidesToShow) {
const dotProps = {
prefix,
rtl,
dotsClass,
slideCount,
slidesToShow,
Expand All @@ -269,6 +270,7 @@ class InnerSlider extends React.Component {

const arrowProps = {
prefix,
rtl,
arrowSize,
arrowPosition,
arrowDirection,
Expand Down
49 changes: 45 additions & 4 deletions src/slider/slick/mixins/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const helpers = {
const slideHeight = this.getHeight(slickList.querySelector('[data-index="0"]'));
const listHeight = slideHeight * props.slidesToShow;

const currentSlide = props.rtl ? slideCount - 1 - props.defaultActiveIndex : props.defaultActiveIndex;
const slidesToShow = props.slidesToShow || 1;
const currentSlide = props.rtl ? slideCount - 1 - (slidesToShow - 1) - props.defaultActiveIndex : props.defaultActiveIndex;

this.setState({
slideCount,
Expand Down Expand Up @@ -88,6 +89,8 @@ const helpers = {
},

slideHandler (index) {
const { rtl } = this.props;

// Functionality of animateSlide and postSlide is merged into this function
let targetSlide, currentSlide;
let callback;
Expand Down Expand Up @@ -139,7 +142,34 @@ const helpers = {
}

targetSlide = index;
if (targetSlide < 0) {

if (rtl) {
if (targetSlide < 0) {
if (this.props.infinite === false) {
currentSlide = 0;
} else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
if (targetSlide + this.props.slidesToScroll <= 0) {
currentSlide = this.state.slideCount + targetSlide;
targetSlide = this.state.slideCount - this.props.slidesToScroll;
} else {
currentSlide = targetSlide = 0;
}
} else {
// this.state.slideCount % this.props.slidesToScroll
currentSlide = this.state.slideCount + targetSlide;
}
} else if (targetSlide >= this.state.slideCount) {
if (this.props.infinite === false) {
currentSlide = this.state.slideCount - this.props.slidesToShow;
} else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
currentSlide = 0;
} else {
currentSlide = targetSlide - this.state.slideCount;
}
} else {
currentSlide = targetSlide;
}
} else if (targetSlide < 0) {
if (this.props.infinite === false) {
currentSlide = 0;
} else if (this.state.slideCount % this.props.slidesToScroll !== 0) {
Expand All @@ -159,6 +189,7 @@ const helpers = {
currentSlide = targetSlide;
}


let targetLeft = getTrackLeft({
slideIndex: targetSlide,
trackRef: this.track,
Expand All @@ -182,10 +213,20 @@ const helpers = {
const slidesToLoad = [];

const sliderIndex = (targetSlide < 0 ? this.state.slideCount + targetSlide : currentSlide);

for (let i = sliderIndex; i < sliderIndex + this.props.slidesToShow; i++) {
loaded = loaded && (this.state.lazyLoadedList.indexOf(i) >= 0);
let k = i;
if (rtl) {
k =
i >= this.state.slideCount ?
this.state.slideCount * 2 - i - 1 :
this.state.slideCount - i - 1;

}

loaded = loaded && (this.state.lazyLoadedList.indexOf(k) >= 0);
if (!loaded) {
slidesToLoad.push(i);
slidesToLoad.push(k);
}
}
if (!loaded) {
Expand Down
8 changes: 7 additions & 1 deletion src/slider/slick/mixins/trackHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ export const getTrackLeft = function(spec) {
verticalOffset = (spec.slideHeight * spec.slidesToShow) * -1;
}
if (spec.slideCount % spec.slidesToScroll !== 0) {
if (spec.slideIndex + spec.slidesToScroll > spec.slideCount && spec.slideCount > spec.slidesToShow) {
let condition = spec.slideIndex + spec.slidesToScroll > spec.slideCount && spec.slideCount > spec.slidesToShow;

if (spec.rtl) {
const slideIndex = spec.slideIndex >= spec.slideCount ? spec.slideCount - spec.slideIndex : spec.slideIndex;
condition = slideIndex + spec.slidesToScroll > spec.slideCount && spec.slideCount > spec.slidesToShow;
}
if (condition) {
if (spec.slideIndex > spec.slideCount) {
slideOffset = ((spec.slidesToShow - (spec.slideIndex - spec.slideCount)) * spec.slideWidth) * -1;
verticalOffset = ((spec.slidesToShow - (spec.slideIndex - spec.slideCount)) * spec.slideHeight) * -1;
Expand Down
14 changes: 7 additions & 7 deletions src/slider/slider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
import {obj} from '../util';
import InnerSlider from './slick/inner-slider';
import ConfigProvider from '../config-provider';

/**
* Slider
*/
export default class Slider extends Component {
static propTypes = {
/**
* 样式前缀
*/
prefix: PropTypes.string,
rtl: PropTypes.bool,
/**
* 自定义传入的样式
*/
Expand Down Expand Up @@ -90,7 +89,6 @@ export default class Slider extends Component {
* 是否启用懒加载
*/
lazyLoad: PropTypes.bool,
rtl: PropTypes.bool,
slide: PropTypes.string,
/**
* 轮播方向
Expand Down Expand Up @@ -230,9 +228,11 @@ export default class Slider extends Component {
}

return (
<div className={clazz} style={style} {...obj.pickOthers({...Slider.propTypes, ...InnerSlider.propTypes}, sliderProps)}>
<InnerSlider ref={InnerSlider => (this.innerSlider = InnerSlider)} {...sliderProps} />
</div>
<ConfigProvider rtl={false}>
<div dir="ltr" className={clazz} style={style} {...obj.pickOthers({...Slider.propTypes, ...InnerSlider.propTypes}, sliderProps)}>
<InnerSlider ref={InnerSlider => (this.innerSlider = InnerSlider)} {...sliderProps} />
</div>
</ConfigProvider>
);
}
}
Expand Down

0 comments on commit c7416ab

Please sign in to comment.