@shopgate/engage 7.29.2-beta.2 → 7.29.3-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- export*from"./appEvents";export{default as usePressHandler}from"./usePressHandler";export{default as useLongPress}from"./useLongPress";export{default as useScrollDirectionChange}from"./useScrollDirectionChange";
1
+ export{default as usePressHandler}from"./usePressHandler";export{default as useLongPress}from"./useLongPress";export{default as useScrollDirectionChange}from"./useScrollDirectionChange";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/engage",
3
- "version": "7.29.2-beta.2",
3
+ "version": "7.29.3-alpha.2",
4
4
  "description": "Shopgate's ENGAGE library.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -17,12 +17,12 @@
17
17
  "dependencies": {
18
18
  "@emotion/react": "^11.14.0",
19
19
  "@shopgate/native-modules": "1.0.0-beta.25",
20
- "@shopgate/pwa-common": "7.29.2-beta.2",
21
- "@shopgate/pwa-common-commerce": "7.29.2-beta.2",
22
- "@shopgate/pwa-core": "7.29.2-beta.2",
23
- "@shopgate/pwa-ui-ios": "7.29.2-beta.2",
24
- "@shopgate/pwa-ui-material": "7.29.2-beta.2",
25
- "@shopgate/pwa-ui-shared": "7.29.2-beta.2",
20
+ "@shopgate/pwa-common": "7.29.3-alpha.2",
21
+ "@shopgate/pwa-common-commerce": "7.29.3-alpha.2",
22
+ "@shopgate/pwa-core": "7.29.3-alpha.2",
23
+ "@shopgate/pwa-ui-ios": "7.29.3-alpha.2",
24
+ "@shopgate/pwa-ui-material": "7.29.3-alpha.2",
25
+ "@shopgate/pwa-ui-shared": "7.29.3-alpha.2",
26
26
  "@stripe/react-stripe-js": "^1.16.5",
27
27
  "@stripe/stripe-js": "^1.3.1",
28
28
  "@virtuous/conductor": "~2.5.0",
@@ -1,4 +1,4 @@
1
- import _regeneratorRuntime from"@babel/runtime/regenerator";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 asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value);}else{Promise.resolve(value).then(_next,_throw);}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value);}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err);}_next(undefined);});};}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{useContext,useMemo,useCallback,useEffect,useState}from'react';import{useSelector,useDispatch}from'react-redux';import{WidgetContext}from'@shopgate/engage/page/components/Widgets';import{ITEMS_PER_LOAD}from'@shopgate/engage/core/constants';import{transformDisplayOptions}from'@shopgate/engage/core/helpers';import{fetchProductsByQuery}from'@shopgate/engage/product';import{makeGetWidgetProducts}from"../selectors";/**
1
+ import _regeneratorRuntime from"@babel/runtime/regenerator";function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value);}else{Promise.resolve(value).then(_next,_throw);}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value);}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err);}_next(undefined);});};}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{useContext,useMemo,useCallback,useEffect,useState}from'react';import{useSelector,useDispatch}from'react-redux';import{WidgetContext}from'@shopgate/engage/page/components/Widgets';import{showInventoryInLists}from'@shopgate/engage/locations/helpers';import{ITEMS_PER_LOAD}from'@shopgate/engage/core/constants';import{transformDisplayOptions}from'@shopgate/engage/core/helpers';import{fetchProductsByQuery}from'@shopgate/engage/product';import{makeGetWidgetProducts}from"../selectors";/**
2
2
  * @typedef {import('../components/Widgets/WidgetContext').WidgetContextType WidgetContextType}
3
3
  */ /**
4
4
  * @typedef {import('./index').UseWidgetProductsOptions} UseWidgetProductsOptions
@@ -12,18 +12,18 @@ import _regeneratorRuntime from"@babel/runtime/regenerator";function _extends(){
12
12
  * @param {UseWidgetProductsOptions} options Hook options
13
13
  * @returns {UseWidgetProductsResult} The products and a function to fetch more products.
14
14
  */export var useWidgetProducts=function useWidgetProducts(){var options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var type=options.type,value=options.value,_options$limit=options.limit,limit=_options$limit===void 0?ITEMS_PER_LOAD:_options$limit,_options$sort=options.sort,sort=_options$sort===void 0?'relevance':_options$sort;var dispatch=useDispatch();var _useWidget=useWidget(),_useWidget$code=_useWidget.code,code=_useWidget$code===void 0?"".concat(type,"_").concat(value,"_").concat(limit,"_").concat(sort):_useWidget$code,isPreview=_useWidget.isPreview;// ###### Products selection ######
15
- var selectorOptions=useMemo(function(){return{sort:transformDisplayOptions(sort),value:value,useDefaultRequestForProductIds:true};},[sort,value]);var getWidgetProducts=useMemo(function(){return makeGetWidgetProducts(type,selectorOptions,code);},[code,selectorOptions,type]);var widgetProducts=useSelector(getWidgetProducts);// ###### Products request ######
15
+ var showInventoryInProductLists=useSelector(showInventoryInLists);var selectorOptions=useMemo(function(){return _extends({sort:transformDisplayOptions(sort),value:value,useDefaultRequestForProductIds:true},showInventoryInProductLists&&{useDefaultRequestForProductIds:true});},[showInventoryInProductLists,sort,value]);var getWidgetProducts=useMemo(function(){return makeGetWidgetProducts(type,selectorOptions,code);},[code,selectorOptions,type]);var widgetProducts=useSelector(getWidgetProducts);// ###### Products request ######
16
16
  // Outside the preview mode the offset and hasNext state are initialized based on previously
17
17
  // fetched product data. That ensures that users see the same product list when they leave
18
18
  // the page and come back later.
19
- var _useState=useState(isPreview?0:widgetProducts.products.length),_useState2=_slicedToArray(_useState,2),offset=_useState2[0],setOffset=_useState2[1];var _useState3=useState(isPreview?true:widgetProducts.totalProductCount>widgetProducts.products.length),_useState4=_slicedToArray(_useState3,2),hasNext=_useState4[0],setHasNext=_useState4[1];var isFetching=widgetProducts.isFetching;var baseRequestOptions=useMemo(function(){return{limit:limit,sort:transformDisplayOptions(sort),useDefaultRequestForProductIds:true};},[limit,sort]);/**
19
+ var _useState=useState(isPreview?0:widgetProducts.products.length),_useState2=_slicedToArray(_useState,2),offset=_useState2[0],setOffset=_useState2[1];var _useState3=useState(isPreview?true:widgetProducts.totalProductCount>widgetProducts.products.length),_useState4=_slicedToArray(_useState3,2),hasNext=_useState4[0],setHasNext=_useState4[1];var isFetching=widgetProducts.isFetching;var baseRequestOptions=useMemo(function(){return _extends({limit:limit,sort:transformDisplayOptions(sort),useDefaultRequestForProductIds:true},showInventoryInProductLists&&{useDefaultRequestForProductIds:true});},[limit,showInventoryInProductLists,sort]);/**
20
20
  * Callback to dispatch the initial fetch request for products when the hook mounts,
21
21
  * or when its parameters change.
22
- */var fetchInitial=useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(){var _ref2;var initialOptions,result;return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:if(value){_context.next=3;break;}setHasNext(false);return _context.abrupt("return");case 3:// Initial request needs to start at offset 0
22
+ */var fetchInitial=useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(){var _result$totalProductC;var initialOptions,result;return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:if(value){_context.next=3;break;}setHasNext(false);return _context.abrupt("return");case 3:// Initial request needs to start at offset 0
23
23
  initialOptions=_extends({},baseRequestOptions,{offset:0});_context.next=6;return dispatch(fetchProductsByQuery(REQUEST_TYPE_MAPPING[type],value,initialOptions,code));case 6:result=_context.sent;// Re-initialize offset and hasNext based on the result
24
24
  setOffset(limit);// When the result comes from a real pipeline request there will be "totalProductCount".
25
25
  // When the result are cached products, it can also be "totalResultCount".
26
- setHasNext(((_ref2=result===null||result===void 0?void 0:result.totalProductCount)!==null&&_ref2!==void 0?_ref2:result===null||result===void 0?void 0:result.totalResultCount)>limit);case 9:case"end":return _context.stop();}},_callee);})),[code,dispatch,type,value,limit,baseRequestOptions]);// Effect to trigger the initial fetch when the component mounts or the parameters change.
26
+ setHasNext(((_result$totalProductC=result.totalProductCount)!==null&&_result$totalProductC!==void 0?_result$totalProductC:result.totalResultCount)>limit);case 9:case"end":return _context.stop();}},_callee);})),[code,dispatch,type,value,limit,baseRequestOptions]);// Effect to trigger the initial fetch when the component mounts or the parameters change.
27
27
  useEffect(function(){if(!isPreview&&offset===0||isPreview){fetchInitial();}// This effect should only run at first render or when the fetchInitial callback updates.
28
28
  // fetchInitial will never be updated on a real "page" at runtime since its dependencies
29
29
  // are static.
@@ -32,6 +32,6 @@ useEffect(function(){if(!isPreview&&offset===0||isPreview){fetchInitial();}// Th
32
32
  },[fetchInitial]);/**
33
33
  * Callback to fetch the next chunk of products when e.g. users interacted with a "Load More"
34
34
  * button.
35
- */var fetchNext=useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(){var _ref4;var nextOptions,result;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:if(!(!hasNext||isFetching||!value)){_context2.next=2;break;}return _context2.abrupt("return");case 2:nextOptions=_extends({},baseRequestOptions,{offset:offset});_context2.next=5;return dispatch(fetchProductsByQuery(REQUEST_TYPE_MAPPING[type],value,nextOptions,code));case 5:result=_context2.sent;setOffset(offset+limit);// When the result comes from a real pipeline request there will be "totalProductCount".
35
+ */var fetchNext=useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(){var _result$totalProductC2;var nextOptions,result;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:if(!(!hasNext||isFetching||!value)){_context2.next=2;break;}return _context2.abrupt("return");case 2:nextOptions=_extends({},baseRequestOptions,{offset:offset});_context2.next=5;return dispatch(fetchProductsByQuery(REQUEST_TYPE_MAPPING[type],value,nextOptions,code));case 5:result=_context2.sent;setOffset(offset+limit);// When the result comes from a real pipeline request there will be "totalProductCount".
36
36
  // When the result are cached products, it can also be "totalResultCount".
37
- setHasNext(((_ref4=result===null||result===void 0?void 0:result.totalProductCount)!==null&&_ref4!==void 0?_ref4:result===null||result===void 0?void 0:result.totalResultCount)>offset+limit);case 8:case"end":return _context2.stop();}},_callee2);})),[code,dispatch,hasNext,isFetching,value,offset,limit,baseRequestOptions,type]);return{fetchNext:fetchNext,hasNext:hasNext,isFetching:isFetching,results:widgetProducts.products.slice(0,offset),totalResultCount:widgetProducts.totalProductCount};};
37
+ setHasNext(((_result$totalProductC2=result.totalProductCount)!==null&&_result$totalProductC2!==void 0?_result$totalProductC2:result.totalResultCount)>offset+limit);case 8:case"end":return _context2.stop();}},_callee2);})),[code,dispatch,hasNext,isFetching,value,offset,limit,baseRequestOptions,type]);return{fetchNext:fetchNext,hasNext:hasNext,isFetching:isFetching,results:widgetProducts.products.slice(0,offset),totalResultCount:widgetProducts.totalProductCount};};
@@ -1,4 +1,4 @@
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{createSelector}from'reselect';import{makeGetMenu,makeGetIsFetchingMenu,getEnableCms2ForAllShoppers}from'@shopgate/engage/core/selectors';import{getFulfillmentParams,getPopulatedProductsResult,SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS}from'@shopgate/engage/product';import{getProductState}from'@shopgate/engage/product/selectors/product';import{LEGAL_MENU}from'@shopgate/engage/core/constants';import{hasNewServices,transformDisplayOptions,generateResultHash}from'@shopgate/engage/core/helpers';import{getIsCMS2PreviewEnabled}from'@shopgate/engage/development/selectors';import{makeGetPageConfigById}from'@shopgate/pwa-common/selectors/page';import{PRIVACY_PATH}from"../constants";export*from'@shopgate/pwa-common/selectors/page';/**
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{createSelector}from'reselect';import{makeGetMenu,makeGetIsFetchingMenu,getEnableCms2ForAllShoppers}from'@shopgate/engage/core/selectors';import{getFulfillmentParams,getPopulatedProductsResult,SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS}from'@shopgate/engage/product';import{getProductState}from'@shopgate/engage/product/selectors/product';import{LEGAL_MENU,SORT_PRICE_ASC,SORT_PRICE_DESC}from'@shopgate/engage/core/constants';import{hasNewServices,transformDisplayOptions,generateResultHash}from'@shopgate/engage/core/helpers';import{getIsCMS2PreviewEnabled}from'@shopgate/engage/development/selectors';import{makeGetPageConfigById}from'@shopgate/pwa-common/selectors/page';import{PRIVACY_PATH}from"../constants";export*from'@shopgate/pwa-common/selectors/page';/**
2
2
  * Creates a selector that retrieves the privacy policy link.
3
3
  *
4
4
  * When the new services are active, the link is extracted from the "shopgate.cms.getMenu" response.
@@ -43,7 +43,7 @@ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<argum
43
43
  * @param {Object} options Request options
44
44
  * @param {string} id Unique identifier to find the result in the state.
45
45
  * @returns {Function} A selector function that generates a hash for the widget products result.
46
- */var makeGetWidgetProductsResultHash=function makeGetWidgetProductsResultHash(type,options,id){var value=options.value,sort=options.sort,productIdType=options.productIdType;var transformedSort=transformDisplayOptions(sort);return createSelector(getFulfillmentParams,function(fulfillmentParams){var _hashParams;var hashParams={};switch(type){case'highlights':hashParams={id:id,pipeline:SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS,sort:transformedSort};break;case'searchTerm':case'brand':hashParams=_extends({id:id,searchPhrase:value,sort:transformedSort},fulfillmentParams);break;case'productIds':hashParams=_extends({id:id,productIds:value,productIdType:productIdType,sort:transformedSort},fulfillmentParams);break;case'category':hashParams=_extends({id:id,categoryId:value,sort:transformedSort},fulfillmentParams);break;default:}return generateResultHash(hashParams,!!((_hashParams=hashParams)===null||_hashParams===void 0?void 0:_hashParams.sort),false);});};/**
46
+ */var makeGetWidgetProductsResultHash=function makeGetWidgetProductsResultHash(type,options,id){var value=options.value,sort=options.sort,useDefaultRequestForProductIds=options.useDefaultRequestForProductIds,productIdType=options.productIdType;var transformedSort=transformDisplayOptions(sort);return createSelector(getFulfillmentParams,function(fulfillmentParams){var _hashParams;var hashParams={};switch(type){case'highlights':hashParams={id:id,pipeline:SHOPGATE_CATALOG_GET_HIGHLIGHT_PRODUCTS,sort:transformedSort};break;case'searchTerm':case'brand':hashParams=_extends({id:id,searchPhrase:value,sort:transformedSort},fulfillmentParams);break;case'productIds':hashParams=_extends({id:id,productIds:value,productIdType:productIdType},!useDefaultRequestForProductIds&&{sort:transformedSort},{},fulfillmentParams);break;case'category':hashParams=_extends({id:id,categoryId:value,sort:transformedSort},fulfillmentParams);break;default:}return generateResultHash(hashParams,!!((_hashParams=hashParams)===null||_hashParams===void 0?void 0:_hashParams.sort),false);});};/**
47
47
  * @param {'searchTerm' | 'productIds' | 'brand' | 'category' |'highlights'} type Type of the
48
48
  * request to make.
49
49
  * @param {Object} options Request options
@@ -56,4 +56,6 @@ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<argum
56
56
  * @param {Object} options Request options
57
57
  * @param {string} id Unique identifier to find the result in the state.
58
58
  * @returns {Function} A selector function that collects products for a widget.
59
- */export var makeGetWidgetProducts=function makeGetWidgetProducts(type,options,id){var getWidgetProductResultsHash=makeGetWidgetProductsResultHash(type,options,id);var getWidgetProductResultsByHash=makeGetWidgetProductResultsByHash(type,options,id);return createSelector(function(state){return state;},function(state,props){return props!==null&&props!==void 0?props:{};},getWidgetProductResultsHash,getWidgetProductResultsByHash,function(state,props,resultsHash,resultsByHash){return _extends({isFetching:(resultsByHash===null||resultsByHash===void 0?void 0:resultsByHash.isFetching)||false},getPopulatedProductsResult(state,props,resultsHash,resultsByHash));});};
59
+ */export var makeGetWidgetProducts=function makeGetWidgetProducts(type,options,id){var getWidgetProductResultsHash=makeGetWidgetProductsResultHash(type,options,id);var getWidgetProductResultsByHash=makeGetWidgetProductResultsByHash(type,options,id);return createSelector(function(state){return state;},function(state,props){return props!==null&&props!==void 0?props:{};},getWidgetProductResultsHash,getWidgetProductResultsByHash,function(state,props,resultsHash,resultsByHash){var result=_extends({isFetching:(resultsByHash===null||resultsByHash===void 0?void 0:resultsByHash.isFetching)||false},getPopulatedProductsResult(state,props,resultsHash,resultsByHash));// Since the getProducts pipeline does not support sorting when a product ID list is
60
+ // provided, we need to sort the products manually here.
61
+ if(type==='productIds'){if(options.sort===SORT_PRICE_ASC){result.products=result.products.sort(function(p1,p2){return p1.price.unitPrice-p2.price.unitPrice;});}if(options.sort===SORT_PRICE_DESC){result.products=result.products.sort(function(p1,p2){return p2.price.unitPrice-p1.price.unitPrice;});}}return result;});};
@@ -1,7 +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 React,{useCallback}from'react';import{ActionButton,I18n}from'@shopgate/engage/components';import{ProductGrid}from'@shopgate/engage/product/components';import{useWidgetProducts}from'@shopgate/engage/page/hooks';import{makeStyles}from'@shopgate/engage/styles';import{useProductListWidget}from"./hooks";import WidgetHeadline from"../../components/WidgetHeadline";var useStyles=makeStyles()({root:{// Prevent that the ActionButton margin messes with the layout of the sibling widgets
1
+ import React from'react';import{ActionButton,I18n}from'@shopgate/engage/components';import{ProductGrid}from'@shopgate/engage/product/components';import{useWidgetProducts}from'@shopgate/engage/page/hooks';import{makeStyles}from'@shopgate/engage/styles';import{useProductListWidget}from"./hooks";import WidgetHeadline from"../../components/WidgetHeadline";var useStyles=makeStyles()({root:{// Prevent that the ActionButton margin messes with the layout of the sibling widgets
2
2
  overflow:'hidden'},grid:{'&&':{marginTop:0}}});/**
3
3
  * The ProductListWidget is used to display product lists.
4
4
  * @returns {JSX.Element}
5
- */var ProductListWidget=function ProductListWidget(){var _useStyles=useStyles(),classes=_useStyles.classes;var _useProductListWidget=useProductListWidget(),productsSearchType=_useProductListWidget.productsSearchType,productsSearchValue=_useProductListWidget.productsSearchValue,sort=_useProductListWidget.sort,productCount=_useProductListWidget.productCount,showLoadMore=_useProductListWidget.showLoadMore,flags=_useProductListWidget.flags,showHeadline=_useProductListWidget.showHeadline,headline=_useProductListWidget.headline,isPreview=_useProductListWidget.isPreview;var _useWidgetProducts=useWidgetProducts({type:productsSearchType,value:productsSearchValue,limit:productCount,sort:sort}),fetchNext=_useWidgetProducts.fetchNext,hasNext=_useWidgetProducts.hasNext,isFetching=_useWidgetProducts.isFetching,results=_useWidgetProducts.results;var handleFetchNext=useCallback(function(e){if(isPreview){// Prevent unintended scroll effects when load more is clicked in preview.
6
- e.stopPropagation();}fetchNext();},[fetchNext,isPreview]);return React.createElement("div",{className:classes.root},showHeadline&&headline&&results.length?React.createElement(WidgetHeadline,{headline:headline}):null,React.createElement(ProductGrid,{products:results,flags:flags,scope:"widgets",infiniteLoad:false,className:classes.grid}),hasNext&&showLoadMore&&React.createElement(ActionButton,_extends({loading:isFetching,onClick:handleFetchNext// Disable click delay in preview mode to enable stopping of propagation.
7
- },isPreview&&{disableClickDelay:true}),React.createElement(I18n.Text,{string:"common.load_more"})));};export default ProductListWidget;
5
+ */var ProductListWidget=function ProductListWidget(){var _useStyles=useStyles(),classes=_useStyles.classes;var _useProductListWidget=useProductListWidget(),productsSearchType=_useProductListWidget.productsSearchType,productsSearchValue=_useProductListWidget.productsSearchValue,sort=_useProductListWidget.sort,productCount=_useProductListWidget.productCount,showLoadMore=_useProductListWidget.showLoadMore,flags=_useProductListWidget.flags,showHeadline=_useProductListWidget.showHeadline,headline=_useProductListWidget.headline;var _useWidgetProducts=useWidgetProducts({type:productsSearchType,value:productsSearchValue,limit:productCount,sort:sort}),fetchNext=_useWidgetProducts.fetchNext,hasNext=_useWidgetProducts.hasNext,isFetching=_useWidgetProducts.isFetching,results=_useWidgetProducts.results;return React.createElement("div",{className:classes.root},showHeadline&&headline&&results.length?React.createElement(WidgetHeadline,{headline:headline}):null,React.createElement(ProductGrid,{products:results,flags:flags,scope:"widgets",infiniteLoad:false,className:classes.grid}),hasNext&&showLoadMore&&React.createElement(ActionButton,{loading:isFetching,onClick:fetchNext},React.createElement(I18n.Text,{string:"common.load_more"})));};export default ProductListWidget;
@@ -18,4 +18,4 @@ import _camelCase from"lodash/camelCase";function _extends(){_extends=Object.ass
18
18
  */ // eslint-disable-next-line valid-jsdoc
19
19
  /**
20
20
  * Hook to access the Product List widget configuration.
21
- */export var useProductListWidget=function useProductListWidget(){/** @type {UseWidgetReturnType} */var _useWidget=useWidget(),config=_useWidget.config,isPreview=_useWidget.isPreview;var products=config.products,productCount=config.productCount,sort=config.sort,_config$loadMoreButto=config.loadMoreButton,loadMoreButton=_config$loadMoreButto===void 0?false:_config$loadMoreButto,_config$showName=config.showName,showName=_config$showName===void 0?false:_config$showName,_config$showPrice=config.showPrice,showPrice=_config$showPrice===void 0?false:_config$showPrice,_config$showRating=config.showRating,showRating=_config$showRating===void 0?false:_config$showRating,_config$showHeadline=config.showHeadline,showHeadline=_config$showHeadline===void 0?false:_config$showHeadline,headline=config.headline;var productSearchParams=useMemo(function(){return getProductSearchParamsFromProductsInputConfig(products);},[products]);var flags=useMemo(function(){return{name:showName,price:showPrice,reviews:showRating};},[showName,showPrice,showRating]);return _extends({},productSearchParams,{sort:_camelCase(sort),productCount:productCount,showLoadMore:loadMoreButton,flags:flags,showHeadline:showHeadline,headline:headline,isPreview:isPreview});};
21
+ */export var useProductListWidget=function useProductListWidget(){/** @type {UseWidgetReturnType} */var _useWidget=useWidget(),config=_useWidget.config;var products=config.products,productCount=config.productCount,sort=config.sort,_config$loadMoreButto=config.loadMoreButton,loadMoreButton=_config$loadMoreButto===void 0?false:_config$loadMoreButto,_config$showName=config.showName,showName=_config$showName===void 0?false:_config$showName,_config$showPrice=config.showPrice,showPrice=_config$showPrice===void 0?false:_config$showPrice,_config$showRating=config.showRating,showRating=_config$showRating===void 0?false:_config$showRating,_config$showHeadline=config.showHeadline,showHeadline=_config$showHeadline===void 0?false:_config$showHeadline,headline=config.headline;var productSearchParams=useMemo(function(){return getProductSearchParamsFromProductsInputConfig(products);},[products]);var flags=useMemo(function(){return{name:showName,price:showPrice,reviews:showRating};},[showName,showPrice,showRating]);return _extends({},productSearchParams,{sort:_camelCase(sort),productCount:productCount,showLoadMore:loadMoreButton,flags:flags,showHeadline:showHeadline,headline:headline});};
@@ -1,7 +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;}import React,{useEffect,useMemo,useState}from'react';import{makeStyles}from'@shopgate/engage/styles';import{useReduceMotion}from'@shopgate/engage/a11y/hooks';import{usePrevious,useAppEventOnReturnFromBackground}from'@shopgate/engage/core/hooks';import{useVideoWidget}from"./hooks";import{isHttpsUrl}from"../../helpers";var useStyles=makeStyles()(function(_theme,_ref){var borderRadius=_ref.borderRadius;return{root:{width:'100%',display:'flex',overflow:'hidden',borderRadius:borderRadius},video:{// Add 1px to the width to prevent visible horizontal hairlines on some browsers
2
- width:'calc(100% + 2px)'}};});/**
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,{useEffect,useMemo,useState}from'react';import{makeStyles}from'@shopgate/engage/styles';import{useReduceMotion}from'@shopgate/engage/a11y/hooks';import{usePrevious}from'@shopgate/engage/core';import{useVideoWidget}from"./hooks";import{isHttpsUrl}from"../../helpers";var useStyles=makeStyles()(function(_theme,_ref){var borderRadius=_ref.borderRadius;return{video:{width:'100%',borderRadius:borderRadius}};});/**
3
2
  * The VideoWidget is used to display a video.
4
3
  * @returns {JSX.Element}
5
- */var Video=function Video(){var _useVideoWidget=useVideoWidget(),url=_useVideoWidget.url,muted=_useVideoWidget.muted,loop=_useVideoWidget.loop,controls=_useVideoWidget.controls,autoplay=_useVideoWidget.autoplay,borderRadius=_useVideoWidget.borderRadius;var _useStyles=useStyles({borderRadius:borderRadius}),classes=_useStyles.classes;var reduceMotion=useReduceMotion();var _useState=useState(false),_useState2=_slicedToArray(_useState,2),hasError=_useState2[0],setHasError=_useState2[1];var videoRef=React.useRef(null);var prevUrl=usePrevious(url);var isValidUrl=useMemo(function(){return url?isHttpsUrl(url):false;},[url]);// Resume video playback when app returned from background
6
- useAppEventOnReturnFromBackground(function(){if(!videoRef.current||reduceMotion||!autoplay){return;}videoRef.current.play();});useEffect(function(){if(!videoRef.current||reduceMotion){return;}if(autoplay){videoRef.current.play();}else{videoRef.current.pause();videoRef.current.currentTime=0;}},[autoplay,reduceMotion]);useEffect(function(){if(!url||url!==prevUrl){setHasError(false);}},[hasError,prevUrl,url]);if(!url||hasError||!isValidUrl)return null;return React.createElement("div",{className:classes.root},React.createElement("video",{ref:videoRef// Set play position to 0.001s to guarantee that there is always a frame shown
7
- ,src:"".concat(url,"#t=0.001"),muted:muted,controls:!autoplay||reduceMotion?true:controls,autoPlay:reduceMotion?false:autoplay,className:classes.video,preload:"auto",playsInline:true,loop:loop,"aria-hidden":true,onError:function onError(){setHasError(true);}},React.createElement("track",{kind:"captions",src:"",srcLang:"de",label:"Deutsch"})));};export default Video;
4
+ */var Video=function Video(){var _useVideoWidget=useVideoWidget(),url=_useVideoWidget.url,muted=_useVideoWidget.muted,loop=_useVideoWidget.loop,controls=_useVideoWidget.controls,autoplay=_useVideoWidget.autoplay,borderRadius=_useVideoWidget.borderRadius;var _useStyles=useStyles({borderRadius:borderRadius}),classes=_useStyles.classes;var reduceMotion=useReduceMotion();var _useState=useState(false),_useState2=_slicedToArray(_useState,2),hasError=_useState2[0],setHasError=_useState2[1];var videoRef=React.useRef(null);var prevAutoPlay=usePrevious(autoplay);var prevUrl=usePrevious(url);var isValidUrl=useMemo(function(){return url?isHttpsUrl(url):false;},[url]);useEffect(function(){if(videoRef.current&&prevAutoPlay&&!autoplay){videoRef.current.pause();videoRef.current.currentTime=0;}if(videoRef.current&&!prevAutoPlay&&autoplay){videoRef.current.play();}if(!url||url!==prevUrl||!hasError){setHasError(false);}},[autoplay,hasError,prevAutoPlay,prevUrl,url]);if(!url||hasError||!isValidUrl)return null;return React.createElement("video",{ref:videoRef,src:url,muted:muted,controls:!autoplay||reduceMotion?true:controls,autoPlay:reduceMotion?false:autoplay,className:classes.video,preload:"auto",playsInline:true,loop:loop,"aria-hidden":true,onError:function onError(){return setHasError(true);}},React.createElement("track",{kind:"captions",src:"",srcLang:"de",label:"Deutsch"}));};export default Video;
@@ -1,83 +0,0 @@
1
- /**
2
- * Additional options for app event hooks.
3
- */
4
- export interface AppEventOptions {
5
- /**
6
- * When false, no listener is registered.
7
- * @default true
8
- */
9
- enabled?: boolean;
10
- /**
11
- * When true, the callback is removed after first call.
12
- * @default false
13
- */
14
- once?: boolean;
15
- }
16
-
17
- /**
18
- * Extended options for return-from-background hook.
19
- */
20
- export interface ReturnFromBackgroundOptions extends AppEventOptions {
21
- /**
22
- * If true, requires a new background event to re-arm before firing again.
23
- * If false, remains armed until disabled or unmounted.
24
- * @default true
25
- */
26
- resetAfterFire?: boolean;
27
- }
28
-
29
- /**
30
- * Registers a callback for a given event from the Shopgate app event bus.
31
- *
32
- * Automatically unsubscribes on unmount. Can optionally run only once.
33
- *
34
- * @param name The event name to subscribe to.
35
- * @param callback The function to call when the event fires.
36
- * @param options Additional options.
37
- */
38
- export declare function useAppEvent(
39
- name: string,
40
- callback: () => void,
41
- options?: AppEventOptions
42
- ): void;
43
-
44
- /**
45
- * Registers a callback that fires when the app will enter foreground.
46
- *
47
- * Automatically unsubscribes on unmount.
48
- *
49
- * @param callback The callback to run when entering foreground.
50
- * @param options Additional options.
51
- */
52
- export declare function useAppEventOnEnterForeground(
53
- callback: () => void,
54
- options?: AppEventOptions
55
- ): void;
56
-
57
- /**
58
- * Registers a callback that fires when the app did enter background.
59
- *
60
- * Automatically unsubscribes on unmount.
61
- *
62
- * @param callback The callback to run when entering background.
63
- * @param options Additional options.
64
- */
65
- export declare function useAppEventOnDidEnterBackground(
66
- callback: () => void,
67
- options?: AppEventOptions
68
- ): void;
69
-
70
- /**
71
- * Invokes a callback only after the app was first sent to background and then
72
- * returns to the foreground — i.e. a complete background → foreground cycle.
73
- *
74
- * Common use case: user leaves the app to open system settings and returns, so you
75
- * can re-check permissions or refresh data.
76
- *
77
- * @param callback The callback to run after returning from background.
78
- * @param options Additional options.
79
- */
80
- export declare function useAppEventOnReturnFromBackground(
81
- callback: () => void,
82
- options?: ReturnFromBackgroundOptions
83
- ): void;
@@ -1,58 +0,0 @@
1
- import{useEffect,useRef}from'react';import{APP_EVENT_APPLICATION_WILL_ENTER_FOREGROUND,APP_EVENT_APPLICATION_DID_ENTER_BACKGROUND}from'@shopgate/engage/core/constants';import{event}from'@shopgate/engage/core/classes';/**
2
- * Returns a stable reference to the given callback, preserving the same function identity
3
- * across renders, while still always calling the latest version of the callback.
4
- *
5
- * Useful when passing callbacks into event listeners or effects so they don't re-subscribe
6
- * on every render but still access up-to-date props/state.
7
- *
8
- * @param {Function} fn The callback function whose latest version should be retained.
9
- * @returns {Function} A stable function reference that always invokes the latest callback.
10
- */function useStableCallback(fn){var ref=useRef(fn);ref.current=fn;var stable=useRef(function(){var _ref$current;for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return(_ref$current=ref.current)===null||_ref$current===void 0?void 0:_ref$current.call.apply(_ref$current,[ref].concat(args));});return stable.current;}/**
11
- * Registers a callback for a given event from the Shopgate app event bus.
12
- *
13
- * Automatically unsubscribes on unmount. Can optionally run only once.
14
- *
15
- * @param {string} name The event name to subscribe to.
16
- * @param {Function} callback The function to call when the event fires.
17
- * @param {Object} [options] Additional options.
18
- * @param {boolean} [options.enabled=true] When false, no listener is registered.
19
- * @param {boolean} [options.once=false] When true, the callback is removed after first call.
20
- */export function useAppEvent(name,callback){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var _options$enabled=options.enabled,enabled=_options$enabled===void 0?true:_options$enabled,_options$once=options.once,once=_options$once===void 0?false:_options$once;var latest=useStableCallback(callback);useEffect(function(){if(!enabled)return undefined;// eslint-disable-next-line require-jsdoc
21
- var handler=function handler(){latest();if(once)event.removeCallback(name,handler);};event.addCallback(name,handler);return function(){return event.removeCallback(name,handler);};},[name,enabled,once,latest]);}/**
22
- * Registers a callback that fires when the app will enter foreground
23
- * (`applicationWillEnterForeground`).
24
- *
25
- * Automatically unsubscribes on unmount. Accepts same options as `useAppEvent`.
26
- *
27
- * @param {Function} callback The callback to run when entering foreground.
28
- * @param {Object} [options] Additional options.
29
- * @param {boolean} [options.enabled=true] When false, the listener is not registered.
30
- * @param {boolean} [options.once=false] Remove after first call.
31
- */export function useAppEventOnEnterForeground(callback,options){useAppEvent(APP_EVENT_APPLICATION_WILL_ENTER_FOREGROUND,callback,options);}/**
32
- * Registers a callback that fires when the app did enter background
33
- * (`applicationDidEnterBackground`).
34
- ** Automatically unsubscribes on unmount. Accepts same options as `useAppEvent`.
35
- *
36
- * @param {Function} callback The callback to run when entering background.
37
- * @param {Object} [options] Additional options.
38
- * @param {boolean} [options.enabled=true] When false, the listener is not registered.
39
- * @param {boolean} [options.once=false] Remove after first call.
40
- */export function useAppEventOnDidEnterBackground(callback,options){useAppEvent(APP_EVENT_APPLICATION_DID_ENTER_BACKGROUND,callback,options);}/**
41
- * Invokes a callback only after the app was first sent to background and then
42
- * returns to the foreground — i.e. a complete background → foreground cycle.
43
- *
44
- * Common use case: user leaves the app to open system settings and returns, so you
45
- * can re-check permissions or refresh data.
46
- *
47
- * Internally, this subscribes to both background and foreground events:
48
- * - Arms itself when entering background
49
- * - Fires on next foreground if armed
50
- *
51
- * @param {Function} callback The callback to run after returning from background.
52
- * @param {Object} [options] Additional options.
53
- * @param {boolean} [options.enabled=true] When false, no listener behavior is active.
54
- * @param {boolean} [options.once=false] When true, callback fires only for the first cycle.
55
- * @param {boolean} [options.resetAfterFire=true]
56
- * If true, requires a new background event to re-arm before firing again.
57
- * If false, remains armed until disabled or unmounted.
58
- */export function useAppEventOnReturnFromBackground(callback){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var _options$enabled2=options.enabled,enabled=_options$enabled2===void 0?true:_options$enabled2,_options$once2=options.once,once=_options$once2===void 0?false:_options$once2,_options$resetAfterFi=options.resetAfterFire,resetAfterFire=_options$resetAfterFi===void 0?true:_options$resetAfterFi;var armedRef=useRef(false);var firedOnceRef=useRef(false);var latest=useStableCallback(callback);useAppEventOnDidEnterBackground(function(){if(!enabled)return;if(once&&firedOnceRef.current)return;armedRef.current=true;},{enabled:enabled});useAppEventOnEnterForeground(function(){if(!enabled)return;if(once&&firedOnceRef.current)return;if(armedRef.current){latest();if(once)firedOnceRef.current=true;if(resetAfterFire)armedRef.current=false;}},{enabled:enabled});}