UNPKG

wix-style-react

Version:
604 lines (510 loc) • 24 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _CarouselWIPSt = require("./CarouselWIP.st.css"); var _wixUiIconsCommon = require("wix-ui-icons-common"); var _Loader = _interopRequireDefault(require("../Loader")); var _Control = _interopRequireDefault(require("./Control")); var _Slide = _interopRequireDefault(require("./Slide")); var _constants = require("./constants"); var _utils = require("./utils"); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** The carousel component creates a slideshow for cycling through a series of content. */ var CarouselWIP = /*#__PURE__*/function (_React$PureComponent) { (0, _inherits2["default"])(CarouselWIP, _React$PureComponent); var _super = _createSuper(CarouselWIP); function CarouselWIP(_props) { var _this; (0, _classCallCheck2["default"])(this, CarouselWIP); _this = _super.call(this, _props); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setImagesOnLoadHandlers", function () { Array.from(_this.carousel.children).forEach(function (child) { var childImages = Array.from(child.getElementsByTagName('img')); childImages.forEach(function (img) { _this.setState({ isLoading: true }); _this.loadingImagesCount++; img.onload = _this._onImageLoad; img.onerror = _this._onImageLoad; }); }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_updateChildCount", function () { var _ref, _this$carousel$childr, _this$carousel, _this$carousel$childr2; var images = _this.props.images; _this.childCount = (_ref = (_this$carousel$childr = (_this$carousel = _this.carousel) === null || _this$carousel === void 0 ? void 0 : (_this$carousel$childr2 = _this$carousel.children) === null || _this$carousel$childr2 === void 0 ? void 0 : _this$carousel$childr2.length) !== null && _this$carousel$childr !== void 0 ? _this$carousel$childr : images === null || images === void 0 ? void 0 : images.length) !== null && _ref !== void 0 ? _ref : 0; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onImageLoad", function () { var initialSlideIndex = _this.props.initialSlideIndex; _this.loadingImagesCount--; if (!_this.loadingImagesCount) { _this.setState({ isLoading: false }); _this._slideTo({ index: initialSlideIndex, immediate: true })["catch"](_utils.nop); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setAutoplayTimer", function (active) { clearInterval(_this.autoplayTimer); if (active) _this.autoplayTimer = setInterval(_this._next, _constants.AUTOPLAY_SPEED); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setVisibleSlides", function () { var _assertThisInitialize = (0, _assertThisInitialized2["default"])(_this), props = _assertThisInitialize.props, carousel = _assertThisInitialize.carousel, childCount = _assertThisInitialize.childCount; var infinite = props.infinite; var firstVisibleChild = Math.max(Array.from(carousel.children).findIndex(function (child) { return (0, _utils.isWhollyInView)(carousel)(child); }), 0); var lastVisibleChild = Math.max(Array.from(carousel.children).findIndex(function (child, i, children) { return (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 }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_slideTo", function () { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { index: 0, alignTo: _constants.ALIGNMENT.LEFT, immediate: false }, index = _ref2.index, alignTo = _ref2.alignTo, immediate = _ref2.immediate; if (_this.childCount === 0) { return Promise.reject('No children to slide to'); } if (!_this.carousel) { return Promise.reject('The Carousel is not mounted'); } var _this$props = _this.props, afterChange = _this$props.afterChange, beforeChange = _this$props.beforeChange, easing = _this$props.easing, duration = _this$props.animationDuration, infinite = _this$props.infinite, startEndOffset = _this$props.startEndOffset; var _this$carousel2 = _this.carousel, children = _this$carousel2.children, scrollLeft = _this$carousel2.scrollLeft, offsetWidth = _this$carousel2.offsetWidth; var slideIndex = (0, _utils.normalizeIndex)(index, _this.childCount, infinite); var visibleSlides = _this.state.visibleSlides; var _visibleSlides = (0, _slicedToArray2["default"])(visibleSlides, 2), firstVisibleSlide = _visibleSlides[0], lastVisibleSlide = _visibleSlides[1]; var delta; if (alignTo === _constants.ALIGNMENT.RIGHT) { delta = children[slideIndex].offsetWidth - (offsetWidth - children[slideIndex].offsetLeft) - scrollLeft + startEndOffset; } else { delta = children[slideIndex].offsetLeft - scrollLeft - startEndOffset; } if (firstVisibleSlide !== slideIndex && beforeChange) { beforeChange(firstVisibleSlide, index); } _this.setState({ isAnimating: true }); return new Promise(function (res, _) { if (immediate) { _this.carousel.scrollLeft = children[slideIndex].offsetLeft; return res(); } else { var originalOverflowX = 'hidden'; var prop = 'scrollLeft'; return res((0, _utils.animate)(_this.carousel, { prop: prop, delta: delta, easing: easing, duration: duration, originalOverflowX: originalOverflowX })); } }).then(function () { _this.setState({ isAnimating: false }); _this._setVisibleSlides(); if (firstVisibleSlide !== slideIndex && afterChange) { return afterChange(slideIndex); } })["catch"](function (_) { _this._setVisibleSlides(); _this.setState({ isAnimating: false }); }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_next", function () { var _this$props2 = _this.props, slidingType = _this$props2.slidingType, infinite = _this$props2.infinite; var visibleSlides = _this.state.visibleSlides; var _visibleSlides2 = (0, _slicedToArray2["default"])(visibleSlides, 2), firstVisibleSlide = _visibleSlides2[0], lastVisibleSlide = _visibleSlides2[1]; 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: alignTo }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_prev", function () { var _this$props3 = _this.props, slidingType = _this$props3.slidingType, infinite = _this$props3.infinite; var visibleSlides = _this.state.visibleSlides; var _visibleSlides3 = (0, _slicedToArray2["default"])(visibleSlides, 2), firstVisibleSlide = _visibleSlides3[0], lastVisibleSlide = _visibleSlides3[1]; 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: alignTo }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setRef", function (r) { _this.carousel = r; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderLeftControl", function () { var isLeftArrowDisabled = _this.state.isLeftArrowDisabled; var _this$props4 = _this.props, controlsPosition = _this$props4.controlsPosition, controlsStartEnd = _this$props4.controlsStartEnd, controlsSize = _this$props4.controlsSize, controlsSkin = _this$props4.controlsSkin; 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, null), size: controlsSize, skin: controlsSkin, disabled: isLeftArrowDisabled, className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.control, _CarouselWIPSt.classes.prev) }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderRightControl", function () { var isRightArrowDisabled = _this.state.isRightArrowDisabled; var _this$props5 = _this.props, controlsPosition = _this$props5.controlsPosition, controlsStartEnd = _this$props5.controlsStartEnd, controlsSize = _this$props5.controlsSize, controlsSkin = _this$props5.controlsSkin; 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, null), size: controlsSize, skin: controlsSkin, disabled: isRightArrowDisabled, className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.control, _CarouselWIPSt.classes.next) }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderSlides", function () { var _this$props6 = _this.props, images = _this$props6.images, children = _this$props6.children, gutter = _this$props6.gutter, imagesPosition = _this$props6.imagesPosition, imagesFit = _this$props6.imagesFit; var slide = function slide(_ref3) { var i = _ref3.i, image = _ref3.image, child = _ref3.child; return /*#__PURE__*/_react["default"].createElement(_Slide["default"], { dataHook: _constants.DATA_HOOKS.child, key: "slide-".concat(i), role: "listitem", width: "auto", gutter: i > 0 ? "".concat(gutter, "px") : '', image: image, children: child, imagePosition: imagesPosition, imageFit: imagesFit }); }; return /*#__PURE__*/_react["default"].createElement("div", { className: _CarouselWIPSt.classes.carousel, role: "list", ref: _this._setRef }, children.length ? _react["default"].Children.map(children, function (child, i) { return slide({ i: i, child: child }); }) : images.map(function (image, i) { return slide({ i: i, image: image }); })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderLoader", function () { return /*#__PURE__*/_react["default"].createElement("div", { className: _CarouselWIPSt.classes.loader }, /*#__PURE__*/_react["default"].createElement(_Loader["default"], { dataHook: _constants.DATA_HOOKS.loader, size: "small" })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderDots", function () { var _this$props7 = _this.props, children = _this$props7.children, images = _this$props7.images; var visibleSlides = _this.state.visibleSlides; var _visibleSlides4 = (0, _slicedToArray2["default"])(visibleSlides, 2), firstVisibleSlide = _visibleSlides4[0], lastVisibleSlide = _visibleSlides4[1]; var slidesCount = children.length || images.length || 0; return /*#__PURE__*/_react["default"].createElement("div", { className: _CarouselWIPSt.classes.dots }, Array(slidesCount).fill(0).map(function (_, index) { return /*#__PURE__*/_react["default"].createElement("div", { "data-hook": _constants.DATA_HOOKS.pageNavigation(index), key: index, className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.dot, { active: index >= firstVisibleSlide && index <= lastVisibleSlide }), onClick: function onClick() { if (index < firstVisibleSlide || index > lastVisibleSlide) _this._slideTo({ index: index, alignTo: index > firstVisibleSlide ? _constants.ALIGNMENT.RIGHT : _constants.ALIGNMENT.LEFT }); } }); })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderStartGradient", function () { return /*#__PURE__*/_react["default"].createElement("div", { className: _CarouselWIPSt.classes.start }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderEndGradient", function () { return /*#__PURE__*/_react["default"].createElement("div", { className: _CarouselWIPSt.classes.end }); }); _this.loadingImagesCount = 0; _this.state = { visibleSlides: [], isAnimating: false, isLoading: false, isLeftArrowDisabled: true, isRightArrowDisabled: true, isShowStartGradient: false, isShowEndGradient: false }; return _this; } (0, _createClass2["default"])(CarouselWIP, [{ key: "componentDidMount", value: function componentDidMount() { var _this$props8 = this.props, initialSlideIndex = _this$props8.initialSlideIndex, autoplay = _this$props8.autoplay; this._updateChildCount(); this._setImagesOnLoadHandlers(); if (!this.loadingImagesCount) { this._slideTo({ index: initialSlideIndex, immediate: true })["catch"](_utils.nop); this._setVisibleSlides(); } this._setAutoplayTimer(autoplay); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var autoplay = this.props.autoplay; if (prevProps.autoplay !== autoplay) this._setAutoplayTimer(autoplay); var lastCount = this.childCount; this._updateChildCount(); if (this.childCount && lastCount !== this.childCount) { this._setVisibleSlides(); } } // 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 }, { key: "render", value: function render() { var _this$props9 = this.props, dataHook = _this$props9.dataHook, className = _this$props9.className, controlsPosition = _this$props9.controlsPosition, controlsSize = _this$props9.controlsSize, showControlsShadow = _this$props9.showControlsShadow, sidesGradientColor = _this$props9.sidesGradientColor, hideDots = _this$props9.hideDots; var _this$state = this.state, isShowStartGradient = _this$state.isShowStartGradient, isShowEndGradient = _this$state.isShowEndGradient, isLoading = _this$state.isLoading; var showSidesGradients = !!sidesGradientColor; return isLoading ? this._renderLoader() : /*#__PURE__*/_react["default"].createElement("div", { "data-hook": dataHook, className: (0, _CarouselWIPSt.st)(_CarouselWIPSt.classes.root, { controlsPosition: controlsPosition, controlsSize: controlsSize, showControlsShadow: showControlsShadow, showSidesGradients: showSidesGradients }, className), style: (0, _defineProperty2["default"])({}, _CarouselWIPSt.vars.sidesGradientColor, sidesGradientColor) }, /*#__PURE__*/_react["default"].createElement("div", { style: { position: 'relative' } }, showSidesGradients && isShowStartGradient && this._renderStartGradient(), this._renderLeftControl(), this._renderSlides(), this._renderRightControl(), showSidesGradients && isShowEndGradient && this._renderEndGradient()), !hideDots && this._renderDots()); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this._setAutoplayTimer(false); } }]); return CarouselWIP; }(_react["default"].PureComponent); (0, _defineProperty2["default"])(CarouselWIP, "displayName", 'CarouselWIP'); (0, _defineProperty2["default"])(CarouselWIP, "propTypes", { /** Applied as data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes["default"].string, /** A css class to be applied to the component's root element */ className: _propTypes["default"].string, /** Any element to render inside */ children: _propTypes["default"].node, /** Array of objects where each contains the `src` of an image (in \<img src="your_src" /\>) */ images: _propTypes["default"].array, /** Sets the skin of the arrow buttons */ controlsSkin: _propTypes["default"].oneOf(['standard', 'inverted', 'light']), /** Show a shadow for the carousel controls */ showControlsShadow: _propTypes["default"].bool, /** Images loop endlessly */ infinite: _propTypes["default"].bool, /** An index of the slide to start on */ initialSlideIndex: _propTypes["default"].number, /** Index change callback. `index => ...` */ afterChange: _propTypes["default"].func, /** Index change callback. `(oldIndex, newIndex) => ...` */ beforeChange: _propTypes["default"].func, /** Sets the arrows position */ controlsPosition: _propTypes["default"].oneOf(['sides', 'overlay', 'bottom', 'none']), /** Sets the arrows position */ controlsSize: _propTypes["default"].oneOf(['tiny', 'small', 'medium']), /** Configure the start and end controls to be shown disabled or hidden. Relevant when infinite prop is set to false. */ controlsStartEnd: _propTypes["default"].oneOf(['disabled', 'hidden']), /** Sliding behaviour type for the carousel */ slidingType: _propTypes["default"].oneOf(['align-to-start', 'reveal-one', 'reveal-chunk']), /** Number of pixels for showing "peeking" cards on the edges of the carousel */ startEndOffset: _propTypes["default"].number, /** Number of pixels dividing between slides */ gutter: _propTypes["default"].number, /** Color for the gradients on the sides of the carousel */ sidesGradientColor: _propTypes["default"].string, /** Sets the images position */ imagesPosition: _propTypes["default"].string, /** Sets the images fit */ imagesFit: _propTypes["default"].oneOf(['fill', 'contain', 'cover', 'none', 'scale-down']), /** Auto-playing of images */ autoplay: _propTypes["default"].bool, /** Hide dots */ hideDots: _propTypes["default"].bool, // TODO: implement prop /** 🚧 Variable width of children */ variableWidth: _propTypes["default"].bool }); (0, _defineProperty2["default"])(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: 0, hideDots: false, autoplay: false }); var _default = CarouselWIP; exports["default"] = _default;