@yncoder/element-react
Version:
Element UI for React
334 lines (277 loc) • 9.88 kB
JavaScript
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React from 'react';
import { throttle } from 'throttle-debounce';
import { Component, PropTypes, Transition, View } from '../../libs';
import { addResizeListener, removeResizeListener } from '../../libs/utils/resize-event';
var Carousel = function (_Component) {
_inherits(Carousel, _Component);
function Carousel(props) {
_classCallCheck(this, Carousel);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_this.state = {
items: [],
activeIndex: -1,
containerWidth: 0,
timer: null,
hover: false
};
_this.throttledArrowClick = throttle(300, true, function (index) {
_this.setActiveItem(index);
});
_this.throttledIndicatorHover = throttle(300, function (index) {
_this.handleIndicatorHover(index);
});
_this.resetItemPosition = _this._resetItemPosition.bind(_this);
return _this;
}
Carousel.prototype.getChildContext = function getChildContext() {
return {
component: this
};
};
Carousel.prototype.componentDidMount = function componentDidMount() {
if (this.props.initialIndex < this.state.items.length && this.props.initialIndex >= 0) {
this.setState({
activeIndex: this.props.initialIndex
});
}
this.startTimer();
};
Carousel.prototype.componentDidUpdate = function componentDidUpdate(props, state) {
addResizeListener(this.refs.root, this.resetItemPosition);
if (state.activeIndex != this.state.activeIndex) {
this.resetItemPosition(state.activeIndex);
if (this.props.onChange) {
this.props.onChange(this.state.activeIndex, state.activeIndex);
}
}
};
Carousel.prototype.componentWillUnmount = function componentWillUnmount() {
removeResizeListener(this.refs.root, this.resetItemPosition);
this.pauseTimer();
};
Carousel.prototype.handleMouseEnter = function handleMouseEnter() {
this.setState({ hover: true });
this.pauseTimer();
};
Carousel.prototype.handleMouseLeave = function handleMouseLeave() {
this.setState({ hover: false });
this.startTimer();
};
Carousel.prototype.itemInStage = function itemInStage(item, index) {
var length = this.state.items.length;
if (index === length - 1 && item.state.inStage && this.state.items[0].state.active || item.state.inStage && this.state.items[index + 1] && this.state.items[index + 1].state.active) {
return 'left';
} else if (index === 0 && item.state.inStage && this.state.items[length - 1].state.active || item.state.inStage && this.state.items[index - 1] && this.state.items[index - 1].state.active) {
return 'right';
}
return false;
};
Carousel.prototype.handleButtonEnter = function handleButtonEnter(arrow) {
var _this2 = this;
this.state.items.forEach(function (item, index) {
if (arrow === _this2.itemInStage(item, index)) {
item.setState({ hover: true });
}
});
};
Carousel.prototype.handleButtonLeave = function handleButtonLeave() {
this.state.items.forEach(function (item) {
item.setState({ hover: false });
});
};
Carousel.prototype._resetItemPosition = function _resetItemPosition(oldIndex) {
var _this3 = this;
this.state.items.forEach(function (item, index) {
item.translateItem(index, _this3.state.activeIndex, oldIndex);
});
};
Carousel.prototype.playSlides = function playSlides() {
var activeIndex = this.state.activeIndex;
if (activeIndex < this.state.items.length - 1) {
activeIndex++;
} else {
activeIndex = 0;
}
this.setState({ activeIndex: activeIndex });
};
Carousel.prototype.pauseTimer = function pauseTimer() {
clearInterval(this.timer);
};
Carousel.prototype.startTimer = function startTimer() {
if (this.props.interval <= 0 || !this.props.autoplay) return;
this.timer = setInterval(this.playSlides.bind(this), Number(this.props.interval));
};
Carousel.prototype.addItem = function addItem(item) {
this.state.items.push(item);
this.setActiveItem(0);
};
Carousel.prototype.removeItem = function removeItem(item) {
this.state.items.splice(this.state.items.indexOf(item), 1);
this.setActiveItem(0);
};
Carousel.prototype.setActiveItem = function setActiveItem(index) {
var activeIndex = this.state.activeIndex;
if (typeof index === 'string') {
var filteredItems = this.state.items.filter(function (item) {
return item.props.name === index;
});
if (filteredItems.length > 0) {
index = this.state.items.indexOf(filteredItems[0]);
}
}
index = Number(index);
if (isNaN(index) || index !== Math.floor(index)) {
process.env.NODE_ENV !== 'production' && console.warn('[Element Warn][Carousel]index must be an integer.');
return;
}
var length = this.state.items.length;
if (index < 0) {
activeIndex = length - 1;
} else if (index >= length) {
activeIndex = 0;
} else {
activeIndex = index;
}
this.setState({ activeIndex: activeIndex });
};
Carousel.prototype.prev = function prev() {
this.setActiveItem(this.state.activeIndex - 1);
};
Carousel.prototype.next = function next() {
this.setActiveItem(this.state.activeIndex + 1);
};
Carousel.prototype.handleIndicatorClick = function handleIndicatorClick(index) {
this.setState({
activeIndex: index
});
};
Carousel.prototype.handleIndicatorHover = function handleIndicatorHover(index) {
if (this.props.trigger === 'hover' && index !== this.state.activeIndex) {
this.setState({
activeIndex: index
});
}
};
Carousel.prototype.render = function render() {
var _this4 = this;
var _props = this.props,
height = _props.height,
arrow = _props.arrow,
indicatorPosition = _props.indicatorPosition;
var _state = this.state,
hover = _state.hover,
activeIndex = _state.activeIndex,
items = _state.items;
return React.createElement(
'div',
{
ref: 'root',
className: this.className('el-carousel', { 'el-carousel--card': this.iscard }),
onMouseEnter: this.handleMouseEnter.bind(this),
onMouseLeave: this.handleMouseLeave.bind(this)
},
React.createElement(
'div',
{
className: 'el-carousel__container',
style: { height: height } },
React.createElement(
Transition,
{ name: 'carousel-arrow-left' },
arrow !== 'never' && React.createElement(
View,
{ show: arrow === 'always' || hover },
React.createElement(
'button',
{
className: 'el-carousel__arrow el-carousel__arrow--left',
onMouseEnter: this.handleButtonEnter.bind(this, 'left'),
onMouseLeave: this.handleButtonLeave.bind(this),
onClick: this.throttledArrowClick.bind(this, activeIndex - 1)
},
React.createElement('i', { className: 'el-icon-arrow-left' })
)
)
),
React.createElement(
Transition,
{ name: 'carousel-arrow-right' },
arrow !== 'never' && React.createElement(
View,
{ show: arrow === 'always' || hover },
React.createElement(
'button',
{
className: 'el-carousel__arrow el-carousel__arrow--right',
onMouseEnter: this.handleButtonEnter.bind(this, 'right'),
onMouseLeave: this.handleButtonLeave.bind(this),
onClick: this.throttledArrowClick.bind(this, activeIndex + 1)
},
React.createElement('i', { className: 'el-icon-arrow-right' })
)
)
),
this.props.children
),
indicatorPosition !== 'none' && React.createElement(
'ul',
{
className: this.classNames('el-carousel__indicators', {
'el-carousel__indicators--outside': indicatorPosition === 'outside' || this.iscard
})
},
items.map(function (item, index) {
return React.createElement(
'li',
{
key: index,
className: _this4.classNames('el-carousel__indicator', { 'is-active': index === activeIndex }),
onMouseEnter: _this4.throttledIndicatorHover.bind(_this4, index),
onClick: _this4.handleIndicatorClick.bind(_this4, index)
},
React.createElement('button', { className: 'el-carousel__button' })
);
})
)
);
};
_createClass(Carousel, [{
key: 'iscard',
get: function get() {
var type = this.props.type;
if (type) {
return type === 'card' || type === 'flatcard';
}
return false;
}
}]);
return Carousel;
}(Component);
export default Carousel;
Carousel.childContextTypes = {
component: PropTypes.any
};
Carousel.propTypes = {
initialIndex: PropTypes.number,
height: PropTypes.string,
trigger: PropTypes.string,
autoplay: PropTypes.bool,
interval: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
indicatorPosition: PropTypes.string,
indicator: PropTypes.bool,
arrow: PropTypes.string,
type: PropTypes.oneOf(['card', 'flatcard']),
onChange: PropTypes.func
};
Carousel.defaultProps = {
initialIndex: 0,
trigger: 'hover',
autoplay: true,
interval: 3000,
indicator: true,
arrow: 'hover'
};