UNPKG

siema-react

Version:

ReactSiema is a lightweight carousel plugin for React. It's a wrapper based on decent library [Siema](https://github.com/pawelgrzybek/siema).

384 lines (342 loc) 15.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _debounce = require('./utils/debounce'); var _debounce2 = _interopRequireDefault(_debounce); var _transformProperty = require('./utils/transformProperty'); var _transformProperty2 = _interopRequireDefault(_transformProperty); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var ReactSiema = function (_Component) { _inherits(ReactSiema, _Component); function ReactSiema(props) { _classCallCheck(this, ReactSiema); var _this = _possibleConstructorReturn(this, (ReactSiema.__proto__ || Object.getPrototypeOf(ReactSiema)).call(this)); _this.events = ['onTouchStart', 'onTouchEnd', 'onTouchMove', 'onMouseDown', 'onMouseUp', 'onMouseLeave', 'onMouseMove', 'onClick']; _this.config = Object.assign({}, { resizeDebounce: 250, duration: 200, easing: 'ease-out', perPage: 1, startIndex: 0, draggable: true, threshold: 20, loop: false, onInit: function onInit() {}, onChange: function onChange() {} }, props); _this.events.forEach(function (handler) { _this[handler] = _this[handler].bind(_this); }); return _this; } _createClass(ReactSiema, [{ key: 'componentDidMount', value: function componentDidMount() { var _this2 = this; this.config.selector = this.selector; this.currentSlide = this.config.startIndex; this.init(); this.onResize = (0, _debounce2.default)(function () { _this2.resize(); _this2.slideToCurrent(); }, this.config.resizeDebounce); window.addEventListener('resize', this.onResize); if (this.config.draggable) { this.pointerDown = false; this.drag = { startX: 0, endX: 0, startY: 0, letItGo: null }; } } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { this.init(); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { window.removeEventListener('resize', this.onResize); } }, { key: 'init', value: function init() { this.setSelectorWidth(); this.setInnerElements(); this.resolveSlidesNumber(); this.setStyle(this.sliderFrame, { width: this.selectorWidth / this.perPage * this.innerElements.length + 'px', webkitTransition: 'all ' + this.config.duration + 'ms ' + this.config.easing, transition: 'all ' + this.config.duration + 'ms ' + this.config.easing }); for (var i = 0; i < this.innerElements.length; i++) { this.setStyle(this.innerElements[i], { width: 100 / this.innerElements.length + '%' }); } this.slideToCurrent(); this.config.onInit.call(this); } }, { key: 'setSelectorWidth', value: function setSelectorWidth() { this.selectorWidth = this.selector.getBoundingClientRect().width; } }, { key: 'setInnerElements', value: function setInnerElements() { this.innerElements = [].slice.call(this.sliderFrame.children); } }, { key: 'resolveSlidesNumber', value: function resolveSlidesNumber() { if (typeof this.config.perPage === 'number') { this.perPage = this.config.perPage; } else if (_typeof(this.config.perPage) === 'object') { this.perPage = 1; for (var viewport in this.config.perPage) { if (window.innerWidth > viewport) { this.perPage = this.config.perPage[viewport]; } } } } }, { key: 'prev', value: function prev() { var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var callback = arguments[1]; if (this.currentSlide === 0 && this.config.loop) { this.currentSlide = this.innerElements.length - this.perPage; } else { this.currentSlide = Math.max(this.currentSlide - Number(n), 0); } this.slideToCurrent(); this.config.onChange.call(this); if (typeof callback === 'function') { callback(); } } }, { key: 'next', value: function next() { var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var callback = arguments[1]; if (this.currentSlide === this.innerElements.length - this.perPage && this.config.loop) { this.currentSlide = 0; } else { this.currentSlide = Math.min(this.currentSlide + Number(n), this.innerElements.length - this.perPage); } this.slideToCurrent(); this.config.onChange.call(this); if (typeof callback === 'function') { callback(); } } }, { key: 'goTo', value: function goTo(index) { this.currentSlide = Math.min(Math.max(index, 0), this.innerElements.length - 1); this.slideToCurrent(); this.config.onChange.call(this); } }, { key: 'slideToCurrent', value: function slideToCurrent() { this.sliderFrame.style[_transformProperty2.default] = 'translate3d(-' + Math.round(this.currentSlide * (this.selectorWidth / this.perPage)) + 'px, 0, 0)'; } }, { key: 'updateAfterDrag', value: function updateAfterDrag() { var movement = this.drag.endX - this.drag.startX; if (movement > 0 && Math.abs(movement) > this.config.threshold) { this.prev(); } else if (movement < 0 && Math.abs(movement) > this.config.threshold) { this.next(); } this.slideToCurrent(); } }, { key: 'resize', value: function resize() { this.resolveSlidesNumber(); this.selectorWidth = this.selector.getBoundingClientRect().width; this.setStyle(this.sliderFrame, { width: this.selectorWidth / this.perPage * this.innerElements.length + 'px' }); } }, { key: 'clearDrag', value: function clearDrag() { this.drag = { startX: 0, endX: 0, startY: 0, letItGo: null }; } }, { key: 'setStyle', value: function setStyle(target, styles) { Object.keys(styles).forEach(function (attribute) { target.style[attribute] = styles[attribute]; }); } }, { key: 'onTouchStart', value: function onTouchStart(e) { e.stopPropagation(); this.pointerDown = true; this.drag.startX = e.touches[0].pageX; this.drag.startY = e.touches[0].pageY; } }, { key: 'onTouchEnd', value: function onTouchEnd(e) { e.stopPropagation(); this.pointerDown = false; this.setStyle(this.sliderFrame, { webkitTransition: 'all ' + this.config.duration + 'ms ' + this.config.easing, transition: 'all ' + this.config.duration + 'ms ' + this.config.easing }); if (this.drag.endX) { this.updateAfterDrag(); } this.clearDrag(); } }, { key: 'onTouchMove', value: function onTouchMove(e) { e.stopPropagation(); if (this.drag.letItGo === null) { this.drag.letItGo = Math.abs(this.drag.startY - e.touches[0].pageY) < Math.abs(this.drag.startX - e.touches[0].pageX); } if (this.pointerDown && this.drag.letItGo) { this.drag.endX = e.touches[0].pageX; this.setStyle(this.sliderFrame, _defineProperty({ webkitTransition: 'all 0ms ' + this.config.easing, transition: 'all 0ms ' + this.config.easing }, _transformProperty2.default, 'translate3d(' + (this.currentSlide * (this.selectorWidth / this.perPage) + (this.drag.startX - this.drag.endX)) * -1 + 'px, 0, 0)')); } } }, { key: 'onMouseDown', value: function onMouseDown(e) { e.preventDefault(); e.stopPropagation(); this.pointerDown = true; this.drag.start = e.pageX; this.wasDragged = false; } }, { key: 'onMouseUp', value: function onMouseUp(e) { e.stopPropagation(); this.pointerDown = false; this.setStyle(this.sliderFrame, { cursor: '-webkit-grab', webkitTransition: 'all ' + this.config.duration + 'ms ' + this.config.easing, transition: 'all ' + this.config.duration + 'ms ' + this.config.easing }); if (this.drag.end) { // If drag.end has a value > 0, the slider has been dragged this.wasDragged = true; this.updateAfterDrag(); } this.clearDrag(); } }, { key: 'onMouseMove', value: function onMouseMove(e) { e.preventDefault(); if (this.pointerDown) { this.drag.endX = e.pageX; this.setStyle(this.sliderFrame, _defineProperty({ cursor: '-webkit-grabbing', webkitTransition: 'all 0ms ' + this.config.easing, transition: 'all 0ms ' + this.config.easing }, _transformProperty2.default, 'translate3d(' + (this.currentSlide * (this.selectorWidth / this.perPage) + (this.drag.startX - this.drag.endX)) * -1 + 'px, 0, 0)')); } } }, { key: 'onMouseLeave', value: function onMouseLeave(e) { if (this.pointerDown) { this.pointerDown = false; this.drag.endX = e.pageX; this.setStyle(this.sliderFrame, { cursor: '-webkit-grab', webkitTransition: 'all ' + this.config.duration + 'ms ' + this.config.easing, transition: 'all ' + this.config.duration + 'ms ' + this.config.easing }); this.updateAfterDrag(); this.clearDrag(); } } }, { key: 'onClick', value: function onClick(e) { if (!this.wasDragged && this.props.onClick) { this.props.onClick(e); } } }, { key: 'render', value: function render() { var _this3 = this; return _react2.default.createElement( 'div', Object.assign({ ref: function ref(selector) { return _this3.selector = selector; }, style: { overflow: 'hidden' } }, this.events.reduce(function (props, event) { return Object.assign({}, props, _defineProperty({}, event, _this3[event])); }, {})), _react2.default.createElement( 'div', { ref: function ref(sliderFrame) { return _this3.sliderFrame = sliderFrame; } }, _react2.default.Children.map(this.props.children, function (children, index) { return _react2.default.cloneElement(children, { key: index, style: { float: 'left' }, onClick: _this3.onClick }); }) ) ); } }]); return ReactSiema; }(_react.Component); ReactSiema.propTypes = { resizeDebounce: _propTypes2.default.number, duration: _propTypes2.default.number, easing: _propTypes2.default.string, perPage: _propTypes2.default.number, startIndex: _propTypes2.default.number, draggable: _propTypes2.default.bool, threshold: _propTypes2.default.number, loop: _propTypes2.default.bool, children: _propTypes2.default.oneOfType([_propTypes2.default.element, _propTypes2.default.arrayOf(_propTypes2.default.element)]), onInit: _propTypes2.default.func, onChange: _propTypes2.default.func }; exports.default = ReactSiema;