@shopgate/engage 7.28.0 → 7.29.0-alpha.10

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.
Files changed (167) hide show
  1. package/category/components/CategoryImage/index.js +1 -1
  2. package/category/components/CategoryList/index.js +7 -3
  3. package/category/components/CategoryList/style.js +1 -1
  4. package/components/ResponsiveContainer/breakpoints.js +2 -2
  5. package/components/SheetList/components/Item/index.js +7 -7
  6. package/components/Typography/Typography.d.ts +132 -0
  7. package/components/Typography/Typography.js +11 -0
  8. package/components/Typography/index.js +1 -0
  9. package/components/View/components/Content/index.js +4 -1
  10. package/components/View/components/Content/style.js +1 -1
  11. package/components/View/context.js +1 -1
  12. package/components/index.js +2 -2
  13. package/core/constants/index.js +8 -2
  14. package/core/constants/merchantSettings.js +1 -1
  15. package/core/constants/shopSettings.js +1 -1
  16. package/core/contexts/ThemeResourcesContext.d.ts +10 -1
  17. package/core/contexts/ThemeResourcesContext.js +1 -1
  18. package/core/helpers/scrollContainer.js +2 -2
  19. package/core/hocs/withThemeResources.js +4 -1
  20. package/core/hooks/events/index.js +1 -1
  21. package/core/hooks/events/useLongPress.js +1 -1
  22. package/core/hooks/events/usePressHandler.js +38 -0
  23. package/core/hooks/useThemeResources.js +6 -5
  24. package/core/providers/ThemeResourcesProvider.js +9 -5
  25. package/core/reducers/merchantSettings.js +1 -1
  26. package/core/reducers/shopSettings.js +1 -1
  27. package/core/selectors/index.js +1 -1
  28. package/core/selectors/merchantSettings.js +5 -2
  29. package/core/selectors/shopSettings.js +5 -2
  30. package/development/action-creators/settings.js +6 -2
  31. package/development/components/ClientInformation/ClientInformation.js +5 -0
  32. package/development/components/ClientInformation/actions.js +4 -0
  33. package/development/components/ClientInformation/index.js +1 -0
  34. package/development/components/DevelopmentSettings/DevelopmentSettings.js +9 -0
  35. package/development/components/DevelopmentSettings/index.js +1 -0
  36. package/development/components/DevelopmentTools/hooks.js +2 -2
  37. package/development/components/index.js +1 -1
  38. package/development/constants/actionTypes.js +1 -1
  39. package/development/reducers/settings.js +3 -3
  40. package/development/selectors/settings.js +4 -1
  41. package/locations/subscriptions.js +2 -2
  42. package/package.json +9 -7
  43. package/page/action-creators/index.js +22 -0
  44. package/page/components/ResponsiveWidgetImage/ResponsiveWidgetImage.js +7 -0
  45. package/page/components/ResponsiveWidgetImage/index.js +1 -0
  46. package/page/components/WidgetHeadline/WidgetHeadline.js +7 -0
  47. package/page/components/WidgetHeadline/index.js +1 -0
  48. package/page/components/WidgetRichText/WidgetRichText.js +6 -0
  49. package/page/components/WidgetRichText/index.js +1 -0
  50. package/page/components/Widgets/Overlay.js +51 -0
  51. package/page/components/Widgets/Tooltip.js +22 -0
  52. package/page/components/Widgets/Widget.js +17 -0
  53. package/page/components/Widgets/WidgetContext.d.ts +42 -0
  54. package/page/components/Widgets/WidgetContext.js +9 -0
  55. package/page/components/Widgets/WidgetProvider.js +8 -0
  56. package/page/components/Widgets/Widgets.js +11 -0
  57. package/page/components/Widgets/WidgetsPreviewContext.js +9 -0
  58. package/page/components/Widgets/WidgetsPreviewProvider.js +8 -0
  59. package/page/components/Widgets/constants.js +4 -0
  60. package/page/components/Widgets/events.js +23 -0
  61. package/page/components/Widgets/helpers.js +23 -0
  62. package/page/components/Widgets/hooks.js +69 -0
  63. package/page/components/Widgets/index.js +1 -0
  64. package/page/components/Widgets/types.d.ts +132 -0
  65. package/page/components/index.js +1 -1
  66. package/page/constants/actionTypes.js +1 -0
  67. package/page/constants/index.js +5 -1
  68. package/page/helpers/index.d.ts +55 -0
  69. package/page/helpers/index.js +17 -0
  70. package/page/hooks/index.d.ts +60 -0
  71. package/page/hooks/index.js +37 -0
  72. package/page/index.js +1 -2
  73. package/page/reducers/index.js +15 -0
  74. package/page/selectors/index.js +56 -2
  75. package/page/subscriptions/index.js +4 -0
  76. package/page/widgets/CategoryList/CategoryList.js +4 -0
  77. package/page/widgets/CategoryList/hooks.js +16 -0
  78. package/page/widgets/CategoryList/index.js +1 -0
  79. package/page/widgets/CategoryList/selectors.js +8 -0
  80. package/page/widgets/HTML/HTML.js +5 -0
  81. package/page/widgets/HTML/hooks.js +12 -0
  82. package/page/widgets/HTML/index.js +1 -0
  83. package/page/widgets/Headline/Headline.js +4 -0
  84. package/page/widgets/Headline/index.js +1 -0
  85. package/page/widgets/HeroBanner/HeroBanner.js +3 -0
  86. package/page/widgets/HeroBanner/hooks.js +14 -0
  87. package/page/widgets/HeroBanner/index.js +1 -0
  88. package/page/widgets/Image/Image.js +4 -0
  89. package/page/widgets/Image/hooks.js +19 -0
  90. package/page/widgets/Image/index.js +1 -0
  91. package/page/widgets/ImageRow/ImageRow.js +4 -0
  92. package/page/widgets/ImageRow/hooks.js +15 -0
  93. package/page/widgets/ImageRow/index.js +1 -0
  94. package/page/widgets/ImageSlider/ImageSlider.js +4 -0
  95. package/page/widgets/ImageSlider/hooks.js +33 -0
  96. package/page/widgets/ImageSlider/index.js +1 -0
  97. package/page/widgets/Placeholder/Placeholder.js +5 -0
  98. package/page/widgets/Placeholder/hooks.js +12 -0
  99. package/page/widgets/Placeholder/index.js +1 -0
  100. package/page/widgets/ProductList/ProductList.js +5 -0
  101. package/page/widgets/ProductList/hooks.js +21 -0
  102. package/page/widgets/ProductList/index.js +1 -0
  103. package/page/widgets/ProductSlider/ProductSlider.js +5 -0
  104. package/page/widgets/ProductSlider/hooks.js +24 -0
  105. package/page/widgets/ProductSlider/index.js +1 -0
  106. package/page/widgets/RichText/RichText.js +3 -0
  107. package/page/widgets/RichText/hooks.js +10 -0
  108. package/page/widgets/RichText/index.js +1 -0
  109. package/page/widgets/index.js +1 -0
  110. package/page/widgets/widgets.json +35 -0
  111. package/product/components/ProductCard/index.js +1 -1
  112. package/product/components/ProductGrid/components/Item/components/ItemDetails/index.js +8 -0
  113. package/product/components/ProductGrid/components/Item/components/ItemDetails/spec.js +1 -0
  114. package/product/components/ProductGrid/components/Item/components/ItemDiscount/index.js +5 -0
  115. package/product/components/ProductGrid/components/Item/components/ItemFavoritesButton/index.js +5 -0
  116. package/product/components/ProductGrid/components/Item/components/ItemFavoritesButton/spec.js +1 -0
  117. package/product/components/ProductGrid/components/Item/components/ItemImage/index.js +5 -0
  118. package/product/components/ProductGrid/components/Item/components/ItemImage/spec.js +1 -0
  119. package/product/components/ProductGrid/components/Item/components/ItemName/index.js +5 -0
  120. package/product/components/ProductGrid/components/Item/components/ItemName/spec.js +1 -0
  121. package/product/components/ProductGrid/components/Item/components/ItemPrice/index.js +5 -0
  122. package/product/components/ProductGrid/components/Item/components/ItemPrice/spec.js +1 -0
  123. package/product/components/ProductGrid/components/Item/index.js +7 -0
  124. package/product/components/ProductGrid/components/Iterator/index.js +5 -0
  125. package/product/components/ProductGrid/components/Layout/index.js +5 -0
  126. package/product/components/ProductGrid/index.js +22 -0
  127. package/product/components/ProductGrid/spec.js +1 -0
  128. package/product/components/ProductGridPrice/index.js +1 -1
  129. package/product/components/ProductSlider/index.js +4 -4
  130. package/product/components/index.js +1 -1
  131. package/styles/helpers/color.js +23 -0
  132. package/styles/helpers/index.js +1 -1
  133. package/styles/helpers/setPageBackgroundColor.js +2 -2
  134. package/styles/index.d.ts +17 -0
  135. package/styles/index.js +1 -1
  136. package/styles/theme/createTheme/createBreakpoints.d.ts +114 -0
  137. package/styles/theme/createTheme/createBreakpoints.js +41 -0
  138. package/styles/theme/createTheme/createPalette.d.ts +36 -0
  139. package/styles/theme/createTheme/createPalette.js +4 -0
  140. package/styles/theme/createTheme/createSpacing.d.ts +23 -0
  141. package/styles/theme/createTheme/createSpacing.js +14 -0
  142. package/styles/theme/createTheme/createTypography.d.ts +55 -0
  143. package/styles/theme/createTheme/createTypography.js +23 -0
  144. package/styles/theme/createTheme/index.d.ts +41 -0
  145. package/styles/theme/createTheme/index.js +5 -0
  146. package/styles/theme/createTheme/transitions.d.ts +100 -0
  147. package/styles/theme/createTheme/transitions.js +26 -0
  148. package/styles/theme/createTheme/zIndex.d.ts +12 -0
  149. package/styles/theme/createTheme/zIndex.js +3 -0
  150. package/styles/theme/hooks/index.d.ts +4 -0
  151. package/styles/theme/hooks/index.js +1 -0
  152. package/styles/theme/hooks/useActiveBreakpoint.d.ts +18 -0
  153. package/styles/theme/hooks/useActiveBreakpoint.js +4 -0
  154. package/styles/theme/hooks/useMediaQuery.d.ts +33 -0
  155. package/styles/theme/hooks/useMediaQuery.js +20 -0
  156. package/styles/theme/hooks/useResponsiveValue.d.ts +27 -0
  157. package/styles/theme/hooks/useResponsiveValue.js +4 -0
  158. package/styles/theme/hooks/useTheme.d.ts +8 -0
  159. package/styles/theme/hooks/useTheme.js +4 -0
  160. package/styles/theme/index.d.ts +8 -0
  161. package/styles/theme/index.js +1 -0
  162. package/styles/theme/providers/ActiveBreakpointProvider.d.ts +21 -0
  163. package/styles/theme/providers/ActiveBreakpointProvider.js +13 -0
  164. package/styles/theme/providers/ThemeProvider.d.ts +18 -0
  165. package/styles/theme/providers/ThemeProvider.js +7 -0
  166. package/styles/tss/index.js +3 -0
  167. package/tracking/selectors/cookieConsent.js +2 -2
@@ -1,4 +1,4 @@
1
- import{createSelector}from'reselect';import{MERCHANT_SETTINGS_LOCATION_BASED_SHOPPING_ENABLED,MERCHANT_SETTINGS_SUBSTITUTION_PREFERENCES_ENABLED,MERCHANT_SETTINGS_CUSTOMER_ATTRIBUTES,MERCHANT_SETTINGS_FULFILLMENT_SCHEDULED_ENABLED,MERCHANT_SETTINGS_RESTRICT_MULTI_LOCATION_ORDERS,MERCHANT_SETTINGS_DEFAULT_CURRENCY,MERCHANT_SETTINGS_ENABLE_WEB_INDEXING,MERCHANT_SETTINGS_PRODUCT_SHOW_ALTERNATIVE_LOCATION,MERCHANT_SETTINGS_PRODUCTLIST_SHOW_INVENTORY}from"../constants";/**
1
+ import{createSelector}from'reselect';import{MERCHANT_SETTINGS_LOCATION_BASED_SHOPPING_ENABLED,MERCHANT_SETTINGS_SUBSTITUTION_PREFERENCES_ENABLED,MERCHANT_SETTINGS_CUSTOMER_ATTRIBUTES,MERCHANT_SETTINGS_FULFILLMENT_SCHEDULED_ENABLED,MERCHANT_SETTINGS_RESTRICT_MULTI_LOCATION_ORDERS,MERCHANT_SETTINGS_DEFAULT_CURRENCY,MERCHANT_SETTINGS_ENABLE_WEB_INDEXING,MERCHANT_SETTINGS_PRODUCT_SHOW_ALTERNATIVE_LOCATION,MERCHANT_SETTINGS_PRODUCTLIST_SHOW_INVENTORY,MERCHANT_SETTINGS_ENABLED_CMS_VERSION}from"../constants";/**
2
2
  * Retrieves the merchantSettings state from the store.
3
3
  * @param {Object} state The current application state.
4
4
  * @return {Object} The locations state.
@@ -7,4 +7,7 @@ import{createSelector}from'reselect';import{MERCHANT_SETTINGS_LOCATION_BASED_SHO
7
7
  * @param {string} key The key of the merchant setting
8
8
  * @param {*} [fallback=null] The fallback value when no value can be determined.
9
9
  * @returns {Function}
10
- */var makeGetMerchantSettingByKey=function makeGetMerchantSettingByKey(key){var fallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;return createSelector(getState,function(state){return typeof(state===null||state===void 0?void 0:state[key])!=='undefined'?state===null||state===void 0?void 0:state[key]:fallback;});};export var getIsLocationBasedShopping=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_LOCATION_BASED_SHOPPING_ENABLED,false);export var getSubstitutionPreferencesEnabled=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_SUBSTITUTION_PREFERENCES_ENABLED,false);export var getMerchantCustomerAttributes=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_CUSTOMER_ATTRIBUTES,[]);export var getFulfillmentSchedulingEnabled=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_FULFILLMENT_SCHEDULED_ENABLED,false);export var getRestrictMultiLocationOrders=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_RESTRICT_MULTI_LOCATION_ORDERS,false);export var getDefaultCurrency=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_DEFAULT_CURRENCY);export var getEnableWebIndexing=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_ENABLE_WEB_INDEXING,false);export var getProductShowAlternativeLocation=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_PRODUCT_SHOW_ALTERNATIVE_LOCATION,false);export var getProductListShowInventory=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_PRODUCTLIST_SHOW_INVENTORY,false);
10
+ */var makeGetMerchantSettingByKey=function makeGetMerchantSettingByKey(key){var fallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;return createSelector(getState,function(state){return typeof(state===null||state===void 0?void 0:state[key])!=='undefined'?state===null||state===void 0?void 0:state[key]:fallback;});};export var getIsLocationBasedShopping=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_LOCATION_BASED_SHOPPING_ENABLED,false);export var getSubstitutionPreferencesEnabled=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_SUBSTITUTION_PREFERENCES_ENABLED,false);export var getMerchantCustomerAttributes=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_CUSTOMER_ATTRIBUTES,[]);export var getFulfillmentSchedulingEnabled=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_FULFILLMENT_SCHEDULED_ENABLED,false);export var getRestrictMultiLocationOrders=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_RESTRICT_MULTI_LOCATION_ORDERS,false);export var getDefaultCurrency=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_DEFAULT_CURRENCY);export var getEnableWebIndexing=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_ENABLE_WEB_INDEXING,false);export var getProductShowAlternativeLocation=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_PRODUCT_SHOW_ALTERNATIVE_LOCATION,false);export var getProductListShowInventory=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_PRODUCTLIST_SHOW_INVENTORY,false);/**
11
+ * Selector that retrieves the enabled CMS version.
12
+ * @type {(state: RootState) => "v1" | "v2" | "both"}
13
+ */export var getEnabledCMSVersion=makeGetMerchantSettingByKey(MERCHANT_SETTINGS_ENABLED_CMS_VERSION,'v1');export{getState};
@@ -1,4 +1,4 @@
1
- import{createSelector}from'reselect';import{WISHLIST_MODE_PERSIST_ON_ADD,SHOP_SETTING_WISHLIST_MODE,SHOP_SETTING_IMAGES,SHOP_SETTING_IMAGES_PRODUCT_PLACEHOLDER,SHOP_SETTING_IMAGES_CATEGORY_PLACEHOLDER,SHOP_SETTING_IMAGES_FAVICON,SHOP_SETTING_NUMBER_OF_ADDRESS_LINES,SHOP_SETTING_GOOGLE_SITE_VERIFICATION_CODE,SHOP_SETTINGS_SHOW_CATEGORY_IMAGES,SHOP_SETTING_REGISTRATION_MODE,SHOP_SETTING_REGISTRATION_MODE_EXTENDED,SHOP_SETTING_LOAD_WISHLIST_ON_APP_START_ENABLED,SHOP_SETTING_WISHLIST_ITEM_QUANTITY_ENABLED,SHOP_SETTING_WISHLIST_ITEM_NOTES_ENABLED,SHOP_SETTING_SHOW_WISHLIST_ITEMS_COUNT_BADGE}from"../constants/shopSettings";/**
1
+ import{createSelector}from'reselect';import{WISHLIST_MODE_PERSIST_ON_ADD,SHOP_SETTING_WISHLIST_MODE,SHOP_SETTING_IMAGES,SHOP_SETTING_IMAGES_PRODUCT_PLACEHOLDER,SHOP_SETTING_IMAGES_CATEGORY_PLACEHOLDER,SHOP_SETTING_IMAGES_FAVICON,SHOP_SETTING_NUMBER_OF_ADDRESS_LINES,SHOP_SETTING_GOOGLE_SITE_VERIFICATION_CODE,SHOP_SETTINGS_SHOW_CATEGORY_IMAGES,SHOP_SETTING_REGISTRATION_MODE,SHOP_SETTING_REGISTRATION_MODE_EXTENDED,SHOP_SETTING_LOAD_WISHLIST_ON_APP_START_ENABLED,SHOP_SETTING_WISHLIST_ITEM_QUANTITY_ENABLED,SHOP_SETTING_WISHLIST_ITEM_NOTES_ENABLED,SHOP_SETTING_SHOW_WISHLIST_ITEMS_COUNT_BADGE,SHOP_SETTING_ENABLE_CMS_2_FOR_ALL_SHOPPERS}from"../constants/shopSettings";/**
2
2
  * Retrieves the shopSettings state from the store.
3
3
  * @param {Object} state The current application state.
4
4
  * @return {Object} The locations state.
@@ -22,4 +22,7 @@ import{createSelector}from'reselect';import{WISHLIST_MODE_PERSIST_ON_ADD,SHOP_SE
22
22
  */export var getNumberOfAddressLines=makeGetShopSettingByKey(SHOP_SETTING_NUMBER_OF_ADDRESS_LINES,2);export var getGoogleSiteVerificationCode=makeGetShopSettingByKey(SHOP_SETTING_GOOGLE_SITE_VERIFICATION_CODE,'');export var getShowCategoryImages=makeGetShopSettingByKey(SHOP_SETTINGS_SHOW_CATEGORY_IMAGES,true);/**
23
23
  * Creates a selector to retrieve the current active registration mode.
24
24
  * When the selector returns "simple" the form will not contain any address related fields.
25
- */export var getRegistrationMode=makeGetShopSettingByKey(SHOP_SETTING_REGISTRATION_MODE,SHOP_SETTING_REGISTRATION_MODE_EXTENDED);export var getWishlistItemQuantityEnabled=makeGetShopSettingByKey(SHOP_SETTING_WISHLIST_ITEM_QUANTITY_ENABLED,false);export var getWishlistItemNotesEnabled=makeGetShopSettingByKey(SHOP_SETTING_WISHLIST_ITEM_NOTES_ENABLED,false);export var getLoadWishlistOnAppStartEnabled=makeGetShopSettingByKey(SHOP_SETTING_LOAD_WISHLIST_ON_APP_START_ENABLED,true);export var getShowWishlistItemsCountBadge=createSelector(getLoadWishlistOnAppStartEnabled,makeGetShopSettingByKey(SHOP_SETTING_SHOW_WISHLIST_ITEMS_COUNT_BADGE,true),function(loadWishlistOnAppStartEnabled,showWishlistItemsCountBadge){return loadWishlistOnAppStartEnabled?showWishlistItemsCountBadge:false;});
25
+ */export var getRegistrationMode=makeGetShopSettingByKey(SHOP_SETTING_REGISTRATION_MODE,SHOP_SETTING_REGISTRATION_MODE_EXTENDED);export var getWishlistItemQuantityEnabled=makeGetShopSettingByKey(SHOP_SETTING_WISHLIST_ITEM_QUANTITY_ENABLED,false);export var getWishlistItemNotesEnabled=makeGetShopSettingByKey(SHOP_SETTING_WISHLIST_ITEM_NOTES_ENABLED,false);export var getLoadWishlistOnAppStartEnabled=makeGetShopSettingByKey(SHOP_SETTING_LOAD_WISHLIST_ON_APP_START_ENABLED,true);export var getShowWishlistItemsCountBadge=createSelector(getLoadWishlistOnAppStartEnabled,makeGetShopSettingByKey(SHOP_SETTING_SHOW_WISHLIST_ITEMS_COUNT_BADGE,true),function(loadWishlistOnAppStartEnabled,showWishlistItemsCountBadge){return loadWishlistOnAppStartEnabled?showWishlistItemsCountBadge:false;});/**
26
+ * Selector that determines if CMS 2 is enabled for all shoppers.
27
+ * @type {(state: RootState) => boolean}
28
+ */export var getEnableCms2ForAllShoppers=makeGetShopSettingByKey(SHOP_SETTING_ENABLE_CMS_2_FOR_ALL_SHOPPERS,false);
@@ -1,4 +1,4 @@
1
- import{DEVELOPMENT_TOOLS_TOGGLE_INSETS,DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT}from"../constants";/**
1
+ import{DEVELOPMENT_TOOLS_TOGGLE_INSETS,DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT,DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW}from"../constants";/**
2
2
  * Toggles the simulation of iOS safe area insets.
3
3
  * @param {boolean} visible Whether the insets should be visible or not.
4
4
  * @returns {Object} The action object.
@@ -6,4 +6,8 @@ import{DEVELOPMENT_TOOLS_TOGGLE_INSETS,DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT}
6
6
  * Toggles the highlighting of the simulated iOS safe area insets.
7
7
  * @param {boolean} visible Whether the insets should be visible or not.
8
8
  * @returns {Object} The action object.
9
- */export var toggleInsetHighlight=function toggleInsetHighlight(){var visible=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;return{type:DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT,visible:visible};};
9
+ */export var toggleInsetHighlight=function toggleInsetHighlight(){var visible=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;return{type:DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT,visible:visible};};/**
10
+ * Toggles the CMS 2.0 preview mode.
11
+ * @param {boolean} enabled Whether the CMS 2.0 preview should be enabled or not.
12
+ * @returns {Object} The action object.
13
+ */export var toggleCms2Preview=function toggleCms2Preview(){var enabled=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;return{type:DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW,enabled:enabled};};
@@ -0,0 +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);}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}from'react';import{useSelector}from'react-redux';import{makeStyles}from'@shopgate/engage/styles';import{useLongPress}from'@shopgate/engage/core/hooks';import{getClientInformation}from'@shopgate/engage/core/selectors';import DevelopmentSettings from"../DevelopmentSettings";var useStyles=makeStyles()(function(theme){return{root:{position:'relative',textAlign:'center',color:theme.palette.grey[500],fontSize:12,paddingBottom:20},unselectable:{WebkitTouchCallout:'none',WebkitUserSelect:'none',userSelect:'none'},deviceId:{wordBreak:['keep-all','break-word'],hyphens:'auto',padding:theme.spacing(0,2)}};});/**
2
+ * @param {Object} props The component props.
3
+ * @returns {JSX.Element}
4
+ */var ClientInformation=function ClientInformation(){var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var _useState=useState(false),_useState2=_slicedToArray(_useState,2),deviceIdVisible=_useState2[0],setDeviceIdVisible=_useState2[1];var _useState3=useState(false),_useState4=_slicedToArray(_useState3,2),developmentSettingsVisible=_useState4[0],setDevelopmentSettingsVisible=_useState4[1];// Press handler to show the device ID
5
+ var longPressAttrs=useLongPress(function(){if(!deviceIdVisible){setDeviceIdVisible(true);}else{setDevelopmentSettingsVisible(true);}},{threshold:5000});var _useSelector=useSelector(getClientInformation),appVersion=_useSelector.appVersion,codebaseVersion=_useSelector.codebaseVersion,deviceId=_useSelector.deviceId,libVersion=_useSelector.libVersion;if(!codebaseVersion){return null;}return React.createElement("div",_extends({className:cx('ui-shared__client-information',classes.root)},longPressAttrs,{"aria-hidden":true}),React.createElement("p",{className:classes.unselectable},"App Version: ".concat(appVersion," (").concat(codebaseVersion,")"),React.createElement("br",null),"Lib Version: ".concat(libVersion)),deviceIdVisible&&React.createElement(React.Fragment,null,React.createElement("p",{className:classes.deviceId},"Device ID: ".concat(deviceId!==null&&deviceId!==void 0?deviceId:'')),React.createElement(DevelopmentSettings,{isOpen:developmentSettingsVisible,onClose:function onClose(){return setDevelopmentSettingsVisible(false);}})));};export default ClientInformation;
@@ -0,0 +1,4 @@
1
+ import{DataRequest}from'@shopgate/engage/core/classes';import{setDebugLoggingEnabled}from'@shopgate/engage/core/commands';/**
2
+ * Enable debug logging.
3
+ * @return {Function} A redux thunk.
4
+ */export var enableDebugLogging=function enableDebugLogging(){return function(){setDebugLoggingEnabled();new DataRequest('ajax_started_live_logging').dispatch();};};
@@ -0,0 +1 @@
1
+ export{default}from"./ClientInformation";
@@ -0,0 +1,9 @@
1
+ import React from'react';import PropTypes from'prop-types';import{useSelector,useDispatch}from'react-redux';import{SheetDrawer,RippleButton}from'@shopgate/engage/components';import{makeStyles}from'@shopgate/engage/styles';import{getEnabledCMSVersion,getEnableCms2ForAllShoppers}from'@shopgate/engage/core/selectors';import{getIsCMS2PreviewEnabled}from"../../selectors";import{toggleCms2Preview}from"../../action-creators";var useStyles=makeStyles()(function(theme){return{container:{padding:theme.spacing(2,2,4),display:'flex',justifyContent:'center'},button:{fontWeight:'normal'}};});/**
2
+ * Development settings component.
3
+ * @param {Object} props The component props.
4
+ * @param {boolean} props.isOpen Whether the drawer is open.
5
+ * @param {Function} props.onClose The function to call when the drawer should be closed.
6
+ * @returns {JSX.Element}
7
+ */var DevelopmentSettings=function DevelopmentSettings(_ref){var isOpen=_ref.isOpen,onClose=_ref.onClose;var _useStyles=useStyles(),classes=_useStyles.classes;var dispatch=useDispatch();var enabledCMSVersion=useSelector(getEnabledCMSVersion);var enableCms2ForAllShoppers=useSelector(getEnableCms2ForAllShoppers);var isCMS2PreviewEnabled=useSelector(getIsCMS2PreviewEnabled);// No need to show the preview toggle if CMS 2.0 is not available for the merchant or if it's
8
+ // already enabled for all shoppers.
9
+ if(enableCms2ForAllShoppers||enabledCMSVersion==='v1'){return null;}return React.createElement(SheetDrawer,{title:" ",isOpen:isOpen,onClose:onClose},React.createElement("div",{className:classes.container},React.createElement(RippleButton,{className:classes.button,type:"simple",onClick:function onClick(){onClose();setTimeout(function(){dispatch(toggleCms2Preview(!isCMS2PreviewEnabled));},300);}},"".concat(isCMS2PreviewEnabled?'Disable':'Enable'," CMS 2.0 Preview"))));};export default DevelopmentSettings;
@@ -0,0 +1 @@
1
+ export{default}from"./DevelopmentSettings";
@@ -4,5 +4,5 @@ import{useEffect,useCallback}from'react';/**
4
4
  *
5
5
  * @param {string} shortcut - Shortcut string using mac-style notation, e.g. 'cmd+i'.
6
6
  * @param {Function} callback - Function to call when the shortcut is triggered.
7
- */export function useShortcut(shortcut,callback){var normalizeShortcut=useCallback(function(){return shortcut.toLowerCase().split('+').map(function(k){return k.trim();}).sort().join('+');},[shortcut]);var handleKeyDown=useCallback(function(event){var keys=[];if(event.ctrlKey)keys.push('ctrl');if(event.metaKey)keys.push('cmd');// Treat meta as cmd
8
- if(event.altKey)keys.push('alt');if(event.shiftKey)keys.push('shift');var key=event.key.toLowerCase();if(!['control','meta','alt','shift'].includes(key)){keys.push(key);}var pressed=keys.sort().join('+');if(pressed===normalizeShortcut()){event.preventDefault();callback(event);}},[callback,normalizeShortcut]);useEffect(function(){window.addEventListener('keydown',handleKeyDown);return function(){return window.removeEventListener('keydown',handleKeyDown);};},[handleKeyDown]);}
7
+ */export function useShortcut(shortcut,callback){var normalizeShortcut=useCallback(function(){return shortcut.toLowerCase().split('+').map(function(k){return k.trim();}).sort().join('+');},[shortcut]);var handleKeyDown=useCallback(function(event){var _event$key;var keys=[];if(event.ctrlKey)keys.push('ctrl');if(event.metaKey)keys.push('cmd');// Treat meta as cmd
8
+ if(event.altKey)keys.push('alt');if(event.shiftKey)keys.push('shift');var key=(_event$key=event.key)===null||_event$key===void 0?void 0:_event$key.toLowerCase();if(!['control','meta','alt','shift'].includes(key)){keys.push(key);}var pressed=keys.sort().join('+');if(pressed===normalizeShortcut()){event.preventDefault();callback(event);}},[callback,normalizeShortcut]);useEffect(function(){window.addEventListener('keydown',handleKeyDown);return function(){return window.removeEventListener('keydown',handleKeyDown);};},[handleKeyDown]);}
@@ -1 +1 @@
1
- export{default as DevelopmentTools}from"./DevelopmentTools";
1
+ export{default as DevelopmentTools}from"./DevelopmentTools";export{default as ClientInformation}from"./ClientInformation";
@@ -1 +1 @@
1
- export var DEVELOPMENT_TOOLS_TOGGLE_INSETS='DEVELOPMENT_TOOLS_TOGGLE_INSETS';export var DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT='DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT';export var DEVELOPMENT_TOOLS_UPDATE_STATUS_BAR_STYLE_STORAGE='DEVELOPMENT_TOOLS_UPDATE_STATUS_BAR_STYLE_STORAGE';
1
+ export var DEVELOPMENT_TOOLS_TOGGLE_INSETS='DEVELOPMENT_TOOLS_TOGGLE_INSETS';export var DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT='DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT';export var DEVELOPMENT_TOOLS_UPDATE_STATUS_BAR_STYLE_STORAGE='DEVELOPMENT_TOOLS_UPDATE_STATUS_BAR_STYLE_STORAGE';export var DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW='DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW';
@@ -1,10 +1,10 @@
1
- import{produce}from'immer';import{isDev}from'@shopgate/engage/core/helpers';import{DEVELOPMENT_TOOLS_TOGGLE_INSETS,DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT}from"../constants";/**
1
+ import{produce}from'immer';import{isDev}from'@shopgate/engage/core/helpers';import{DEVELOPMENT_TOOLS_TOGGLE_INSETS,DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT,DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW}from"../constants";/**
2
2
  * @typedef {Object} DevToolsSettingsState
3
3
  * @property {boolean} showInsets
4
4
  * @property {boolean} showInsetHighlight
5
- */ /** @type DevToolsSettingsState */var initialState={showInsets:null,showInsetHighlight:false};/**
5
+ */ /** @type DevToolsSettingsState */var initialState={showInsets:null,showInsetHighlight:false,cms2PreviewEnabled:false};/**
6
6
  * The reducer for all development tools settings related states.
7
7
  * @param {Object} state The application state.
8
8
  * @param {Object} action The redux action.
9
9
  * @returns {Object}
10
- */export default function settingsReducer(){var state=arguments.length>0&&arguments[0]!==undefined?arguments[0]:initialState;var action=arguments.length>1?arguments[1]:undefined;/* eslint-disable no-param-reassign */var producer=produce(/** @param {DevToolsSettingsState} draft The draft */function(draft){if(!isDev){return;}switch(action.type){case DEVELOPMENT_TOOLS_TOGGLE_INSETS:{draft.showInsets=action.visible;break;}case DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT:{draft.showInsetHighlight=action.visible;break;}default:break;}});/* eslint-enable no-param-reassign */return producer(state);}
10
+ */export default function settingsReducer(){var state=arguments.length>0&&arguments[0]!==undefined?arguments[0]:initialState;var action=arguments.length>1?arguments[1]:undefined;/* eslint-disable no-param-reassign */var producer=produce(/** @param {DevToolsSettingsState} draft The draft */function(draft){switch(action.type){case DEVELOPMENT_TOOLS_TOGGLE_INSETS:{if(isDev){draft.showInsets=action.visible;}break;}case DEVELOPMENT_TOOLS_TOGGLE_INSET_HIGHLIGHT:{if(isDev){draft.showInsetHighlight=action.visible;}break;}case DEVELOPMENT_TOOLS_TOGGLE_CMS2_PREVIEW:{draft.cms2PreviewEnabled=action.enabled;break;}default:break;}});/* eslint-enable no-param-reassign */return producer(state);}
@@ -18,4 +18,7 @@ import{createSelector}from'reselect';import MobileDetect from'mobile-detect';imp
18
18
  if(!isDev){return false;}// No insets injected if PWA is running inside the app
19
19
  if(hasSGJavaScriptBridge()){return false;}// If the state contains a bool value, respect is.
20
20
  if(typeof insetsVisible==='boolean'){return insetsVisible;}// Show insets on simulated iOS devices by default if insets decision is not set.
21
- return insetsVisible===null&&md.os()==='iOS';});
21
+ return insetsVisible===null&&md.os()==='iOS';});/**
22
+ * Creates a selector to determine if the CMS2 preview is enabled.
23
+ * @type {(state: any) => boolean}
24
+ */export var getIsCMS2PreviewEnabled=createSelector(getState,function(settings){return!!settings.cms2PreviewEnabled;});
@@ -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);});};}import{getProductsResult,productIsReady$,productsReceived$,productsReceivedCached$,RECEIVE_PRODUCTS_CACHED,variantDidChange$}from'@shopgate/engage/product';import{appDidStart$,routeWillEnter$,UIEvents,getCurrentRoute,hex2bin,getThemeSettings,getCurrentSearchQuery,appWillInit$,appInitialization}from'@shopgate/engage/core';import{cartReceived$,fetchCart,cartDidEnter$,getCartItems}from'@shopgate/engage/cart';import{userDidLogin$}from'@shopgate/engage/user';import{receiveFavoritesWhileVisible$}from'@shopgate/pwa-common-commerce/favorites/streams';import{getFavoritesProductsIds,isFetching}from'@shopgate/pwa-common-commerce/favorites/selectors';import{categoryDidBackEnter$}from'@shopgate/pwa-common-commerce/category/streams';import{searchDidBackEntered$}from'@shopgate/pwa-common-commerce/search/streams';import{hasNewServices}from'@shopgate/engage/core/helpers';import{cookieConsentInitialized$}from'@shopgate/engage/tracking/streams';import{getUserSearch,getStoreFinderSearch,getPreferredLocation,getIsPending,getProductAlternativeLocationParams,getProductAlternativeLocations,makeGetLocation}from"./selectors";import{fetchDefaultLocation,fetchLocations,fetchProductLocations,setPending,setUserGeolocation}from"./actions";import{setShowInventoryInLists,showInventoryInLists}from"./helpers";import fetchInventories from"./actions/fetchInventories";import{EVENT_SET_OPEN}from"./providers/FulfillmentProvider";import fetchProductInventories from"./actions/fetchProductInventories";import{submitReservationSuccess$,userSearchChanged$,storeFinderWillEnter$,preferredLocationDidUpdateOnPDP$,provideAlternativeLocation$,preferredLocationDidUpdateGlobalOnWishlist$,storeDetailPageWillEnter$}from"./locations.streams";import selectLocation from"./action-creators/selectLocation";import{NEARBY_LOCATIONS_RADIUS,SET_STORE_FINDER_SEARCH_RADIUS,NEARBY_LOCATIONS_LIMIT}from"./constants";import selectGlobalLocation from"./action-creators/selectGlobalLocation";var initialLocationsResolve;var initialLocationsReject;var initialLocationsPromise=new Promise(function(resolve,reject){initialLocationsResolve=resolve;initialLocationsReject=reject;});/**
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);});};}import{getProductsResult,productIsReady$,productsReceived$,productsReceivedCached$,RECEIVE_PRODUCTS_CACHED,variantDidChange$}from'@shopgate/engage/product';import{appDidStart$,routeWillEnter$,UIEvents,getCurrentRoute,hex2bin,getThemeSettings,getCurrentSearchQuery,appWillInit$,appInitialization}from'@shopgate/engage/core';import{cartReceived$,fetchCart,cartDidEnter$,getCartItems}from'@shopgate/engage/cart';import{userDidLogin$}from'@shopgate/engage/user';import{receiveFavoritesWhileVisible$}from'@shopgate/pwa-common-commerce/favorites/streams';import{getFavoritesProductsIds,isFetching}from'@shopgate/pwa-common-commerce/favorites/selectors';import{categoryDidBackEnter$}from'@shopgate/pwa-common-commerce/category/streams';import{searchDidBackEntered$}from'@shopgate/pwa-common-commerce/search/streams';import{hasNewServices}from'@shopgate/engage/core/helpers';import{cookieConsentInitialized$}from'@shopgate/engage/tracking/streams';import{IS_PAGE_PREVIEW_ACTIVE}from'@shopgate/engage/page/constants';import{getUserSearch,getStoreFinderSearch,getPreferredLocation,getIsPending,getProductAlternativeLocationParams,getProductAlternativeLocations,makeGetLocation}from"./selectors";import{fetchDefaultLocation,fetchLocations,fetchProductLocations,setPending,setUserGeolocation}from"./actions";import{setShowInventoryInLists,showInventoryInLists}from"./helpers";import fetchInventories from"./actions/fetchInventories";import{EVENT_SET_OPEN}from"./providers/FulfillmentProvider";import fetchProductInventories from"./actions/fetchProductInventories";import{submitReservationSuccess$,userSearchChanged$,storeFinderWillEnter$,preferredLocationDidUpdateOnPDP$,provideAlternativeLocation$,preferredLocationDidUpdateGlobalOnWishlist$,storeDetailPageWillEnter$}from"./locations.streams";import selectLocation from"./action-creators/selectLocation";import{NEARBY_LOCATIONS_RADIUS,SET_STORE_FINDER_SEARCH_RADIUS,NEARBY_LOCATIONS_LIMIT}from"./constants";import selectGlobalLocation from"./action-creators/selectGlobalLocation";var initialLocationsResolve;var initialLocationsReject;var initialLocationsPromise=new Promise(function(resolve,reject){initialLocationsResolve=resolve;initialLocationsReject=reject;});/**
2
2
  * Sets a location once the location has been validated.
3
3
  * @param {string} locationCode Location code
4
4
  * @param {Function} dispatch Redux dispatch function
@@ -6,7 +6,7 @@ import _regeneratorRuntime from"@babel/runtime/regenerator";function _extends(){
6
6
  */var setLocationOnceAvailable=/*#__PURE__*/function(){var _ref=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(locationCode,dispatch){var _ref3,initialLocations;return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:_context.prev=0;_context.next=3;return initialLocationsPromise;case 3:_ref3=_context.sent;initialLocations=_ref3.locations;if(initialLocations.some(function(l){return l.code===locationCode;})){_context.next=7;break;}return _context.abrupt("return");case 7:_context.next=9;return dispatch(selectLocation({location:{code:locationCode}}));case 9:requestAnimationFrame(function(){dispatch(setPending(false));});_context.next=14;break;case 12:_context.prev=12;_context.t0=_context["catch"](0);case 14:case"end":return _context.stop();}},_callee,null,[[0,12]]);}));return function setLocationOnceAvailable(_x,_x2){return _ref.apply(this,arguments);};}();/**
7
7
  * Locations subscriptions.
8
8
  * @param {Function} subscribe The subscribe function.
9
- */function locationsSubscriber(subscribe){subscribe(appWillInit$,function(){appInitialization.set('location',/*#__PURE__*/function(){var _ref5=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref4){var dispatch;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:dispatch=_ref4.dispatch;if(!hasNewServices()){_context2.next=4;break;}_context2.next=4;return dispatch(fetchDefaultLocation());case 4:case"end":return _context2.stop();}},_callee2);}));return function(_x3){return _ref5.apply(this,arguments);};}());});subscribe(cookieConsentInitialized$,/*#__PURE__*/function(){var _ref7=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref6){var dispatch,getState,userSearch,_ref9,locations,preferredLocation,code,hasLocation,_ref11,preferredLocationDefault,locationToPreselect;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:dispatch=_ref6.dispatch,getState=_ref6.getState;if(hasNewServices()){_context3.next=3;break;}return _context3.abrupt("return");case 3:// Fetch merchants locations.
9
+ */function locationsSubscriber(subscribe){subscribe(appWillInit$,function(){appInitialization.set('location',/*#__PURE__*/function(){var _ref5=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref4){var dispatch;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:dispatch=_ref4.dispatch;if(!(hasNewServices()&&!IS_PAGE_PREVIEW_ACTIVE)){_context2.next=4;break;}_context2.next=4;return dispatch(fetchDefaultLocation());case 4:case"end":return _context2.stop();}},_callee2);}));return function(_x3){return _ref5.apply(this,arguments);};}());});subscribe(cookieConsentInitialized$,/*#__PURE__*/function(){var _ref7=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref6){var dispatch,getState,userSearch,_ref9,locations,preferredLocation,code,hasLocation,_ref11,preferredLocationDefault,locationToPreselect;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:dispatch=_ref6.dispatch,getState=_ref6.getState;if(hasNewServices()){_context3.next=3;break;}return _context3.abrupt("return");case 3:// Fetch merchants locations.
10
10
  userSearch=getUserSearch(getState());_context3.prev=4;_context3.next=7;return dispatch(fetchLocations(userSearch));case 7:_ref9=_context3.sent;locations=_ref9.locations;preferredLocation=getPreferredLocation(getState());if(!preferredLocation){_context3.next=16;break;}code=preferredLocation.code;// Check if the preferred location is included within the fetched locations
11
11
  hasLocation=!!locations.find(function(location){return location.code===code;});if(hasLocation){_context3.next=16;break;}_context3.next=16;return dispatch(fetchLocations({codes:[code]}));case 16:// Preset preferredLocation if configured
12
12
  _ref11=getThemeSettings('@shopgate/engage/locations')||{},preferredLocationDefault=_ref11.preferredLocationDefault;if(!preferredLocationDefault){_context3.next=23;break;}if(preferredLocation){_context3.next=23;break;}locationToPreselect=locations.find(function(l){return l.code===preferredLocationDefault;});if(!locationToPreselect){_context3.next=23;break;}_context3.next=23;return dispatch(selectLocation({location:{code:preferredLocationDefault}}));case 23:initialLocationsResolve(locations);_context3.next=29;break;case 26:_context3.prev=26;_context3.t0=_context3["catch"](4);initialLocationsReject(_context3.t0);case 29:UIEvents.addListener(EVENT_SET_OPEN,function(){var route=getCurrentRoute(getState());if(!route.params.productId&&!route.state.productId){return;}var productId=route.state.productId||hex2bin(route.params.productId);if(productId){dispatch(fetchProductLocations(productId,getUserSearch(getState())));}});case 30:case"end":return _context3.stop();}},_callee3,null,[[4,26]]);}));return function(_x4){return _ref7.apply(this,arguments);};}());subscribe(userSearchChanged$,/*#__PURE__*/function(){var _ref13=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref12){var dispatch,getState,action,productId,isStoreFinder,silent,state,userSearch,storeFinderSearch;return _regeneratorRuntime.wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:dispatch=_ref12.dispatch,getState=_ref12.getState,action=_ref12.action;productId=action.productId,isStoreFinder=action.isStoreFinder,silent=action.silent;if(!(silent===true)){_context4.next=4;break;}return _context4.abrupt("return");case 4:state=getState();userSearch=getUserSearch(state);if(!(isStoreFinder||action.type===SET_STORE_FINDER_SEARCH_RADIUS)){_context4.next=12;break;}storeFinderSearch=getStoreFinderSearch(state);_context4.next=10;return dispatch(fetchLocations(_extends({},userSearch,{},storeFinderSearch,{enableInLocationFinder:true})));case 10:_context4.next=19;break;case 12:if(productId){_context4.next=17;break;}_context4.next=15;return dispatch(fetchLocations(userSearch));case 15:_context4.next=19;break;case 17:_context4.next=19;return dispatch(fetchProductLocations(productId,userSearch));case 19:case"end":return _context4.stop();}},_callee4);}));return function(_x5){return _ref13.apply(this,arguments);};}());var productInventoryNeedsUpdate$=productIsReady$.merge(variantDidChange$).merge(preferredLocationDidUpdateOnPDP$).debounceTime(200);subscribe(productInventoryNeedsUpdate$,function(_ref14){var action=_ref14.action,dispatch=_ref14.dispatch,getState=_ref14.getState;var productData=action.productData;// Skip if no fulfillment methods are set.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/engage",
3
- "version": "7.28.0",
3
+ "version": "7.29.0-alpha.10",
4
4
  "description": "Shopgate's ENGAGE library.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -15,13 +15,14 @@
15
15
  "connect"
16
16
  ],
17
17
  "dependencies": {
18
+ "@emotion/react": "^11.14.0",
18
19
  "@shopgate/native-modules": "1.0.0-beta.25",
19
- "@shopgate/pwa-common": "7.28.0",
20
- "@shopgate/pwa-common-commerce": "7.28.0",
21
- "@shopgate/pwa-core": "7.28.0",
22
- "@shopgate/pwa-ui-ios": "7.28.0",
23
- "@shopgate/pwa-ui-material": "7.28.0",
24
- "@shopgate/pwa-ui-shared": "7.28.0",
20
+ "@shopgate/pwa-common": "7.29.0-alpha.10",
21
+ "@shopgate/pwa-common-commerce": "7.29.0-alpha.10",
22
+ "@shopgate/pwa-core": "7.29.0-alpha.10",
23
+ "@shopgate/pwa-ui-ios": "7.29.0-alpha.10",
24
+ "@shopgate/pwa-ui-material": "7.29.0-alpha.10",
25
+ "@shopgate/pwa-ui-shared": "7.29.0-alpha.10",
25
26
  "@stripe/react-stripe-js": "^1.16.5",
26
27
  "@stripe/stripe-js": "^1.3.1",
27
28
  "@virtuous/conductor": "~2.5.0",
@@ -40,6 +41,7 @@
40
41
  "react-phone-number-input": "^3.2.16",
41
42
  "react-player": "1.11.0",
42
43
  "react-portal": "^3.1.0",
44
+ "tss-react": "^4.9.18",
43
45
  "validate.js": "^0.13.1"
44
46
  },
45
47
  "devDependencies": {
@@ -0,0 +1,22 @@
1
+ import{REQUEST_PAGE_CONFIG_V2,RECEIVE_PAGE_CONFIG_V2,ERROR_PAGE_CONFIG_V2}from"../constants";/**
2
+ * @typedef {'cms' | 'category'} PageType
3
+ */ /**
4
+ * Creates the dispatched REQUEST_PAGE_CONFIG_V2 action object.
5
+ * @param {Object} params The action params
6
+ * @param {PageType} [params.type="cms"] The type of the page.
7
+ * @param {string} [params.slug=null] The slug of the page (optional).
8
+ * @returns {Object} The dispatched action object.
9
+ */export var requestPageConfigV2=function requestPageConfigV2(_ref){var _ref$type=_ref.type,type=_ref$type===void 0?'cms':_ref$type,_ref$slug=_ref.slug,slug=_ref$slug===void 0?null:_ref$slug;return{type:REQUEST_PAGE_CONFIG_V2,pageType:type,pageSlug:slug};};/**
10
+ * Creates the dispatched RECEIVE_PAGE_CONFIG_V2 action object.
11
+ * @param {Object} params The action params
12
+ * @param {PageType} [params.type="cms"] The type of the page.
13
+ * @param {Object} params.data The page data
14
+ * @param {string} [params.slug=null] The slug of the page (optional).
15
+ * @returns {Object} The dispatched action object.
16
+ */export var receivePageConfigV2=function receivePageConfigV2(_ref2){var _ref2$type=_ref2.type,type=_ref2$type===void 0?'cms':_ref2$type,data=_ref2.data,_ref2$slug=_ref2.slug,slug=_ref2$slug===void 0?null:_ref2$slug;return{type:RECEIVE_PAGE_CONFIG_V2,pageType:type,pageSlug:slug,data:data};};/**
17
+ * Creates the dispatched ERROR_PAGE_CONFIG_V2 action object.
18
+ * @param {Object} params The action params
19
+ * @param {PageType} [params.type="cms"] The type of the page.
20
+ * @param {string} [params.slug=null] The slug of the page (optional).
21
+ * @returns {Object} The dispatched action object.
22
+ */export var errorPageConfigV2=function errorPageConfigV2(_ref3){var _ref3$type=_ref3.type,type=_ref3$type===void 0?'cms':_ref3$type,_ref3$slug=_ref3.slug,slug=_ref3$slug===void 0?null:_ref3$slug;return{type:ERROR_PAGE_CONFIG_V2,pageType:type,pageSlug:slug};};
@@ -0,0 +1,7 @@
1
+ var _excluded=["src","alt","breakpoint"];function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}import React,{useMemo}from'react';import PropTypes from'prop-types';import{useTheme,makeStyles}from'@shopgate/engage/styles';import{parseImageUrl}from"../../helpers";/** @typedef {import('@shopgate/engage/styles').Theme} Theme */ /** @typedef {Theme['breakpoints']['keys'][0]} Breakpoint */ /** @typedef {React.ImgHTMLAttributes<HTMLImageElement>} ImgProps */ /** @typedef {{breakpoint: Breakpoint} & ImgProps} ResponsiveImageProps */var useStyles=makeStyles()({preventSave:{userSelect:'none',' img':{userSelect:'none',pointerEvents:'none'}}});/**
2
+ * The ResponsiveWidgetImage component renders an image that adapts to different screen sizes.
3
+ * It uses the <picture> element to provide a higher resolution image for medium and larger screens.
4
+ *
5
+ * @param {ResponsiveImageProps} props The component props.
6
+ * @returns {JSX.Element}
7
+ */var ResponsiveWidgetImage=function ResponsiveWidgetImage(_ref){var src=_ref.src,alt=_ref.alt,breakpoint=_ref.breakpoint,imgProps=_objectWithoutProperties(_ref,_excluded);var _useTheme=useTheme(),breakpoints=_useTheme.breakpoints;var _useStyles=useStyles(),classes=_useStyles.classes;var src2x=useMemo(function(){return parseImageUrl(src,true);},[src]);if(!src){return null;}return React.createElement("picture",{onContextMenu:function onContextMenu(e){return e.preventDefault();},className:classes.preventSave},React.createElement("source",{media:"(width >= ".concat(breakpoints.values[breakpoint],"px)"),srcSet:src2x}),React.createElement("img",_extends({src:src,alt:alt,loading:"lazy"},imgProps)));};ResponsiveWidgetImage.defaultProps={alt:null,breakpoint:'md'};export default ResponsiveWidgetImage;
@@ -0,0 +1 @@
1
+ export{default}from"./ResponsiveWidgetImage";
@@ -0,0 +1,7 @@
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,{useMemo}from'react';import{makeStyles}from'@shopgate/engage/styles';import{Typography}from'@shopgate/engage/components';import PropTypes from'prop-types';var useStyles=makeStyles()(function(theme){return{root:{padding:theme.spacing(2)}};});/**
2
+ * The WidgetHeadline is used to display a headline for the widget.
3
+ * @param {Object} props The component props.
4
+ * @param {Object} props.headline The headline props.
5
+ * @returns {JSX.Element}
6
+ */var WidgetHeadline=function WidgetHeadline(_ref){var headline=_ref.headline,className=_ref.className;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx,css=_useStyles.css;var _ref2=headline||{},_ref2$typography=_ref2.typography,typography=_ref2$typography===void 0?'h3':_ref2$typography,text=_ref2.text,textAlign=_ref2.textAlign,bold=_ref2.bold,italic=_ref2.italic,underline=_ref2.underline;var styles=useMemo(function(){return _extends({},bold&&{fontWeight:'bold'},{},italic&&{fontStyle:'italic'},{},underline&&{textDecoration:'underline'});},[bold,italic,underline]);if(!text)return null;return React.createElement(Typography,{variant:typography,align:textAlign// && increases the specificity of the styles which guarantees that defaults are overridden
7
+ ,className:cx(css({'&&':_extends({},styles)}),classes.root,className)},text);};WidgetHeadline.defaultProps={className:null};export default WidgetHeadline;
@@ -0,0 +1 @@
1
+ export{default}from"./WidgetHeadline";
@@ -0,0 +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 React from'react';import PropTypes from'prop-types';import{HtmlSanitizer}from'@shopgate/engage/components';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()(function(theme){return{root:{width:'100%','& > :first-child':{marginTop:0},'& > :last-child':{marginBottom:0},'& p':{margin:'0px 0px 1rem 0px',':empty':{minHeight:'1rem'}},'ul, ol':{paddingLeft:'40px'},'ul li':{listStyleType:'disc'},'ol li':{listStyleType:'decimal'},h1:_extends({},theme.typography.h1,{margin:'0px 0px 1rem 0px'}),h2:_extends({},theme.typography.h2,{margin:'0px 0px 1rem 0px'}),h3:_extends({},theme.typography.h3,{margin:'0px 0px 1rem 0px'}),h4:_extends({},theme.typography.h4,{margin:'0px 0px 1rem 0px'}),h5:_extends({},theme.typography.h5,{margin:'0px 0px 1rem 0px'}),h6:_extends({},theme.typography.h6,{margin:'0px 0px 1rem 0px'})}};});/**
2
+ * @param {Object} props The component props.
3
+ * @param {string} props.content The rich text content.
4
+ * @param {string} [props.className] An optional class name.
5
+ * @returns {JSX.Element}
6
+ */var WidgetRichText=function WidgetRichText(_ref){var content=_ref.content,className=_ref.className;var _useStyles=useStyles(),cx=_useStyles.cx,classes=_useStyles.classes;if(!content)return null;return React.createElement(HtmlSanitizer,{processStyles:true,settings:{html:content},className:cx(classes.root,className)},content);};WidgetRichText.defaultProps={content:'',className:null};export default WidgetRichText;
@@ -0,0 +1 @@
1
+ export{default}from"./WidgetRichText";
@@ -0,0 +1,51 @@
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 React,{useState,useRef,useEffect,useCallback}from'react';import PropTypes from'prop-types';import{makeStyles,keyframes,colorToRgba}from'@shopgate/engage/styles';import{useRoute}from'@shopgate/engage/core/hooks';import{getScrollContainer}from"./helpers";import{useWidgetPreviewEvent}from"./events";import{useWidgetsPreview}from"./hooks";/**
2
+ * @typedef {Object} OverlayStyle
3
+ * @property {number} top Style for the top position of the overlay.
4
+ * @property {number} left Style for the left position of the overlay.
5
+ * @property {number} width Style for the width of the overlay.
6
+ * @property {number} height Style for the height of the overlay.
7
+ */ /**
8
+ * @typedef {Object} MarginOverlayStyles
9
+ * @property {OverlayStyle} top Style for the top margin overlay.
10
+ * @property {OverlayStyle} left Style for the left margin overlay.
11
+ * @property {OverlayStyle} bottom Style for the bottom margin overlay.
12
+ * @property {OverlayStyle} right Style for the right margin overlay.
13
+ */var useStyles=makeStyles({name:'WidgetPreviewOverlay'})(function(_,_ref){var highlightColor=_ref.highlightColor,overlayBorderColor=_ref.overlayBorderColor,marginOverlayColor=_ref.marginOverlayColor,isFlashing=_ref.isFlashing;return{root:{},mainOverlay:_extends({position:'absolute',pointerEvents:'none',zIndex:10,boxShadow:'0 0 8px 2px rgba(34, 42, 69, 0.07)',outline:"1px solid ".concat(overlayBorderColor||'#50A9AD')},isFlashing&&{animationName:keyframes({'0%':{backgroundColor:'transparent'},'50%':{backgroundColor:colorToRgba(highlightColor||'#50A9AD',0.5)},'100%':{backgroundColor:'transparent'}}),animationDuration:'0.5s',animationTimingFunction:'ease-in-out',animationFillMode:'forwards'}),marginOverlay:{position:'absolute',backgroundColor:colorToRgba(marginOverlayColor||'#50A9AD',0.1),pointerEvents:'none',zIndex:9}};});/**
14
+ * The Overlay component is used to highlight the active widget when preview mode is active.
15
+ * It also visualizes the margins of the widget and the borders to its sibling widgets.
16
+ * @param {Object} props The component props.
17
+ * @param {React.Ref<HTMLDivElement>} props.containerRef The reference to the container element that
18
+ * holds the widgets.
19
+ * @returns {JSX.Element|null}
20
+ */var Overlay=function Overlay(_ref2){var containerRef=_ref2.containerRef;var _useRoute=useRoute(),_useRoute$query=_useRoute.query,highlightColor=_useRoute$query.highlightColor,overlayBorderColor=_useRoute$query.overlayBorderColor,marginOverlayColor=_useRoute$query.marginOverlayColor;var _useWidgetsPreview=useWidgetsPreview(),activeWidget=_useWidgetsPreview.activeWidget;/**
21
+ * State to hold the style for the main overlay that highlights the active widget.
22
+ * @type {[OverlayStyle|null, React.Dispatch<React.SetStateAction<OverlayStyle|null>>]}
23
+ */var _useState=useState(null),_useState2=_slicedToArray(_useState,2),mainOverlayStyle=_useState2[0],setMainOverlayStyle=_useState2[1];/**
24
+ * State to hold the styles for the margin overlays that visualize the widget margins.
25
+ * @type {[MarginOverlayStyles|null,
26
+ * React.Dispatch<React.SetStateAction<MarginOverlayStyles|null>>]}
27
+ */var _useState3=useState(null),_useState4=_slicedToArray(_useState3,2),marginOverlays=_useState4[0],setMarginOverlays=_useState4[1];var _useState5=useState(false),_useState6=_slicedToArray(_useState5,2),isFlashing=_useState6[0],setIsFlashing=_useState6[1];var _useStyles=useStyles({highlightColor:highlightColor,overlayBorderColor:overlayBorderColor,marginOverlayColor:marginOverlayColor,isFlashing:isFlashing}),classes=_useStyles.classes;/**
28
+ * @type {import('react').MutableRefObject<ResizeObserver|null>}
29
+ */var resizeRef=useRef(null);/**
30
+ * @type {import('react').MutableRefObject<MutationObserver|null>}
31
+ */var mutationRef=useRef(null);/**
32
+ * Callback to update the overlay position, margin overlays and size based on the active widget.
33
+ */var updateOverlay=useCallback(function(){if(!containerRef.current||!activeWidget){return;}var target=containerRef.current.querySelector("#widget-code-".concat(activeWidget));if(!target){setMainOverlayStyle(null);return;}var scrollContainer=getScrollContainer();// Get the computed styles of the active widget to calculate margins
34
+ var styles=window.getComputedStyle(target);var marginLeft=parseFloat(styles.marginLeft);var marginRight=parseFloat(styles.marginRight);var marginTop=parseFloat(styles.marginTop);var marginBottom=parseFloat(styles.marginBottom);// Get bounding rectangles for the target widget and the scroll container
35
+ var elementRect=target.getBoundingClientRect();var containerRect=scrollContainer.getBoundingClientRect();var baseTop=elementRect.top-containerRect.top+scrollContainer.scrollTop;var baseLeft=elementRect.left-containerRect.left+scrollContainer.scrollLeft;var top=baseTop;var left=baseLeft-marginLeft;var width=target.offsetWidth+marginLeft+marginRight;var height=target.offsetHeight;// Keep a backdoor to re-enable overlay outline inside the widget margins
36
+ var mainOverlayBordersOnMarginEdges=true;var mainTop=baseTop-(mainOverlayBordersOnMarginEdges?marginTop:0);var mainHeight=height+(mainOverlayBordersOnMarginEdges?marginTop+marginBottom:0);setMainOverlayStyle({top:mainTop+1,left:left,width:width,height:mainHeight-2});setMarginOverlays({top:{top:top-marginTop,left:left,width:width,height:marginTop},bottom:{top:top+height,left:left,width:width,height:marginBottom},left:{top:top,left:left,width:marginLeft,height:height},right:{top:top,left:left+width-marginRight,width:marginRight,height:height}});},[activeWidget,containerRef]);// Effect to setup observers that watch for changes in the container and its children.
37
+ // Needed to update the overlay style when the layout changes.
38
+ useEffect(function(){var containerEl=containerRef.current;if(!containerEl)return undefined;// Create a ResizeObserver to watch for size changes of children
39
+ resizeRef.current=new ResizeObserver(function(){// Whenever any observed child resizes, update overlay
40
+ updateOverlay();});// Observe all existing children
41
+ Array.from(containerEl.children).forEach(function(child){if(child.nodeType===Node.ELEMENT_NODE){resizeRef.current.observe(child);}});// Create one MutationObserver on the container to watch for changes in the DOM
42
+ mutationRef.current=new MutationObserver(function(mutations){// eslint-disable-next-line no-restricted-syntax
43
+ var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=mutations[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var mutation=_step.value;if(mutation.type==='childList'){// Handle newly added nodes - observe them for size changes
44
+ mutation.addedNodes.forEach(function(node){if(node.nodeType===Node.ELEMENT_NODE){resizeRef.current.observe(node);}});// Handle removed nodes - remove them from observation
45
+ mutation.removedNodes.forEach(function(node){if(node.nodeType===Node.ELEMENT_NODE){resizeRef.current.unobserve(node);}});// If children were added/removed, recalculate overlay position
46
+ updateOverlay();}else if(mutation.type==='attributes'&&(mutation.attributeName==='class'||mutation.attributeName==='style')){// Update overlay if the class or style of a child changes
47
+ if(mutation.target.parentElement===containerEl){updateOverlay();}}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator["return"]!=null){_iterator["return"]();}}finally{if(_didIteratorError){throw _iteratorError;}}}});// Start observing:
48
+ // - childList:true → to catch added/removed children
49
+ // - subtree:true + attributes:true → to catch any class/style changes in descendants
50
+ mutationRef.current.observe(containerEl,{childList:true,subtree:true,attributes:true,attributeFilter:['class','style']});// Cleanup on unmount or if updateOverlay changes:
51
+ return function(){if(resizeRef.current){resizeRef.current.disconnect();resizeRef.current=null;}if(mutationRef.current){mutationRef.current.disconnect();mutationRef.current=null;}};},[containerRef,updateOverlay]);useWidgetPreviewEvent('highlight-widget',function(){setIsFlashing(true);});var handleAnimationEnd=useCallback(function(){setIsFlashing(false);},[]);if(!mainOverlayStyle)return null;return React.createElement("div",{className:classes.root},React.createElement("div",{className:classes.mainOverlay,style:mainOverlayStyle,onAnimationEnd:handleAnimationEnd}),marginOverlays&&Object.entries(marginOverlays).map(function(_ref3){var _ref4=_slicedToArray(_ref3,2),key=_ref4[0],overlayStyle=_ref4[1];return React.createElement("div",{key:key,className:classes.marginOverlay,style:overlayStyle});}));};export default Overlay;
@@ -0,0 +1,22 @@
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _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,useRef,useEffect}from'react';import ReactDOM from'react-dom';import PropTypes from'prop-types';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()(function(){return{wrapper:{display:'inline-block',position:'relative',cursor:'help'},tooltipBox:{position:'absolute',padding:'6px 10px',backgroundColor:'rgba(0, 0, 0, 0.87)',color:'#fff',fontSize:'0.875rem',fontWeight:400,borderRadius:'4px',whiteSpace:'normal',// allow multiline
2
+ wordBreak:'break-word',maxWidth:'200px',zIndex:1000,pointerEvents:'none',opacity:0,transform:'scale(0.9)',transition:'opacity 0.1s ease-in-out, transform 0.1s ease-in-out','&[data-visible="true"]':{opacity:1,transform:'scale(1)'}},arrowTop:{'&::before':{content:"''",position:'absolute',bottom:'-6px',left:'var(--arrow-left, 50%)',transform:'translateX(-50%)',borderWidth:'6px 6px 0 6px',borderStyle:'solid',borderColor:'rgba(0, 0, 0, 0.87) transparent transparent transparent'}},arrowBottom:{'&::before':{content:"''",position:'absolute',top:'-6px',left:'var(--arrow-left, 50%)',transform:'translateX(-50%) rotate(180deg)',borderWidth:'6px 6px 0 6px',borderStyle:'solid',borderColor:'rgba(0, 0, 0, 0.87) transparent transparent transparent'}}};});/**
3
+ * AI generated Tooltip component to display additional information on hover.
4
+ * @param {Object} props The component props.
5
+ * @param {React.ReactNode} props.children The child elements to wrap.
6
+ * @param {string} props.text The tooltip text to display.
7
+ * @returns {JSX.Element}
8
+ */function Tooltip(_ref){var children=_ref.children,text=_ref.text;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var wrapperRef=useRef(null);var _useState=useState(false),_useState2=_slicedToArray(_useState,2),visible=_useState2[0],setVisible=_useState2[1];var _useState3=useState(false),_useState4=_slicedToArray(_useState3,2),mounted=_useState4[0],setMounted=_useState4[1];var _useState5=useState(false),_useState6=_slicedToArray(_useState5,2),animate=_useState6[0],setAnimate=_useState6[1];var _useState7=useState({left:0,top:0}),_useState8=_slicedToArray(_useState7,2),coords=_useState8[0],setCoords=_useState8[1];var _useState9=useState(null),_useState10=_slicedToArray(_useState9,2),arrowLeft=_useState10[0],setArrowLeft=_useState10[1];var _useState11=useState('top'),_useState12=_slicedToArray(_useState11,2),positionState=_useState12[0],setPositionState=_useState12[1];// 'top' or 'bottom'
9
+ var tooltipId=useRef(Math.random().toString(36).slice(2,11));// Handle mounting/unmounting and trigger fade animation
10
+ useEffect(function(){var timeoutId;if(visible){setMounted(true);// allow DOM to insert before starting the fade-in
11
+ timeoutId=setTimeout(function(){return setAnimate(true);},10);}else{setAnimate(false);// after fade-out duration, unmount
12
+ timeoutId=setTimeout(function(){return setMounted(false);},200);}return function(){return clearTimeout(timeoutId);};},[visible]);// Compute position, flipping if needed, when mounted
13
+ useEffect(function(){if(!mounted||!wrapperRef.current)return;var wrapperRect=wrapperRef.current.getBoundingClientRect();var selector=".tooltip-box[data-tooltip-id=\"".concat(tooltipId.current,"\"]");var tooltipEl=document.querySelector(selector);if(!tooltipEl)return;var ttRect=tooltipEl.getBoundingClientRect();var margin=8;var vw=window.innerWidth;var vh=window.innerHeight;// 1) Try "top" placement
14
+ var left=wrapperRect.left+wrapperRect.width/2-ttRect.width/2;var top=wrapperRect.top-ttRect.height-8;// Clamp horizontal even before deciding flip, to calculate arrow offset
15
+ if(left<margin){left=margin;}else if(left+ttRect.width>vw-margin){left=vw-ttRect.width-margin;}// If top would be too high (tooltip clipped), switch to "bottom"
16
+ var finalPosition='top';if(top<margin){// try bottom
17
+ var bottomTop=wrapperRect.bottom+8;if(bottomTop+ttRect.height<=vh-margin){finalPosition='bottom';top=bottomTop;}else{// can't fit fully in bottom either; clamp top to margin
18
+ top=margin;}}// If using "top", ensure vertical clamp if it goes off bottom
19
+ if(finalPosition==='top'){if(top+ttRect.height>vh-margin){top=vh-ttRect.height-margin;}}// If using "bottom", clamp bottom if it would go off bottom
20
+ if(finalPosition==='bottom'){if(top+ttRect.height>vh-margin){top=vh-ttRect.height-margin;}}// 2) Compute arrow offset so it points to wrapper’s center X
21
+ var wrapperCenterX=wrapperRect.left+wrapperRect.width/2;var computedArrowLeft=wrapperCenterX-left;// Clamp arrow within [6px, ttRect.width - 6px]
22
+ var minArrow=6;var maxArrow=ttRect.width-6;if(computedArrowLeft<minArrow){computedArrowLeft=minArrow;}else if(computedArrowLeft>maxArrow){computedArrowLeft=maxArrow;}setPositionState(finalPosition);setCoords({left:left,top:top});setArrowLeft(computedArrowLeft);},[mounted]);if(!text){return children;}var portalStyle=_extends({left:"".concat(coords.left,"px"),top:"".concat(coords.top,"px")},arrowLeft!==null?{'--arrow-left':"".concat(arrowLeft,"px")}:{});var arrowClass=positionState==='top'?classes.arrowTop:classes.arrowBottom;return React.createElement("span",{className:classes.wrapper,ref:wrapperRef,"data-tooltip-id":tooltipId.current,onMouseEnter:function onMouseEnter(){return setVisible(true);},onMouseLeave:function onMouseLeave(){return setVisible(false);}},children,mounted&&ReactDOM.createPortal(React.createElement("div",{className:cx(classes.tooltipBox,arrowClass,'tooltip-box'),style:portalStyle,"data-visible":animate?'true':'false',"data-tooltip-id":tooltipId.current,dangerouslySetInnerHTML:{__html:text}}),document.body));}Tooltip.defaultProps={text:null};export default Tooltip;
@@ -0,0 +1,17 @@
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}import React,{Suspense,useCallback}from'react';import PropTypes from'prop-types';import{makeStyles}from'@shopgate/engage/styles';import{VisibilityOffIcon,TimeIcon,Loading}from'@shopgate/engage/components';import{usePressHandler}from'@shopgate/engage/core/hooks';import WidgetProvider from"./WidgetProvider";import{dispatchWidgetPreviewEvent}from"./events";import{useWidgetsPreview}from"./hooks";import Tooltip from"./Tooltip";var useStyles=makeStyles()(function(theme,_ref){var marginTop=_ref.marginTop,marginLeft=_ref.marginLeft;return{root:{position:'relative'},widgetInfo:{zIndex:12,position:'absolute',top:-marginTop+(theme.spacing(0.5)+1),left:-marginLeft+theme.spacing(0.5),fontSize:24,padding:theme.spacing(0.5),display:'flex',gap:theme.spacing(1),background:'#fff',borderRadius:4,border:'1px solid rgba(0, 0, 0, 0.23)',':empty':{display:'none'}},preview:{cursor:'pointer'},visibilityIcon:{color:'#f44336'},scheduledIcon:{color:'#347DD3'},scheduledIconExpired:{color:'#f44336'}};});/**
2
+ * @typedef {import('./types').WidgetDefinition} WidgetDefinition
3
+ */ /**
4
+ * @typedef {import('./types').ScheduledStatus} ScheduledStatus
5
+ */ /**
6
+ * The Widget component.
7
+ * @param {Object} props The component props.
8
+ * @param {React.ComponentType} props.component The widget component to render.
9
+ * @param {WidgetDefinition} props.definition The widget definition data.
10
+ * @param {boolean} props.isPreview Whether the widget is in preview mode.
11
+ * @param {boolean} props.isCustomLegacyWidget Whether the widget is a legacy custom widget provided
12
+ * by an extension that's configured via an HTML comment inside a HTML widget.
13
+ * @returns {JSX.Element}
14
+ */var Widget=function Widget(_ref2){var _ref3,_definition$layout,_ref4,_definition$layout2,_ref5,_definition$layout3,_ref6,_definition$layout4,_definition$layout5,_definition$layout6,_definition$layout7,_definition$layout8,_definition$meta,_definition$meta$sche,_definition$meta2,_definition$meta2$sch,_definition$meta3,_definition$meta3$sch,_definition$meta4,_definition$meta4$hid,_definition$meta5,_definition$meta5$hid;var Component=_ref2.component,definition=_ref2.definition,isPreview=_ref2.isPreview,isCustomLegacyWidget=_ref2.isCustomLegacyWidget;var _useStyles=useStyles({marginTop:(_ref3=definition===null||definition===void 0?void 0:(_definition$layout=definition.layout)===null||_definition$layout===void 0?void 0:_definition$layout.marginTop)!==null&&_ref3!==void 0?_ref3:0,marginBottom:(_ref4=definition===null||definition===void 0?void 0:(_definition$layout2=definition.layout)===null||_definition$layout2===void 0?void 0:_definition$layout2.marginBottom)!==null&&_ref4!==void 0?_ref4:0,marginLeft:(_ref5=definition===null||definition===void 0?void 0:(_definition$layout3=definition.layout)===null||_definition$layout3===void 0?void 0:_definition$layout3.marginLeft)!==null&&_ref5!==void 0?_ref5:0,marginRight:(_ref6=definition===null||definition===void 0?void 0:(_definition$layout4=definition.layout)===null||_definition$layout4===void 0?void 0:_definition$layout4.marginRight)!==null&&_ref6!==void 0?_ref6:0}),classes=_useStyles.classes,cx=_useStyles.cx;var _useWidgetsPreview=useWidgetsPreview(),setActiveWidget=_useWidgetsPreview.setActiveWidget,activeWidget=_useWidgetsPreview.activeWidget;// Handle clicks on the widget container in preview mode. Take care that highlighting only happens
15
+ // when the widget is not already active, otherwise it would be confusing when users want to
16
+ // interact with widget elements.
17
+ var handleInteraction=useCallback(function(){setActiveWidget(definition.code,activeWidget!==definition.code);if(activeWidget!==definition.code){dispatchWidgetPreviewEvent('widget-clicked',definition.code);}},[activeWidget,definition.code,setActiveWidget]);var handlers=usePressHandler(handleInteraction);if(!Component){return null;}return React.createElement("section",_extends({id:"widget-code-".concat(definition.code),className:cx(classes.root,_defineProperty({},classes.preview,isPreview)),style:{marginTop:definition===null||definition===void 0?void 0:(_definition$layout5=definition.layout)===null||_definition$layout5===void 0?void 0:_definition$layout5.marginTop,marginBottom:definition===null||definition===void 0?void 0:(_definition$layout6=definition.layout)===null||_definition$layout6===void 0?void 0:_definition$layout6.marginBottom,marginLeft:definition===null||definition===void 0?void 0:(_definition$layout7=definition.layout)===null||_definition$layout7===void 0?void 0:_definition$layout7.marginLeft,marginRight:definition===null||definition===void 0?void 0:(_definition$layout8=definition.layout)===null||_definition$layout8===void 0?void 0:_definition$layout8.marginRight},"data-widget-name":definition.widgetConfigDefinitionCode},isPreview&&_extends({},handlers)),isPreview&&(definition===null||definition===void 0?void 0:definition.meta)&&React.createElement("div",{className:classes.widgetInfo},((_definition$meta=definition.meta)===null||_definition$meta===void 0?void 0:(_definition$meta$sche=_definition$meta.scheduled)===null||_definition$meta$sche===void 0?void 0:_definition$meta$sche.isScheduled)&&React.createElement(Tooltip,{text:(_definition$meta2=definition.meta)===null||_definition$meta2===void 0?void 0:(_definition$meta2$sch=_definition$meta2.scheduled)===null||_definition$meta2$sch===void 0?void 0:_definition$meta2$sch.tooltip},React.createElement(TimeIcon,{className:cx(classes.scheduledIcon,_defineProperty({},classes.scheduledIconExpired,(_definition$meta3=definition.meta)===null||_definition$meta3===void 0?void 0:(_definition$meta3$sch=_definition$meta3.scheduled)===null||_definition$meta3$sch===void 0?void 0:_definition$meta3$sch.isExpired))})),((_definition$meta4=definition.meta)===null||_definition$meta4===void 0?void 0:(_definition$meta4$hid=_definition$meta4.hidden)===null||_definition$meta4$hid===void 0?void 0:_definition$meta4$hid.isHidden)&&React.createElement(Tooltip,{text:(_definition$meta5=definition.meta)===null||_definition$meta5===void 0?void 0:(_definition$meta5$hid=_definition$meta5.hidden)===null||_definition$meta5$hid===void 0?void 0:_definition$meta5$hid.tooltip},React.createElement(VisibilityOffIcon,{className:classes.visibilityIcon}))),React.createElement(WidgetProvider,{definition:definition,isPreview:isPreview},React.createElement(Suspense,{fallback:React.createElement(Loading,null)},React.createElement(Component,isCustomLegacyWidget?{settings:definition.widgetConfig}:{}))));};Widget.defaultProps={isCustomLegacyWidget:false};export default Widget;
@@ -0,0 +1,42 @@
1
+ import { type Context } from 'react';
2
+ import {
3
+ type WidgetDefinitionLayout,
4
+ type WidgetDefinitionVisibility,
5
+ type WidgetDefinition,
6
+ } from './types'
7
+
8
+ export { WidgetDefinition } from './types';
9
+
10
+ export interface WidgetContextType<C = Record<string, any>> {
11
+ /**
12
+ * The unique code of the widget instance
13
+ */
14
+ code: string;
15
+ /**
16
+ * The name of the widget
17
+ */
18
+ name: string;
19
+ /**
20
+ * The widget configuration
21
+ */
22
+ config: C;
23
+ /**
24
+ * The widget layout settings
25
+ */
26
+ layout: WidgetDefinitionLayout;
27
+ /**
28
+ * The widget visibility settings
29
+ */
30
+ visibility: WidgetDefinitionVisibility;
31
+ /**
32
+ * Whether the widget is rendered in preview mode
33
+ */
34
+ isPreview: boolean;
35
+ }
36
+
37
+ /**
38
+ * React context for widgets.
39
+ */
40
+ declare const WidgetContext: Context<WidgetContextType>;
41
+
42
+ export default WidgetContext;
@@ -0,0 +1,9 @@
1
+ import{createContext}from'react';/**
2
+ * @typedef {import('./Widgets.jsx').WidgetDefinition} WidgetDefinition
3
+ */ /**
4
+ * @typedef {Object} WidgetContextType
5
+ * @property {WidgetDefinition['code']} code The unique widget code.
6
+ * @property {WidgetDefinition['widgetConfig']} config The widget configuration.
7
+ * @property {WidgetDefinition['layout']} layout The widget layout settings.
8
+ * @property {WidgetDefinition['visibility']} visibility The widget visibility settings.
9
+ */ /** @type {React.Context<WidgetContextType>} */export var WidgetContext=createContext({});
@@ -0,0 +1,8 @@
1
+ import React,{useMemo}from'react';import PropTypes from'prop-types';import{WidgetContext}from"./WidgetContext";/** @typedef {import('./WidgetContext').WidgetContextType} WidgetContextType */ /** @typedef {import('./WidgetContext').WidgetDefinition} WidgetDefinition */ /**
2
+ * The WidgetProvider component provides the context for a single widget.
3
+ * @param {Object} props The component props.
4
+ * @param {WidgetDefinition} props.definition The widget definition data.
5
+ * @param {boolean} props.isPreview Whether the widget is in preview mode.
6
+ * @param {React.ReactNode} props.children The child components to render.
7
+ * @returns {JSX.Element}
8
+ */var WidgetProvider=function WidgetProvider(_ref){var children=_ref.children,definition=_ref.definition,isPreview=_ref.isPreview;/** @type {WidgetContextType} */var value=useMemo(function(){var widgetConfig=definition.widgetConfig,layout=definition.layout,visibility=definition.visibility,code=definition.code,widgetConfigDefinitionCode=definition.widgetConfigDefinitionCode;return{code:code,name:widgetConfigDefinitionCode,config:widgetConfig,layout:layout,visibility:visibility,isPreview:isPreview};},[definition,isPreview]);return React.createElement(WidgetContext.Provider,{value:value},children);};export default WidgetProvider;
@@ -0,0 +1,11 @@
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,{useMemo,useRef}from'react';import PropTypes from'prop-types';import{makeStyles}from'@shopgate/engage/styles';import{useRoute,useThemeWidgets}from'@shopgate/engage/core/hooks';import{PAGE_PREVIEW_PATTERN}from'@shopgate/engage/page/constants';import{ConditionalWrapper}from'@shopgate/engage/components';import WidgetsPreviewProvider from"./WidgetsPreviewProvider";import Widget from"./Widget";import Overlay from"./Overlay";import{checkScheduled}from"./helpers";import{usePreviewIframeCommunication}from"./hooks";/**
2
+ * @typedef {import('./types').WidgetDefinition} WidgetDefinition
3
+ */var PLACEHOLDER_COMPONENT='@shopgate/widgetsInternal/Placeholder';var useStyles=makeStyles()({preview:{'& *':{scrollbarWidth:'thin'}}});/**
4
+ * The Widgets component renders a list of widgets.
5
+ * @param {Object} props The component props.
6
+ * @param {Array<WidgetDefinition>} props.widgets The list of widgets to render.
7
+ * @returns {JSX.Element}
8
+ */var Widgets=function Widgets(_ref){var _ref$widgets=_ref.widgets,widgetsProp=_ref$widgets===void 0?[]:_ref$widgets;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var _useRoute=useRoute(),pattern=_useRoute.pattern;var widgetsRef=useRef(null);var isPreview=pattern===PAGE_PREVIEW_PATTERN;var widgetComponents=useThemeWidgets('v2');usePreviewIframeCommunication(isPreview);// Create sanitized widgets array that only includes widgets with valid components.
9
+ var widgets=useMemo(function(){if(isPreview){// All widgets are allowed in preview mode.
10
+ return widgetsProp;}// Remove widgets that do not have a valid component.
11
+ return widgetsProp.filter(function(widget){return!!widgetComponents[widget.widgetConfigDefinitionCode]&&checkScheduled({from:widget===null||widget===void 0?void 0:widget.visibility.scheduleStartDate,to:widget===null||widget===void 0?void 0:widget.visibility.scheduleEndDate}).isActive;});},[isPreview,widgetComponents,widgetsProp]);if(!Array.isArray(widgets)||widgets.length===0){return null;}return React.createElement(ConditionalWrapper,{condition:isPreview,wrapper:function wrapper(children){return React.createElement(WidgetsPreviewProvider,null,children,React.createElement(Overlay,{containerRef:widgetsRef}));}},React.createElement("div",{className:cx('engage__widgets',_defineProperty({},classes.preview,isPreview)),ref:widgetsRef},widgets.map(function(widget){var component=widgetComponents[widget.widgetConfigDefinitionCode]||widgetComponents[PLACEHOLDER_COMPONENT];return React.createElement(Widget,{key:widget.code,definition:widget,isPreview:isPreview,component:component,isCustomLegacyWidget:widget.isCustomLegacyWidget});})));};Widgets.defaultProps={widgets:null};export default Widgets;
@@ -0,0 +1,9 @@
1
+ import _noop from"lodash/noop";import{createContext}from'react';/**
2
+ * @callback SetActiveWidget
3
+ * @param {string} code The code of the widget to set as active.
4
+ * @param {boolean} [highlight=false] Whether to highlight the widget after setting it as active.
5
+ */ /**
6
+ * @typedef {Object} WidgetsPreviewContextType
7
+ * @property {string} activeWidget The code of the currently active widget.
8
+ * @property {SetActiveWidget} setActiveWidget A function to set the active widget code
9
+ */ /** @type {React.Context<WidgetsPreviewContextType>} */export var WidgetsPreviewContext=createContext({activeWidget:null,setActiveWidget:_noop});
@@ -0,0 +1,8 @@
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,{useMemo,useState,useCallback}from'react';import PropTypes from'prop-types';import{useWidgetPreviewEvent,dispatchWidgetPreviewEvent}from"./events";import{WidgetsPreviewContext}from"./WidgetsPreviewContext";/**
2
+ * The WidgetsPreviewProvider component is used by the Widgets component when it's rendered
3
+ * in preview mode. It provides functionality for the Widget component that's needed when
4
+ * the widgets are rendered in the preview iframe.
5
+ * @param {Object} props The component props.
6
+ * @param {React.ReactNode} props.children The child components to render.
7
+ * @returns {JSX.Element}
8
+ */var WidgetsPreviewProvider=function WidgetsPreviewProvider(_ref){var children=_ref.children;var _useState=useState(null),_useState2=_slicedToArray(_useState,2),activeWidget=_useState2[0],setActiveWidget=_useState2[1];useWidgetPreviewEvent('set-active-widget-id',function(e){setActiveWidget(e.detail.widgetCode);});var handleSetActiveWidget=useCallback(function(code){var highlight=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;setActiveWidget(code);if(highlight){dispatchWidgetPreviewEvent('highlight-widget',code);}},[]);var value=useMemo(function(){return{activeWidget:activeWidget,setActiveWidget:handleSetActiveWidget};},[activeWidget,handleSetActiveWidget]);return React.createElement(WidgetsPreviewContext.Provider,{value:value},children);};export default WidgetsPreviewProvider;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * List of allowed origins for cms page preview iFrame communication.
3
+ */export var ALLOWED_PAGE_PREVIEW_ORIGINS=['https://next.admin.shopgatedev.com','https://next.admin.shopgatepg.com','https://next.admin.shopgate.com','https://next.us.admin.shopgate.com','http://localhost:1337'];// Whether to consider vertical margins when calculating the overlay position.
4
+ export var CONSIDER_CONTAINER_MARGINS_ON_SCROLL_DEFAULT=false;
@@ -0,0 +1,23 @@
1
+ import{useEffect}from'react';/**
2
+ * @typedef {"highlight-widget"|"widget-clicked"|"set-active-widget-id"} WidgetPreviewEventName
3
+ */ /**
4
+ * @typedef {Object} WidgetPreviewEventDetail
5
+ * @property {string} widgetCode The code of the widget related to the event.
6
+ * @property {any} [payload] Optional payload data related to the event.
7
+ */ /**
8
+ * @callback WidgetPreviewEventHandler
9
+ * @param {CustomEvent<WidgetPreviewEventDetail>} event The custom event dispatched for the widget
10
+ * preview.
11
+ */ /**
12
+ * Hook to listen for widget preview events.
13
+ * These events are dispatched in the context of iFrame communication at the widget preview.
14
+ * @param {WidgetPreviewEventName} eventName Name of the listened event
15
+ * @param {WidgetPreviewEventHandler} handler A callback function to handle the event
16
+ */export var useWidgetPreviewEvent=function useWidgetPreviewEvent(eventName,handler){useEffect(function(){window.addEventListener("widget-preview-".concat(eventName),handler);return function(){window.removeEventListener("widget-preview-".concat(eventName),handler);};},[eventName,handler]);};/**
17
+ * Dispatches widget preview related events.
18
+ * Used to trigger iFrame postMessage events to the parent window or to react on incoming
19
+ * postMessage events from the parent window.
20
+ * @param {WidgetPreviewEventName} eventName Name of the event to dispatch
21
+ * @param {string} widgetCode Code of the widget to dispatch the event for
22
+ * @param {Object} [payload] Optional payload to include with the event
23
+ */export var dispatchWidgetPreviewEvent=function dispatchWidgetPreviewEvent(eventName,widgetCode){var payload=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var event=new CustomEvent("widget-preview-".concat(eventName),{detail:{widgetCode:widgetCode,payload:payload}});window.dispatchEvent(event);};