@shopgate/pwa-common 7.23.1 → 7.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}import React,{useMemo,useState,useEffect,useRef,useCallback,memo}from'react';import PropTypes from'prop-types';import classNames from'classnames';import noop from'lodash/noop';import{themeConfig}from'@shopgate/engage';import{getFullImageSource}from'@shopgate/engage/core/helpers';import styles from"./style";import ImageInner from"./ImageInner";var themeColors=themeConfig.colors;/**
2
+ * Calculates the Greatest Common Divisor (GCD) of two numbers using the Euclidean algorithm.
3
+ *
4
+ * @param {number} a - The first number (must be a positive integer).
5
+ * @param {number} b - The second number (must be a positive integer).
6
+ * @returns {number} The greatest common divisor of `a` and `b`.
7
+ *
8
+ * @example
9
+ * gcd(1920, 1080); // Returns 120
10
+ * gcd(10, 15); // Returns 5
11
+ * gcd(100, 25); // Returns 25
12
+ */var gcd=function gcd(a,b){return b===0?a:gcd(b,a%b);};/**
13
+ * The image component.
14
+ * @param {Object} props The components props.
15
+ * @returns {JSX.Element}
16
+ */var Image=function Image(_ref){var alt=_ref.alt,animating=_ref.animating,backgroundColor=_ref.backgroundColor,className=_ref.className,classNameImg=_ref.classNameImg,parentRendersPlaceholder=_ref.forcePlaceholder,highestResolutionLoaded=_ref.highestResolutionLoaded,onError=_ref.onError,onLoad=_ref.onLoad,ratio=_ref.ratio,resolutions=_ref.resolutions,src=_ref.src,lazy=_ref.lazy,unwrapped=_ref.unwrapped;// Prepare two image sources - a small preview image and a large main image. The idea is to
17
+ // display an image as soon as possible. Small images might be also available in the cache from
18
+ // the previous page.
19
+ var sources=useMemo(function(){// Create a preview source when resolutions array has more than one element
20
+ var preview=resolutions.length>1?getFullImageSource(src,resolutions[resolutions.length-2]):null;// Create a main source when resolutions array has at least one element (highest resolution)
21
+ var main=resolutions.length>0?getFullImageSource(src,resolutions[resolutions.length-1]):null;return{// Only assign preview source if it is different from the main source. Image swap logic
22
+ // will not run when no preview source is available.
23
+ preview:preview!==main?preview:null,main:main};},[resolutions,src]);var imgRef=useRef(null);var _useState=useState(false),_useState2=_slicedToArray(_useState,2),imageLoaded=_useState2[0],setImageLoaded=_useState2[1];var _useState3=useState(!lazy),_useState4=_slicedToArray(_useState3,2),isInView=_useState4[0],setIsInView=_useState4[1];/**
24
+ * Determines if the initial image is cached.
25
+ *
26
+ * This hook uses the `useMemo` hook to memoize the result. It creates a new
27
+ * `Image` object, sets its `src` to either the preview or main source, and checks
28
+ * if the image is complete (cached). The `src` is then reset to an empty string to abort
29
+ * the image request. The actual request is handled by the img tag.
30
+ *
31
+ * @returns {boolean} - Returns `true` if the image is cached, otherwise `false`.
32
+ */var initialImageCached=useMemo(function(){// The return value of this hook is used to determine if the image should fade in after loading
33
+ // from the server. When the `animating` prop is set to false, the image should not fade in,
34
+ // so we return true to disable the fade-in mechanism.
35
+ if(!animating)return true;var img=new window.Image();img.src=sources.preview||sources.main;var complete=img.complete;img.src='';return complete;},[animating,sources.main,sources.preview]);// Effect to create an Intersection Observer to enable lazy loading of preview images
36
+ useEffect(function(){if(!lazy)return undefined;// Intersection Observer to check if the image is in (or near) the viewport
37
+ var observer=new IntersectionObserver(function(_ref2){var _ref3=_slicedToArray(_ref2,1),entry=_ref3[0];if(entry.isIntersecting){setIsInView(true);// stop observing once visible
38
+ observer.unobserve(entry.target);}},// load a bit earlier
39
+ {rootMargin:'100px'});if(imgRef.current){// start observing the image element
40
+ observer.observe(imgRef.current);}return function(){// disconnect the observer when the component is unmounted
41
+ observer.disconnect();};},[lazy]);/**
42
+ * Handles the onLoad event of the image.
43
+ */var handleOnLoad=useCallback(function(e){highestResolutionLoaded();onLoad(e);setImageLoaded(true);},[highestResolutionLoaded,onLoad]);/**
44
+ * Handles the onError event of the image.
45
+ */var handleOnError=useCallback(function(e){onError(e);},[onError]);/**
46
+ * Memoized calculation of aspect ratio and CSS padding-hack ratio for responsive elements.
47
+ *
48
+ * Returns n object containing:
49
+ * - `aspectRatio` {string} - The aspect ratio in the format `width / height` (e.g., `16 / 9`).
50
+ * - `paddingHackRatio` {string} - The CSS padding-hack ratio as a percentage for older browsers
51
+ * (e.g., `56.250%` for a 16:9 ratio).
52
+ */var _useMemo=useMemo(function(){var width;var height;if(ratio){var _ratio=_slicedToArray(ratio,2);width=_ratio[0];height=_ratio[1];}else{var _resolutions=resolutions[resolutions.length-1];width=_resolutions.width;height=_resolutions.height;}var divisor=gcd(width,height);return{aspectRatio:"".concat(width/divisor," / ").concat(height/divisor),paddingHackRatio:"".concat((height/width*100).toFixed(3),"%")};},[ratio,resolutions]),aspectRatio=_useMemo.aspectRatio,paddingHackRatio=_useMemo.paddingHackRatio;if(unwrapped){if(!(src&&!parentRendersPlaceholder))return null;return React.createElement(ImageInner,{ref:imgRef,src:sources.main,className:classNames(classNameImg,_defineProperty(_defineProperty({},styles.imageAnimated,animating&&!initialImageCached),styles.imageVisible,animating&&(initialImageCached||imageLoaded))),style:_extends({aspectRatio:aspectRatio},isInView&&sources.preview&&{backgroundImage:"url(".concat(sources.preview,")"),backgroundSize:'cover'}),alt:alt,lazy:lazy,onLoad:handleOnLoad,onError:handleOnError});}var containerStyle=styles.container(backgroundColor,paddingHackRatio);return React.createElement("div",{className:classNames(containerStyle,className)},src&&!parentRendersPlaceholder&&React.createElement(ImageInner,{ref:imgRef,src:sources.main,className:classNames(classNameImg,_defineProperty(_defineProperty({},styles.imageAnimated,animating&&!initialImageCached),styles.imageVisible,animating&&(initialImageCached||imageLoaded))),style:_extends({aspectRatio:aspectRatio},isInView&&sources.preview&&{backgroundImage:"url(".concat(sources.preview,")"),backgroundSize:'cover'}),alt:alt,lazy:lazy,onLoad:handleOnLoad,onError:handleOnError}));};var defaultResolutions=[{width:440,height:440}];Image.defaultProps={alt:null,animating:false,backgroundColor:themeColors.placeholder,className:'',classNameImg:'',forcePlaceholder:false,highestResolutionLoaded:noop,onError:noop,onLoad:noop,ratio:null,resolutions:defaultResolutions,src:null,unwrapped:false,lazy:true};export default memo(Image);
@@ -0,0 +1,6 @@
1
+ import React,{forwardRef}from'react';import PropTypes from'prop-types';import classNames from'classnames';import noop from'lodash/noop';import styles from"./style";/**
2
+ * The ImageInner component renders tha actual image of the Image component.
3
+ * @param {Object} props The component props
4
+ * @param {Function} ref The component reference
5
+ * @returns {JSX.Element}
6
+ */var ImageInner=forwardRef(function(_ref,ref){var src=_ref.src,className=_ref.className,alt=_ref.alt,lazy=_ref.lazy,onLoad=_ref.onLoad,onError=_ref.onError,style=_ref.style;return React.createElement("img",{ref:ref,loading:lazy?'lazy':'eager',src:src,className:classNames(className,styles.image,'common__image'),alt:alt,"aria-label":alt,role:"presentation","data-test-id":"image",onLoad:onLoad,onError:onError,style:style});});ImageInner.propTypes={alt:PropTypes.string,className:PropTypes.string,lazy:PropTypes.bool,onError:PropTypes.func,onLoad:PropTypes.func,src:PropTypes.string,style:PropTypes.shape()};ImageInner.defaultProps={src:null,alt:null,className:null,lazy:false,style:null,onError:noop,onLoad:noop};export default ImageInner;
@@ -1,31 +1 @@
1
- function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj;};}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;};}return _typeof(obj);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}function _callSuper(_this,derived,args){function isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{return!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));}catch(e){return false;}}derived=_getPrototypeOf(derived);return _possibleConstructorReturn(_this,isNativeReflectConstruct()?Reflect.construct(derived,args||[],_getPrototypeOf(_this).constructor):derived.apply(_this,args));}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}import React,{Component}from'react';import PropTypes from'prop-types';import{themeColors}from'@shopgate/pwa-common/helpers/config';import{getFullImageSource,logger}from'@shopgate/engage/core';import Transition from"../Transition";import styles from"./style";/**
2
- * The image component. It supports lazy and progressive loading of images.
3
- */var Image=/*#__PURE__*/function(_Component){/**
4
- * Sets the initial state, to not render image slider component yet.
5
- * @param {Object} props The components props.
6
- */function Image(props){var _this2;_classCallCheck(this,Image);_this2=_callSuper(this,Image,[props]);logger.assert(!props.srcmap,'Use of srcmap prop is deprecated. Use resolutions instead');/**
7
- * The initial component state.
8
- * Pre-loads all resolutions if already cached will
9
- * set the state for the resolution to true.
10
- * @type {Object}
11
- */if(props.srcmap){_this2.state={loaded:props.srcmap.map(function(image,index){return _this2.loadImage(image,index);})};}else{_this2.state={loaded:props.resolutions.map(function(resolution,index){return _this2.loadImage(_this2.props.src,index);})};}_this2.mounted=false;return _this2;}/**
12
- * When component is added to the DOM.
13
- */_inherits(Image,_Component);return _createClass(Image,[{key:"componentDidMount",value:function componentDidMount(){this.mounted=true;}/**
14
- * When component was removed from DOM.
15
- */},{key:"componentWillUnmount",value:function componentWillUnmount(){this.mounted=false;}/**
16
- * Sets the image ratio based on width and height.
17
- * @return {number} The image ratio.
18
- */},{key:"imageRatio",get:function get(){if(this.props.ratio){var _this$props$ratio2=_slicedToArray(this.props.ratio,2),x=_this$props$ratio2[0],y=_this$props$ratio2[1];return(y/x*100).toFixed(3);}var _this$props$resolutio=this.props.resolutions[this.props.resolutions.length-1],width=_this$props$resolutio.width,height=_this$props$resolutio.height;return(height/width*100).toFixed(3);}/**
19
- * Image loaded event listener
20
- * @param {number} resolutionIndex The index of the loaded resolution
21
- */},{key:"imageLoaded",value:function imageLoaded(resolutionIndex){if(!this.mounted){return;}this.setState(function(_ref){var loaded=_ref.loaded;return{loaded:loaded.map(function(entry,index){if(resolutionIndex===index){return true;}return entry;})};});if(!this.props.srcmap&&resolutionIndex===this.props.resolutions.length-1){this.props.highestResolutionLoaded();}if(this.props.srcmap&&resolutionIndex===this.props.srcmap.length-1){this.props.highestResolutionLoaded();}}/**
22
- * Pre-loads the given image in given resolution
23
- * @param {string} src Source to the image.
24
- * @param {number} resolutionIndex The index of the loaded resolution.
25
- * @returns {number} true if image is already in cache.
26
- */},{key:"loadImage",value:function loadImage(src,resolutionIndex){var _this3=this;var image=new window.Image();image.onload=function(){_this3.imageLoaded(resolutionIndex);if(_this3.props.onLoad){_this3.props.onLoad();}};image.onerror=function(){if(_this3.props.onError){_this3.props.onError();}};if(!this.props.srcmap){image.src=getFullImageSource(src,this.props.resolutions[resolutionIndex]);}else{image.src=src;}return image.complete;}/**
27
- * Renders the smooth image component.
28
- * @returns {JSX}
29
- */},{key:"render",value:function render(){var index=this.state.loaded.lastIndexOf(true);var src=null;if(index>-1){src=!this.props.srcmap?getFullImageSource(this.props.src,this.props.resolutions[index]):this.props.srcmap[index];}var innerImage=null;if(src&&!this.props.forcePlaceholder){// Applies a blur effect to every resolution that has the blur flag set to true.
30
- var inlineStyles={width:'100%'};if(!this.props.srcmap&&this.props.resolutions[index].blur){inlineStyles.filter="blur(".concat(this.props.resolutions[index].blur,"px)");}// Renders the actual image.
31
- innerImage=React.createElement("img",{className:"".concat(this.props.classNameImg||styles.image," common__image"),src:src,style:inlineStyles,alt:this.props.alt,"aria-label":this.props.alt,role:"presentation","data-test-id":"image"});}if(this.props.unwrapped){return innerImage;}var containerStyle=styles.container(this.props.backgroundColor,"".concat(this.imageRatio,"%"));if(!this.props.animating||!this.props.transition){return React.createElement("div",{className:"".concat(containerStyle," ").concat(this.props.className)},innerImage);}return React.createElement(Transition,{childrenStyles:this.props.transition,className:"".concat(containerStyle," ").concat(this.props.className)},innerImage);}}]);}(Component);_defineProperty(Image,"defaultProps",{alt:null,animating:true,backgroundColor:themeColors.placeholder,className:'',classNameImg:'',forcePlaceholder:false,highestResolutionLoaded:function highestResolutionLoaded(){},onError:null,onLoad:null,ratio:null,resolutions:[{width:440,height:440}],src:null,srcmap:null,transition:null,unwrapped:false});export default Image;
1
+ export{default}from"./Image";
@@ -2,4 +2,4 @@ import{css}from'glamor';import{themeColors}from'@shopgate/pwa-common/helpers/con
2
2
  * @param {string} [background=themeColors.placeholder] The background color.
3
3
  * @param {string} [paddingTop='100%'] The padding top value.
4
4
  * @returns {string} The compiled class names.
5
- */var container=function container(){var background=arguments.length>0&&arguments[0]!==undefined?arguments[0]:themeColors.placeholder;var paddingTop=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'100%';return css({background:background,position:'relative',zIndex:0,':before':{display:'block',content:'""',width:'100%',paddingTop:paddingTop}}).toString();};var image=css({position:'absolute',top:0,left:0,width:'100%',maxHeight:'100%',WebkitTouchCallout:'none'}).toString();export default{container:container,image:image};
5
+ */var container=function container(){var background=arguments.length>0&&arguments[0]!==undefined?arguments[0]:themeColors.placeholder;var paddingTop=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'100%';return css({background:background,position:'relative',zIndex:0,':before':{display:'block',content:'""',width:'100%',paddingTop:paddingTop}}).toString();};var image=css({position:'absolute',top:0,left:0,width:'100%',maxHeight:'100%',WebkitTouchCallout:'none'}).toString();var imageAnimated=css({opacity:0,transition:'opacity 0.2s ease-in-out'}).toString();var imageVisible=css({opacity:1}).toString();export default{container:container,image:image,imageAnimated:imageAnimated,imageVisible:imageVisible};
@@ -1,5 +1,7 @@
1
- import React from'react';import PropTypes from'prop-types';import classNames from'classnames';import{item}from"./styles";/**
1
+ var _excluded=["children","className"];function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}import React from'react';import PropTypes from'prop-types';import classNames from'classnames';import{SwiperSlide}from'swiper/react';import{item}from"./styles";/**
2
+ * @typedef {import('swiper/react').SwiperSlideProps} SwiperSlideProps
3
+ */ /**
2
4
  * The basic swiper item component.
3
- * @param {Object} props The component props.
5
+ * @param {SwiperSlideProps} props The component props.
4
6
  * @returns {React.Node}
5
- */function SwiperItem(_ref){var children=_ref.children,className=_ref.className;return React.createElement("div",{className:classNames(item,className),"data-test-id":"Slider"},children);}SwiperItem.defaultProps={className:null};export default SwiperItem;
7
+ */function SwiperItem(_ref){var children=_ref.children,className=_ref.className,slideProps=_objectWithoutProperties(_ref,_excluded);return React.createElement(SwiperSlide,_extends({},slideProps,{className:classNames(item,className),"data-test-id":"Slider"}),children);}SwiperItem.displayName='SwiperSlide';SwiperItem.defaultProps={className:null};export default SwiperItem;
@@ -1 +1 @@
1
- import React from'react';import{shallow}from'enzyme';import SwiperItem from'.';describe('<SwiperItem />',function(){it('should not render without children',function(){var wrapper=shallow(React.createElement(SwiperItem,null,React.createElement("div",null)));expect(wrapper).toMatchSnapshot();expect(wrapper.html()).toEqual('<div class="css-10a4qrv" data-test-id="Slider"><div></div></div>');});it('should add custom className',function(){var wrapper=shallow(React.createElement(SwiperItem,{className:"test"},React.createElement("div",null)));expect(wrapper).toMatchSnapshot();expect(wrapper.html()).toEqual('<div class="css-10a4qrv test" data-test-id="Slider"><div></div></div>');});});
1
+ import React from'react';import{shallow}from'enzyme';import SwiperItem from'.';describe('<SwiperItem />',function(){it('should not render without children',function(){var wrapper=shallow(React.createElement(SwiperItem,null,React.createElement("div",null)));expect(wrapper).toMatchSnapshot();expect(wrapper.html()).toEqual('<div class="swiper-slide css-10a4qrv" data-test-id="Slider"><div></div></div>');});it('should add custom className',function(){var wrapper=shallow(React.createElement(SwiperItem,{className:"test"},React.createElement("div",null)));expect(wrapper).toMatchSnapshot();expect(wrapper.html()).toEqual('<div class="swiper-slide css-10a4qrv test" data-test-id="Slider"><div></div></div>');});});
@@ -1 +1 @@
1
- import{css}from'glamor';export var item=css({position:'relative',height:'100%'});
1
+ import{css}from'glamor';export var item=css({position:'relative',height:'100%'}).toString();
@@ -1,16 +1,16 @@
1
- var _excluded=["autoPlay","interval","children","controls","className","classNames","slidesPerView","maxIndicators","indicators","loop","snapItems","onSlideChange","disabled","aria-hidden"];function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj;};}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;};}return _typeof(obj);}function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}import'react-id-swiper/lib/styles/css/swiper.css';import React,{useRef}from'react';import PropTypes from'prop-types';import cls from'classnames';import IDSwiper from'react-id-swiper';import{Pagination,Navigation,Autoplay,Zoom}from'swiper/dist/js/swiper.esm';import SwiperItem from"./components/SwiperItem";import{container,innerContainer,zoomFix,buttonNext,buttonPrev}from"./styles";/**
2
- * The basic swiper component.
3
- * @param {Object} props The component props.
1
+ var _excluded=["maxIndicators","indicators","controls","aria-hidden","disabled","autoPlay","interval","classNames","className","onSlideChange","additionalModules","children"];function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj;};}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;};}return _typeof(obj);}function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}import React,{useMemo,useCallback}from'react';import PropTypes from'prop-types';import cls from'classnames';import{Swiper as SwiperCmp}from'swiper/react';import{A11y,Autoplay,FreeMode,Navigation,Pagination,Zoom}from'swiper';import'swiper/swiper.min.css';import'swiper/modules/a11y/a11y.min.css';import'swiper/modules/pagination/pagination.min.css';import'swiper/modules/navigation/navigation.min.css';import'swiper/modules/zoom/zoom.min.css';import SwiperItem from"./components/SwiperItem";import{container,innerContainer,zoomFix,buttonNext,buttonPrev}from"./styles";/**
2
+ * @typedef {import('swiper/react').SwiperProps} SwiperCmpProps
3
+ */ /**
4
+ * The basic Swiper component. It acts as a wrapper for the Swiper JS library.
5
+ *
6
+ * This component wraps the [Swiper](https://swiperjs.com/) library's main component.
7
+ * Refer to the [Swiper documentation](https://v9.swiperjs.com/react) for details on the available props.
8
+ *
9
+ * @param {SwiperCmpProps} props The component props.
4
10
  * @returns {React.Node}
5
- */var Swiper=function Swiper(props){var autoPlay=props.autoPlay,interval=props.interval,children=props.children,controls=props.controls,className=props.className,classNames=props.classNames,slidesPerView=props.slidesPerView,maxIndicators=props.maxIndicators,indicators=props.indicators,loop=props.loop,snapItems=props.snapItems,onSlideChange=props.onSlideChange,disabled=props.disabled,ariaHidden=props['aria-hidden'],additionalParams=_objectWithoutProperties(props,_excluded);var zoom=props.zoom,freeMode=props.freeMode,initialSlide=props.initialSlide,rebuildOnUpdate=props.rebuildOnUpdate;var swiperInstance=useRef(null);/**
6
- * Updates the swiper instance reference.
7
- * @param {Object} instance A Swiper instance.
8
- */var updateSwiper=function updateSwiper(instance){// Only update the instance, when it differs from the current one.
9
- if(instance!==null&&instance!==swiperInstance.current){swiperInstance.current=instance;instance.on('slideChange',function(){return onSlideChange(instance.realIndex);});instance.on('transitionEnd',function(){// In loop mode the Swiper duplicates elements, which are not in the virtual DOM
10
- if(loop){var autoplayRunning=instance.autoplay.running;var previousIndex=instance.activeIndex;// Skip duplicated elements
11
- if(instance.activeIndex<1){instance.slideToLoop(children.length-1,0);}else if(instance.activeIndex>children.length){instance.slideToLoop(0,0);}if(autoplayRunning&&instance.activeIndex!==previousIndex){// Restart the autoplay when it was active before the auto slide.
12
- instance.autoplay.start();}}});}};var useFraction=maxIndicators&&maxIndicators<children.length;var paginationType=useFraction?'fraction':'bullets';var el=indicators&&children.length>1?'.swiper-pagination':null;var navigation;if(typeof controls==='boolean'&&controls===false){navigation={nextEl:null,prevEl:null};}if(typeof controls==='boolean'&&controls===true){navigation={// Important to use dot notation (swiper internally use it as selector)
13
- nextEl:".swiper-button-next.".concat(buttonNext),prevEl:".swiper-button-prev.".concat(buttonPrev)};}if(_typeof(controls)==='object'){navigation=controls;}var zoomEnabled=zoom===true||_typeof(zoom)==='object'&&Object.keys(zoom).length;var params={modules:[Pagination,Navigation,Autoplay,Zoom],containerClass:cls(innerContainer,classNames.container,_defineProperty({},zoomFix,zoomEnabled)),autoplay:autoPlay?{delay:interval}:false,initialSlide:initialSlide,navigation:navigation,pagination:{el:el,type:paginationType,bulletClass:classNames.bulletClass||'swiper-pagination-bullet',bulletActiveClass:classNames.bulletActiveClass||'swiper-pagination-bullet-active',dynamicBullets:true},loop:loop,rebuildOnUpdate:rebuildOnUpdate,// looping does not work with multiple slides per view
14
- slidesPerView:loop?1:slidesPerView,freeMode:freeMode?true:!snapItems,getSwiper:updateSwiper,zoom:zoom,allowSlidePrev:!disabled,allowSlideNext:!disabled};return React.createElement("div",{className:cls(container,className,'common__swiper'),"aria-hidden":ariaHidden},React.createElement(IDSwiper,_extends({},params,additionalParams),children));};Swiper.Item=SwiperItem;Swiper.defaultProps={'aria-hidden':false,autoPlay:false,className:null,classNames:{},controls:false,indicators:false,initialSlide:0,interval:3000,loop:false,// @deprecated
15
- maxIndicators:null,onSlideChange:function onSlideChange(){},rebuildOnUpdate:true,slidesPerView:1,freeMode:false,// @deprecated
16
- snapItems:true,zoom:false,disabled:false};export default Swiper;
11
+ */var Swiper=function Swiper(_ref){var maxIndicators=_ref.maxIndicators,indicators=_ref.indicators,controls=_ref.controls,ariaHidden=_ref['aria-hidden'],disabled=_ref.disabled,autoPlay=_ref.autoPlay,interval=_ref.interval,classNames=_ref.classNames,className=_ref.className,onSlideChange=_ref.onSlideChange,additionalModules=_ref.additionalModules,children=_ref.children,swiperProps=_objectWithoutProperties(_ref,_excluded);var useFraction=maxIndicators&&maxIndicators<children.length;var paginationType=useFraction?'fraction':'bullets';var showPagination=indicators&&children.length>1;var hasControls=typeof controls==='boolean'&&controls===true;var navigation;if(hasControls){navigation={// Important to use dot notation (swiper internally use it as selector)
12
+ nextEl:".swiper-button-next.".concat(buttonNext),prevEl:".swiper-button-prev.".concat(buttonPrev)};}if(_typeof(controls)==='object'){navigation=controls;}var handleSlideChange=useCallback(function(swiper){if(typeof onSlideChange==='function'){onSlideChange(swiper.realIndex,swiper);}},[onSlideChange]);/**
13
+ * @type {SwiperCmpProps}
14
+ */var internalProps=useMemo(function(){return _extends({modules:[A11y,Autoplay,FreeMode,Navigation,Pagination,Zoom].concat(Array.isArray(additionalModules)?additionalModules:[]),className:cls(innerContainer,classNames.container,_defineProperty({},zoomFix,swiperProps===null||swiperProps===void 0?void 0:swiperProps.zoom)),autoplay:autoPlay?{delay:interval}:false,navigation:navigation},showPagination&&{pagination:{el:undefined,type:paginationType,bulletClass:classNames.bulletClass||'swiper-pagination-bullet',bulletActiveClass:classNames.bulletActiveClass||'swiper-pagination-bullet-active',dynamicBullets:true,clickable:true,enabled:indicators&&children.length>1}},{allowSlidePrev:!disabled,allowSlideNext:!disabled,// Next two parameters are used to improve swiper usability when users quickly swipe through
15
+ // slides. In this case the screen shouldn't scroll in other directions than the swipe.
16
+ touchStartForcePreventDefault:true,touchMoveStopPropagation:true,onSlideChange:handleSlideChange});},[autoPlay,additionalModules,children.length,classNames.bulletActiveClass,classNames.bulletClass,classNames.container,disabled,indicators,interval,navigation,paginationType,showPagination,handleSlideChange,swiperProps]);return React.createElement("div",{className:cls(container,className),"aria-hidden":ariaHidden},React.createElement(SwiperCmp,_extends({},internalProps,swiperProps),children,hasControls&&React.createElement(React.Fragment,null,React.createElement("div",{className:"swiper-button-next ".concat(buttonNext)}),React.createElement("div",{className:"swiper-button-prev ".concat(buttonPrev)}))));};Swiper.Item=SwiperItem;Swiper.defaultProps={'aria-hidden':false,additionalModules:null,autoPlay:false,className:null,classNames:{},controls:false,indicators:false,interval:3000,maxIndicators:null,disabled:false,onSlideChange:null};export default Swiper;
@@ -1,6 +1,8 @@
1
1
  import{css}from'glamor';import{themeColors}from'@shopgate/pwa-common/helpers/config';export var container=css({position:'relative',maxHeight:'100%'// This needs to be 100vw to compensate a chrome 80 bug - see related ticket / pr. (PWA-2509)
2
2
  // commented out for now since it causes issues in the responsive layout
3
3
  // width: '100vw',
4
- }).toString();export var innerContainer=css({overflow:'hidden',' .swiper-wrapper':{alignItems:'stretch'},' .swiper-slide':{height:'auto'},' .swiper-pagination':{transform:'translate3d(-50%,0,0) !important',' .swiper-pagination-bullet':{background:themeColors.gray,opacity:'.5',margin:'0 4px',transition:'opacity 300ms cubic-bezier(0.25, 0.1, 0.25, 1)'},' .swiper-pagination-bullet-active.swiper-pagination-bullet-active-main':{opacity:1}}}).toString();/**
4
+ }).toString();export var innerContainer=css({overflow:'hidden','--swiper-navigation-color':themeColors.gray,' .swiper-wrapper':{alignItems:'stretch'},' .swiper-slide':{height:'auto'},' .swiper-pagination':{' .swiper-pagination-bullet':{background:themeColors.gray,opacity:'.5',margin:'0 4px',transition:'opacity 300ms cubic-bezier(0.25, 0.1, 0.25, 1)'},' .swiper-pagination-bullet-active.swiper-pagination-bullet-active-main':{opacity:1}}}).toString();/**
5
5
  * Prevents a visible shrink animation of swiped out slides which where in a zoomed state before.
6
- */export var zoomFix=css({' .swiper-slide':{overflow:'hidden'}}).toString();export var wrapper=css({flexShrink:0});export var buttonNext=css({backgroundImage:"url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important"}).toString();export var buttonPrev=css({backgroundImage:"url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important"}).toString();
6
+ */export var zoomFix=css({' .swiper-slide':{overflow:'hidden'}}).toString();export var wrapper=css({flexShrink:0});export var buttonNext=css({backgroundImage:"url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important",// Hide original SwiperJS chevron
7
+ ':after':{color:'transparent'}}).toString();export var buttonPrev=css({backgroundImage:"url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23808080'%2F%3E%3C%2Fsvg%3E\") !important",// Hide original SwiperJS chevron
8
+ ':after':{color:'transparent'}}).toString();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/pwa-common",
3
- "version": "7.23.1",
3
+ "version": "7.23.2",
4
4
  "description": "Common library for the Shopgate Connect PWA.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "@redux-devtools/extension": "^3.3.0",
19
19
  "@sentry/browser": "6.0.1",
20
- "@shopgate/pwa-benchmark": "7.23.1",
20
+ "@shopgate/pwa-benchmark": "7.23.2",
21
21
  "@virtuous/conductor": "~2.5.0",
22
22
  "@virtuous/react-conductor": "~2.5.0",
23
23
  "@virtuous/redux-persister": "1.1.0-beta.7",
@@ -31,7 +31,6 @@
31
31
  "path-match": "^1.2.4",
32
32
  "react-dotdotdot": "~1.3.0",
33
33
  "react-helmet": "^5.1.3",
34
- "react-id-swiper": "~2.3.1",
35
34
  "react-inline-transition-group": "^2.2.1",
36
35
  "react-portal": "^3.1.0",
37
36
  "react-redux": "^8.1.3",
@@ -40,11 +39,11 @@
40
39
  "redux-thunk": "^2.4.2",
41
40
  "reselect": "^4.1.8",
42
41
  "rxjs": "~5.5.12",
43
- "swiper": "~4.5.0",
42
+ "swiper": "9.4.1",
44
43
  "url-search-params": "^0.10.0"
45
44
  },
46
45
  "devDependencies": {
47
- "@shopgate/pwa-core": "7.23.1",
46
+ "@shopgate/pwa-core": "7.23.2",
48
47
  "@types/react-portal": "^3.0.9",
49
48
  "lodash": "^4.17.4",
50
49
  "prop-types": "~15.8.1",
@@ -1,3 +0,0 @@
1
- function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}import React from'react';import{mount}from'enzyme';import Image from"./index";window.requestAnimationFrame=function(){};jest.unmock('@shopgate/pwa-core');describe('<Image />',function(){var loadedImages=[];global.Image=/*#__PURE__*/function(){/**
2
- * Saves all images on init
3
- */function _class(){_classCallCheck(this,_class);this.complete=true;loadedImages.push(this);}return _createClass(_class);}();it('should render placeholders if forced to',function(){var wrapper=mount(React.createElement(Image,{src:"foo/bar",forcePlaceholder:true}));expect(wrapper).toMatchSnapshot();expect(wrapper.find('img').length).toEqual(0);});it('should render placeholders if src is null',function(){var wrapper=mount(React.createElement(Image,{src:"foo/bar"}));expect(wrapper).toMatchSnapshot();expect(wrapper.find('img').length).toEqual(1);});});