UNPKG

react-material-ui-carousel

Version:

A Generic, extendible Carousel UI component for React using Material UI

548 lines (454 loc) 21.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 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 _Fade = require('@material-ui/core/Fade'); var _Fade2 = _interopRequireDefault(_Fade); var _Slide = require('@material-ui/core/Slide'); var _Slide2 = _interopRequireDefault(_Slide); var _IconButton = require('@material-ui/core/IconButton'); var _IconButton2 = _interopRequireDefault(_IconButton); var _styles = require('@material-ui/core/styles'); var _autoBind = require('auto-bind'); var _autoBind2 = _interopRequireDefault(_autoBind); var _FiberManualRecord = require('@material-ui/icons/FiberManualRecord'); var _FiberManualRecord2 = _interopRequireDefault(_FiberManualRecord); var _NavigateBefore = require('@material-ui/icons/NavigateBefore'); var _NavigateBefore2 = _interopRequireDefault(_NavigateBefore); var _NavigateNext = require('@material-ui/icons/NavigateNext'); var _NavigateNext2 = _interopRequireDefault(_NavigateNext); var _reactSwipeable = require('react-swipeable'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: 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 styles = { root: { position: "relative", overflow: "hidden" }, indicators: { width: "100%", marginTop: "10px", textAlign: "center" }, indicator: { cursor: "pointer", transition: "200ms", padding: 0, color: "#afafaf", '&:hover': { color: "#1f1f1f" }, '&:active': { color: "#1f1f1f" } }, indicatorIcon: { fontSize: "15px" }, active: { color: "#494949" }, buttonWrapper: { position: "absolute", height: "100px", backgroundColor: "transparent", top: "calc(50% - 70px)", '&:hover': { '& $button': { backgroundColor: "black", filter: "brightness(120%)", opacity: "0.4" } } }, fullHeightHoverWrapper: { height: "100%", // This is 100% - indicator height - indicator margin top: "0" }, buttonVisible: { opacity: "1" }, buttonHidden: { opacity: "0" }, button: { margin: "0 10px", position: "relative", backgroundColor: "#494949", top: "calc(50% - 20px) !important", color: "white", fontSize: "30px", transition: "200ms", cursor: "pointer", '&:hover': { opacity: "0.6 !important" } }, next: { right: 0 }, prev: { left: 0 } }; var sanitizeStyleProps = function sanitizeStyleProps(props) { return props !== undefined ? { style: props.style !== undefined ? props.style : {}, className: props.className !== undefined ? props.className : "" } : { style: {}, className: "" }; }; var sanitizeProps = function sanitizeProps(props) { var animation = props.animation !== undefined ? props.animation : "fade"; var timeout = props.timeout !== undefined ? props.timeout : animation === "fade" ? 500 : 200; return { className: props.className !== undefined ? props.className : "", children: props.children ? props.children : [], index: props.index !== undefined ? props.index : 0, strictIndexing: props.strictIndexing !== undefined ? props.strictIndexing : true, autoPlay: props.autoPlay !== undefined ? props.autoPlay : true, stopAutoPlayOnHover: props.stopAutoPlayOnHover !== undefined ? props.stopAutoPlayOnHover : true, interval: props.interval !== undefined ? props.interval : 4000, animation: animation, timeout: timeout, swipe: props.swipe !== undefined ? props.swipe : true, navButtonsAlwaysInvisible: props.navButtonsAlwaysInvisible !== undefined ? props.navButtonsAlwaysInvisible : false, navButtonsAlwaysVisible: props.navButtonsAlwaysVisible !== undefined ? props.navButtonsAlwaysVisible : false, cycleNavigation: props.cycleNavigation !== undefined ? props.cycleNavigation : true, fullHeightHover: props.fullHeightHover !== undefined ? props.fullHeightHover : true, navButtonsWrapperProps: sanitizeStyleProps(props.navButtonsWrapperProps), navButtonsProps: sanitizeStyleProps(props.navButtonsProps), NavButton: props.NavButton, NextIcon: props.NextIcon !== undefined ? props.NextIcon : _react2.default.createElement(_NavigateNext2.default, null), PrevIcon: props.PrevIcon !== undefined ? props.PrevIcon : _react2.default.createElement(_NavigateBefore2.default, null), indicators: props.indicators !== undefined ? props.indicators : true, indicatorContainerProps: sanitizeStyleProps(props.indicatorContainerProps), indicatorIconButtonProps: sanitizeStyleProps(props.indicatorIconButtonProps), activeIndicatorIconButtonProps: sanitizeStyleProps(props.activeIndicatorIconButtonProps), IndicatorIcon: props.IndicatorIcon, onChange: props.onChange !== undefined ? props.onChange : function () {}, changeOnFirstRender: props.changeOnFirstRender !== undefined ? props.changeOnFirstRender : false, next: props.next !== undefined ? props.next : function () {}, prev: props.prev !== undefined ? props.prev : function () {} }; }; var Carousel = function (_Component) { _inherits(Carousel, _Component); function Carousel(props) { _classCallCheck(this, Carousel); var _this = _possibleConstructorReturn(this, (Carousel.__proto__ || Object.getPrototypeOf(Carousel)).call(this, props)); (0, _autoBind2.default)(_this); _this.state = { active: 0, prevActive: 0, displayed: 0 }; _this.timer = null; return _this; } _createClass(Carousel, [{ key: 'componentDidMount', value: function componentDidMount() { var _sanitizeProps = sanitizeProps(this.props), index = _sanitizeProps.index, changeOnFirstRender = _sanitizeProps.changeOnFirstRender; this.setActive(index, undefined, changeOnFirstRender); this.start(); } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.stop(); } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps, prevState) { prevProps = sanitizeProps(prevProps); var _sanitizeProps2 = sanitizeProps(this.props), autoPlay = _sanitizeProps2.autoPlay, interval = _sanitizeProps2.interval, children = _sanitizeProps2.children, index = _sanitizeProps2.index; if (autoPlay !== prevProps.autoPlay || interval !== prevProps.interval) { this.reset(); } if (children.length !== prevProps.children.length) { this.setActive(index); } if (prevProps.index !== index) { this.setActive(index); } } }, { key: 'stop', value: function stop() { if (this.timer) { clearInterval(this.timer); this.timer = null; } } }, { key: 'start', value: function start() { var _sanitizeProps3 = sanitizeProps(this.props), autoPlay = _sanitizeProps3.autoPlay, interval = _sanitizeProps3.interval; if (autoPlay) { this.timer = setInterval(this.next, interval); } } }, { key: 'reset', value: function reset() { var _sanitizeProps4 = sanitizeProps(this.props), autoPlay = _sanitizeProps4.autoPlay; this.stop(); if (autoPlay) { this.start(); } } }, { key: 'setActive', value: function setActive(index) { var _this2 = this; var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; var runCallbacks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; var _sanitizeProps5 = sanitizeProps(this.props), onChange = _sanitizeProps5.onChange, timeout = _sanitizeProps5.timeout, children = _sanitizeProps5.children, strictIndexing = _sanitizeProps5.strictIndexing; // if index is bigger than the children length, set it to be the last child (if strictIndexing) if (Array.isArray(children)) { if (strictIndexing && index > children.length - 1) index = children.length - 1; if (strictIndexing && index < 0) index = 0; } else { index = 0; } var prevActive = this.state.active; this.setState({ active: index, prevActive: prevActive, displayed: prevActive }, this.reset); setTimeout(function () { _this2.setState({ displayed: index }, function () { if (runCallbacks) { // Call user defined callbacks callback(index, prevActive); onChange(index, prevActive); } }); }, timeout.exit ? timeout.exit : timeout); } }, { key: 'next', value: function next(event) { var _sanitizeProps6 = sanitizeProps(this.props), children = _sanitizeProps6.children, next = _sanitizeProps6.next, cycleNavigation = _sanitizeProps6.cycleNavigation; var nextActive = this.state.active + 1 > children.length - 1 ? cycleNavigation ? 0 : this.state.active : this.state.active + 1; this.setActive(nextActive, next); if (event) event.stopPropagation(); } }, { key: 'prev', value: function prev(event) { var _sanitizeProps7 = sanitizeProps(this.props), children = _sanitizeProps7.children, prev = _sanitizeProps7.prev, cycleNavigation = _sanitizeProps7.cycleNavigation; var nextActive = this.state.active - 1 < 0 ? cycleNavigation ? children.length - 1 : this.state.active : this.state.active - 1; this.setActive(nextActive, prev); if (event) event.stopPropagation(); } }, { key: 'render', value: function render() { var _this3 = this; var _sanitizeProps8 = sanitizeProps(this.props), children = _sanitizeProps8.children, className = _sanitizeProps8.className, stopAutoPlayOnHover = _sanitizeProps8.stopAutoPlayOnHover, animation = _sanitizeProps8.animation, timeout = _sanitizeProps8.timeout, swipe = _sanitizeProps8.swipe, navButtonsAlwaysInvisible = _sanitizeProps8.navButtonsAlwaysInvisible, navButtonsAlwaysVisible = _sanitizeProps8.navButtonsAlwaysVisible, cycleNavigation = _sanitizeProps8.cycleNavigation, fullHeightHover = _sanitizeProps8.fullHeightHover, navButtonsProps = _sanitizeProps8.navButtonsProps, navButtonsWrapperProps = _sanitizeProps8.navButtonsWrapperProps, NavButton = _sanitizeProps8.NavButton, NextIcon = _sanitizeProps8.NextIcon, PrevIcon = _sanitizeProps8.PrevIcon, indicators = _sanitizeProps8.indicators, indicatorContainerProps = _sanitizeProps8.indicatorContainerProps, indicatorIconButtonProps = _sanitizeProps8.indicatorIconButtonProps, activeIndicatorIconButtonProps = _sanitizeProps8.activeIndicatorIconButtonProps, IndicatorIcon = _sanitizeProps8.IndicatorIcon; var classes = this.props.classes; var buttonVisibilityClassValue = (navButtonsAlwaysVisible ? classes.buttonVisible : classes.buttonHidden) + '}'; var buttonCssClassValue = classes.button + ' ' + buttonVisibilityClassValue + ' ' + (fullHeightHover ? classes.fullHeightHoverButton : "") + ' ' + navButtonsProps.className; var buttonWrapperCssClassValue = classes.buttonWrapper + ' ' + (fullHeightHover ? classes.fullHeightHoverWrapper : "") + ' ' + navButtonsWrapperProps.className; var compareActiveDisplayed = function compareActiveDisplayed() { if (_this3.state.active === 0 && _this3.state.prevActive === children.length - 1) { return false; } if (_this3.state.active === children.length - 1 && _this3.state.prevActive === 0) { return true; } if (_this3.state.active > _this3.state.prevActive) { return true; } return false; }; var showButton = function showButton() { var next = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; if (cycleNavigation) return true; if (next && _this3.state.active + 1 > children.length - 1) return false; if (!next && _this3.state.active - 1 < 0) return false; return true; }; return _react2.default.createElement( 'div', { className: classes.root + ' ' + (className ? className : ""), onMouseOver: function onMouseOver() { stopAutoPlayOnHover && _this3.stop(); }, onMouseOut: function onMouseOut() { stopAutoPlayOnHover && _this3.reset(); } }, Array.isArray(children) ? children.map(function (child, index) { return _react2.default.createElement(CarouselItem, { key: 'carousel-item' + index, display: index === _this3.state.displayed ? true : false, active: index === _this3.state.active ? true : false, isNext: compareActiveDisplayed(), child: child, animation: animation, timeout: timeout, swipe: swipe, next: _this3.next, prev: _this3.prev }); }) : _react2.default.createElement(CarouselItem, { key: 'carousel-item0', display: true, active: true, child: children, animation: animation, timeout: timeout }), !navButtonsAlwaysInvisible && showButton(true) && _react2.default.createElement( 'div', { className: buttonWrapperCssClassValue + ' ' + classes.next, style: navButtonsWrapperProps.style }, NavButton !== undefined ? NavButton({ onClick: this.next, className: buttonCssClassValue, style: navButtonsProps.style, next: true, prev: false }) : _react2.default.createElement( _IconButton2.default, { className: '' + buttonCssClassValue, onClick: this.next, 'aria-label': 'Next', style: navButtonsProps.style }, NextIcon ) ), !navButtonsAlwaysInvisible && showButton(false) && _react2.default.createElement( 'div', { className: buttonWrapperCssClassValue + ' ' + classes.prev, style: navButtonsWrapperProps.style }, NavButton !== undefined ? NavButton({ onClick: this.prev, className: buttonCssClassValue, style: navButtonsProps.style, next: false, prev: true }) : _react2.default.createElement( _IconButton2.default, { className: '' + buttonCssClassValue, onClick: this.prev, 'aria-label': 'Previous', style: navButtonsProps.style }, PrevIcon ) ), indicators ? _react2.default.createElement(Indicators, { classes: classes, length: children.length, active: this.state.active, press: this.setActive, indicatorContainerProps: indicatorContainerProps, indicatorIconButtonProps: indicatorIconButtonProps, activeIndicatorIconButtonProps: activeIndicatorIconButtonProps, IndicatorIcon: IndicatorIcon }) : null ); } }]); return Carousel; }(_react.Component); function CarouselItem(props) { var swipeHandlers = (0, _reactSwipeable.useSwipeable)({ onSwipedLeft: function onSwipedLeft() { return props.next(); }, onSwipedRight: function onSwipedRight() { return props.prev(); } }); swipeHandlers = props.swipe ? swipeHandlers : {}; return props.display ? _react2.default.createElement( 'div', _extends({}, swipeHandlers, { className: 'CarouselItem' }), props.animation === "slide" ? _react2.default.createElement( _Slide2.default, { direction: props.active ? props.isNext ? "left" : "right" : props.isNext ? "right" : "left", 'in': props.active, timeout: props.timeout }, _react2.default.createElement( 'div', null, props.child ) ) : _react2.default.createElement( _Fade2.default, { 'in': props.active, timeout: props.timeout }, _react2.default.createElement( 'div', null, props.child ) ) ) : null; } function Indicators(props) { var classes = props.classes; var IndicatorIcon = props.IndicatorIcon !== undefined ? props.IndicatorIcon : _react2.default.createElement(_FiberManualRecord2.default, { size: 'small', className: classes.indicatorIcon }); var indicators = []; var _loop = function _loop(i) { var className = i === props.active ? classes.indicator + ' ' + props.indicatorIconButtonProps.className + ' ' + classes.active + ' ' + props.activeIndicatorIconButtonProps.className : classes.indicator + ' ' + props.indicatorIconButtonProps.className; var style = i === props.active ? Object.assign({}, props.indicatorIconButtonProps.style, props.activeIndicatorIconButtonProps.style) : props.indicatorIconButtonProps.style; var item = _react2.default.createElement( _IconButton2.default, { key: i, className: className, style: style, onClick: function onClick() { props.press(i); }, size: 'small' }, IndicatorIcon ); indicators.push(item); }; for (var i = 0; i < props.length; i++) { _loop(i); } var wrapperStyle = props.indicatorContainerProps !== undefined ? props.indicatorContainerProps.style : undefined; var wrapperClassName = props.indicatorContainerProps !== undefined ? props.indicatorContainerProps.className : ""; return _react2.default.createElement( 'div', { className: classes.indicators + ' ' + wrapperClassName, style: wrapperStyle }, indicators ); } exports.default = (0, _styles.withStyles)(styles)(Carousel);