UNPKG

@yncoder/element-react

Version:
334 lines (277 loc) 9.88 kB
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' };