"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _CarouselWIPSt = require("./CarouselWIP.st.css.js");
var _wixUiIconsCommon = require("@wix/wix-ui-icons-common");
var _Loader = _interopRequireDefault(require("../Loader"));
var _Control = _interopRequireDefault(require("./Control"));
var _Slide = _interopRequireDefault(require("./Slide"));
var _deprecationLog = _interopRequireDefault(require("../utils/deprecationLog"));
var _constants = require("./constants");
var _utils = require("./utils");
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/CarouselWIP/CarouselWIP.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
/**
 * The carousel component creates a slideshow for cycling through a series of content.
 * @deprecated CarouselWIP is deprecated and will be removed in the next major version. Please migrate to Carousel which now supports all CarouselWIP features. See the migration guide under Deprecated/CarouselWIP in Storybook.
 */
class CarouselWIP extends _react.PureComponent {
  constructor(_props) {
    var _this;
    super(_props);
    _this = this;
    this.loadingImagesCount = 0;
    this.childCount = 0;
    this.autoplayTimer = -1;
    this.carousel = void 0;
    this.dragStartX = null;
    this.initialScrollLeft = 0;
    this.capturedPointerId = null;
    this.hasSetPointerCapture = false;
    // Need to wait for images to load so we know which images are visible
    // Adding onLoad and onError callbacks to all images under the component
    this._setImagesOnLoadHandlers = () => {
      Array.from(this.carousel.children).forEach(child => {
        var childImages = Array.from(child.getElementsByTagName('img'));
        childImages.forEach(img => {
          if (img.complete) {
            return;
          }
          this.setState({
            isLoading: true
          });
          this.loadingImagesCount++;
          img.onload = this._onImageLoad;
          img.onerror = this._onImageLoad;
        });
      });
    };
    this._updateChildCount = () => {
      var _ref, _this$carousel$childr, _this$carousel;
      var {
        images
      } = this.props;
      this.childCount = (_ref = (_this$carousel$childr = (_this$carousel = this.carousel) == null || (_this$carousel = _this$carousel.children) == null ? void 0 : _this$carousel.length) !== null && _this$carousel$childr !== void 0 ? _this$carousel$childr : images == null ? void 0 : images.length) !== null && _ref !== void 0 ? _ref : 0;
    };
    this._onImageLoad = () => {
      var {
        initialSlideIndex
      } = this.props;
      this.loadingImagesCount--;
      if (!this.loadingImagesCount) {
        this.setState({
          isLoading: false
        });
        this._slideTo({
          index: initialSlideIndex,
          immediate: true
        }).catch(_utils.nop);
      }
    };
    this._setAutoplayTimer = active => {
      clearInterval(this.autoplayTimer);
      if (active) {
        this.autoplayTimer = window.setInterval(this._next, _constants.AUTOPLAY_SPEED);
      }
    };
    this._setVisibleSlides = () => {
      var {
        props,
        carousel,
        childCount
      } = this;
      var {
        infinite
      } = props;
      var firstVisibleChild = Math.max(Array.from(carousel.children).findIndex(child => (0, _utils.isWhollyInView)(carousel)(child)), 0);
      var lastVisibleChild = Math.max(Array.from(carousel.children).findIndex((child, i, children) => (0, _utils.isWhollyInView)(carousel)(child) && (i === children.length - 1 || !(0, _utils.isWhollyInView)(carousel)(children[i + 1]))), 0);
      this.setState({
        visibleSlides: [firstVisibleChild, lastVisibleChild],
        isLeftArrowDisabled: !infinite && firstVisibleChild === 0,
        isRightArrowDisabled: !infinite && lastVisibleChild === childCount - 1,
        isShowStartGradient: firstVisibleChild > 0,
        isShowEndGradient: lastVisibleChild < childCount - 1
      });
    };
    this._slideTo = function () {
      var {
        index = 0,
        alignTo = _constants.ALIGNMENT.LEFT,
        immediate
      } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        index: 0,
        alignTo: _constants.ALIGNMENT.LEFT,
        immediate: false
      };
      if (_this.childCount === 0) {
        return Promise.reject('No children to slide to');
      }
      if (!_this.carousel) {
        return Promise.reject('The Carousel is not mounted');
      }
      var {
        afterChange,
        beforeChange,
        easing,
        animationDuration: duration,
        infinite,
        startEndOffset = 0
      } = _this.props;
      var {
        children,
        scrollLeft,
        offsetWidth
      } = _this.carousel;
      var slideIndex = (0, _utils.normalizeIndex)(index, _this.childCount, infinite);
      var {
        visibleSlides
      } = _this.state;
      var [firstVisibleSlide] = visibleSlides;
      var delta;
      var child = children[slideIndex];
      if (alignTo === _constants.ALIGNMENT.RIGHT) {
        delta = child.offsetWidth - (offsetWidth - child.offsetLeft) - scrollLeft + startEndOffset;
      } else {
        delta = child.offsetLeft - scrollLeft - startEndOffset;
      }
      if (firstVisibleSlide !== slideIndex && beforeChange) {
        beforeChange(firstVisibleSlide, index);
      }
      _this.setState({
        isAnimating: true
      });
      return new Promise((res, _) => {
        if (immediate) {
          _this.carousel.scrollLeft = child.offsetLeft;
          return res();
        } else {
          var prop = 'scrollLeft';
          return res((0, _utils.animate)(_this.carousel, {
            prop,
            delta,
            easing,
            duration
          }));
        }
      }).then(() => {
        _this.setState({
          isAnimating: false
        });
        _this._setVisibleSlides();
        if (firstVisibleSlide !== slideIndex && afterChange) {
          return afterChange(slideIndex);
        }
      }).catch(_ => {
        _this._setVisibleSlides();
        _this.setState({
          isAnimating: false
        });
      });
    };
    this._next = () => {
      var {
        slidingType,
        infinite
      } = this.props;
      var {
        visibleSlides
      } = this.state;
      var [firstVisibleSlide, lastVisibleSlide] = visibleSlides;
      var nextSlide, alignTo;
      if ([_constants.SLIDING_TYPE.REVEAL_CHUNK, _constants.SLIDING_TYPE.REVEAL_ONE].includes(slidingType)) {
        if (lastVisibleSlide === this.childCount - 1) {
          nextSlide = infinite ? 0 : lastVisibleSlide;
        } else {
          nextSlide = lastVisibleSlide + 1;
        }
        alignTo = slidingType === _constants.SLIDING_TYPE.REVEAL_CHUNK ? _constants.ALIGNMENT.LEFT : _constants.ALIGNMENT.RIGHT;
      } else {
        if (firstVisibleSlide === this.childCount - 1) {
          nextSlide = infinite ? 0 : firstVisibleSlide;
        } else {
          nextSlide = firstVisibleSlide + 1;
        }
        alignTo = _constants.ALIGNMENT.LEFT;
      }
      if (nextSlide === this.childCount - 1) {
        this.setState({
          isRightArrowDisabled: true,
          isShowEndGradient: false
        });
      }
      if (firstVisibleSlide === 0) {
        this.setState({
          isLeftArrowDisabled: false,
          isShowStartGradient: true
        });
      }
      return this._slideTo({
        index: nextSlide,
        alignTo
      });
    };
    this._prev = () => {
      var {
        slidingType,
        infinite
      } = this.props;
      var {
        visibleSlides
      } = this.state;
      var [firstVisibleSlide, lastVisibleSlide] = visibleSlides;
      var prevSlide, alignTo;
      if ([_constants.SLIDING_TYPE.REVEAL_CHUNK, _constants.SLIDING_TYPE.REVEAL_ONE].includes(slidingType)) {
        if (firstVisibleSlide === 0) {
          prevSlide = infinite ? this.childCount - 1 : firstVisibleSlide;
        } else {
          prevSlide = firstVisibleSlide - 1;
        }
        alignTo = slidingType === _constants.SLIDING_TYPE.REVEAL_CHUNK ? _constants.ALIGNMENT.RIGHT : _constants.ALIGNMENT.LEFT;
      } else {
        if (firstVisibleSlide === 0) {
          prevSlide = infinite ? this.childCount - 1 : 0;
        } else {
          prevSlide = firstVisibleSlide - 1;
        }
        alignTo = _constants.ALIGNMENT.LEFT;
      }
      if (prevSlide === 0) {
        this.setState({
          isLeftArrowDisabled: true,
          isShowStartGradient: false
        });
      }
      if (lastVisibleSlide === this.childCount - 1) {
        this.setState({
          isRightArrowDisabled: false,
          isShowEndGradient: true
        });
      }
      return this._slideTo({
        index: prevSlide,
        alignTo
      });
    };
    this._setRef = r => {
      this.carousel = r;
    };
    this._renderLeftControl = () => {
      var {
        isLeftArrowDisabled
      } = this.state;
      var {
        controlsPosition,
        controlsStartEnd,
        controlsSize,
        controlsSkin
      } = this.props;
      return controlsPosition !== 'none' && (!isLeftArrowDisabled || controlsStartEnd === _constants.CONTROLS_START_END.DISABLED) && /*#__PURE__*/_react.default.createElement(_Control.default, {
        dataHook: _constants.DATA_HOOKS.prevButton,
        onClick: this._prev,
        icon: /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.ChevronLeftSmall, {
          __self: this,
          __source: {
            fileName: _jsxFileName,
            lineNumber: 345,
            columnNumber: 17
          }
        }),
        size: controlsSize,
        skin: controlsSkin,
        disabled: isLeftArrowDisabled,
        className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.control, _CarouselWIPSt.classes.prev),
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 342,
          columnNumber: 9
        }
      });
    };
    this._renderRightControl = () => {
      var {
        isRightArrowDisabled
      } = this.state;
      var {
        controlsPosition,
        controlsStartEnd,
        controlsSize,
        controlsSkin
      } = this.props;
      return controlsPosition !== 'none' && (!isRightArrowDisabled || controlsStartEnd === _constants.CONTROLS_START_END.DISABLED) && /*#__PURE__*/_react.default.createElement(_Control.default, {
        dataHook: _constants.DATA_HOOKS.nextButton,
        onClick: this._next,
        icon: /*#__PURE__*/_react.default.createElement(_wixUiIconsCommon.ChevronRightSmall, {
          __self: this,
          __source: {
            fileName: _jsxFileName,
            lineNumber: 367,
            columnNumber: 17
          }
        }),
        size: controlsSize,
        skin: controlsSkin,
        disabled: isRightArrowDisabled,
        className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.control, _CarouselWIPSt.classes.next),
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 364,
          columnNumber: 9
        }
      });
    };
    this._handlePointerDown = e => {
      if (!e.isPrimary) return;
      e.preventDefault();
      this.dragStartX = e.clientX;
      this.initialScrollLeft = this.carousel.scrollLeft;
      this.capturedPointerId = e.pointerId;
      this.setState({
        isDragging: true
      });
    };
    this.requestAnimationFrameId = null;
    this._handlePointerMove = e => {
      var {
        isDragging
      } = this.state;
      if (!isDragging || !this.dragStartX || e.pointerId !== this.capturedPointerId) {
        return;
      }
      e.preventDefault();
      if (!this.hasSetPointerCapture) {
        e.currentTarget.setPointerCapture(e.pointerId);
        this.hasSetPointerCapture = true;
      }
      if (this.requestAnimationFrameId) {
        cancelAnimationFrame(this.requestAnimationFrameId);
      }
      var swipeDistance = e.clientX - this.dragStartX;
      this.requestAnimationFrameId = requestAnimationFrame(() => {
        this.carousel.scrollLeft = this.initialScrollLeft - swipeDistance;
      });
    };
    this._handlePointerUp = e => {
      var {
        isDragging
      } = this.state;
      if (!isDragging || !this.dragStartX || e.pointerId !== this.capturedPointerId) return;
      this._handleSwipeEnd(e);
      this._releasePointerCapture(e.pointerId);
      this._resetDragState();
    };
    this._handlePointerCancel = e => {
      if (e.pointerId !== this.capturedPointerId || !this.dragStartX) {
        return;
      }
      this._handleSwipeEnd(e);
      this._releasePointerCapture(e.pointerId);
      this._resetDragState();
    };
    this._handleKeyDown = e => {
      var {
        infinite
      } = this.props;
      var {
        isLeftArrowDisabled,
        isRightArrowDisabled
      } = this.state;
      if (e.key === 'ArrowLeft') {
        e.preventDefault();
        if (infinite || !isLeftArrowDisabled) {
          this._prev();
        }
      } else if (e.key === 'ArrowRight') {
        e.preventDefault();
        if (infinite || !isRightArrowDisabled) {
          this._next();
        }
      }
    };
    this._handleFocusCapture = e => {
      if (!this.carousel) return;
      var focusedElement = e.target;
      var slides = Array.from(this.carousel.children);
      var slideIndex = slides.findIndex(slide => slide.contains(focusedElement));
      if (slideIndex === -1) return;
      var slide = slides[slideIndex];
      if (!(0, _utils.isWhollyInView)(this.carousel)(slide)) {
        this._slideTo({
          index: slideIndex,
          alignTo: _constants.ALIGNMENT.LEFT
        });
      }
    };
    this._handleSwipeEnd = e => {
      if (!this.dragStartX) return;
      var swipeDistance = e.clientX - this.dragStartX;
      if (Math.abs(swipeDistance) > _constants.SWIPE_THRESHOLD) {
        if (swipeDistance > 0) {
          // Swiped right - go to previous slide
          this._prev();
        } else {
          // Swiped left - go to next slide
          this._next();
        }
      } else {
        var {
          easing,
          animationDuration: duration
        } = this.props;

        // sliding back to the original position
        (0, _utils.animate)(this.carousel, {
          prop: 'scrollLeft',
          delta: swipeDistance,
          easing,
          duration
        });
      }
    };
    this._releasePointerCapture = capturedPointerId => {
      var _this$carousel2;
      if ((_this$carousel2 = this.carousel) != null && _this$carousel2.hasPointerCapture != null && _this$carousel2.hasPointerCapture(capturedPointerId)) {
        var _this$carousel3;
        (_this$carousel3 = this.carousel) == null || _this$carousel3.releasePointerCapture == null || _this$carousel3.releasePointerCapture(capturedPointerId);
      }
    };
    this._resetDragState = () => {
      this.dragStartX = null;
      this.initialScrollLeft = 0;
      this.capturedPointerId = null;
      this.hasSetPointerCapture = false;
      this.setState({
        isDragging: false
      });
    };
    this._renderSlides = () => {
      var {
        images = [],
        children,
        gutter,
        imagesPosition,
        imagesFit
      } = this.props;
      var {
        visibleSlides
      } = this.state;
      var [firstVisibleSlide, lastVisibleSlide] = visibleSlides;
      var slide = _ref2 => {
        var {
          i,
          image,
          child
        } = _ref2;
        var isVisible = i >= firstVisibleSlide && i <= lastVisibleSlide;
        return /*#__PURE__*/_react.default.createElement(_Slide.default, {
          dataHook: _constants.DATA_HOOKS.child,
          className: _CarouselWIPSt.classes.slide,
          key: "slide-".concat(i),
          width: "auto",
          gutter: i > 0 && gutter != null ? "".concat(gutter, "px") : undefined,
          image: image,
          children: child,
          imagePosition: imagesPosition,
          imageFit: imagesFit,
          isVisible: isVisible,
          __self: this,
          __source: {
            fileName: _jsxFileName,
            lineNumber: 549,
            columnNumber: 9
          }
        });
      };
      return /*#__PURE__*/_react.default.createElement("div", {
        className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.carousel, {
          dragging: this.state.isDragging
        }),
        role: "list",
        ref: this._setRef,
        "data-hook": _constants.DATA_HOOKS.carousel,
        onPointerDown: this._handlePointerDown,
        onPointerMove: this._handlePointerMove,
        onPointerUp: this._handlePointerUp,
        onPointerCancel: this._handlePointerCancel,
        onFocusCapture: this._handleFocusCapture,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 565,
          columnNumber: 7
        }
      }, _react.Children.count(children) ? _react.Children.map(children, (child, i) => slide({
        i,
        child
      })) : images.map((image, i) => slide({
        i,
        image
      })));
    };
    this._renderLoader = () => /*#__PURE__*/_react.default.createElement("div", {
      className: _CarouselWIPSt.classes.loader,
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 584,
        columnNumber: 5
      }
    }, /*#__PURE__*/_react.default.createElement(_Loader.default, {
      dataHook: _constants.DATA_HOOKS.loader,
      size: "small",
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 585,
        columnNumber: 7
      }
    }));
    this._renderDots = () => {
      var {
        children,
        images
      } = this.props;
      var {
        visibleSlides
      } = this.state;
      var [firstVisibleSlide, lastVisibleSlide] = visibleSlides;
      var slidesCount = _react.Children.count(children) || (images == null ? void 0 : images.length) || 0;
      return /*#__PURE__*/_react.default.createElement("div", {
        className: _CarouselWIPSt.classes.dots,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 596,
          columnNumber: 7
        }
      }, Array(slidesCount).fill(0).map((_, index) => /*#__PURE__*/_react.default.createElement("div", {
        "data-hook": _constants.DATA_HOOKS.pageNavigation(index),
        key: index,
        "aria-hidden": index !== firstVisibleSlide,
        className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.dot, {
          active: index >= firstVisibleSlide && index <= lastVisibleSlide
        }),
        onClick: () => {
          if (index < firstVisibleSlide || index > lastVisibleSlide) this._slideTo({
            index,
            alignTo: index > firstVisibleSlide ? _constants.ALIGNMENT.RIGHT : _constants.ALIGNMENT.LEFT
          });
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 600,
          columnNumber: 13
        }
      })));
    };
    this._renderStartGradient = () => /*#__PURE__*/_react.default.createElement("div", {
      className: _CarouselWIPSt.classes.start,
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 623,
        columnNumber: 32
      }
    });
    this._renderEndGradient = () => /*#__PURE__*/_react.default.createElement("div", {
      className: _CarouselWIPSt.classes.end,
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 625,
        columnNumber: 30
      }
    });
    this.loadingImagesCount = 0;
    this.state = {
      visibleSlides: [],
      isAnimating: false,
      isLoading: false,
      isLeftArrowDisabled: true,
      isRightArrowDisabled: true,
      isShowStartGradient: false,
      isShowEndGradient: false,
      isDragging: false
    };
  }
  componentDidMount() {
    var {
      initialSlideIndex = 0,
      autoplay
    } = this.props;
    (0, _deprecationLog.default)('<CarouselWIP/> is deprecated and will be removed in the next major version. Please migrate to <Carousel/> which now supports all CarouselWIP features.');
    this._updateChildCount();
    this._setImagesOnLoadHandlers();
    if (!this.loadingImagesCount) {
      this._slideTo({
        index: initialSlideIndex,
        immediate: true
      }).catch(_utils.nop);
      this._setVisibleSlides();
    }
    this._setAutoplayTimer(autoplay);
  }
  componentDidUpdate(prevProps) {
    var {
      autoplay
    } = this.props;
    if (prevProps.autoplay !== autoplay) this._setAutoplayTimer(autoplay);
    var lastCount = this.childCount;
    this._updateChildCount();
    if (this.childCount && lastCount !== this.childCount) {
      this._setVisibleSlides();
    }
  }
  render() {
    var {
      dataHook,
      className,
      controlsPosition,
      controlsSize,
      showControlsShadow,
      sidesGradientColor,
      hideDots
    } = this.props;
    var {
      isShowStartGradient,
      isShowEndGradient,
      isLoading
    } = this.state;
    var showSidesGradients = !!sidesGradientColor;
    return isLoading ? this._renderLoader() : /*#__PURE__*/_react.default.createElement("div", {
      "data-hook": dataHook,
      className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.root, {
        controlsPosition,
        controlsSize,
        showControlsShadow,
        showSidesGradients,
        hideDots
      }, className),
      "aria-roledescription": "carousel",
      style: {
        [_CarouselWIPSt.vars.sidesGradientColor]: sidesGradientColor
      },
      onKeyDown: this._handleKeyDown,
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 643,
        columnNumber: 7
      }
    }, /*#__PURE__*/_react.default.createElement("div", {
      style: {
        position: 'relative'
      },
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 660,
        columnNumber: 9
      }
    }, /*#__PURE__*/_react.default.createElement("div", {
      role: "group",
      "aria-label": "Carousel navigation",
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 661,
        columnNumber: 11
      }
    }, this._renderLeftControl(), this._renderRightControl()), showSidesGradients && isShowStartGradient && this._renderStartGradient(), showSidesGradients && isShowEndGradient && this._renderEndGradient(), this._renderSlides()), !hideDots && this._renderDots());
  }
  componentWillUnmount() {
    if (this.capturedPointerId) {
      this._releasePointerCapture(this.capturedPointerId);
    }
    this._setAutoplayTimer(false);
  }
}
CarouselWIP.displayName = 'CarouselWIP';
CarouselWIP.defaultProps = {
  children: [],
  infinite: true,
  controlsSkin: 'standard',
  controlsStartEnd: 'disabled',
  showControlsShadow: false,
  images: [],
  initialSlideIndex: 0,
  controlsPosition: 'sides',
  controlsSize: 'medium',
  slidingType: 'align-to-start',
  startEndOffset: 0,
  gutter: undefined,
  hideDots: false,
  autoplay: false
};
var _default = exports.default = CarouselWIP;
//# sourceMappingURL=CarouselWIP.js.map