text: "use strict";
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  exports.__esModule = true;
  exports.default = void 0;
  
  var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
  
  var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
  
  var _react = _interopRequireDefault(require("react"));
  
  var _propTypes = _interopRequireDefault(require("prop-types"));
  
  var _classnames = _interopRequireDefault(require("classnames"));
  
  var _CarouselItem = _interopRequireDefault(require("./CarouselItem"));
  
  var _utils = require("./utils");
  
  var SWIPE_THRESHOLD = 40;
  
  var Carousel =
  /*#__PURE__*/
  function (_React$Component) {
    (0, _inheritsLoose2.default)(Carousel, _React$Component);
  
    function Carousel(props) {
      var _this;
  
      _this = _React$Component.call(this, props) || this;
      _this.handleKeyPress = _this.handleKeyPress.bind((0, _assertThisInitialized2.default)(_this));
      _this.renderItems = _this.renderItems.bind((0, _assertThisInitialized2.default)(_this));
      _this.hoverStart = _this.hoverStart.bind((0, _assertThisInitialized2.default)(_this));
      _this.hoverEnd = _this.hoverEnd.bind((0, _assertThisInitialized2.default)(_this));
      _this.handleTouchStart = _this.handleTouchStart.bind((0, _assertThisInitialized2.default)(_this));
      _this.handleTouchEnd = _this.handleTouchEnd.bind((0, _assertThisInitialized2.default)(_this));
      _this.touchStartX = 0;
      _this.touchStartY = 0;
      _this.state = {
        activeIndex: _this.props.activeIndex,
        direction: 'right',
        indicatorClicked: false
      };
      return _this;
    }
  
    var _proto = Carousel.prototype;
  
    _proto.getChildContext = function getChildContext() {
      return {
        direction: this.state.direction
      };
    };
  
    _proto.componentDidMount = function componentDidMount() {
      // Set up the cycle
      if (this.props.ride === 'carousel') {
        this.setInterval();
      } // TODO: move this to the specific carousel like bootstrap. Currently it will trigger ALL carousels on the page.
  
  
      document.addEventListener('keyup', this.handleKeyPress);
    };
  
    Carousel.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
      var newState = null;
      var activeIndex = prevState.activeIndex,
          direction = prevState.direction,
          indicatorClicked = prevState.indicatorClicked;
  
      if (nextProps.activeIndex !== activeIndex) {
        // Calculate the direction to turn
        if (nextProps.activeIndex === activeIndex + 1) {
          direction = 'right';
        } else if (nextProps.activeIndex === activeIndex - 1) {
          direction = 'left';
        } else if (nextProps.activeIndex < activeIndex) {
          direction = indicatorClicked ? 'left' : 'right';
        } else if (nextProps.activeIndex !== activeIndex) {
          direction = indicatorClicked ? 'right' : 'left';
        }
  
        newState = {
          activeIndex: nextProps.activeIndex,
          direction: direction,
          indicatorClicked: false
        };
      }
  
      return newState;
    };
  
    _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
      if (prevState.activeIndex === this.state.activeIndex) return;
      this.setInterval(this.props);
    };
  
    _proto.componentWillUnmount = function componentWillUnmount() {
      this.clearInterval();
      document.removeEventListener('keyup', this.handleKeyPress);
    };
  
    _proto.setInterval = function (_setInterval) {
      function setInterval() {
        return _setInterval.apply(this, arguments);
      }
  
      setInterval.toString = function () {
        return _setInterval.toString();
      };
  
      return setInterval;
    }(function (props) {
      if (props === void 0) {
        props = this.props;
      }
  
      // make sure not to have multiple intervals going...
      this.clearInterval();
  
      if (props.interval) {
        this.cycleInterval = setInterval(function () {
          props.next();
        }, parseInt(props.interval, 10));
      }
    });
  
    _proto.clearInterval = function (_clearInterval) {
      function clearInterval() {
        return _clearInterval.apply(this, arguments);
      }
  
      clearInterval.toString = function () {
        return _clearInterval.toString();
      };
  
      return clearInterval;
    }(function () {
      clearInterval(this.cycleInterval);
    });
  
    _proto.hoverStart = function hoverStart() {
      if (this.props.pause === 'hover') {
        this.clearInterval();
      }
  
      if (this.props.mouseEnter) {
        var _this$props;
  
        (_this$props = this.props).mouseEnter.apply(_this$props, arguments);
      }
    };
  
    _proto.hoverEnd = function hoverEnd() {
      if (this.props.pause === 'hover') {
        this.setInterval();
      }
  
      if (this.props.mouseLeave) {
        var _this$props2;
  
        (_this$props2 = this.props).mouseLeave.apply(_this$props2, arguments);
      }
    };
  
    _proto.handleKeyPress = function handleKeyPress(evt) {
      if (this.props.keyboard) {
        if (evt.keyCode === 37) {
          this.props.previous();
        } else if (evt.keyCode === 39) {
          this.props.next();
        }
      }
    };
  
    _proto.handleTouchStart = function handleTouchStart(e) {
      if (!this.props.enableTouch) {
        return;
      }
  
      this.touchStartX = e.changedTouches[0].screenX;
      this.touchStartY = e.changedTouches[0].screenY;
    };
  
    _proto.handleTouchEnd = function handleTouchEnd(e) {
      if (!this.props.enableTouch) {
        return;
      }
  
      var currentX = e.changedTouches[0].screenX;
      var currentY = e.changedTouches[0].screenY;
      var diffX = Math.abs(this.touchStartX - currentX);
      var diffY = Math.abs(this.touchStartY - currentY); // Don't swipe if Y-movement is bigger than X-movement
  
      if (diffX < diffY) {
        return;
      }
  
      if (diffX < SWIPE_THRESHOLD) {
        return;
      }
  
      if (currentX < this.touchStartX) {
        this.props.next();
      } else {
        this.props.previous();
      }
    };
  
    _proto.renderItems = function renderItems(carouselItems, className) {
      var _this2 = this;
  
      var slide = this.props.slide;
      return _react.default.createElement("div", {
        className: className
      }, carouselItems.map(function (item, index) {
        var isIn = index === _this2.state.activeIndex;
        return _react.default.cloneElement(item, {
          in: isIn,
          slide: slide
        });
      }));
    };
  
    _proto.render = function render() {
      var _this3 = this;
  
      var _this$props3 = this.props,
          cssModule = _this$props3.cssModule,
          slide = _this$props3.slide,
          className = _this$props3.className;
      var outerClasses = (0, _utils.mapToCssModules)((0, _classnames.default)(className, 'carousel', slide && 'slide'), cssModule);
      var innerClasses = (0, _utils.mapToCssModules)((0, _classnames.default)('carousel-inner'), cssModule); // filter out booleans, null, or undefined
  
      var children = this.props.children.filter(function (child) {
        return child !== null && child !== undefined && typeof child !== 'boolean';
      });
      var slidesOnly = children.every(function (child) {
        return child.type === _CarouselItem.default;
      }); // Rendering only slides
  
      if (slidesOnly) {
        return _react.default.createElement("div", {
          className: outerClasses,
          onMouseEnter: this.hoverStart,
          onMouseLeave: this.hoverEnd
        }, this.renderItems(children, innerClasses));
      } // Rendering slides and controls
  
  
      if (children[0] instanceof Array) {
        var _carouselItems = children[0];
        var _controlLeft = children[1];
        var _controlRight = children[2];
        return _react.default.createElement("div", {
          className: outerClasses,
          onMouseEnter: this.hoverStart,
          onMouseLeave: this.hoverEnd
        }, this.renderItems(_carouselItems, innerClasses), _controlLeft, _controlRight);
      } // Rendering indicators, slides and controls
  
  
      var indicators = children[0];
  
      var wrappedOnClick = function wrappedOnClick(e) {
        if (typeof indicators.props.onClickHandler === 'function') {
          _this3.setState({
            indicatorClicked: true
          }, function () {
            return indicators.props.onClickHandler(e);
          });
        }
      };
  
      var wrappedIndicators = _react.default.cloneElement(indicators, {
        onClickHandler: wrappedOnClick
      });
  
      var carouselItems = children[1];
      var controlLeft = children[2];
      var controlRight = children[3];
      return _react.default.createElement("div", {
        className: outerClasses,
        onMouseEnter: this.hoverStart,
        onMouseLeave: this.hoverEnd,
        onTouchStart: this.handleTouchStart,
        onTouchEnd: this.handleTouchEnd
      }, wrappedIndicators, this.renderItems(carouselItems, innerClasses), controlLeft, controlRight);
    };
  
    return Carousel;
  }(_react.default.Component);
  
  Carousel.propTypes = {
    // the current active slide of the carousel
    activeIndex: _propTypes.default.number,
    // a function which should advance the carousel to the next slide (via activeIndex)
    next: _propTypes.default.func.isRequired,
    // a function which should advance the carousel to the previous slide (via activeIndex)
    previous: _propTypes.default.func.isRequired,
    // controls if the left and right arrow keys should control the carousel
    keyboard: _propTypes.default.bool,
  
    /* If set to "hover", pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on
     * mouseleave. If set to false, hovering over the carousel won't pause it. (default: "hover")
     */
    pause: _propTypes.default.oneOf(['hover', false]),
    // Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.
    // This is how bootstrap defines it... I would prefer a bool named autoplay or something...
    ride: _propTypes.default.oneOf(['carousel']),
    // the interval at which the carousel automatically cycles (default: 5000)
    // eslint-disable-next-line react/no-unused-prop-types
    interval: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string, _propTypes.default.bool]),
    children: _propTypes.default.array,
    // called when the mouse enters the Carousel
    mouseEnter: _propTypes.default.func,
    // called when the mouse exits the Carousel
    mouseLeave: _propTypes.default.func,
    // controls whether the slide animation on the Carousel works or not
    slide: _propTypes.default.bool,
    cssModule: _propTypes.default.object,
    className: _propTypes.default.string,
    enableTouch: _propTypes.default.bool
  };
  Carousel.defaultProps = {
    interval: 5000,
    pause: 'hover',
    keyboard: true,
    slide: true,
    enableTouch: true
  };
  Carousel.childContextTypes = {
    direction: _propTypes.default.string
  };
  var _default = Carousel;
  exports.default = _default;