@shopgate/engage 7.20.0-beta.8 → 7.20.0
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.
- package/cart/components/CartSummaryWide/CartSummaryWideCheckoutButton.js +1 -1
- package/cart/components/PaymentBar/PaymentBarCheckoutButton.js +1 -1
- package/cart/components/PaymentBar/PaymentBarReserveButton.js +1 -1
- package/components/ChipLayout/style.js +2 -2
- package/components/QuantityInput/QuantityInput.js +5 -4
- package/components/ResponsiveContainer/ResponsiveContainer.js +2 -6
- package/components/ResponsiveContainer/breakpoints.js +2 -1
- package/components/ResponsiveContainer/hooks.js +20 -0
- package/components/ScrollHeader/index.js +2 -2
- package/components/ScrollHeader/style.js +1 -1
- package/components/View/index.js +2 -2
- package/core/actions/updateStatusBarBackground.js +2 -2
- package/core/helpers/errorBehavior.js +1 -1
- package/core/helpers/featureFlag.js +1 -1
- package/core/helpers/updateLegacyNavigationBar.js +3 -1
- package/core/hooks/index.js +1 -1
- package/core/streams/index.js +1 -1
- package/filter/components/FilterPageContent/components/ApplyButton/index.js +7 -0
- package/filter/components/FilterPageContent/components/ApplyButton/spec.js +1 -0
- package/filter/components/FilterPageContent/components/ApplyButton/style.js +1 -0
- package/filter/components/FilterPageContent/components/ResetButton/index.js +7 -0
- package/filter/components/FilterPageContent/components/ResetButton/spec.js +1 -0
- package/filter/components/FilterPageContent/components/ResetButton/style.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/Selected/index.js +7 -0
- package/filter/components/FilterPageContent/components/Selector/components/Selected/spec.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/Selected/style.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/Toggle/index.js +7 -0
- package/filter/components/FilterPageContent/components/Selector/components/Toggle/spec.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/Toggle/style.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/ValueButton/index.js +7 -0
- package/filter/components/FilterPageContent/components/Selector/components/ValueButton/spec.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/components/ValueButton/style.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/index.js +19 -0
- package/filter/components/FilterPageContent/components/Selector/spec.js +1 -0
- package/filter/components/FilterPageContent/components/Selector/style.js +1 -0
- package/filter/components/FilterPageContent/index.js +6 -0
- package/filter/components/FilterPageContentWithProvider/index.js +16 -0
- package/filter/components/PriceSlider/components/Label/index.js +1 -1
- package/filter/components/PriceSlider/index.js +1 -1
- package/filter/hooks/filterPage.js +5 -0
- package/filter/hooks/index.js +1 -1
- package/filter/providers/FilterPageProvider.context.js +54 -0
- package/filter/providers/FilterPageProvider.js +98 -0
- package/filter/providers/index.js +1 -1
- package/locations/action-creators/receiveInventories.js +3 -5
- package/locations/components/StockInfo/StockInfo.js +1 -1
- package/locations/components/StoreList/Store.style.js +1 -1
- package/locations/components/StoreList/StoreAddress.js +2 -2
- package/locations/components/StoreList/StoreDetails.js +2 -2
- package/locations/components/StoreList/StoreListSearch.js +3 -1
- package/package.json +7 -7
- package/product/components/EffectivityDates/helpers.js +1 -1
- package/product/components/Options/components/Content/spec.js +1 -1
- package/product/helpers/index.js +1 -1
- package/product/helpers/redirects.js +1 -1
- package/product/selectors/product.js +12 -2
- package/push-opt-in/components/PushOptInModal/push-opt-in.svg +58 -58
- package/styles/helpers/loadCustomStyles.js +2 -2
- package/styles/helpers/setPageBackgroundColor.js +1 -1
- package/styles/helpers/toggleBodyScroll.js +1 -1
- package/tracking/components/CookieConsentModal/tracking-opt-in.svg +14 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
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,{useContext,useMemo}from'react';import classNames from'classnames';import I18n from'@shopgate/pwa-common/components/I18n';import Link from'@shopgate/pwa-common/components/Link';import{SurroundPortals}from'@shopgate/engage/components';import{CART_CHECKOUT_BUTTON}from'@shopgate/pwa-common-commerce/cart/constants/Portals';import RippleButton from'@shopgate/pwa-ui-shared/RippleButton';import{CHECKOUT_PATH}from'@shopgate/pwa-common/constants/RoutePaths';import{CartContext}from"../../cart.context";import{container,button,disabledButton}from"./CartSummaryWideCheckoutButton.style";import connect from"./CartSummaryWideCheckoutButton.connector";/**
|
|
2
2
|
* @param {Object} props The component props
|
|
3
3
|
* @returns {JSX}
|
|
4
|
-
*/var CartSummaryWideCheckoutButton=function CartSummaryWideCheckoutButton(_ref){var isOrderable=_ref.isOrderable;var _useContext=useContext(CartContext),isLoading=_useContext.isLoading;var isActive=useMemo(function(){return isOrderable&&!isLoading;},[isLoading,isOrderable]);var classes=classNames(button,_defineProperty({},disabledButton,!isActive));return React.createElement("div",{className:container},React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,
|
|
4
|
+
*/var CartSummaryWideCheckoutButton=function CartSummaryWideCheckoutButton(_ref){var isOrderable=_ref.isOrderable;var _useContext=useContext(CartContext),isLoading=_useContext.isLoading;var isActive=useMemo(function(){return isOrderable&&!isLoading;},[isLoading,isOrderable]);var classes=classNames(button,_defineProperty({},disabledButton,!isActive));return React.createElement("div",{className:container},React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,portalProps:{isActive:isActive}},React.createElement(Link,{href:CHECKOUT_PATH,disabled:!isActive},React.createElement(RippleButton,{disabled:!isActive,type:"regular",className:classes},React.createElement(I18n.Text,{string:"cart.checkout"})))));};CartSummaryWideCheckoutButton.defaultProps={isOrderable:true};export default connect(CartSummaryWideCheckoutButton);
|
|
@@ -2,4 +2,4 @@ import React,{useContext,useMemo}from'react';import I18n from'@shopgate/pwa-comm
|
|
|
2
2
|
* Renders the cart payment bar checkout button.
|
|
3
3
|
* @param {boolean} isOrderable Whether the cart is orderable.
|
|
4
4
|
* @return {JSX}
|
|
5
|
-
*/function PaymentBarCheckoutButton(_ref){var isOrderable=_ref.isOrderable;var _useContext=useContext(CartContext),isLoading=_useContext.isLoading;var isActive=useMemo(function(){return isOrderable&&!isLoading;},[isLoading,isOrderable]);return React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,
|
|
5
|
+
*/function PaymentBarCheckoutButton(_ref){var isOrderable=_ref.isOrderable;var _useContext=useContext(CartContext),isLoading=_useContext.isLoading;var isActive=useMemo(function(){return isOrderable&&!isLoading;},[isLoading,isOrderable]);return React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,portalProps:{isActive:isActive}},React.createElement(Link,{href:CHECKOUT_PATH,disabled:!isActive},React.createElement(RippleButton,{disabled:!isActive,type:"regular",className:isActive?button:disabledButton},React.createElement(I18n.Text,{string:"cart.checkout"}))));}PaymentBarCheckoutButton.defaultProps={isOrderable:true};export default connect(PaymentBarCheckoutButton);
|
|
@@ -4,4 +4,4 @@ import*as React from'react';import{I18n,SurroundPortals,RippleButton}from'@shopg
|
|
|
4
4
|
* @return {JSX}
|
|
5
5
|
*/function PaymentBarReserveButton(_ref){var historyReset=_ref.historyReset;var _React$useContext=React.useContext(CartContext),orderable=_React$useContext.flags.orderable;/**
|
|
6
6
|
* Handles the click on the button.
|
|
7
|
-
*/function handleClick(){FulfillmentSheet.open({stage:STAGE_RESERVE_FORM,callback:function callback(l,p,orderSuccess){if(orderSuccess===true){historyReset();}}});}return React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,
|
|
7
|
+
*/function handleClick(){FulfillmentSheet.open({stage:STAGE_RESERVE_FORM,callback:function callback(l,p,orderSuccess){if(orderSuccess===true){historyReset();}}});}return React.createElement(SurroundPortals,{portalName:CART_CHECKOUT_BUTTON,portalProps:{isActive:orderable}},React.createElement(RippleButton,{onClick:handleClick,disabled:!orderable,type:"regular",className:orderable?button:disabledButton},React.createElement(I18n.Text,{string:"cart.reserve"})));}export default connect(PaymentBarReserveButton);
|
|
@@ -1,5 +1,5 @@
|
|
|
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);}import{css}from'glamor';import{themeConfig}from'@shopgate/pwa-common/helpers/config';var
|
|
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);}import{css}from'glamor';import{themeConfig}from'@shopgate/pwa-common/helpers/config';var variables=themeConfig.variables;/**
|
|
2
2
|
* Returns the styling based on the container height.
|
|
3
3
|
* @param {number} height The maximum height for the container.
|
|
4
4
|
* @returns {string}
|
|
5
|
-
*/var container=function container(height){return css({position:'relative',maxHeight:height,overflow:'hidden',marginBottom:variables.gap.small}).toString();};var layout=css({display:'flex',alignContent:'flex-start',flexWrap:'wrap',padding:'8px 5px',overflow:'hidden'}).toString();var moreButtonWrapper=css({position:'absolute',right:0,bottom:
|
|
5
|
+
*/var container=function container(height){return css({position:'relative',maxHeight:height,overflow:'hidden',marginBottom:variables.gap.small}).toString();};var layout=css({display:'flex',alignContent:'flex-start',flexWrap:'wrap',padding:'8px 5px',overflow:'hidden'}).toString();var moreButtonWrapper=css({position:'absolute',right:0,bottom:6,marginLeft:'auto'}).toString();var moreButtonBase={marginLeft:'auto',outline:0,padding:9,fontSize:'0.8rem',fontWeight:500,textTransform:'uppercase'};var moreButton=css(_extends({},moreButtonBase)).toString();var moreButtonInverted=css(_extends({},moreButtonBase)).toString();export default{container:container,layout:layout,moreButtonWrapper:moreButtonWrapper,moreButton:moreButton,moreButtonInverted:moreButtonInverted};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
var _excluded=["className","onChange","onFocus","onBlur","value","maxDecimals","unit","minValue","maxValue"];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 _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 _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,{useRef,useState,useCallback,useLayoutEffect,useEffect,forwardRef}from'react';import PropTypes from'prop-types';import{isIOs}from'@shopgate/pwa-core';import{parseFloatString,formatFloat}from"./helper";/**
|
|
1
|
+
var _excluded=["className","onChange","onFocus","onBlur","value","maxDecimals","unit","minValue","maxValue","onKeyDown"];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 _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 _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,{useRef,useState,useCallback,useLayoutEffect,useEffect,forwardRef}from'react';import PropTypes from'prop-types';import noop from'lodash/noop';import{isIOs}from'@shopgate/pwa-core';import{parseFloatString,formatFloat}from"./helper";/**
|
|
2
2
|
* A Quantity Input with unit support.
|
|
3
3
|
* @returns {JSX}
|
|
4
|
-
*/var QuantityInput=forwardRef(function(_ref,outerInputRef){var className=_ref.className,onChange=_ref.onChange,customOnFocus=_ref.onFocus,customOnBlur=_ref.onBlur,value=_ref.value,maxDecimals=_ref.maxDecimals,unit=_ref.unit,minValue=_ref.minValue,maxValue=_ref.maxValue,inputProps=_objectWithoutProperties(_ref,_excluded);var inputRef=outerInputRef||useRef();var _useState=useState(formatFloat(value,maxDecimals)),_useState2=_slicedToArray(_useState,2),inputValue=_useState2[0],setInputValue=_useState2[1];var _useState3=useState(false),_useState4=_slicedToArray(_useState3,2),isFocused=_useState4[0],setIsFocused=_useState4[1];var onFocus=useCallback(function(event){customOnFocus(event);setIsFocused(true);},[customOnFocus]);var onBlur=useCallback(function(event){var newValue=parseFloatString(inputValue,maxDecimals);setIsFocused(false);// If invalid switch to old value.
|
|
5
|
-
if(Number.isNaN(parseFloat(inputValue))){setInputValue(formatFloat(value,maxDecimals));return;}if(minValue&&newValue<minValue){newValue=minValue;}if(maxValue&&newValue>maxValue){newValue=maxValue;}setInputValue("".concat(newValue));if(newValue!==value){onChange(newValue);}customOnBlur(event,newValue);},[customOnBlur,inputValue,maxDecimals,maxValue,minValue,onChange,value]);var handleChange=useCallback(function(event){var newValue=event.target.value;setInputValue(newValue);},[])
|
|
4
|
+
*/var QuantityInput=forwardRef(function(_ref,outerInputRef){var className=_ref.className,onChange=_ref.onChange,customOnFocus=_ref.onFocus,customOnBlur=_ref.onBlur,value=_ref.value,maxDecimals=_ref.maxDecimals,unit=_ref.unit,minValue=_ref.minValue,maxValue=_ref.maxValue,onKeyDown=_ref.onKeyDown,inputProps=_objectWithoutProperties(_ref,_excluded);var inputRef=outerInputRef||useRef();var _useState=useState(formatFloat(value,maxDecimals)),_useState2=_slicedToArray(_useState,2),inputValue=_useState2[0],setInputValue=_useState2[1];var _useState3=useState(false),_useState4=_slicedToArray(_useState3,2),isFocused=_useState4[0],setIsFocused=_useState4[1];var onFocus=useCallback(function(event){customOnFocus(event);setIsFocused(true);},[customOnFocus]);var onBlur=useCallback(function(event){var newValue=parseFloatString(inputValue,maxDecimals);setIsFocused(false);// If invalid switch to old value.
|
|
5
|
+
if(Number.isNaN(parseFloat(inputValue))){setInputValue(formatFloat(value,maxDecimals));return;}if(minValue&&newValue<minValue){newValue=minValue;}if(maxValue&&newValue>maxValue){newValue=maxValue;}setInputValue("".concat(newValue));if(newValue!==value){onChange(newValue);}customOnBlur(event,newValue);},[customOnBlur,inputValue,maxDecimals,maxValue,minValue,onChange,value]);var handleChange=useCallback(function(event){var newValue=event.target.value;setInputValue(newValue);},[]);var handleKeyDown=useCallback(function(event){if(event.key==='Enter'){// Prevents false positive validation error when enter key is pressed inside input
|
|
6
|
+
event.preventDefault();if(inputRef.current){inputRef.current.blur();}}if(typeof onKeyDown==='function'){onKeyDown(event);}},[inputRef,onKeyDown]);// Select the current input value after focus.
|
|
6
7
|
useLayoutEffect(function(){if(isFocused&&isIOs){inputRef.current.select();}},[inputRef,isFocused]);// Sync actual float value with displayed content.
|
|
7
8
|
useEffect(function(){setInputValue(formatFloat(value,maxDecimals));},[maxDecimals,value]);// Stop the context menu from opening.
|
|
8
|
-
useLayoutEffect(function(){inputRef.current.addEventListener('contextmenu',function(event){event.preventDefault();event.stopPropagation();return false;});},[inputRef]);var displayedValue=!isFocused&&unit?"".concat(inputValue," ").concat(unit):inputValue;return React.createElement("input",_extends({ref:inputRef},inputProps,{inputMode:maxDecimals>0?'decimal':'numeric'/* Pattern signals some browsers to use specialized keyboard (if inputmode not supported */,pattern:maxDecimals>0?'[0-9.,]*':'[0–9]*',onFocus:onFocus,onBlur:onBlur,className:className,value:displayedValue,onChange:handleChange,onClick:function onClick(event){event.preventDefault();event.stopPropagation();if(inputRef.current){inputRef.current.focus();}}}));});QuantityInput.defaultProps={className:'',maxDecimals:2,unit:null,minValue:null,maxValue:null,onFocus:
|
|
9
|
+
useLayoutEffect(function(){inputRef.current.addEventListener('contextmenu',function(event){event.preventDefault();event.stopPropagation();return false;});},[inputRef]);var displayedValue=!isFocused&&unit?"".concat(inputValue," ").concat(unit):inputValue;return React.createElement("input",_extends({ref:inputRef},inputProps,{inputMode:maxDecimals>0?'decimal':'numeric'/* Pattern signals some browsers to use specialized keyboard (if inputmode not supported */,pattern:maxDecimals>0?'[0-9.,]*':'[0–9]*',onFocus:onFocus,onBlur:onBlur,className:className,value:displayedValue,onChange:handleChange,onKeyDown:handleKeyDown,onClick:function onClick(event){event.preventDefault();event.stopPropagation();if(inputRef.current){inputRef.current.focus();}}}));});QuantityInput.defaultProps={className:'',maxDecimals:2,unit:null,minValue:null,maxValue:null,onFocus:noop,onChange:noop,onBlur:noop,onKeyDown:noop};export default QuantityInput;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import PropTypes from'prop-types';import{useResponsiveValue}from"./hooks";/**
|
|
2
2
|
* Renders a responsive container that allows to render based on width.
|
|
3
3
|
* @param {Object} props Component props.
|
|
4
4
|
* @returns {React.Node}
|
|
5
|
-
*/var ResponsiveContainer=function ResponsiveContainer(_ref){var breakpoint=_ref.breakpoint,webOnly=_ref.webOnly,webAlways=_ref.webAlways,appOnly=_ref.appOnly,appAlways=_ref.appAlways,children=_ref.children
|
|
6
|
-
var _useState=useState(null),_useState2=_slicedToArray(_useState,2),activeBreakpoint=_useState2[0],setActiveBreakpoint=_useState2[1];// Calculate if should render due to visibility.
|
|
7
|
-
/* eslint-disable react-hooks/exhaustive-deps */var breakpointSafe=useMemo(function(){var parsed=parser(comparators,breakpoint,{breakpoint:breakpoint,webOnly:webOnly,webAlways:webAlways,appOnly:appOnly,appAlways:appAlways});return parsed;},[activeBreakpoint,breakpoint]);/* eslint-enable react-hooks/exhaustive-deps */ // Watch for resize changes.
|
|
8
|
-
useEffect(function(){return addListener(function(newBreakpoint){setActiveBreakpoint(newBreakpoint);});},[]);// Ignore rendering if one of given condition applies.
|
|
9
|
-
if(!breakpointSafe){return null;}return children;};ResponsiveContainer.propTypes={appAlways:PropTypes.bool,appOnly:PropTypes.bool,breakpoint:PropTypes.string,// eslint-disable-next-line react/forbid-prop-types
|
|
5
|
+
*/var ResponsiveContainer=function ResponsiveContainer(_ref){var breakpoint=_ref.breakpoint,webOnly=_ref.webOnly,webAlways=_ref.webAlways,appOnly=_ref.appOnly,appAlways=_ref.appAlways,children=_ref.children;var render=useResponsiveValue(breakpoint,{webOnly:webOnly,webAlways:webAlways,appOnly:appOnly,appAlways:appAlways});if(!render){return null;}return children;};ResponsiveContainer.propTypes={appAlways:PropTypes.bool,appOnly:PropTypes.bool,breakpoint:PropTypes.string,// eslint-disable-next-line react/forbid-prop-types
|
|
10
6
|
children:PropTypes.any,webAlways:PropTypes.bool,webOnly:PropTypes.bool};ResponsiveContainer.defaultProps={children:null,breakpoint:'>=xs',appAlways:false,webAlways:false,webOnly:false,appOnly:false};export default ResponsiveContainer;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// Ugly imports to avoid breaking tests due to circular dependencies
|
|
2
|
+
import{isIOSTheme}from'@shopgate/engage/core/helpers/isIOSTheme';import{hasWebBridge}from'@shopgate/engage/core/helpers/bridge';var iosThemeActive=isIOSTheme();/* eslint-disable extra-rules/no-single-line-objects */var breakpoints=[{name:'xs',from:0,to:600},{name:'sm',from:600,to:960},{name:'md',from:960,to:1280},{name:'lg',from:1280,to:1920},{name:'xl',from:1920,to:Number.MAX_VALUE}];/* eslint-enable extra-rules/no-single-line-objects */ /**
|
|
2
3
|
* Generates a media query for different breakpoints and platform.
|
|
3
4
|
* @param {Object} comparators Comparators.
|
|
4
5
|
* @param {string} breakpoint Breakpoint rule.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
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 _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);}import{useState,useMemo,useEffect}from'react';import{addListener}from"./listener";import{parser}from"./breakpoints";var comparators={'>=':function _(from,to,width){return width>=from;},'>':function _(from,to,width){return width>=to;},'<':function _(from,to,width){return width<from;},'<=':function _(from,to,width){return width<to;},'':function _(from,to,width){return width>=from&&width<to;}};/**
|
|
2
|
+
* Custom hook to determine the visibility or value based on the current active breakpoint
|
|
3
|
+
* and provided conditions.
|
|
4
|
+
* It listens for changes in the viewport or platform breakpoints and returns a value.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} [breakpoint=">=xs"] - The breakpoint condition to match (e.g., '>=md', '<lg').
|
|
7
|
+
* @param {Object} [options={}] - Additional options for customizing behavior.
|
|
8
|
+
* @param {*} [options.valueMatch=true] - Return value when the provided conditions match.
|
|
9
|
+
* @param {*} [options.valueMiss=false] - Return value when the provided conditions do not match.
|
|
10
|
+
* @param {boolean} [options.webOnly=false] If true, the hook will only match in PWA website mode.
|
|
11
|
+
* @param {boolean} [options.webAlways=false] If true, the hook will always match in PWA website
|
|
12
|
+
* mode regardless of the breakpoint.
|
|
13
|
+
* @param {boolean} [options.appOnly=false] If true, the hook will only match in PWA app mode.
|
|
14
|
+
* @param {boolean} [options.appAlways=false] If true, the hook will always match in PWA app mode,
|
|
15
|
+
* regardless of the breakpoint.
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/export var useResponsiveValue=function useResponsiveValue(){var breakpoint=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'>=xs';var options=arguments.length>1?arguments[1]:undefined;var _valueMatch$valueMiss=_extends({valueMatch:true,valueMiss:false,appAlways:false,appOnly:false,webAlways:false,webOnly:false},options),webOnly=_valueMatch$valueMiss.webOnly,webAlways=_valueMatch$valueMiss.webAlways,appOnly=_valueMatch$valueMiss.appOnly,appAlways=_valueMatch$valueMiss.appAlways,valueMiss=_valueMatch$valueMiss.valueMiss,valueMatch=_valueMatch$valueMiss.valueMatch;// Active breakpoint used for triggering rerenders on resize.
|
|
18
|
+
var _useState=useState(null),_useState2=_slicedToArray(_useState,2),activeBreakpoint=_useState2[0],setActiveBreakpoint=_useState2[1];// Calculate if we have a match for the conditions
|
|
19
|
+
/* eslint-disable react-hooks/exhaustive-deps */var isMatch=useMemo(function(){var parsed=parser(comparators,breakpoint,{breakpoint:breakpoint,webOnly:webOnly,webAlways:webAlways,appOnly:appOnly,appAlways:appAlways});return parsed;},[activeBreakpoint,breakpoint]);/* eslint-enable react-hooks/exhaustive-deps */ // Watch for resize changes.
|
|
20
|
+
useEffect(function(){return addListener(function(newBreakpoint){setActiveBreakpoint(newBreakpoint);});},[]);return isMatch?valueMatch:valueMiss;};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
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,{useState,
|
|
1
|
+
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,{useState,useCallback,useEffect}from'react';import PropTypes from'prop-types';import classNames from'classnames';import{viewScroll$}from'@shopgate/engage/core/streams';import{root,scrolledIn,scrolledOut,transition}from"./style";/**
|
|
2
2
|
* Scroll Header component
|
|
3
3
|
* @param {Object} props props
|
|
4
4
|
* @returns {JSX}
|
|
5
|
-
*/function ScrollHeader(_ref){var className=_ref.className,children=_ref.children
|
|
5
|
+
*/function ScrollHeader(_ref){var className=_ref.className,children=_ref.children,hideOnScroll=_ref.hideOnScroll,scrollOffset=_ref.scrollOffset;var _useState=useState(false),_useState2=_slicedToArray(_useState,2),shouldHideHeader=_useState2[0],setShouldHideHeader=_useState2[1];var onScroll=useCallback(function(scrollEvent){var scrollTop=scrollEvent.scrollTop,scrolled=scrollEvent.scrolled,scrollOut=scrollEvent.scrollOut,scrollIn=scrollEvent.scrollIn;if(!scrolled){return;}if(!shouldHideHeader&&scrollOut&&scrollTop>=scrollOffset){setShouldHideHeader(true);}if(shouldHideHeader&&scrollIn){setShouldHideHeader(false);}},[scrollOffset,shouldHideHeader]);useEffect(function(){if(hideOnScroll){var subscription=viewScroll$.subscribe(onScroll);return function(){return subscription.unsubscribe();};}return undefined;});return React.createElement("div",{className:classNames(root,transition,className,_defineProperty(_defineProperty({},scrolledIn,!shouldHideHeader),scrolledOut,shouldHideHeader))},children);}ScrollHeader.defaultProps={className:null,hideOnScroll:true,scrollOffset:100};export default ScrollHeader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
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{css}from'glamor';import{responsiveMediaQuery}from'@shopgate/engage/styles';export var
|
|
1
|
+
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{css}from'glamor';import{responsiveMediaQuery}from'@shopgate/engage/styles';export var root=css(_defineProperty({position:'sticky',left:0,backgroundColor:'#fff'},responsiveMediaQuery('<=xs',{appAlways:true}),{boxShadow:'rgba(0, 0, 0, 0.118) 0px 1px 6px, rgba(0, 0, 0, 0.118) 0px 1px 4px'}));export var scrolledIn=css({'&&':{transform:'translateY(0%)'}});export var scrolledOut=css({'&&':{transform:'translateY(-250%)'}});export var transition=css({transition:'transform 0.2s ease,transform 0.2s'});
|
package/components/View/index.js
CHANGED
|
@@ -2,8 +2,8 @@ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<argum
|
|
|
2
2
|
export{ViewContext};/**
|
|
3
3
|
* The View container component.
|
|
4
4
|
* @param {Object} props The component props.
|
|
5
|
-
* @return {JSX}
|
|
5
|
+
* @return {JSX.Element}
|
|
6
6
|
*/function ViewContainer(_ref){var background=_ref.background,children=_ref.children,noScrollOnKeyboard=_ref.noScrollOnKeyboard,visible=_ref.visible,ariaHidden=_ref['aria-hidden'],noContentPortal=_ref.noContentPortal,noKeyboardListener=_ref.noKeyboardListener;if(visible){setPageBackgroundColor(background);}var style={display:visible?'flex':'none'};return React.createElement(ViewProvider,null,React.createElement(ViewContext.Consumer,null,function(_ref2){var setContentRef=_ref2.setContentRef,ariaHiddenContext=_ref2.ariaHidden;return React.createElement("section",{className:"".concat(styles," engage__view"),style:style,"aria-hidden":ariaHidden||ariaHiddenContext},React.createElement(Content,{noScrollOnKeyboard:noScrollOnKeyboard,noKeyboardListener:noKeyboardListener,setContentRef:setContentRef,noContentPortal:noContentPortal},children));}));}ViewContainer.defaultProps={'aria-hidden':false,background:colors.light,children:null,noScrollOnKeyboard:false,noContentPortal:false,noKeyboardListener:false};/**
|
|
7
7
|
* @param {Object} props The component props.
|
|
8
|
-
* @returns {JSX}
|
|
8
|
+
* @returns {JSX.Element}
|
|
9
9
|
*/export default function View(props){return React.createElement(RouteContext.Consumer,null,function(_ref3){var visible=_ref3.visible;return React.createElement(ViewContainer,_extends({},props,{visible:visible}));});}
|
|
@@ -1,6 +1,6 @@
|
|
|
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);}import{
|
|
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);}import{isIos}from'@shopgate/pwa-common/selectors/client';import{updateLegacyNavigationBar}from"../helpers/updateLegacyNavigationBar";/**
|
|
2
2
|
* Updates the status bar background on iOS devices.
|
|
3
3
|
* @param {string} color The background color.
|
|
4
4
|
* @param {boolean} isDefault When set, the status bar will init with the color on next app start.
|
|
5
5
|
* @return {Function} A redux thunk.
|
|
6
|
-
*/export default function updateStatusBarBackground(color){var isDefault=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;return function(dispatch,getState){if(!
|
|
6
|
+
*/export default function updateStatusBarBackground(color){var isDefault=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;return function(dispatch,getState){if(!isIos(getState())){return;}updateLegacyNavigationBar(_extends({},color&&{statusBarBackground:color},{isDefault:isDefault}));};}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ToastProvider}from'@shopgate/pwa-common/providers';import{MODAL_PIPELINE_ERROR}from'@shopgate/pwa-common/constants/ModalTypes';import showModal from'@shopgate/pwa-common/actions/modal/showModal';import{logger,i18n}from'@shopgate/engage/core';/**
|
|
1
|
+
import{ToastProvider}from'@shopgate/pwa-common/providers';import{MODAL_PIPELINE_ERROR}from'@shopgate/pwa-common/constants/ModalTypes';import showModal from'@shopgate/pwa-common/actions/modal/showModal';import{logger,i18n}from'@shopgate/engage/core/helpers';/**
|
|
2
2
|
* Creates an error message for a pipeline and a code
|
|
3
3
|
* @param {string} message The pipeline message
|
|
4
4
|
* @param {Object} params Additional params for the message
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{themeName,shopNumber}from'@shopgate/pwa-common/helpers/config';import{isDev}from'@shopgate/engage/core';var STORE_KEY_PREFIX="sgFeatureFlag_".concat(shopNumber,"_").concat(themeName,"__");/**
|
|
1
|
+
import{themeName,shopNumber}from'@shopgate/pwa-common/helpers/config';import{isDev}from'@shopgate/engage/core/helpers';var STORE_KEY_PREFIX="sgFeatureFlag_".concat(shopNumber,"_").concat(themeName,"__");/**
|
|
2
2
|
* @param {string} key key
|
|
3
3
|
* @returns {string}
|
|
4
4
|
*/export function getFeatureFlag(key){return window.localStorage.getItem("".concat(STORE_KEY_PREFIX).concat(key));}/**
|
|
@@ -1,4 +1,6 @@
|
|
|
1
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);}import Color from'color';import{isAvailable,StatusBar}from'@shopgate/native-modules';import broadcastEvent from'@shopgate/pwa-core/commands/broadcastEvent';/**
|
|
2
2
|
* Updates the styles of the navigation bar of iOS devices.
|
|
3
3
|
* @param {Object} options Options for the status bar.
|
|
4
|
-
*/export var updateLegacyNavigationBar=function updateLegacyNavigationBar(){var options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var targetTab=options.targetTab||'main';var isDefault=options.isDefault;var styles=_extends({},options.color&&{color:options.color},{},options.background&&{background:options.background},{},options.buttonColor&&{buttonColor:options.buttonColor},{},options.buttonColorDisabled&&{buttonColorDisabled:options.buttonColorDisabled},{},options.statusBarBackground&&{statusBarBackground:options.statusBarBackground});if(!styles.statusBarBackground&&styles.background){styles.statusBarBackground=styles.background;}var statusBarStyle;if(options.statusBarStyle){statusBarStyle=options.statusBarStyle;}else if(styles.statusBarBackground){statusBarStyle=Color(styles.statusBarBackground).isDark()?'light':'dark';}
|
|
4
|
+
*/export var updateLegacyNavigationBar=function updateLegacyNavigationBar(){var options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var targetTab=options.targetTab||'main';var isDefault=options.isDefault;var styles=_extends({},options.color&&{color:options.color},{},options.background&&{background:options.background},{},options.buttonColor&&{buttonColor:options.buttonColor},{},options.buttonColorDisabled&&{buttonColorDisabled:options.buttonColorDisabled},{},options.statusBarBackground&&{statusBarBackground:options.statusBarBackground});if(!styles.statusBarBackground&&styles.background){styles.statusBarBackground=styles.background;}var statusBarStyle;if(options.statusBarStyle){statusBarStyle=options.statusBarStyle;}else if(styles.statusBarBackground){statusBarStyle=Color(styles.statusBarBackground).isDark()?'light':'dark';}// Status bar update via native-modules deactivated for now since it doesn't work
|
|
5
|
+
// reliable when opening a page inside the In-App-Browser.
|
|
6
|
+
if(false&&isAvailable()){var style=statusBarStyle==='dark'?'dark-content':'light-content';StatusBar.setBarStyle({style:style});if(styles.statusBarBackground){StatusBar.setBackgroundColor({color:styles.statusBarBackground});}return;}broadcastEvent({event:'updateNavigationBarStyle',parameters:[_extends({},statusBarStyle&&{statusBarStyle:statusBarStyle},{},isDefault&&{isDefault:isDefault},{targetTab:targetTab,styles:styles})]});};
|
package/core/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{useAsyncMemo}from"./useAsyncMemo";export{useRoute}from"./useRoute";export{useTheme}from"./useTheme";export{useApp}from"./useApp";export{useCurrentProduct}from"./useCurrentProduct";export{useNavigation}from"./useNavigation";export{usePageConfig}from"./usePageConfig";export{usePageSettings}from"./usePageSettings";export{useWidgetConfig}from"./useWidgetConfig";export{useWidgetSettings}from"./useWidgetSettings";export{useWidgetStyles}from"./useWidgetStyles";export*from"./html";export{useScroll}from"./useScroll";export{usePrevious}from"./usePrevious";
|
|
1
|
+
export{useAsyncMemo}from"./useAsyncMemo";export{useRoute}from"./useRoute";export{useTheme}from"./useTheme";export{useApp}from"./useApp";export{useCurrentProduct}from"./useCurrentProduct";export{useNavigation}from"./useNavigation";export{usePageConfig}from"./usePageConfig";export{usePageSettings}from"./usePageSettings";export{useWidgetConfig}from"./useWidgetConfig";export{useWidgetSettings}from"./useWidgetSettings";export{useWidgetStyles}from"./useWidgetStyles";export*from"./html";export{useScroll}from"./useScroll";export{usePrevious}from"./usePrevious";export{useResponsiveValue}from'@shopgate/engage/components/ResponsiveContainer/hooks';
|
package/core/streams/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export*from"./app";export*from"./appPermissions";export*from'@shopgate/pwa-common/streams/main';export*from'@shopgate/pwa-common/streams/error';// --------------- APP --------------- //
|
|
1
|
+
export*from"./app";export*from"./appPermissions";export*from'@shopgate/pwa-common/streams/main';export*from'@shopgate/pwa-common/streams/error';export*from'@shopgate/pwa-common/streams/view';// --------------- APP --------------- //
|
|
2
2
|
export*from'@shopgate/pwa-common/streams/app';// --------------- CLIENT --------------- //
|
|
3
3
|
export*from'@shopgate/pwa-common/streams/client';// --------------- ROUTER --------------- //
|
|
4
4
|
export*from'@shopgate/pwa-common/streams/router';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React,{memo}from'react';import PropTypes from'prop-types';import{I18n,Button,SurroundPortals}from'@shopgate/engage/components';import{PORTAL_FILTER_APPLY_BUTTON}from'@shopgate/engage/filter/constants';import{withWidgetSettings}from'@shopgate/engage/core';import styles from"./style";/**
|
|
2
|
+
* The filter apply button component.
|
|
3
|
+
* @param {Object} props The component props
|
|
4
|
+
* @param {boolean} props.disabled Whether the button is disabled
|
|
5
|
+
* @param {Function} props.onClick Click handler for the button
|
|
6
|
+
* @returns {JSX.Element}
|
|
7
|
+
*/var FilterApplyButton=function FilterApplyButton(_ref){var disabled=_ref.disabled,onClick=_ref.onClick,widgetSettings=_ref.widgetSettings;var buttonTextColor=widgetSettings.buttonTextColor,buttonTextColorDisabled=widgetSettings.buttonTextColorDisabled;var buttonColor=!disabled?buttonTextColor:buttonTextColorDisabled;return React.createElement(SurroundPortals,{portalName:PORTAL_FILTER_APPLY_BUTTON,portalProps:{disabled:disabled,onClick:onClick,widgetSettings:widgetSettings}},React.createElement("div",{className:styles.wrapper},React.createElement(Button,{className:styles.button,flat:true,type:"primary",onClick:onClick,disabled:disabled,testId:"applyFilterButton"},React.createElement(I18n.Text,{string:"filter.apply",style:{color:buttonColor}}))));};FilterApplyButton.defaultProps={disabled:false};export default withWidgetSettings(memo(FilterApplyButton),'@shopgate/engage/components/AppBar');
|
|
@@ -0,0 +1 @@
|
|
|
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);}import React from'react';import{shallow}from'enzyme';import ApplyButton from"./index";var clickMock=jest.fn();jest.mock('@shopgate/engage/components');jest.mock('@shopgate/engage/core',function(){return{withWidgetSettings:function withWidgetSettings(Comp){return function(props){return React.createElement(Comp,_extends({widgetSettings:{}},props));};}};});jest.mock('@shopgate/engage/components',function(){return{SurroundPortals:function SurroundPortals(_ref){var children=_ref.children;return children;},I18n:{Text:function Text(){return'I18n.Text';}},Button:function Button(){return'Button';}};});describe('Filter: <ApplyButton />',function(){it('should render as activated',function(){var wrapper=shallow(React.createElement(ApplyButton,{onClick:function onClick(){}})).dive();expect(wrapper).toMatchSnapshot();});it('should render as deactivated',function(){var wrapper=shallow(React.createElement(ApplyButton,{disabled:true,onClick:function onClick(){}})).dive();expect(wrapper).toMatchSnapshot();});it('should handle clicks',function(){var wrapper=shallow(React.createElement(ApplyButton,{onClick:clickMock})).dive();expect(wrapper).toMatchSnapshot();wrapper.find('Button').simulate('click');expect(clickMock).toHaveBeenCalled();});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';var wrapper=css({display:'flex'});var button=css({padding:'0 !important'}).toString();export default{wrapper:wrapper,button:button};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React,{memo}from'react';import PropTypes from'prop-types';import{I18n,Button,SurroundPortals}from'@shopgate/engage/components';import{PORTAL_FILTER_RESET_BUTTON}from'@shopgate/engage/filter/constants';import styles from"./style";/**
|
|
2
|
+
* The filter reset button component.
|
|
3
|
+
* @param {Object} props The component props.
|
|
4
|
+
* @param {boolean} props.disabled Whether the button is disabled
|
|
5
|
+
* @param {Function} props.onClick Click handler for the button
|
|
6
|
+
* @returns {JSX.Element}
|
|
7
|
+
*/var FilterResetButton=function FilterResetButton(_ref){var disabled=_ref.disabled,onClick=_ref.onClick;return React.createElement(SurroundPortals,{portalName:PORTAL_FILTER_RESET_BUTTON,portalProps:{disabled:disabled,onClick:onClick}},React.createElement("div",{className:styles},React.createElement(Button,{flat:true,type:"primary",onClick:onClick,disabled:disabled,testId:"clearAllButton"},React.createElement(I18n.Text,{string:"filter.reset"}))));};FilterResetButton.defaultProps={disabled:false};export default memo(FilterResetButton);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from'react';import{shallow}from'enzyme';import ResetButton from"./index";var clickMock=jest.fn();jest.mock('@shopgate/engage/components');describe('Filter: <ResetButton />',function(){it('should render as activated',function(){var wrapper=shallow(React.createElement(ResetButton,{onClick:function onClick(){}}));expect(wrapper).toMatchSnapshot();});it('should render as deactivated',function(){var wrapper=shallow(React.createElement(ResetButton,{disabled:true,onClick:function onClick(){}}));expect(wrapper).toMatchSnapshot();});it('should handle clicks',function(){var wrapper=shallow(React.createElement(ResetButton,{onClick:clickMock}));expect(wrapper).toMatchSnapshot();wrapper.find('Button').simulate('click');expect(clickMock).toHaveBeenCalled();});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';export default css({marginTop:4,marginBottom:40,textAlign:'right'});
|
|
@@ -0,0 +1,7 @@
|
|
|
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 _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,{Fragment,PureComponent}from'react';import PropTypes from'prop-types';import*as styles from"./style";/**
|
|
2
|
+
* The filter selected component.
|
|
3
|
+
*/var Selected=/*#__PURE__*/function(_PureComponent){function Selected(){_classCallCheck(this,Selected);return _callSuper(this,Selected,arguments);}_inherits(Selected,_PureComponent);return _createClass(Selected,[{key:"getItems",value:/**
|
|
4
|
+
* @returns {Array}
|
|
5
|
+
*/function getItems(){var _this$props=this.props,selected=_this$props.selected,values=_this$props.values;return values.reduce(function(prevValues,value){if(selected.includes(value.id)){prevValues.push(value.label);}return prevValues;},[]);}/**
|
|
6
|
+
* @returns {JSX}
|
|
7
|
+
*/},{key:"render",value:function render(){if(!this.props.selected||this.props.selected.length===0){return null;}var items=this.getItems();return React.createElement(Fragment,null,items.map(function(item,index){return React.createElement(Fragment,{key:item},React.createElement("span",{className:styles.elipsed},item),index<items.length-1?React.createElement("span",{className:styles.comma},", "):'');}));}}]);}(PureComponent);_defineProperty(Selected,"defaultProps",{selected:null});export default Selected;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from'react';import{shallow}from'enzyme';import Selected from"./index";var values=[{id:'foo',label:'fooLabel'},{id:'bar',label:'barLabel'}];describe('Filter: <Selected />',function(){it('should not render without selected',function(){var wrapper=shallow(React.createElement(Selected,{values:values}));expect(wrapper).toMatchSnapshot();});it('should render with selected',function(){var wrapper=shallow(React.createElement(Selected,{values:values,selected:['foo']}));expect(wrapper).toMatchSnapshot();});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';export var item=css({whiteSpace:'nowrap',flexShrink:0,flexGrow:0,alignSelf:'flex-end'});export var elipsed=css({maxWidth:'95%',overflow:'hidden',textAlign:'right',textOverflow:'ellipsis',whiteSpace:'nowrap'});export var comma=css({' + span':{marginLeft:'0.65ch'}});
|
|
@@ -0,0 +1,7 @@
|
|
|
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 _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,{PureComponent}from'react';import PropTypes from'prop-types';import classNames from'classnames';import*as styles from"./style";/**
|
|
2
|
+
* The toggle component.
|
|
3
|
+
*/var Toggle=/*#__PURE__*/function(_PureComponent){function Toggle(){_classCallCheck(this,Toggle);return _callSuper(this,Toggle,arguments);}_inherits(Toggle,_PureComponent);return _createClass(Toggle,[{key:"className",get:/**
|
|
4
|
+
* @returns {string}
|
|
5
|
+
*/function get(){var open=this.props.open;return classNames(_defineProperty(_defineProperty(_defineProperty({},styles.label,true),styles.open,open),styles.closed,!open));}/**
|
|
6
|
+
* @returns {JSX}
|
|
7
|
+
*/},{key:"render",value:function render(){var _this$props=this.props,label=_this$props.label,selected=_this$props.selected;return React.createElement("div",{className:styles.toggle},React.createElement("span",{className:this.className},label),selected&&React.createElement("span",{className:styles.selected},selected));}}]);}(PureComponent);_defineProperty(Toggle,"defaultProps",{open:false,selected:null});export default Toggle;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from'react';import{render}from'enzyme';import Toggle from"./index";describe('<Toggle />',function(){it('should render without selected',function(){var wrapper=render(React.createElement(Toggle,{label:"somelabel"}));expect(wrapper).toMatchSnapshot();});it('should render without selected as open',function(){var wrapper=render(React.createElement(Toggle,{label:"somelabel",open:true}));expect(wrapper).toMatchSnapshot();});it('should render with selected',function(){var wrapper=render(React.createElement(Toggle,{label:"somelabel",selected:"Some, Thing, Selected"}));expect(wrapper).toMatchSnapshot();});it('should render with selected as open',function(){var wrapper=render(React.createElement(Toggle,{label:"somelabel",selected:"Some, Thing, Selected",open:true}));expect(wrapper).toMatchSnapshot();});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';export var toggle=css({display:'flex',flexFlow:'row no-wrap',alignContent:'stretch',alignItems:'flex-start'});export var label=css({whiteSpace:'no-wrap',flexShrink:0,flexGrow:1,textAlign:'left',maxWidth:'50%',minWidth:'35%',paddingRight:'16px'});export var selected=css({display:'flex',flexFlow:'row wrap',flexGrow:1,justifyContent:'flex-end',minWidth:'50%',maxWidth:'65%'});export var closed=css({fontWeight:'normal'});export var open=css({fontWeight:'bold'});
|
package/filter/components/FilterPageContent/components/Selector/components/ValueButton/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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 _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,{PureComponent}from'react';import PropTypes from'prop-types';import classNames from'classnames';import*as styles from"./style";/**
|
|
2
|
+
* The value button component.
|
|
3
|
+
*/var ValueButton=/*#__PURE__*/function(_PureComponent){function ValueButton(){_classCallCheck(this,ValueButton);return _callSuper(this,ValueButton,arguments);}_inherits(ValueButton,_PureComponent);return _createClass(ValueButton,[{key:"className",get:/**
|
|
4
|
+
* @returns {string}
|
|
5
|
+
*/function get(){var isActive=this.props.isActive;return classNames(_defineProperty(_defineProperty({},styles.inactive,!isActive),styles.active,isActive));}/**
|
|
6
|
+
* @returns {JSX}
|
|
7
|
+
*/},{key:"render",value:function render(){var _this$props=this.props,label=_this$props.label,id=_this$props.id,onClick=_this$props.onClick,isActive=_this$props.isActive;return React.createElement("button",{className:this.className,value:id,onClick:onClick,"data-test-id":id,type:"button",role:"checkbox","aria-checked":isActive},label);}}]);}(PureComponent);_defineProperty(ValueButton,"defaultProps",{id:null,label:null,isActive:false,onClick:function onClick(){}});export default ValueButton;
|
package/filter/components/FilterPageContent/components/Selector/components/ValueButton/spec.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from'react';import{shallow}from'enzyme';import ValueButton from"./index";var onClick=jest.fn();describe('<ValueButton />',function(){it('should render as inactive',function(){var wrapper=shallow(React.createElement(ValueButton,{id:"someid",label:"somelabel"}));expect(wrapper).toMatchSnapshot();});it('should render as active',function(){var wrapper=shallow(React.createElement(ValueButton,{id:"someid",label:"somelabel",isActive:true}));expect(wrapper).toMatchSnapshot();});it('should handle click event',function(){var wrapper=shallow(React.createElement(ValueButton,{id:"someid",label:"somelabel",onClick:onClick}));wrapper.simulate('click');expect(wrapper).toMatchSnapshot();expect(onClick).toHaveBeenCalledTimes(1);});});
|
package/filter/components/FilterPageContent/components/Selector/components/ValueButton/style.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';import{themeColors}from'@shopgate/pwa-common/helpers/config';export var inactive=css({border:"1px solid ".concat(themeColors.darkGray),borderRadius:2,color:'inherit',height:42,marginLeft:8,marginBottom:8,maxWidth:'100%',minWidth:42,outline:0,overflow:'hidden',padding:'0 8px',textOverflow:'ellipsis',whiteSpace:'nowrap',transition:'color 100ms cubic-bezier(0.25, 0.1, 0.25, 1), border-color 100ms cubic-bezier(0.25, 0.1, 0.25, 1)',willChange:'color, border-color'});export var active=css(inactive,{borderColor:"var(--color-secondary, ".concat(themeColors.accent,")"),color:"var(--color-secondary, ".concat(themeColors.accent,")")});
|
|
@@ -0,0 +1,19 @@
|
|
|
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 _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 _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,{PureComponent}from'react';import PropTypes from'prop-types';import{Accordion,SurroundPortals}from'@shopgate/engage/components';import{i18n}from'@shopgate/engage/core';import{FilterItem}from'@shopgate/engage/filter';import{PORTAL_FILTER_SELECTOR}from'@shopgate/engage/filter/constants';import ValueButton from"./components/ValueButton";import Toggle from"./components/Toggle";import Selected from"./components/Selected";import*as styles from"./style";/**
|
|
2
|
+
* The selector component.
|
|
3
|
+
*/var Selector=/*#__PURE__*/function(_PureComponent){function Selector(){var _this2;_classCallCheck(this,Selector);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}_this2=_callSuper(this,Selector,[].concat(args));_defineProperty(_this2,"state",{selected:_this2.props.selected||[]});/**
|
|
4
|
+
* @param {SyntheticEvent} event The button click event.
|
|
5
|
+
*/_defineProperty(_this2,"handleClick",function(event){var value=event.target.value;var selected=_this2.state.selected;var _this2$props=_this2.props,id=_this2$props.id,multi=_this2$props.multi,onChange=_this2$props.onChange;var newSelected=[].concat(selected,[value]);// If in single select mode, only allow one selected value.
|
|
6
|
+
if(!multi&&selected.length===1){newSelected=[value];}// If the clicked value was already selected, remove it again.
|
|
7
|
+
if(selected.includes(value)){newSelected=selected.filter(function(item){return item!==value;});}// Set it if it wasn't selected already.
|
|
8
|
+
_this2.setState({selected:newSelected});onChange(id,newSelected);});/**
|
|
9
|
+
* Filter value change handler for the portal props. Invokes handleClick method with a mocked
|
|
10
|
+
* click event
|
|
11
|
+
* @param {string} updatedId Id of the updated filter value
|
|
12
|
+
*/_defineProperty(_this2,"handlePortalChange",function(updatedId){_this2.handleClick({target:{value:updatedId}});});/**
|
|
13
|
+
* @param {Object} props The send render props.
|
|
14
|
+
* @return {JSX}
|
|
15
|
+
*/_defineProperty(_this2,"renderLabel",function(props){var _this2$props2=_this2.props,label=_this2$props2.label,values=_this2$props2.values;var selected=_this2.state.selected;return React.createElement(Toggle,_extends({},props,{label:label,selected:React.createElement(Selected,{values:values,selected:selected})}));});return _this2;}_inherits(Selector,_PureComponent);return _createClass(Selector,[{key:"UNSAFE_componentWillReceiveProps",value:/**
|
|
16
|
+
* @param {Object} nextProps The new incoming props.
|
|
17
|
+
*/function UNSAFE_componentWillReceiveProps(_ref){var selected=_ref.selected;if(selected!==this.state.selected){this.setState({selected:selected});}}},{key:"render",value:/**
|
|
18
|
+
* @returns {JSX}
|
|
19
|
+
*/function render(){var _this3=this;var _this$props=this.props,values=_this$props.values,id=_this$props.id,label=_this$props.label,multi=_this$props.multi;var selected=this.state.selected;return React.createElement(SurroundPortals,{portalName:PORTAL_FILTER_SELECTOR,portalProps:{filter:{id:id,label:label,values:values,isMultiSelect:multi},selectedValueIds:selected,onChange:this.handlePortalChange}},React.createElement(FilterItem,null,React.createElement(Accordion,{renderLabel:this.renderLabel,testId:id,handleLabel:i18n.text('filter.filter_by',{label:label}),className:styles.accordion},React.createElement("div",{className:styles.content},values.map(function(value){return React.createElement(ValueButton,{key:value.id,id:value.id,label:value.label,isActive:selected&&selected.includes(value.id),onClick:_this3.handleClick});})))));}}]);}(PureComponent);_defineProperty(Selector,"defaultProps",{multi:false,onChange:function onChange(){},selected:null});export default Selector;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import React from'react';import{shallow}from'enzyme';import Selector from"./index";jest.mock('@shopgate/engage/core',function(){return{hasWebBridge:function hasWebBridge(){return false;},i18n:{text:function text(string){return string;}}};});jest.mock('@shopgate/engage/components',function(){return{Accordion:function Accordion(_ref){var children=_ref.children;return children;}};});jest.mock('@shopgate/engage/filter',function(){return{FilterItem:function FilterItem(_ref2){var children=_ref2.children;return children;}};});var values=[{id:'foo',label:'fooLabel'},{id:'bar',label:'barLabel'}];describe('Filter: <Selector />',function(){it('should render with minimum props',function(){var wrapper=shallow(React.createElement(Selector,{id:"foo",label:"bar",values:values}));expect(wrapper).toMatchSnapshot();});});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{css}from'glamor';export var accordion=css({overflow:'hidden'}).toString();export var content=css({marginLeft:-8,marginBottom:-8});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React,{Fragment}from'react';import PropTypes from'prop-types';import{SurroundPortals,ResponsiveContainer}from'@shopgate/engage/components';import{useFilterPage}from'@shopgate/engage/filter/hooks';import{PORTAL_FILTER_PRICE_RANGE,PORTAL_FILTER_PAGE_CONTENT,FILTER_TYPE_RANGE,FILTER_TYPE_MULTISELECT,PriceSlider}from'@shopgate/engage/filter';import Selector from"./components/Selector";import ApplyButton from"./components/ApplyButton";import ResetButton from"./components/ResetButton";/**
|
|
2
|
+
* The FilterPageContent component renders all filters for the filter page.
|
|
3
|
+
* @param {Object} props The component props.
|
|
4
|
+
* @param {React.ComponentType} props.AppBarComponent The component to be rendered as the app bar
|
|
5
|
+
* @returns {JSX.Element}
|
|
6
|
+
*/var FilterPageContent=function FilterPageContent(_ref){var AppBarComponent=_ref.AppBarComponent;var _useFilterPage=useFilterPage(),apiFilters=_useFilterPage.apiFilters,resetPossible=_useFilterPage.resetPossible,hasChanged=_useFilterPage.hasChanged,applyFilters=_useFilterPage.applyFilters,resetAllFilters=_useFilterPage.resetAllFilters,getSelectedFilterValues=_useFilterPage.getSelectedFilterValues,updateSelectedFilterValues=_useFilterPage.updateSelectedFilterValues;return React.createElement(SurroundPortals,{portalName:PORTAL_FILTER_PAGE_CONTENT},AppBarComponent&&React.createElement(AppBarComponent,{title:"titles.filter",right:React.createElement(ApplyButton,{disabled:!hasChanged,onClick:applyFilters})}),apiFilters.map(function(filter){var portalProps={filter:filter};var value=getSelectedFilterValues(filter.id);if(filter.type===FILTER_TYPE_RANGE){return React.createElement(Fragment,{key:filter.id},React.createElement(SurroundPortals,{portalName:PORTAL_FILTER_PRICE_RANGE,portalProps:portalProps},React.createElement(PriceSlider,{id:filter.id,key:filter.id,min:filter.minimum,max:filter.maximum,onChange:updateSelectedFilterValues,value:value})));}return React.createElement(Selector,{id:filter.id,key:filter.id,label:filter.label,values:filter.values,multi:filter.type===FILTER_TYPE_MULTISELECT,onChange:updateSelectedFilterValues,selected:value});}),React.createElement(ResponsiveContainer,{breakpoint:"<sm",appAlways:true},React.createElement(ResetButton,{disabled:!resetPossible,onClick:resetAllFilters})));};FilterPageContent.defaultProps={AppBarComponent:null};export default FilterPageContent;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from'react';import PropTypes from'prop-types';import{FilterPageProvider}from"../../providers";// eslint-disable-next-line no-unused-vars, import/named
|
|
2
|
+
import{RouteFilters}from"../../providers/FilterPageProvider.context";import Content from"../FilterPageContent";/**
|
|
3
|
+
* The FilterPageContent component
|
|
4
|
+
* @param {Object} props The component props
|
|
5
|
+
* @param {RouteFilters} [props.activeFilters] Object with the active filters for a filtered product
|
|
6
|
+
* list
|
|
7
|
+
* @param {string} [props.parentRouteId] Id of the route with the product list that's supposed to be
|
|
8
|
+
* filtered
|
|
9
|
+
* @param {string} [props.categoryId] A category to be used for filter selection from Redux
|
|
10
|
+
* @param {string} [props.searchPhrase] A search phrase to be used for filter selection from Redux
|
|
11
|
+
* @param {RouteFilters} [props.filters] Object with filters that are used for requests. Might
|
|
12
|
+
* contain filters that aren't included in "activeFilters", since they are not supposed to be
|
|
13
|
+
* visible to the user, but only used in product requests.
|
|
14
|
+
* @param {React.ComponentType} [props.AppBarComponent] The component to be rendered as the app bar
|
|
15
|
+
* @returns {JSX.Element}
|
|
16
|
+
*/var FilterPageContentWithProvider=function FilterPageContentWithProvider(_ref){var categoryId=_ref.categoryId,searchPhrase=_ref.searchPhrase,activeFilters=_ref.activeFilters,filters=_ref.filters,parentRouteId=_ref.parentRouteId,AppBarComponent=_ref.AppBarComponent;return React.createElement(FilterPageProvider,{activeFilters:activeFilters,categoryId:categoryId,searchPhrase:searchPhrase,filters:filters,parentRouteId:parentRouteId},React.createElement(Content,{AppBarComponent:AppBarComponent}));};FilterPageContentWithProvider.defaultProps={activeFilters:null,filters:null,categoryId:null,searchPhrase:null,parentRouteId:null,AppBarComponent:null};export default FilterPageContentWithProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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,{memo,useState,useEffect,useRef}from'react';import PropTypes from'prop-types';import appConfig from'@shopgate/pwa-common/helpers/config';import{I18n}from'@shopgate/engage/components';import{i18n}from'@shopgate/engage/core';import styles from"../../style";var currency=appConfig.currency;/**
|
|
2
2
|
* The filter price range slider label component.
|
|
3
3
|
* @param {Object} props The component props.
|
|
4
|
-
|
|
4
|
+
* @returns {JSX.Element}
|
|
5
5
|
*/function Label(props){var priceLength=props.priceLength,priceMax=props.priceMax,priceMin=props.priceMin,onChange=props.onChange;var _useState=useState(priceMin),_useState2=_slicedToArray(_useState,2),minValue=_useState2[0],setMinValue=_useState2[1];var _useState3=useState(priceMax),_useState4=_slicedToArray(_useState3,2),maxValue=_useState4[0],setMaxValue=_useState4[1];var _useState5=useState(0),_useState6=_slicedToArray(_useState5,2),minOffset=_useState6[0],setMinOffset=_useState6[1];var _useState7=useState(0),_useState8=_slicedToArray(_useState7,2),maxOffset=_useState8[0],setMMaxOffset=_useState8[1];var minRef=useRef(null);var maxRef=useRef(null);// Set new values, when prices change from outside.
|
|
6
6
|
useEffect(function(){setMinValue(priceMin);setMaxValue(priceMax);},[priceMin,priceMax]);// Store the leftOffset when the reference changes.
|
|
7
7
|
useEffect(function(){setMinOffset(minRef.current.offsetLeft);setMMaxOffset(maxRef.current.offsetLeft);},[minRef,maxRef]);/**
|
|
@@ -6,7 +6,7 @@ function _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="s
|
|
|
6
6
|
*/function PriceSlider(props){var _this2;_classCallCheck(this,PriceSlider);_this2=_callSuper(this,PriceSlider,[props]);/**
|
|
7
7
|
* The callback function that is given to the RangeSlider.
|
|
8
8
|
* @param {Array} value The lower and upper boundary of the set range.
|
|
9
|
-
*/_defineProperty(_this2,"onChange",function(value){var roundedValue=[Math.floor(value[0]),Math.ceil(value[1])];_this2.setState({value:value});_this2.props.onChange(_this2.props.id,roundedValue);});var initialValue=
|
|
9
|
+
*/_defineProperty(_this2,"onChange",function(value){var roundedValue=[Math.floor(value[0]),Math.ceil(value[1])];_this2.setState({value:value});_this2.props.onChange(_this2.props.id,roundedValue);});var initialValue=[props.min,props.max];if(Array.isArray(props.value)&&props.value.length>0){initialValue=props.value;}_this2.state={value:initialValue};return _this2;}/**
|
|
10
10
|
* Updates the value state.
|
|
11
11
|
* @param {Object} nextProps The next component props.
|
|
12
12
|
*/_inherits(PriceSlider,_PureComponent);return _createClass(PriceSlider,[{key:"UNSAFE_componentWillReceiveProps",value:function UNSAFE_componentWillReceiveProps(nextProps){if(!isEqual(nextProps.value,this.props.value)){this.setState({value:nextProps.value});}}},{key:"render",value:/**
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{useContext}from'react';import FilterPageProvider from"../providers/FilterPageProvider.context";// Adding a return type would break type inference
|
|
2
|
+
// eslint-disable-next-line valid-jsdoc
|
|
3
|
+
/**
|
|
4
|
+
* Returns the value of the filter page provider state.
|
|
5
|
+
*/export var useFilterPage=function useFilterPage(){return useContext(FilterPageProvider);};
|
package/filter/hooks/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{useContext}from'react';import SortProvider from"../providers/SortProvider.context";/**
|
|
2
2
|
* Returns the value of the sort provider state.
|
|
3
3
|
* @returns {Object}
|
|
4
|
-
*/export var useSort=function useSort(){return useContext(SortProvider);};
|
|
4
|
+
*/export var useSort=function useSort(){return useContext(SortProvider);};export*from"./filterPage";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import{createContext}from'react';import noop from'lodash/noop';/**
|
|
2
|
+
* @typedef {Object} APIFilterValue
|
|
3
|
+
* @property {string} id Filter value id
|
|
4
|
+
* @property {string} label Filter value label
|
|
5
|
+
* @property {number} hits Number of hits for the filter value
|
|
6
|
+
*/export{};/**
|
|
7
|
+
* @typedef {Object} APIFilter
|
|
8
|
+
* @property {string} id Filter id
|
|
9
|
+
* @property {string} label Filter label
|
|
10
|
+
* @property {"range"|"multiselect"|"single_select"} type Filter type
|
|
11
|
+
* @property {string} [source] Filter source
|
|
12
|
+
* @property {number} [minimum] Minimum value for a range filter
|
|
13
|
+
* @property {number} [maximum] Maximum value for a range filter
|
|
14
|
+
* @property {APIFilterValue[]} values
|
|
15
|
+
*/export{};/**
|
|
16
|
+
* @typedef {Object} RouteFilterValue
|
|
17
|
+
* @property {string} id Filter value id
|
|
18
|
+
* @property {string} label Filter value label
|
|
19
|
+
*/ /**
|
|
20
|
+
* @typedef {Object} RouteFilter
|
|
21
|
+
* @property {string} id Filter id
|
|
22
|
+
* @property {string} label Filter label
|
|
23
|
+
* @property {string} source Filter source
|
|
24
|
+
* @property {"range"|"multiselect"|"single_select"} type Filter type
|
|
25
|
+
* @property {RouteFilterValue[]} values Selected values for the filter
|
|
26
|
+
*/ /**
|
|
27
|
+
* @typedef {Object.<string, RouteFilter>} RouteFilters
|
|
28
|
+
* Object with the active filters for a route with filtered product list
|
|
29
|
+
*/export{};/**
|
|
30
|
+
* @callback GetSelectedFilterValuesFn
|
|
31
|
+
* @param {string} filterId The id of the filter
|
|
32
|
+
*/ /**
|
|
33
|
+
* @callback UpdateSelectedFilterValuesFn
|
|
34
|
+
* @param {string} filterId The id of the filter to be updated
|
|
35
|
+
* @param {string[]} selectedValues The updated selected values
|
|
36
|
+
* @returns {void}
|
|
37
|
+
*/ /**
|
|
38
|
+
* @typedef {Object} FilterPageContext
|
|
39
|
+
* @property {boolean} hasChanged Whether the filter selection has changed since the filters page
|
|
40
|
+
* was opened
|
|
41
|
+
* @property {boolean} resetPossible Whether a reset of the active filters is possible
|
|
42
|
+
* @property {APIFilter[]} apiFilters List of available filters from the API
|
|
43
|
+
* @property {RouteFilters} filters Object that represents the current state of all filters
|
|
44
|
+
* @property {function():void} resetAllFilters Resets all filters which have been changed by the
|
|
45
|
+
* user
|
|
46
|
+
* @property {function():void} resetChangedFilters Resets all filters which have been changed by the
|
|
47
|
+
* user since the filters page was opened
|
|
48
|
+
* @property {function():void} applyFilters Applies the current filter selection to the parent route
|
|
49
|
+
* with a product list to be filtered
|
|
50
|
+
* @property {GetSelectedFilterValuesFn} getSelectedFilterValues Retrieves a list of currently
|
|
51
|
+
* selected values for a filter
|
|
52
|
+
* @property {UpdateSelectedFilterValuesFn} updateSelectedFilterValues Updates the selection for a
|
|
53
|
+
* filter
|
|
54
|
+
*/ /** @type {import('react').Context<FilterPageContext>} */var context=createContext({hasChanged:false,resetPossible:false,apiFilters:[],filters:{},resetAllFilters:noop,resetChangedFilters:noop,applyFilters:noop,getSelectedFilterValues:noop,updateSelectedFilterValues:noop});export default context;
|
|
@@ -0,0 +1,98 @@
|
|
|
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 _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;}function _toPropertyKey(arg){var key=_toPrimitive(arg,"string");return _typeof(key)==="symbol"?key:String(key);}function _toPrimitive(input,hint){if(_typeof(input)!=="object"||input===null)return input;var prim=input[Symbol.toPrimitive];if(prim!==undefined){var res=prim.call(input,hint||"default");if(_typeof(res)!=="object")return res;throw new TypeError("@@toPrimitive must return a primitive value.");}return(hint==="string"?String:Number)(input);}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 _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,useCallback}from'react';import PropTypes from'prop-types';import{connect}from'react-redux';import debounce from'lodash/debounce';import isEqual from'lodash/isEqual';import{router}from'@shopgate/engage/core';import{getFiltersByHash}from'@shopgate/engage/filter';// eslint-disable-next-line no-unused-vars, import/named
|
|
2
|
+
import Context,{APIFilter,RouteFilters}from"./FilterPageProvider.context";import{buildInitialFilters,buildUpdatedFilters}from"../helpers";/**
|
|
3
|
+
* @param {Object} state The application state.
|
|
4
|
+
* @param {Object} props The component props.
|
|
5
|
+
* @returns {Object}
|
|
6
|
+
*/var mapStateToProps=function mapStateToProps(state,props){return{filters:getFiltersByHash(state,props)};};/**
|
|
7
|
+
* @param {Object} next The next component props.
|
|
8
|
+
* @param {Object} prev The previous component props.
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/var areStatePropsEqual=function areStatePropsEqual(next,prev){if(!prev.filters&&next.filters||!isEqual(prev.filters,next.filters)){return false;}return true;};/**
|
|
11
|
+
* The FilterPageProvider component provides all relevant data and callbacks to represent and modify
|
|
12
|
+
* the current state of the "filter" page.
|
|
13
|
+
* @param {Object} props Provider props
|
|
14
|
+
* @param {APIFilter[]} props.filters Array of available filters
|
|
15
|
+
* @param {RouteFilters} props.activeFilters Object with the active filters for a filtered product
|
|
16
|
+
* list
|
|
17
|
+
* @param {string} props.parentRouteId Id of the route with the product list that's supposed to be
|
|
18
|
+
* filtered
|
|
19
|
+
* @param {Function} [props.onApply] Callback invoked when users pressed the apply button
|
|
20
|
+
* @param {string} [props.categoryId] A category to be used for filter selection from Redux
|
|
21
|
+
* @param {string} [props.searchPhrase] A search phrase to be used for filter selection from Redux
|
|
22
|
+
* @param {NodeList} children Provider children
|
|
23
|
+
* @returns {JSX.Element}
|
|
24
|
+
*/var FilterPageProvider=function FilterPageProvider(_ref){var filtersProp=_ref.filters,activeFiltersProp=_ref.activeFilters,parentRouteId=_ref.parentRouteId,onApply=_ref.onApply,children=_ref.children;var _useState=useState(activeFiltersProp||{}),_useState2=_slicedToArray(_useState,2),currentFilters=_useState2[0],setCurrentFilters=_useState2[1];/**
|
|
25
|
+
* Storage that hosts an object that represents the initial state of the filters page.
|
|
26
|
+
* It's created from the "filters" array that contains all available filters, and the
|
|
27
|
+
* "activeFilters" object that represents filters with an active value selection.
|
|
28
|
+
*/var _useState3=useState(buildInitialFilters(filtersProp,activeFiltersProp)),_useState4=_slicedToArray(_useState3,2),initialFilters=_useState4[0],setInitialFilters=_useState4[1];/**
|
|
29
|
+
* Storage that hosts an object that represents the a partial state of the filters page with
|
|
30
|
+
* all filters that where modified since the filters page was opened.
|
|
31
|
+
*/var _useState5=useState({}),_useState6=_slicedToArray(_useState5,2),changedFilters=_useState6[0],setChangedFilters=_useState6[1];// Object that represents the current state of all filters
|
|
32
|
+
var mergedFilters=useMemo(function(){return _extends({},initialFilters,{},changedFilters);},[changedFilters,initialFilters]);/**
|
|
33
|
+
* Effect that updates the "initialFilters" state when it doesn't have content yet
|
|
34
|
+
*/useEffect(function(){setInitialFilters(function(currentState){if(Object.keys(currentState).length>0){return currentState;}return buildInitialFilters(filtersProp,activeFiltersProp);});},[activeFiltersProp,filtersProp]);/**
|
|
35
|
+
* Whether a reset of the active filters is possible.
|
|
36
|
+
*
|
|
37
|
+
* Reset is possible whenever filters where selected by the user before, or when filters where
|
|
38
|
+
* modified since the filters page was opened.
|
|
39
|
+
* @type {boolean}
|
|
40
|
+
*/var resetPossible=useMemo(function(){return!!(Object.keys(currentFilters).length||Object.keys(changedFilters).length);},[changedFilters,currentFilters]);/**
|
|
41
|
+
* Whether the filter selection has changed since the filters page was opened
|
|
42
|
+
* @type {boolean}
|
|
43
|
+
*/var hasChanged=useMemo(function(){return Object.keys(changedFilters).length>0||!!(Object.keys(currentFilters).length===0&&activeFiltersProp);},[activeFiltersProp,changedFilters,currentFilters]);/**
|
|
44
|
+
* Retrieves a list of currently selected values for a filter
|
|
45
|
+
* @callback getSelectedFilterValues
|
|
46
|
+
* @param {string} filterId The id of the filter
|
|
47
|
+
* @returns {string[]}
|
|
48
|
+
*/var getSelectedFilterValues=useCallback(/**
|
|
49
|
+
* @param {string} filterId The id of the filter
|
|
50
|
+
* @returns {string[]}
|
|
51
|
+
*/function(filterId){var _initialFilters$filte;var value=changedFilters[filterId]?changedFilters[filterId].value:((_initialFilters$filte=initialFilters[filterId])===null||_initialFilters$filte===void 0?void 0:_initialFilters$filte.value)||[];return value.map(function(entry){return entry.id||entry;});},[changedFilters,initialFilters]);/**
|
|
52
|
+
* Resets all filters which have been changed by the user
|
|
53
|
+
*/var resetAllFilters=useCallback(function(){setInitialFilters(buildInitialFilters(filtersProp,{}));setCurrentFilters({});setChangedFilters({});},[filtersProp]);/**
|
|
54
|
+
* Resets all filters which have been changed by the user since the filters page was opened
|
|
55
|
+
*/var resetChangedFilters=useCallback(function(){setChangedFilters({});},[]);/**
|
|
56
|
+
* Adds or updates the selection for a changed filter
|
|
57
|
+
* @callback updateChangedFilterInternal
|
|
58
|
+
* @param {string} filterId The id of the filter to be updated
|
|
59
|
+
* @param {string[]} selectedValues The updated selected values
|
|
60
|
+
*/var updateChangedFilterInternal=useCallback(/**
|
|
61
|
+
* @param {string} filterId The id of the filter to be updated
|
|
62
|
+
* @param {string[]} selectedValues The updated selected values
|
|
63
|
+
*/function(filterId,selectedValues){setChangedFilters(function(currentState){return _extends({},currentState,_defineProperty({},filterId,selectedValues));});},[]);/**
|
|
64
|
+
* Removes a changed filter
|
|
65
|
+
* @callback removeChangedFilterInternal
|
|
66
|
+
* @param {string} filterId The id of the filter to be updated
|
|
67
|
+
* @param {string[]} selectedValues The updated selected values
|
|
68
|
+
*/var removeChangedFilterInternal=useCallback(/**
|
|
69
|
+
* @param {string} filterId The id of the filter to be removed
|
|
70
|
+
*/function(filterId){setChangedFilters(function(currentState){// Separate the given id from the other set filters.
|
|
71
|
+
var removed=currentState[filterId],remainingFilters=_objectWithoutProperties(currentState,[filterId].map(_toPropertyKey));return remainingFilters;});},[]);/**
|
|
72
|
+
* Updates the selection for a filter
|
|
73
|
+
*
|
|
74
|
+
* @param {string} filterId The id of the filter to be updated
|
|
75
|
+
* @param {string[]} selectedValues The updated selected values
|
|
76
|
+
*/var updateSelectedFilterValues=useCallback(debounce(/**
|
|
77
|
+
* @param {string} filterId The id of the filter to be updated
|
|
78
|
+
* @param {string[]} selectedValues The updated selected values
|
|
79
|
+
*/function(filterId,selectedValues){// Retrieve data of filter to be updated from the filters array.
|
|
80
|
+
var filter=filtersProp.find(function(entry){return entry.id===filterId;});// Retrieve the values for the updated filter that where set when the filter page was opened
|
|
81
|
+
var initialValues=initialFilters[filterId].value;// Prepare the update payload
|
|
82
|
+
var stateValue=[].concat(selectedValues);/**
|
|
83
|
+
* No initial values where set for this filter, and the update contains no values. So we
|
|
84
|
+
* can remove the filter from the changedFilters storage.
|
|
85
|
+
*/if(initialValues.length===0&&selectedValues.length===0){removeChangedFilterInternal(filterId);return;}/**
|
|
86
|
+
* When the filter update would recreate the state that the filter initially had, we
|
|
87
|
+
* remove the filter from the changedFilters storage.
|
|
88
|
+
*
|
|
89
|
+
* That enables proper behavior for the "reset" and "update" button states.
|
|
90
|
+
*/if(initialValues.length!==0&&selectedValues.length!==0){if(initialValues.every(function(initial,i){return initial===selectedValues[i];})){removeChangedFilterInternal(filterId);return;}}if(Array.isArray(filter.values)){/**
|
|
91
|
+
* The selectedValues array only contains a list of ids.
|
|
92
|
+
* For the getProducts request that's dispatched after the current filter selection was
|
|
93
|
+
* applied, id and label is required at the filter values level.
|
|
94
|
+
*/stateValue=selectedValues.map(function(valueId){var match=filter.values.find(function(entry){return entry.id===valueId;});return{id:match.id,label:match.label};});}updateChangedFilterInternal(filterId,_extends({id:filterId,type:filter.type,label:filter.label,value:stateValue},filter.source&&{source:filter.source}));},50),[filtersProp,initialFilters,removeChangedFilterInternal,updateChangedFilterInternal]);/**
|
|
95
|
+
* Applies the current filter selection to the parent route with a product list to be filtered
|
|
96
|
+
*/var applyFilters=useCallback(function(){var filters=buildUpdatedFilters(currentFilters,changedFilters);router.update(parentRouteId,{filters:filters});onApply(filters);},[changedFilters,currentFilters,onApply,parentRouteId]);var value=useMemo(function(){return{resetPossible:resetPossible,hasChanged:hasChanged,apiFilters:filtersProp||[],filters:mergedFilters,resetAllFilters:resetAllFilters,resetChangedFilters:resetChangedFilters,getSelectedFilterValues:getSelectedFilterValues,updateSelectedFilterValues:updateSelectedFilterValues,applyFilters:applyFilters};},[hasChanged,resetPossible,filtersProp,mergedFilters,resetAllFilters,resetChangedFilters,getSelectedFilterValues,updateSelectedFilterValues,applyFilters]);return React.createElement(Context.Provider,{value:value},children);};FilterPageProvider.defaultProps={children:null,activeFilters:null,parentRouteId:null,filters:null,onApply:function onApply(){return setTimeout(router.pop,250);}};/**
|
|
97
|
+
* @type FilterPageProvider
|
|
98
|
+
*/export default connect(mapStateToProps,null,null,{areStatePropsEqual:areStatePropsEqual})(FilterPageProvider);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{default as SortProvider}from"./SortProvider";
|
|
1
|
+
export{default as SortProvider}from"./SortProvider";export{default as FilterPageProvider}from"./FilterPageProvider";
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import{RECEIVE_INVENTORIES}from"../constants";/**
|
|
2
|
-
* Creates the dispatched
|
|
3
|
-
* @param {Array}
|
|
4
|
-
* @
|
|
5
|
-
* @param {Array} inventories List of product invetories.
|
|
6
|
-
* @return {Object} The RECEIVE_PRODUCT_LOCATIONS action.
|
|
2
|
+
* Creates the dispatched RECEIVE_INVENTORIES action object.
|
|
3
|
+
* @param {Array} productInventories List of product inventories.
|
|
4
|
+
* @return {Object} The RECEIVE_INVENTORIES action.
|
|
7
5
|
*/var receiveInventories=function receiveInventories(productInventories){return{type:RECEIVE_INVENTORIES,productInventories:productInventories};};export default receiveInventories;
|
|
@@ -5,4 +5,4 @@ import*as React from'react';import{css}from'glamor';import{connect}from'react-re
|
|
|
5
5
|
* Renders visible stock information based on the given location.
|
|
6
6
|
* @param {Object} props The component props.
|
|
7
7
|
* @return {JSX}
|
|
8
|
-
*/var StockInfoUnwrapped=function StockInfoUnwrapped(_ref){var location=_ref.location,inventory=_ref.inventory,className=_ref.className;var _ref2=getThemeSettings('product')||{},locationStockInfo=_ref2.locationStockInfo;var settings=defaultsDeep(locationStockInfo,defaultSettings);var _getAvailabilitySetti=getAvailabilitySettings(settings,location,inventory),_getAvailabilitySetti2=_getAvailabilitySetti.availabilityText,availabilityText=_getAvailabilitySetti2===void 0?'':_getAvailabilitySetti2,_getAvailabilitySetti3=_getAvailabilitySetti.availabilityTextColor,availabilityTextColor=_getAvailabilitySetti3===void 0?'inherit':_getAvailabilitySetti3,_getAvailabilitySetti4=_getAvailabilitySetti.comingSoon,comingSoon=_getAvailabilitySetti4===void 0?false:_getAvailabilitySetti4;var defaultClassName=css({color:availabilityTextColor,fontSize:'0.75rem',margin:0,':not(:empty) ~ *':{marginLeft:14}}).toString();var portalProps=React.useMemo(function(){return{location:location,className:className,availabilityText:availabilityText,availabilityTextColor:availabilityTextColor};},[availabilityText,availabilityTextColor,className,location]);return React.createElement(SurroundPortals,{portalName:PRODUCT_LOCATION_STOCK_INFO,portalProps:portalProps},React.createElement("span",{className:classNames(defaultClassName,css(className).toString())},React.createElement(StockInfoInventory,{availabilityText:availabilityText,comingSoon:comingSoon,location:location,inventory:inventory,maxNumberVisible:settings.maxNumberOfVisibleInventory,aboveMaxExtension:settings.aboveMaxExtension})));};StockInfoUnwrapped.defaultProps={className:null};export var StockInfo=connect(makeMapStateToProps)(StockInfoUnwrapped);
|
|
8
|
+
*/var StockInfoUnwrapped=function StockInfoUnwrapped(_ref){var location=_ref.location,inventory=_ref.inventory,className=_ref.className;var _ref2=getThemeSettings('product')||{},locationStockInfo=_ref2.locationStockInfo;var settings=defaultsDeep(locationStockInfo,defaultSettings);var _getAvailabilitySetti=getAvailabilitySettings(settings,location,inventory),_getAvailabilitySetti2=_getAvailabilitySetti.availabilityText,availabilityText=_getAvailabilitySetti2===void 0?'':_getAvailabilitySetti2,_getAvailabilitySetti3=_getAvailabilitySetti.availabilityTextColor,availabilityTextColor=_getAvailabilitySetti3===void 0?'inherit':_getAvailabilitySetti3,_getAvailabilitySetti4=_getAvailabilitySetti.comingSoon,comingSoon=_getAvailabilitySetti4===void 0?false:_getAvailabilitySetti4;var defaultClassName=css({color:availabilityTextColor,fontSize:'0.75rem',margin:0,':not(:empty) ~ *':{marginLeft:14}}).toString();var portalProps=React.useMemo(function(){return{location:location,inventory:inventory,comingSoon:comingSoon,settings:settings,className:className,availabilityText:availabilityText,availabilityTextColor:availabilityTextColor};},[availabilityText,availabilityTextColor,className,comingSoon,inventory,location,settings]);return React.createElement(SurroundPortals,{portalName:PRODUCT_LOCATION_STOCK_INFO,portalProps:portalProps},React.createElement("span",{className:classNames(defaultClassName,css(className).toString())},React.createElement(StockInfoInventory,{availabilityText:availabilityText,comingSoon:comingSoon,location:location,inventory:inventory,maxNumberVisible:settings.maxNumberOfVisibleInventory,aboveMaxExtension:settings.aboveMaxExtension})));};StockInfoUnwrapped.defaultProps={className:null};export var StockInfo=connect(makeMapStateToProps)(StockInfoUnwrapped);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
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{css}from'glamor';import{themeVariables,themeColors}from'@shopgate/pwa-common/helpers/config';import{responsiveMediaQuery}from'@shopgate/engage/styles';var gap=themeVariables.gap;var baseCardPadding="".concat(gap.small,"px ").concat(gap.big,"px");var gapM=gap.small+gap.xsmall;export var stores=css(_defineProperty({background:"var(--color-background-accent, ".concat(themeColors.background,")"),padding:"".concat(gapM,"px ").concat(gapM,"px ").concat(gap.big,"px"),fontSize:'0.875rem'},responsiveMediaQuery('<=sm'),{boxShadow:'inset rgba(0, 0, 0, .117647) 0 1px 6px, inset rgba(0, 0, 0, .117647) 0 1px 4px'})).toString();export var storeCard=css({background:themeColors.light,marginBottom:gapM,':last-of-type':{marginBottom:0},border:"1px solid ".concat(themeColors.shade7),boxSizing:'border-box',boxShadow:'0px 1px 2px rgba(0, 0, 0, 0.25)',borderRadius:'0px 0px 3px 3px'}).toString();export var storeCardPlaceholder=css({margin:'10px 0',height:36}).toString();export var storeHeader=css({cursor:'pointer',padding:"".concat(baseCardPadding," ").concat(gap.xsmall,"px")}).toString();export var disabled=css({cursor:'not-allowed'}).toString();export var storeName=css({fontSize:'1rem',fontWeight:500}).toString();export var storeDistance=css(_defineProperty({whiteSpace:'nowrap',color:"var(--color-text-medium-emphasis, ".concat(themeColors.gray,")")},responsiveMediaQuery('>sm',{webOnly:true}),{fontSize:'0.875rem'})).toString();export var storeDetailsBody=css({padding:baseCardPadding,borderTop:"1px solid ".concat(themeColors.shade7)}).toString();export var storeDetailsAccordion=css({justifyContent:'space-between'}).toString();export var storeHoursToday=css({color:"var(--color-text-low-emphasis, ".concat(themeColors.gray,")")}).toString();export var address=css({display:'flex',flexFlow:'row nowrap',color:"var(--color-text-low-emphasis, ".concat(themeColors.gray,")"),marginBottom:
|
|
1
|
+
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{css}from'glamor';import{themeVariables,themeColors}from'@shopgate/pwa-common/helpers/config';import{responsiveMediaQuery}from'@shopgate/engage/styles';var gap=themeVariables.gap;var baseCardPadding="".concat(gap.small,"px ").concat(gap.big,"px");var gapM=gap.small+gap.xsmall;export var stores=css(_defineProperty({background:"var(--color-background-accent, ".concat(themeColors.background,")"),padding:"".concat(gapM,"px ").concat(gapM,"px ").concat(gap.big,"px"),fontSize:'0.875rem'},responsiveMediaQuery('<=sm'),{boxShadow:'inset rgba(0, 0, 0, .117647) 0 1px 6px, inset rgba(0, 0, 0, .117647) 0 1px 4px'})).toString();export var storeCard=css({background:themeColors.light,marginBottom:gapM,':last-of-type':{marginBottom:0},border:"1px solid ".concat(themeColors.shade7),boxSizing:'border-box',boxShadow:'0px 1px 2px rgba(0, 0, 0, 0.25)',borderRadius:'0px 0px 3px 3px'}).toString();export var storeCardPlaceholder=css({margin:'10px 0',height:36}).toString();export var storeHeader=css({cursor:'pointer',padding:"".concat(baseCardPadding," ").concat(gap.xsmall,"px")}).toString();export var disabled=css({cursor:'not-allowed'}).toString();export var storeName=css({fontSize:'1rem',fontWeight:500}).toString();export var storeDistance=css(_defineProperty({whiteSpace:'nowrap',color:"var(--color-text-medium-emphasis, ".concat(themeColors.gray,")")},responsiveMediaQuery('>sm',{webOnly:true}),{fontSize:'0.875rem'})).toString();export var storeDetailsBody=css({padding:baseCardPadding,borderTop:"1px solid ".concat(themeColors.shade7)}).toString();export var storeDetailsAccordion=css({justifyContent:'space-between'}).toString();export var storeHoursToday=css({color:"var(--color-text-low-emphasis, ".concat(themeColors.gray,")")}).toString();export var address=css({display:'flex',flexFlow:'row nowrap',color:"var(--color-text-low-emphasis, ".concat(themeColors.gray,")"),marginBottom:4}).toString();export var addressIcon=css({color:themeColors.shade7,fontSize:'1.4rem',padding:"".concat(gap.xsmall,"px ").concat(gap.big,"px 0 0")}).toString();export var detailsIcon=css({color:themeColors.shade3,fontSize:'1.4rem',padding:"".concat(gap.xsmall,"px ").concat(gap.big,"px 0 0")}).toString();export var detailsIconLinked=css({color:'var(--color-primary)'}).toString();export var detailsLine=css({marginTop:gapM}).toString();export var details=css({paddingTop:gap.xsmall}).toString();export var openingHours=css({display:'table',color:'var(--color-text-low-emphasis)'}).toString();export var openingHoursRow=css({display:'table-row'}).toString();export var openingHoursDay=css({display:'table-cell',paddingRight:gap.big}).toString();export var detailsPrimary=css({color:"var(--color-primary, ".concat(themeColors.primary,")"),lineHeight:'1.375rem'}).toString();export var detailsSecondary=css({color:"var(--color-text-medium-emphasis, ".concat(themeColors.shade3,")"),fontSize:'0.75rem'}).toString();export var selectLocationButtonWrapper=css(_defineProperty({padding:"0 ".concat(gap.big,"px ").concat(gap.small,"px ").concat(gap.big,"px")},responsiveMediaQuery('>=sm',{webOnly:true}),{padding:"0 0 ".concat(gap.small,"px 0")}));export var stockInfoContainer=css({marginTop:8,':empty':{display:'none'}});export var selectLocationButton=css({width:'100%',fontSize:'.875rem !important',':not(:disabled)':{background:"var(--color-primary, ".concat(themeColors.primary,")!important"),color:"var(--color-primary-contrast, ".concat(themeColors.primaryContrast,")!important")}});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import*as React from'react';import{LocationIcon}from"../../../components";import{i18n}from"../../../core";import{address as container,addressIcon}from"./Store.style";/**
|
|
1
|
+
import*as React from'react';import{ResponsiveContainer}from'@shopgate/engage/components';import{StoreContext}from"./Store.context";import{FulfillmentContext}from"../../locations.context";import{StockInfo}from"../StockInfo";import{LocationIcon}from"../../../components";import{i18n}from"../../../core";import{address as container,addressIcon,stockInfoContainer}from"./Store.style";/**
|
|
2
2
|
* Renders the pickup location's address information.
|
|
3
3
|
* @param {Object} props The component props.
|
|
4
4
|
* @returns {JSX}
|
|
5
|
-
*/export function StoreAddress(_ref){var address=_ref.address,pure=_ref.pure;if(!address){return null;}var addressContent=React.createElement("div",null,React.createElement("div",{"data-test-id":"street"},address.street),address.street2&&address.street2!==''&&React.createElement("div",{"data-test-id":"street2"},address.street2),address.street3&&address.street3!==''&&React.createElement("div",{"data-test-id":"street3"},address.street3),address.street4&&address.street4!==''&&React.createElement("div",{"data-test-id":"street4"},address.street4),i18n.text('locations.address',address));if(pure){return addressContent;}return React.createElement("div",{className:container},React.createElement("div",{className:addressIcon},React.createElement(LocationIcon,null)),React.createElement("div",null,addressContent));}StoreAddress.defaultProps={address:null,pure:false};
|
|
5
|
+
*/export function StoreAddress(_ref){var address=_ref.address,pure=_ref.pure;var store=React.useContext(StoreContext);var _React$useContext=React.useContext(FulfillmentContext),product=_React$useContext.product;if(!address){return null;}var addressContent=React.createElement("div",null,React.createElement("div",{"data-test-id":"street"},address.street),address.street2&&address.street2!==''&&React.createElement("div",{"data-test-id":"street2"},address.street2),address.street3&&address.street3!==''&&React.createElement("div",{"data-test-id":"street3"},address.street3),address.street4&&address.street4!==''&&React.createElement("div",{"data-test-id":"street4"},address.street4),i18n.text('locations.address',address));if(pure){return addressContent;}return React.createElement("div",{className:container},React.createElement("div",{className:addressIcon},React.createElement(LocationIcon,null)),React.createElement("div",null,addressContent,React.createElement(ResponsiveContainer,{breakpoint:"<sm",appAlways:true},React.createElement("div",{className:stockInfoContainer},React.createElement(StockInfo,{location:store,product:product,showStoreName:false})))));}StoreAddress.defaultProps={address:null,pure:false};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React,{useContext
|
|
1
|
+
import React,{useContext}from'react';import{Accordion}from"../../../components";import{StoreContext}from"./Store.context";import{StoreOpeningHours}from"./StoreOpeningHours";import{StoreAddress}from"./StoreAddress";import{StorePhoneNumber}from"./StorePhoneNumber";import{StoreAddressShort}from"./StoreAddressShort";import{storeDetailsBody,storeDetailsAccordion}from"./Store.style";/**
|
|
2
2
|
* Renders a single store details.
|
|
3
3
|
* @returns {JSX}
|
|
4
|
-
*/export function StoreDetails(){var store=useContext(StoreContext);
|
|
4
|
+
*/export function StoreDetails(){var store=useContext(StoreContext);if(!store){return null;}return React.createElement(Accordion,{className:storeDetailsAccordion,renderLabel:function renderLabel(){return React.createElement(StoreAddress,{address:store.address});},contentClassName:storeDetailsBody},React.createElement(StoreOpeningHours,{hours:store.operationHours}),store.address&&React.createElement(StorePhoneNumber,{phone:store.address.phoneNumber}),React.createElement(StoreAddressShort,{showFull:true,address:store.address}));}
|
|
@@ -7,7 +7,9 @@ import _regeneratorRuntime from"@babel/runtime/regenerator";function asyncGenera
|
|
|
7
7
|
setMessage('locations.error_no_store_found');}else{setMessage('');}},[isLoading,locations,message]);/**
|
|
8
8
|
* Triggers an update when the value of the country selector changed.
|
|
9
9
|
* @param {SyntheticEvent} event A React event object.
|
|
10
|
-
*/var handleCountrySelectChange=useCallback(function(event){setCountryCode(event.target.value,productId,isStoreFinder);},[isStoreFinder,productId,setCountryCode])
|
|
10
|
+
*/var handleCountrySelectChange=useCallback(function(event){setCountryCode(event.target.value,productId,isStoreFinder);},[isStoreFinder,productId,setCountryCode]);useEffect(function(){if(!Array.isArray(supportedCountries)||!supportedCountries.length){return;}// Check if current countryCode is included in supportedCountries. Update the code to a valid
|
|
11
|
+
// one if nothing was found.
|
|
12
|
+
if(!supportedCountries.includes(countryCode)){handleCountrySelectChange({target:{value:supportedCountries[0]}});}},[countryCode,handleCountrySelectChange,supportedCountries]);/**
|
|
11
13
|
* Blurs the postal code input to trigger an update.
|
|
12
14
|
* @param {SyntheticEvent} event A React event object.
|
|
13
15
|
*/var handlePostalCodeSubmitKeyDown=useCallback(function(event){if(event.keyCode===13){inputEl.current.blur();}},[]);/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopgate/engage",
|
|
3
|
-
"version": "7.20.0
|
|
3
|
+
"version": "7.20.0",
|
|
4
4
|
"description": "Shopgate's ENGAGE library.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Shopgate <support@shopgate.com>",
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@shopgate/native-modules": "1.0.0-beta.18",
|
|
19
|
-
"@shopgate/pwa-common": "7.20.0
|
|
20
|
-
"@shopgate/pwa-common-commerce": "7.20.0
|
|
21
|
-
"@shopgate/pwa-core": "7.20.0
|
|
22
|
-
"@shopgate/pwa-ui-ios": "7.20.0
|
|
23
|
-
"@shopgate/pwa-ui-material": "7.20.0
|
|
24
|
-
"@shopgate/pwa-ui-shared": "7.20.0
|
|
19
|
+
"@shopgate/pwa-common": "7.20.0",
|
|
20
|
+
"@shopgate/pwa-common-commerce": "7.20.0",
|
|
21
|
+
"@shopgate/pwa-core": "7.20.0",
|
|
22
|
+
"@shopgate/pwa-ui-ios": "7.20.0",
|
|
23
|
+
"@shopgate/pwa-ui-material": "7.20.0",
|
|
24
|
+
"@shopgate/pwa-ui-shared": "7.20.0",
|
|
25
25
|
"@stripe/react-stripe-js": "^1.1.2",
|
|
26
26
|
"@stripe/stripe-js": "^1.3.1",
|
|
27
27
|
"@virtuous/conductor": "~2.5.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{isBeta,isAfter,isBefore,addDuration}from'@shopgate/engage/core/helpers';import{getThemeSettings}from'@shopgate/engage/core/config';import{ALWAYS,NEVER}from"./constants";/**
|
|
2
2
|
* Build params to fetch category products
|
|
3
3
|
* @returns {Object|{showScheduled: string}}
|
|
4
4
|
*/export var buildShowScheduledParams=function buildShowScheduledParams(){if(!isBeta()){return{};}var cachedTime=null;var _ref=getThemeSettings('product')||{},_ref$effectivityDates=_ref.effectivityDates,_ref$effectivityDates2=_ref$effectivityDates===void 0?{}:_ref$effectivityDates,showScheduled=_ref$effectivityDates2.showScheduled;if(showScheduled===ALWAYS){showScheduled='P1Y';}else if(showScheduled===NEVER){showScheduled='PT0S';cachedTime=60000;// 1 minute min effective precision
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from'react';import{mount,shallow}from'enzyme';import{PickerUtilize as Picker}from'@shopgate/engage/components';import Options from"./index";jest.mock('@shopgate/engage/product/contexts',function(){return{ProductContext:{Consumer:jest.fn(function(_ref){var children=_ref.children;return children({setOption:jest.fn(),currency:'EUR'});})}};})
|
|
1
|
+
import React from'react';import{mount,shallow}from'enzyme';import{PickerUtilize as Picker}from'@shopgate/engage/components';import Options from"./index";jest.mock('@shopgate/engage/components');jest.mock('@shopgate/engage/product/contexts',function(){return{ProductContext:{Consumer:jest.fn(function(_ref){var children=_ref.children;return children({setOption:jest.fn(),currency:'EUR'});})}};});// Mock the redux connect() method instead of providing a fake store.
|
|
2
2
|
jest.mock("./connector",function(){return function(obj){var newObj=obj;var mockOptions=[{id:'test-id',type:'select',label:'label',items:[{currency:'USD',price:10,priceDifference:0},{currency:'USD',price:10,priceDifference:0}]}];newObj.defaultProps={options:mockOptions,currentOptions:{}};return newObj;};});describe('<Options />',function(){var mockOptions=[{id:'test-id',type:'select',label:'label',items:[{currency:'USD',price:10,priceDifference:0},{currency:'USD',price:10,priceDifference:0}]}];describe('Given the component was mounted to the DOM',function(){it('should match snapshot',function(){var wrapper=shallow(React.createElement(Options,{currentOptions:{}})).dive();expect(wrapper).toMatchSnapshot();});it('should render correct number of options',function(){var wrapper=mount(React.createElement(Options,{options:mockOptions}));var picker=wrapper.find(Picker);expect(picker.length).toBe(mockOptions.length);});});});
|
package/product/helpers/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
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 _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);}import configuration from'@shopgate/pwa-common/collections/Configuration';import{DEFAULT_PRODUCTS_FETCH_PARAMS}from'@shopgate/pwa-common/constants/Configuration';import{getFullImageSource,
|
|
1
|
+
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 _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);}import configuration from'@shopgate/pwa-common/collections/Configuration';import{DEFAULT_PRODUCTS_FETCH_PARAMS}from'@shopgate/pwa-common/constants/Configuration';import{getFullImageSource,isBeta,loadImage}from'@shopgate/engage/core/helpers';import{getThemeSettings}from'@shopgate/engage/core/config';import{buildShowScheduledParams}from"../components/EffectivityDates/helpers";export*from'@shopgate/pwa-common-commerce/product/helpers';export*from"../components/Media/helpers";export*from"./redirects";/**
|
|
2
2
|
* Build params to fetch category products
|
|
3
3
|
* @returns {undefined|{params: Object}}
|
|
4
4
|
*/export var buildFetchCategoryProductsParams=function buildFetchCategoryProductsParams(){if(!isBeta()){return{params:{}};}var scheduled=buildShowScheduledParams();return _extends({params:_extends({characteristics:true},scheduled.params)},scheduled.cachedTime&&{cachedTime:scheduled.cachedTime});};/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{isBeta,redirects
|
|
1
|
+
import{isBeta,isAfter}from'@shopgate/engage/core/helpers';import{redirects}from'@shopgate/engage/core/collections';import{getThemeSettings}from'@shopgate/engage/core/config';import{ITEM_PATTERN}from'@shopgate/pwa-common-commerce/product/constants';import{makeGetProductEffectivityDates}from"../selectors/product";/**
|
|
2
2
|
* Enable redirect handler for effectivity dates and more
|
|
3
3
|
* @returns {void}
|
|
4
4
|
*/export var enableRedirectHandler=function enableRedirectHandler(){if(!isBeta()){return;}/** Effectivity dates */var _ref=getThemeSettings('product')||{},_ref$effectivityDates=_ref.effectivityDates,_ref$effectivityDates2=_ref$effectivityDates===void 0?{}:_ref$effectivityDates,accessExpired=_ref$effectivityDates2.accessExpired;if(accessExpired){return;}var getProductEffectivityDates=makeGetProductEffectivityDates();redirects.set(ITEM_PATTERN,function(_ref2){var action=_ref2.action,getState=_ref2.getState;var pathname=action.params.pathname,productId=action.route.state.productId;var effectivityDates=getProductEffectivityDates(getState(),{productId:productId});if(effectivityDates){// Forbid redirect if endDate is expired
|
|
@@ -71,11 +71,21 @@ var _product$baseProductI=product.baseProductId,baseProductId=_product$baseProdu
|
|
|
71
71
|
* @returns {Function}
|
|
72
72
|
*/export function makeGetProductFeaturedMedia(){return createSelector(getProduct,function(product){if(!product){return null;}return!product.featuredMedia?null:product.featuredMedia;});}/**
|
|
73
73
|
* Creates a selector to indicate if a product is active.
|
|
74
|
+
*
|
|
75
|
+
* @param {boolean} [returnNullIfProductMissing=false] - Flag to determine the return value when
|
|
76
|
+
* the product is not found. If set to `true`, the selector will return `null` when the product
|
|
77
|
+
* is not found. If `false`, it will return `false`.
|
|
78
|
+
*
|
|
74
79
|
* @returns {Function}
|
|
75
|
-
*/export var makeIsProductActive=function makeIsProductActive(){return createSelector(getProduct,function(product){if(!product){return false;}return(product===null||product===void 0?void 0:product.active)||false;});};/**
|
|
80
|
+
*/export var makeIsProductActive=function makeIsProductActive(){var returnNullIfProductMissing=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;return createSelector(getProduct,function(product){if(!product){return returnNullIfProductMissing?null:false;}return(product===null||product===void 0?void 0:product.active)||false;});};/**
|
|
76
81
|
* Creates a selector to indicate if the base product is active.
|
|
82
|
+
*
|
|
83
|
+
* @param {boolean} [returnNullIfProductMissing=false] - Flag to determine the return value when
|
|
84
|
+
* the product is not found. If set to `true`, the selector will return `null` when the product
|
|
85
|
+
* is not found. If `false`, it will return `false`.
|
|
86
|
+
*
|
|
77
87
|
* @returns {Function}
|
|
78
|
-
*/export var makeIsBaseProductActive=function makeIsBaseProductActive(){return createSelector(getBaseProduct,function(baseProduct){if(!baseProduct){return false;}return(baseProduct===null||baseProduct===void 0?void 0:baseProduct.active)||false;});};/**
|
|
88
|
+
*/export var makeIsBaseProductActive=function makeIsBaseProductActive(){var returnNullIfProductMissing=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;return createSelector(getBaseProduct,function(baseProduct){if(!baseProduct){return returnNullIfProductMissing?null:false;}return(baseProduct===null||baseProduct===void 0?void 0:baseProduct.active)||false;});};/**
|
|
79
89
|
* Creates a selector to get the property of a product based on a given label
|
|
80
90
|
* @returns {Function}
|
|
81
91
|
*/export var makeGetCurrentProductPropertyByLabel=function makeGetCurrentProductPropertyByLabel(){var getProductPropertiesUnfiltered=makeGetProductPropertiesUnfiltered();return createSelector(getProductPropertiesUnfiltered,function(state,props){return props.widgetSettings;},function(currentProductProperties,widgetSettings){if(!currentProductProperties||!widgetSettings||!widgetSettings.propertyLabel){return null;}return currentProductProperties.find(function(_ref3){var label=_ref3.label;return label===widgetSettings.propertyLabel;});});};/**
|
|
@@ -1,62 +1,62 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
2
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
3
3
|
<svg width="100%" height="100%" viewBox="0 0 1107 791" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
4
|
+
<g transform="matrix(1,0,0,1,-88.9596,-502.577)">
|
|
5
|
+
<g transform="matrix(1.28381,0,0,1.28381,-145.009,-328.293)">
|
|
6
|
+
<g>
|
|
7
|
+
<g transform="matrix(0.738616,0,0,0.7166,142.625,351.19)">
|
|
8
|
+
<path d="M1052.9,1091.68C1052.9,1062.46 1029.88,1038.73 1001.53,1038.73L244.024,1038.73C215.667,1038.73 192.646,1062.46 192.646,1091.68L192.646,1219.08C192.646,1248.3 215.667,1272.03 244.024,1272.03L1001.53,1272.03C1029.88,1272.03 1052.9,1248.3 1052.9,1219.08L1052.9,1091.68Z" style="fill:rgb(193,193,193);"/>
|
|
9
|
+
</g>
|
|
10
|
+
<g transform="matrix(0.859568,0,0,0.833947,80.1965,145.713)">
|
|
11
|
+
<path d="M1052.9,1091.68C1052.9,1062.46 1029.88,1038.73 1001.53,1038.73L244.024,1038.73C215.667,1038.73 192.646,1062.46 192.646,1091.68L192.646,1219.08C192.646,1248.3 215.667,1272.03 244.024,1272.03L1001.53,1272.03C1029.88,1272.03 1052.9,1248.3 1052.9,1219.08L1052.9,1091.68Z" style="fill:rgb(216,216,216);"/>
|
|
12
|
+
</g>
|
|
13
|
+
<g transform="matrix(1.00203,0,0,0.972164,-10.791,-90.8989)">
|
|
14
|
+
<path d="M1052.9,1091.68C1052.9,1062.46 1029.88,1038.73 1001.53,1038.73L244.024,1038.73C215.667,1038.73 192.646,1062.46 192.646,1091.68L192.646,1219.08C192.646,1248.3 215.667,1272.03 244.024,1272.03L1001.53,1272.03C1029.88,1272.03 1052.9,1248.3 1052.9,1219.08L1052.9,1091.68Z" style="fill:rgb(235,235,235);"/>
|
|
15
|
+
</g>
|
|
16
|
+
<g transform="matrix(1.00203,0,0,0.972164,-10.791,-362.62)">
|
|
17
|
+
<path d="M1052.9,1091.68C1052.9,1062.46 1029.88,1038.73 1001.53,1038.73L244.024,1038.73C215.667,1038.73 192.646,1062.46 192.646,1091.68L192.646,1219.08C192.646,1248.3 215.667,1272.03 244.024,1272.03L1001.53,1272.03C1029.88,1272.03 1052.9,1248.3 1052.9,1219.08L1052.9,1091.68Z" style="fill:rgb(235,235,235);"/>
|
|
18
|
+
</g>
|
|
19
|
+
</g>
|
|
20
|
+
<g transform="matrix(1.00052,0,0,1,-19.3912,30.3377)">
|
|
21
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.762,1033.42 949.281,1033.42L424.519,1033.42C422.039,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.039,1065.77 424.519,1065.77L949.281,1065.77C951.762,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
22
|
+
</g>
|
|
23
|
+
<g transform="matrix(0.823791,0,0,1,54.8392,-16.3916)">
|
|
24
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.33,1033.42 948.317,1033.42L425.484,1033.42C422.471,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.471,1065.77 425.484,1065.77L948.317,1065.77C951.33,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
25
|
+
</g>
|
|
26
|
+
<g transform="matrix(0.904048,0,0,1,21.129,-67.1309)">
|
|
27
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.547,1033.42 948.801,1033.42L424.999,1033.42C422.254,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.254,1065.77 424.999,1065.77L948.801,1065.77C951.547,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
28
|
+
</g>
|
|
29
|
+
<g transform="matrix(1.02071,0,0,1.04641,-38.8586,-763.331)">
|
|
30
|
+
<path d="M393.702,1679.71C393.702,1660.56 377.767,1645.02 358.141,1645.02L287.019,1645.02C267.393,1645.02 251.458,1660.56 251.458,1679.71L251.458,1749.29C251.458,1768.44 267.393,1783.98 287.019,1783.98L358.141,1783.98C377.767,1783.98 393.702,1768.44 393.702,1749.29L393.702,1679.71Z" style="fill:rgb(85,217,92);"/>
|
|
31
|
+
<clipPath id="_clip1">
|
|
32
|
+
<path d="M393.702,1679.71C393.702,1660.56 377.767,1645.02 358.141,1645.02L287.019,1645.02C267.393,1645.02 251.458,1660.56 251.458,1679.71L251.458,1749.29C251.458,1768.44 267.393,1783.98 287.019,1783.98L358.141,1783.98C377.767,1783.98 393.702,1768.44 393.702,1749.29L393.702,1679.71Z"/>
|
|
33
|
+
</clipPath>
|
|
34
|
+
<g clip-path="url(#_clip1)">
|
|
35
|
+
<g transform="matrix(0.76313,0,0,0.744387,148.731,1102.32)">
|
|
36
|
+
<path d="M226.411,745.537L243.421,797.888L298.467,797.888L253.934,830.243L270.944,882.594L226.411,850.239L181.879,882.594L198.889,830.243L154.356,797.888L209.402,797.888L226.411,745.537Z" style="fill:white;"/>
|
|
37
|
+
</g>
|
|
38
|
+
</g>
|
|
39
|
+
</g>
|
|
40
|
+
<g transform="matrix(0.933678,0,0,1,8.6838,-241.981)">
|
|
41
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.617,1033.42 948.959,1033.42L424.841,1033.42C422.183,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.183,1065.77 424.841,1065.77L948.959,1065.77C951.617,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
42
|
+
</g>
|
|
43
|
+
<g transform="matrix(1,0,0,1,-19.173,-288.71)">
|
|
44
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.761,1033.42 949.279,1033.42L424.522,1033.42C422.04,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.04,1065.77 424.522,1065.77L949.279,1065.77C951.761,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
45
|
+
</g>
|
|
46
|
+
<g transform="matrix(0.844941,0,0,1,45.9556,-337.889)">
|
|
47
|
+
<path d="M953.776,1037.91C953.776,1035.43 951.391,1033.42 948.453,1033.42L425.347,1033.42C422.409,1033.42 420.025,1035.43 420.025,1037.91L420.025,1061.27C420.025,1063.75 422.409,1065.77 425.347,1065.77L948.453,1065.77C951.391,1065.77 953.776,1063.75 953.776,1061.27L953.776,1037.91Z" style="fill:rgb(187,196,198);fill-opacity:0.65;"/>
|
|
48
|
+
</g>
|
|
49
|
+
<g transform="matrix(1.02071,0,0,1.04641,-38.8586,-1035.65)">
|
|
50
|
+
<path d="M393.702,1679.71C393.702,1660.56 377.767,1645.02 358.141,1645.02L287.019,1645.02C267.393,1645.02 251.458,1660.56 251.458,1679.71L251.458,1749.29C251.458,1768.44 267.393,1783.98 287.019,1783.98L358.141,1783.98C377.767,1783.98 393.702,1768.44 393.702,1749.29L393.702,1679.71Z" style="fill:rgb(86,216,95);"/>
|
|
51
|
+
<clipPath id="_clip2">
|
|
52
|
+
<path d="M393.702,1679.71C393.702,1660.56 377.767,1645.02 358.141,1645.02L287.019,1645.02C267.393,1645.02 251.458,1660.56 251.458,1679.71L251.458,1749.29C251.458,1768.44 267.393,1783.98 287.019,1783.98L358.141,1783.98C377.767,1783.98 393.702,1768.44 393.702,1749.29L393.702,1679.71Z"/>
|
|
53
|
+
</clipPath>
|
|
54
|
+
<g clip-path="url(#_clip2)">
|
|
55
|
+
<g transform="matrix(0.979712,0,0,0.955649,69.3286,762.785)">
|
|
56
|
+
<text x="193.673px" y="1041.62px" style="font-family:'HelveticaNeue-Bold', 'Helvetica Neue';font-weight:700;font-size:128px;fill:white;">%</text>
|
|
57
|
+
</g>
|
|
58
|
+
</g>
|
|
59
|
+
</g>
|
|
60
|
+
</g>
|
|
61
|
+
</g>
|
|
62
62
|
</svg>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import appConfig from'@shopgate/pwa-common/helpers/config';import{
|
|
1
|
+
import appConfig from'@shopgate/pwa-common/helpers/config';import{initCSSCustomProps,initCSSCustomPropsFallback}from"./initCSSCustomProperties";/**
|
|
2
2
|
* Loads external CSS with custom properties
|
|
3
3
|
* @returns {void}
|
|
4
4
|
*/export var loadCustomStyles=function loadCustomStyles(){var id='external-css';var href=appConfig.customStyleUrl;var linkTag=document.querySelector("#".concat(id));/**
|
|
5
5
|
* Error handler
|
|
6
|
-
*/var onError=function onError(){
|
|
6
|
+
*/var onError=function onError(){initCSSCustomPropsFallback();};if(!href){onError();}if(href&&!linkTag){linkTag=document.createElement('link');linkTag.setAttribute('rel','stylesheet');linkTag.setAttribute('type','text/css');linkTag.setAttribute('href',href);linkTag.setAttribute('id',id);linkTag.onload=initCSSCustomProps;linkTag.onerror=onError;document.querySelector('head').appendChild(linkTag);}};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{themeConfig}from'@shopgate/pwa-common/helpers/config';import{hasWebBridge}from'@shopgate/engage/core';import{setCSSCustomProp}from"./cssCustomProperties";var defaultBackgroundColor=themeConfig.colors.light;/**
|
|
1
|
+
import{themeConfig}from'@shopgate/pwa-common/helpers/config';import{hasWebBridge}from'@shopgate/engage/core/helpers';import{setCSSCustomProp}from"./cssCustomProperties";var defaultBackgroundColor=themeConfig.colors.light;/**
|
|
2
2
|
* Updates the page background color.
|
|
3
3
|
* @param {string} color The new background color.
|
|
4
4
|
*/export var setPageBackgroundColor=function setPageBackgroundColor(){var color=arguments.length>0&&arguments[0]!==undefined?arguments[0]:defaultBackgroundColor;// Curbside website changes never its background color
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import MobileDetect from'mobile-detect';import{logger}from'@shopgate/engage/core';var md=new MobileDetect(navigator.userAgent);var SELECTOR_BODY='html, body';var SELECTOR_CONTENT='#AppContent';var currentRef=null;/**
|
|
1
|
+
import MobileDetect from'mobile-detect';import{logger}from'@shopgate/engage/core/helpers';var md=new MobileDetect(navigator.userAgent);var SELECTOR_BODY='html, body';var SELECTOR_CONTENT='#AppContent';var currentRef=null;/**
|
|
2
2
|
* Toggles the body scroll on mobile phones
|
|
3
3
|
* @param {boolean} locked The lock state
|
|
4
4
|
* @param {*} ref A reference parameter to take care that only the locker can unlock
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
2
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
3
3
|
<svg width="100%" height="100%" viewBox="0 0 895 895" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
<g transform="matrix(1,0,0,1,-197.772,-376.125)">
|
|
5
|
+
<g transform="matrix(1.28727,0,0,1.28727,-185.288,-236.524)">
|
|
6
|
+
<g transform="matrix(1.25456,0,0,1.25456,-164.192,-209.593)">
|
|
7
|
+
<circle cx="645" cy="823.354" r="276.929" style="fill:rgb(235,235,235);"/>
|
|
8
|
+
</g>
|
|
9
|
+
<g transform="matrix(17.6233,0,0,17.6233,433.521,611.874)">
|
|
10
|
+
<path d="M12,0C8.629,2.866 6.516,3 3,3L3,14.535C3,19.138 6.203,20.339 12,24C17.797,20.339 21,19.138 21,14.535L21,3C17.484,3 15.371,2.866 12,0Z" style="fill:rgb(86,217,95);fill-rule:nonzero;"/>
|
|
11
|
+
<path d="M12.99,-1.164C12.419,-1.649 11.581,-1.649 11.01,-1.164C8.014,1.383 6.125,1.472 3,1.472C2.156,1.472 1.472,2.156 1.472,3L1.472,14.535C1.472,17.357 2.45,19.137 4.32,20.771C5.891,22.144 8.2,23.407 11.184,25.292C11.682,25.607 12.318,25.607 12.816,25.292C15.8,23.407 18.109,22.144 19.68,20.771C21.55,19.137 22.528,17.357 22.528,14.535L22.528,3C22.528,2.156 21.844,1.472 21,1.472C17.875,1.472 15.986,1.383 12.99,-1.164ZM12,0C8.629,2.866 6.516,3 3,3L3,14.535C3,19.138 6.203,20.339 12,24C17.797,20.339 21,19.138 21,14.535L21,3C17.484,3 15.371,2.866 12,0Z" style="fill:rgb(216,216,216);"/>
|
|
12
|
+
</g>
|
|
13
|
+
<g transform="matrix(24.4351,0,0,24.4351,340.416,541.775)">
|
|
14
|
+
<path d="M15.762,8.047L11.381,12.522L9.166,10.399L7.93,11.638L11.381,15L17,9.285L15.762,8.047Z" style="fill:white;fill-rule:nonzero;"/>
|
|
15
|
+
</g>
|
|
16
|
+
</g>
|
|
17
|
+
</g>
|
|
18
18
|
</svg>
|