wix-style-react
Version:
307 lines (262 loc) • 12.3 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["currentSlide", "slideCount"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(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; } }
import React from 'react';
import PropTypes from 'prop-types';
import ChevronLeftLarge from 'wix-ui-icons-common/ChevronLeftLarge';
import ChevronRightLarge from 'wix-ui-icons-common/ChevronRightLarge';
import ChevronLeftLargeSmall from 'wix-ui-icons-common/ChevronLeftLargeSmall';
import ChevronRightLargeSmall from 'wix-ui-icons-common/ChevronRightLargeSmall';
import ChevronLeftSmall from 'wix-ui-icons-common/ChevronLeftSmall';
import ChevronRightSmall from 'wix-ui-icons-common/ChevronRightSmall'; // This is here and not in the test setup because we don't want consumers to need to run it as well
import '../common/match-media-register';
import Slider from 'react-slick';
import { st, classes } from './Carousel.st.css';
import Pagination from './Pagination';
import SliderArrow from './SliderArrow';
import Loader from '../Loader';
import Proportion from '../Proportion';
var AUTOPLAY_SPEED = 2000;
var TRANSITION_SPEED = 600;
var dataHooks = {
imagesContainer: 'images-container',
carouselImage: 'carousel-img',
loader: 'loader',
prevButton: 'prev-button',
nextButton: 'next-button',
pageNavigation: function pageNavigation(index) {
return "page-navigation-".concat(index);
}
};
var WrappedSliderArrow = function WrappedSliderArrow(_ref) {
var currentSlide = _ref.currentSlide,
slideCount = _ref.slideCount,
rest = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/React.createElement(SliderArrow, rest);
};
var Carousel = /*#__PURE__*/function (_React$Component) {
_inherits(Carousel, _React$Component);
var _super = _createSuper(Carousel);
function Carousel(props) {
var _this;
_classCallCheck(this, Carousel);
_this = _super.call(this, props);
_defineProperty(_assertThisInitialized(_this), "leftIconByControlSize", function (controlSize) {
switch (controlSize) {
case 'tiny':
return /*#__PURE__*/React.createElement(ChevronLeftSmall, null);
case 'small':
return /*#__PURE__*/React.createElement(ChevronLeftLargeSmall, null);
default:
return /*#__PURE__*/React.createElement(ChevronLeftLarge, null);
}
});
_defineProperty(_assertThisInitialized(_this), "rightIconByControlSize", function (controlSize) {
switch (controlSize) {
case 'tiny':
return /*#__PURE__*/React.createElement(ChevronRightSmall, null);
case 'small':
return /*#__PURE__*/React.createElement(ChevronRightLargeSmall, null);
default:
return /*#__PURE__*/React.createElement(ChevronRightLarge, null);
}
});
_defineProperty(_assertThisInitialized(_this), "_resolveSliderSettings", function (_ref2) {
var infinite = _ref2.infinite,
autoplay = _ref2.autoplay,
dots = _ref2.dots,
variableWidth = _ref2.variableWidth,
buttonSkin = _ref2.buttonSkin,
initialSlideIndex = _ref2.initialSlideIndex,
afterChange = _ref2.afterChange,
beforeChange = _ref2.beforeChange,
controlsPosition = _ref2.controlsPosition,
controlsSize = _ref2.controlsSize,
controlsStartEnd = _ref2.controlsStartEnd;
return {
infinite: infinite,
autoplay: autoplay,
speed: TRANSITION_SPEED,
autoplaySpeed: AUTOPLAY_SPEED,
initialSlide: initialSlideIndex,
dots: dots,
slidesToShow: 1,
slidesToScroll: 1,
variableWidth: variableWidth,
afterChange: afterChange,
beforeChange: beforeChange,
nextArrow: /*#__PURE__*/React.createElement(WrappedSliderArrow, {
dataHook: dataHooks.nextButton,
buttonSkin: buttonSkin,
arrowSize: controlsSize,
icon: _this.rightIconByControlSize(controlsSize),
controlsStartEnd: controlsStartEnd
}),
prevArrow: /*#__PURE__*/React.createElement(WrappedSliderArrow, {
dataHook: dataHooks.prevButton,
buttonSkin: buttonSkin,
arrowSize: controlsSize,
icon: _this.leftIconByControlSize(controlsSize),
controlsStartEnd: controlsStartEnd
}),
arrows: controlsPosition !== 'none',
appendDots: function appendDots(pages) {
/*
* originalClassName is a workaround for stylable API extend to work and pass an extendable className.
* This is because react-slick overrides brutally the className prop with cloneElement().
*/
return /*#__PURE__*/React.createElement(Pagination, {
originalClassName: classes.pagination,
pages: pages
});
},
customPaging: function customPaging(i) {
return /*#__PURE__*/React.createElement("div", {
className: classes.pageNavigation,
"data-hook": dataHooks.pageNavigation(i)
}, i);
}
};
});
_defineProperty(_assertThisInitialized(_this), "_renderImages", function (images) {
var _this$props = _this.props,
imagesPosition = _this$props.imagesPosition,
imagesFit = _this$props.imagesFit;
return images.map(function (image, index) {
return /*#__PURE__*/React.createElement(Proportion, {
key: "".concat(index).concat(image.src),
aspectRatio: Proportion.PREDEFINED_RATIOS.landscape
}, /*#__PURE__*/React.createElement("div", {
className: st(classes.imageContainer, {
isLoading: _this._isLoading(image.src)
}),
"data-hook": dataHooks.imagesContainer
}, /*#__PURE__*/React.createElement("img", _extends({}, image, {
"data-hook": dataHooks.carouselImage,
className: classes.image,
onLoad: function onLoad() {
return _this._onImageLoad(image.src);
},
style: _objectSpread({
objectPosition: imagesPosition,
objectFit: imagesFit
}, image.style)
}))), _this._isLoading(image.src) && /*#__PURE__*/React.createElement("div", {
className: classes.loader
}, /*#__PURE__*/React.createElement(Loader, {
dataHook: "loader",
size: "small"
})));
});
});
_this.state = {
sliderSettings: _this._resolveSliderSettings(props),
loadedImages: []
};
return _this;
}
_createClass(Carousel, [{
key: "render",
value: function render() {
var _this$props2 = this.props,
dataHook = _this$props2.dataHook,
className = _this$props2.className,
images = _this$props2.images,
children = _this$props2.children,
controlsPosition = _this$props2.controlsPosition,
controlsSize = _this$props2.controlsSize,
showControlsShadow = _this$props2.showControlsShadow;
var sliderSettings = this.state.sliderSettings;
var hasImages = !children && images.length > 0;
return /*#__PURE__*/React.createElement("div", {
"data-hook": dataHook,
className: st(classes.root, {
controlsPosition: controlsPosition,
controlsSize: controlsSize,
showControlsShadow: showControlsShadow
}, className)
}, /*#__PURE__*/React.createElement(Slider, sliderSettings, children, hasImages && this._renderImages(images)));
}
}, {
key: "_onImageLoad",
value: function _onImageLoad(src) {
this.setState(function (state) {
return {
loadedImages: [].concat(_toConsumableArray(state.loadedImages), [src])
};
});
}
}, {
key: "_isLoading",
value: function _isLoading(src) {
return !this.state.loadedImages.includes(src);
}
}]);
return Carousel;
}(React.Component);
_defineProperty(Carousel, "displayName", 'Carousel');
_defineProperty(Carousel, "propTypes", {
/** Applied as data-hook HTML attribute that can be used in the tests */
dataHook: PropTypes.string,
/** A single CSS class name to be appended to the Carousel's wrapper element. */
className: PropTypes.string,
/** Array of objects where each contains the `src` of an image (in \<img src="your_src" /\>) */
images: PropTypes.array,
/** Sets the images position */
imagesPosition: PropTypes.string,
/** Sets the images fit */
imagesFit: PropTypes.oneOf(['fill', 'contain', 'cover', 'none', 'scale-down']),
/** Any element to render inside */
children: PropTypes.node,
/** Sets the skin of the arrow buttons */
buttonSkin: PropTypes.oneOf(['standard', 'inverted', 'light']),
/** Show a shadow for the carousel controls */
showControlsShadow: PropTypes.bool,
/** Images loop endlessly */
infinite: PropTypes.bool,
/** Auto-playing of images */
autoplay: PropTypes.bool,
/** Show dots */
dots: PropTypes.bool,
/** Variable width of children */
variableWidth: PropTypes.bool,
/** An index of the slide to start on */
initialSlideIndex: PropTypes.number,
/** Index change callback. `index => ...` */
afterChange: PropTypes.func,
/** Index change callback. `(oldIndex, newIndex) => ...` */
beforeChange: PropTypes.func,
/** Sets the arrows position */
controlsPosition: PropTypes.oneOf(['sides', 'overlay', 'bottom', 'none']),
/** Sets the arrows size */
controlsSize: PropTypes.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.oneOf(['disabled', 'hidden'])
});
_defineProperty(Carousel, "defaultProps", {
infinite: true,
dots: true,
variableWidth: false,
initialSlideIndex: 0,
images: [],
imagesPosition: 'center top',
imagesFit: 'contain',
buttonSkin: 'standard',
controlsPosition: 'sides',
controlsSize: 'medium',
controlsStartEnd: 'disabled',
showControlsShadow: false
});
export default Carousel;