wix-style-react
Version:
604 lines (510 loc) • 24 kB
JavaScript
"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;