@shopgate/engage 7.27.5-alpha.1 → 7.27.5

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 (139) hide show
  1. package/category/components/CategoryImage/index.js +1 -1
  2. package/category/components/CategoryList/index.js +3 -7
  3. package/category/components/CategoryList/style.js +1 -1
  4. package/category/streams/index.js +1 -1
  5. package/components/ResponsiveContainer/breakpoints.js +2 -2
  6. package/components/SheetList/components/Item/index.js +7 -7
  7. package/components/View/components/Content/style.js +1 -1
  8. package/components/View/context.js +1 -1
  9. package/components/index.js +1 -1
  10. package/core/constants/index.js +1 -7
  11. package/core/contexts/ThemeResourcesContext.d.ts +1 -10
  12. package/core/contexts/ThemeResourcesContext.js +1 -1
  13. package/core/helpers/scrollContainer.js +2 -2
  14. package/core/hocs/withThemeResources.js +1 -4
  15. package/core/hooks/events/index.js +1 -1
  16. package/core/hooks/useThemeResources.js +5 -6
  17. package/core/providers/ThemeResourcesProvider.js +5 -9
  18. package/locations/action-creators/index.js +1 -1
  19. package/locations/action-creators/selectLocation.js +8 -5
  20. package/locations/action-creators/sendDefaultLocationCode.js +14 -0
  21. package/locations/actions/fetchDefaultLocation.js +1 -1
  22. package/locations/actions/sendDefaultLocationCode.js +2 -2
  23. package/locations/components/GlobalLocationSelector/GlobalLocationSelector.js +2 -2
  24. package/locations/components/GlobalLocationSwitcher/GlobalLocationSwitcher.js +3 -1
  25. package/locations/constants/ActionTypes.js +2 -1
  26. package/locations/constants/index.js +1 -1
  27. package/locations/index.js +1 -1
  28. package/locations/locations.streams.js +3 -1
  29. package/locations/providers/FulfillmentProvider.js +6 -5
  30. package/locations/providers/StoreDetailsProvider.js +4 -2
  31. package/locations/providers/StoreFinderProvider.js +5 -3
  32. package/locations/subscriptions.js +12 -13
  33. package/package.json +7 -9
  34. package/page/components/index.js +1 -1
  35. package/page/constants/index.js +1 -5
  36. package/page/index.js +2 -1
  37. package/page/selectors/index.js +2 -48
  38. package/product/components/ProductCard/index.js +1 -1
  39. package/product/components/ProductGridPrice/index.js +1 -1
  40. package/product/components/ProductSlider/index.js +4 -4
  41. package/product/components/index.js +1 -1
  42. package/styles/helpers/index.js +1 -1
  43. package/styles/helpers/setPageBackgroundColor.js +2 -2
  44. package/styles/index.js +1 -1
  45. package/tracking/selectors/cookieConsent.js +2 -2
  46. package/components/Typography/Typography.d.ts +0 -132
  47. package/components/Typography/Typography.js +0 -11
  48. package/components/Typography/index.js +0 -1
  49. package/core/hooks/events/usePressHandler.js +0 -38
  50. package/page/action-creators/index.js +0 -22
  51. package/page/components/Widgets/Overlay.js +0 -51
  52. package/page/components/Widgets/Tooltip.js +0 -22
  53. package/page/components/Widgets/Widget.js +0 -15
  54. package/page/components/Widgets/WidgetContext.d.ts +0 -42
  55. package/page/components/Widgets/WidgetContext.js +0 -9
  56. package/page/components/Widgets/WidgetProvider.js +0 -8
  57. package/page/components/Widgets/Widgets.js +0 -11
  58. package/page/components/Widgets/WidgetsPreviewContext.js +0 -9
  59. package/page/components/Widgets/WidgetsPreviewProvider.js +0 -8
  60. package/page/components/Widgets/constants.js +0 -4
  61. package/page/components/Widgets/events.js +0 -23
  62. package/page/components/Widgets/helpers.js +0 -23
  63. package/page/components/Widgets/hooks.js +0 -69
  64. package/page/components/Widgets/index.js +0 -1
  65. package/page/components/Widgets/types.d.ts +0 -127
  66. package/page/constants/actionTypes.js +0 -1
  67. package/page/hooks/index.d.ts +0 -60
  68. package/page/hooks/index.js +0 -25
  69. package/page/reducers/index.js +0 -6
  70. package/page/subscriptions/index.js +0 -4
  71. package/page/widgets/CategoryList/CategoryList.js +0 -4
  72. package/page/widgets/CategoryList/hooks.js +0 -14
  73. package/page/widgets/CategoryList/index.js +0 -1
  74. package/page/widgets/HTML/HTML.js +0 -5
  75. package/page/widgets/HTML/hooks.js +0 -12
  76. package/page/widgets/HTML/index.js +0 -1
  77. package/page/widgets/Headline/Headline.js +0 -5
  78. package/page/widgets/Headline/hooks.js +0 -8
  79. package/page/widgets/Headline/index.js +0 -1
  80. package/page/widgets/Placeholder/Placeholder.js +0 -5
  81. package/page/widgets/Placeholder/hooks.js +0 -12
  82. package/page/widgets/Placeholder/index.js +0 -1
  83. package/page/widgets/ProductList/ProductList.js +0 -5
  84. package/page/widgets/ProductList/hooks.js +0 -25
  85. package/page/widgets/ProductList/index.js +0 -1
  86. package/page/widgets/ProductSlider/ProductSlider.js +0 -5
  87. package/page/widgets/ProductSlider/hooks.js +0 -28
  88. package/page/widgets/ProductSlider/index.js +0 -1
  89. package/page/widgets/index.js +0 -1
  90. package/page/widgets/widgets.json +0 -20
  91. package/product/components/ProductGrid/components/Item/components/ItemDetails/index.js +0 -8
  92. package/product/components/ProductGrid/components/Item/components/ItemDetails/spec.js +0 -1
  93. package/product/components/ProductGrid/components/Item/components/ItemDiscount/index.js +0 -5
  94. package/product/components/ProductGrid/components/Item/components/ItemFavoritesButton/index.js +0 -5
  95. package/product/components/ProductGrid/components/Item/components/ItemFavoritesButton/spec.js +0 -1
  96. package/product/components/ProductGrid/components/Item/components/ItemImage/index.js +0 -5
  97. package/product/components/ProductGrid/components/Item/components/ItemImage/spec.js +0 -1
  98. package/product/components/ProductGrid/components/Item/components/ItemName/index.js +0 -5
  99. package/product/components/ProductGrid/components/Item/components/ItemName/spec.js +0 -1
  100. package/product/components/ProductGrid/components/Item/components/ItemPrice/index.js +0 -5
  101. package/product/components/ProductGrid/components/Item/components/ItemPrice/spec.js +0 -1
  102. package/product/components/ProductGrid/components/Item/index.js +0 -7
  103. package/product/components/ProductGrid/components/Iterator/index.js +0 -5
  104. package/product/components/ProductGrid/components/Layout/index.js +0 -5
  105. package/product/components/ProductGrid/index.js +0 -22
  106. package/product/components/ProductGrid/spec.js +0 -1
  107. package/styles/helpers/color.js +0 -23
  108. package/styles/index.d.ts +0 -17
  109. package/styles/theme/createTheme/createBreakpoints.d.ts +0 -114
  110. package/styles/theme/createTheme/createBreakpoints.js +0 -41
  111. package/styles/theme/createTheme/createPalette.d.ts +0 -36
  112. package/styles/theme/createTheme/createPalette.js +0 -4
  113. package/styles/theme/createTheme/createSpacing.d.ts +0 -23
  114. package/styles/theme/createTheme/createSpacing.js +0 -14
  115. package/styles/theme/createTheme/createTypography.d.ts +0 -55
  116. package/styles/theme/createTheme/createTypography.js +0 -23
  117. package/styles/theme/createTheme/index.d.ts +0 -41
  118. package/styles/theme/createTheme/index.js +0 -5
  119. package/styles/theme/createTheme/transitions.d.ts +0 -100
  120. package/styles/theme/createTheme/transitions.js +0 -26
  121. package/styles/theme/createTheme/zIndex.d.ts +0 -12
  122. package/styles/theme/createTheme/zIndex.js +0 -3
  123. package/styles/theme/hooks/index.d.ts +0 -4
  124. package/styles/theme/hooks/index.js +0 -1
  125. package/styles/theme/hooks/useActiveBreakpoint.d.ts +0 -18
  126. package/styles/theme/hooks/useActiveBreakpoint.js +0 -4
  127. package/styles/theme/hooks/useMediaQuery.d.ts +0 -33
  128. package/styles/theme/hooks/useMediaQuery.js +0 -20
  129. package/styles/theme/hooks/useResponsiveValue.d.ts +0 -27
  130. package/styles/theme/hooks/useResponsiveValue.js +0 -4
  131. package/styles/theme/hooks/useTheme.d.ts +0 -8
  132. package/styles/theme/hooks/useTheme.js +0 -4
  133. package/styles/theme/index.d.ts +0 -8
  134. package/styles/theme/index.js +0 -1
  135. package/styles/theme/providers/ActiveBreakpointProvider.d.ts +0 -21
  136. package/styles/theme/providers/ActiveBreakpointProvider.js +0 -13
  137. package/styles/theme/providers/ThemeProvider.d.ts +0 -18
  138. package/styles/theme/providers/ThemeProvider.js +0 -7
  139. package/styles/tss/index.js +0 -3
@@ -1,14 +0,0 @@
1
- import _camelCase from"lodash/camelCase";import{useWidget}from'@shopgate/engage/page/hooks';import{useSelector,useDispatch}from'react-redux';import{getCategory}from'@shopgate/pwa-common-commerce/category/selectors';import{fetchCategoryOrRootCategories}from'@shopgate/engage/category/actions';import{useEffect,useMemo}from'react';import{getCategoriesById}from'@shopgate/theme-ios11/widgets/selectors';/**
2
- * @typedef {Object} CategoryListWidgetConfig
3
- * @property {string} category The parent category ID to display categories for.
4
- * @property {string} [sort] The sort order for categories
5
- * @property {boolean} [showImages] Whether to display images for categories.
6
- */ /**
7
- * @typedef {ReturnType< typeof import('@shopgate/engage/page/hooks')
8
- * .useWidget<CategoryListWidgetConfig> >} UseWidgetReturnType
9
- */ // eslint-disable-next-line valid-jsdoc
10
- /**
11
- * Hook to access the Category List widget configuration and data.
12
- */export var useCategoryListWidget=function useCategoryListWidget(){/** @type {UseWidgetReturnType} */var _useWidget=useWidget(),config=_useWidget.config;var dispatch=useDispatch();var category=config.category,sort=config.sort,showImages=config.showImages;var sortCC=useMemo(function(){return _camelCase(sort);},[sort]);// Get the parent category object from the selected category
13
- var parentCategory=useSelector(function(state){return category?getCategory(state,{categoryId:category}):null;});// Get category children of the selected category (pipeline handles sorting)
14
- var categories=useSelector(function(state){return typeof category==='string'?getCategoriesById(state,{categoryId:category}):null;});var sortedCategories=useMemo(function(){if(!categories){return[];}if(sortCC==='relevance'){return categories;}var isAsc=sortCC==='nameAsc';return[].concat(categories).sort(function(a,b){return a.name.localeCompare(b.name,undefined,{sensitivity:'base'})*(isAsc?1:-1);});},[categories,sortCC]);useEffect(function(){dispatch(fetchCategoryOrRootCategories(category));},[category,dispatch]);return{parentCategory:parentCategory,showImages:showImages,categories:sortedCategories};};
@@ -1 +0,0 @@
1
- export{default}from"./CategoryList";
@@ -1,5 +0,0 @@
1
- import React from'react';import{HtmlSanitizer}from'@shopgate/engage/components';import{makeStyles}from'@shopgate/engage/styles';import{themeConfig}from'@shopgate/engage';import{useHtmlWidget}from"./hooks";var colors=themeConfig.colors;var useStyles=makeStyles()({root:{' h1, h2, h3, h4, h5, h6, p, ul, ol':{margin:'1rem 0'},' h1, h2, h3, h4, h5, h6':{fontWeight:600},' h1':{fontSize:'1.5rem'},' h2':{fontSize:'1.25rem'},' h3':{fontSize:'1.1rem'},' h4, h5, h6':{fontSize:'1rem'},' ol, ul':{paddingLeft:'1rem'},' ol > li':{listStyle:'decimal'},' ul > li':{listStyle:'disc'},' img':{display:'initial'},' img[style*="float: left"], img[style*="float:left"], img.pull-left':{marginRight:'1rem'},' img[style*="float: right"], img[style*="float:right"], img.pull-right':{marginLeft:'1rem'},' code, pre':{whiteSpace:'pre-wrap'},' blockquote, q':{paddingLeft:'1rem',margin:'2rem 0',borderLeft:".25rem solid ".concat(colors.shade6),fontStyle:'italic'},' > :first-child':{marginTop:0},// Clearfix for floated widget content
2
- ':after':{clear:'both',content:'.',display:'block',visibility:'hidden',height:0}}});/**
3
- * The HtmlWidget component is used to display html code.
4
- * @returns {JSX.Element}
5
- */var HtmlWidget=function HtmlWidget(){var _useStyles=useStyles(),classes=_useStyles.classes;var _useHtmlWidget=useHtmlWidget(),html=_useHtmlWidget.html;return React.createElement(HtmlSanitizer,{settings:{html:html},processStyles:true,className:classes.root},html);};export default HtmlWidget;
@@ -1,12 +0,0 @@
1
- import{useWidget}from'@shopgate/engage/page/hooks';/**
2
- * @typedef {Object} HtmlWidgetConfig
3
- * @property {string} [html] - The HTML content to render.
4
- * @property {string} [internalDescription] - Internal description for the widget.
5
- */ /**
6
- * @typedef {Object} UseHtmlWidgetReturnType
7
- * @property {string} [html] - The HTML content to render.
8
- * @property {string} [internalDescription] - Internal description for the widget.
9
- */ /**
10
- * Hook to access the html widget configuration.
11
- * @returns {UseHtmlWidgetReturnType} the html widget configuration
12
- */export var useHtmlWidget=function useHtmlWidget(){/** @type {UseWidgetReturnType} */var _useWidget=useWidget(),config=_useWidget.config;var html=config.html;return{html:html};};
@@ -1 +0,0 @@
1
- export{default}from"./HTML";
@@ -1,5 +0,0 @@
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{makeStyles}from'@shopgate/engage/styles';import{Typography}from'@shopgate/engage/components';import{useHeadlineWidget}from"./hooks";var useStyles=makeStyles()(function(theme){return{root:{padding:theme.spacing(2)}};});/**
2
- * The HeadlineWidget is used to display a headline text.
3
- * @returns {JSX.Element}
4
- */var Headline=function Headline(){var _useStyles=useStyles(),cx=_useStyles.cx,css=_useStyles.css,classes=_useStyles.classes;var _useHeadlineWidget=useHeadlineWidget(),headline=_useHeadlineWidget.headline,align=_useHeadlineWidget.align,variant=_useHeadlineWidget.variant,styles=_useHeadlineWidget.styles;if(!headline)return null;return React.createElement(Typography// && increases the specificity of the styles which guarantees that defaults are overridden
5
- ,{className:cx(css({'&&':_extends({},styles)}),classes.root),variant:variant,align:align,gutterBottom:true},headline);};export default Headline;
@@ -1,8 +0,0 @@
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{useWidget}from'@shopgate/engage/page/hooks';/**
2
- * @typedef {Object} HeadlineWidgetConfig
3
- * @property {Object} [headline] - The headline configuration object.
4
- * @property {string} [headline.text] - The text to display as the headline.
5
- */ // eslint-disable-next-line valid-jsdoc
6
- /**
7
- * Custom hook to retrieve the headline widget configuration.
8
- */export var useHeadlineWidget=function useHeadlineWidget(){var _useWidget=useWidget(),config=_useWidget.config;var _config$headline=config.headline,bold=_config$headline.bold,italic=_config$headline.italic,text=_config$headline.text,underline=_config$headline.underline,textAlign=_config$headline.textAlign,typography=_config$headline.typography;var styles=_extends({},bold&&{fontWeight:'bold'},{},italic&&{fontStyle:'italic'},{},underline&&{textDecoration:'underline'});return{headline:text,variant:typography!==null&&typography!==void 0?typography:'h3',align:textAlign,styles:styles};};
@@ -1 +0,0 @@
1
- export{default}from"./Headline";
@@ -1,5 +0,0 @@
1
- import React from'react';import{makeStyles}from'@shopgate/engage/styles';import{usePlaceholderWidget}from"./hooks";var useStyles=makeStyles()(function(theme){return{root:{padding:theme.spacing(2),minHeight:200},name:{fontSize:14},pre:{background:'#f7f9fc',border:'1px solid #dbdde2',borderRadius:8,color:'#000',fontSize:10,overflowY:'auto',padding:theme.spacing(1)}};});/**
2
- * The PlaceholderWidget component is used to display a placeholder for widget types that
3
- * are not implemented yet.
4
- * @returns {JSX.Element}
5
- */var PlaceholderWidget=function PlaceholderWidget(){var _useStyles=useStyles(),classes=_useStyles.classes;var _usePlaceholderWidget=usePlaceholderWidget(),code=_usePlaceholderWidget.code,name=_usePlaceholderWidget.name,config=_usePlaceholderWidget.config,layout=_usePlaceholderWidget.layout,visibility=_usePlaceholderWidget.visibility;return React.createElement("div",{className:classes.root},React.createElement("div",{className:classes.name},name),React.createElement("pre",{className:classes.pre},JSON.stringify({code:code,config:config,layout:layout,visibility:visibility},null,2)));};export default PlaceholderWidget;
@@ -1,12 +0,0 @@
1
- import{useWidget}from'@shopgate/engage/page/hooks';/**
2
- * @typedef {Object} PlaceholderWidgetConfig
3
- * @property {string} foo Example property for the widget configuration.
4
- * @property {number} bar Another example property for the widget configuration.
5
- */ /**
6
- * @typedef {ReturnType< typeof import('@shopgate/engage/page/hooks')
7
- * .useWidget<PlaceholderWidgetConfig> >} HookReturnType
8
- */ /**
9
- * Local example hook to demonstrate how to extend the useWidget hook with a custom type for
10
- * the widget configuration.
11
- * @returns {HookReturnType}
12
- */export var usePlaceholderWidget=function usePlaceholderWidget(){return useWidget();};
@@ -1 +0,0 @@
1
- export{default}from"./Placeholder";
@@ -1,5 +0,0 @@
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";var useStyles=makeStyles()({root:{// Prevent that the ActionButton margin messes with the layout of the sibling widgets
2
- overflow:'hidden'},grid:{'&&':{marginTop:0}}});/**
3
- * The ProductListWidget is used to display product lists.
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;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},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;
@@ -1,25 +0,0 @@
1
- import _camelCase from"lodash/camelCase";import{useMemo}from'react';import{useWidget}from'@shopgate/engage/page/hooks';/**
2
- * @typedef {Object} ProductListWidgetProducts
3
- * @property {"searchTerm" | "brand" | "category" | "itemNumbers"} productSelectorType Source type
4
- * for the product list.
5
- * @property {string} productsSearchTerm A search term to filter products by
6
- * @property {string} productsBrand A brand to filter products by
7
- * @property {string} productsCategory A category to filter products by
8
- * @property {string} productsItemNumbers A comma-separated list of item numbers to filter products
9
- * by
10
- */ /**
11
- * @typedef {Object} ProductListWidgetConfig
12
- * @property {ProductListWidgetProducts} products The products configuration for the widget.
13
- * @property {number} productCount The number of products to display in the widget
14
- * @property {"relevance" | "PriceDesc" | "PriceAsc"} sort Sort order for the products
15
- * @property {boolean} loadMoreButton Whether to display a "Load more" button
16
- * @property {boolean} showName Whether to display product names
17
- * @property {boolean} showPrice Whether to display product prices
18
- * @property {boolean} showRating Whether to display product ratings
19
- */ /**
20
- * @typedef {ReturnType< typeof import('@shopgate/engage/page/hooks')
21
- * .useWidget<ProductListWidgetConfig> >} UseWidgetReturnType
22
- */ // eslint-disable-next-line valid-jsdoc
23
- /**
24
- * Hook to access the Product List widget configuration.
25
- */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;var productSelectorType=products.productSelectorType,productsBrand=products.productsBrand,productsCategory=products.productsCategory,productsItemNumbers=products.productsItemNumbers,productsSearchTerm=products.productsSearchTerm;var value=useMemo(function(){switch(productSelectorType){case'brand':return productsBrand;case'category':return productsCategory;case'itemNumbers':return productsItemNumbers.split(',').map(function(item){return item.trim();});case'searchTerm':default:return productsSearchTerm;}},[productSelectorType,productsBrand,productsCategory,productsItemNumbers,productsSearchTerm]);var flags=useMemo(function(){return{name:showName,price:showPrice,reviews:showRating};},[showName,showPrice,showRating]);return{productsSearchType:productSelectorType,productsSearchValue:value,sort:_camelCase(sort),productCount:productCount,showLoadMore:loadMoreButton,flags:flags};};
@@ -1 +0,0 @@
1
- export{default}from"./ProductList";
@@ -1,5 +0,0 @@
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,{useMemo}from'react';import{ProductSlider}from'@shopgate/engage/product/components';import{useWidgetProducts}from'@shopgate/engage/page/hooks';import{useTheme}from'@shopgate/engage/styles';import{useProductSliderWidget}from"./hooks";/**
2
- * The ProductSliderWidget is used to display a product slider.
3
- * @returns {JSX.Element}
4
- */var ProductSliderWidget=function ProductSliderWidget(){var _useProductSliderWidg=useProductSliderWidget(),productsSearchType=_useProductSliderWidg.productsSearchType,productsSearchValue=_useProductSliderWidg.productsSearchValue,sort=_useProductSliderWidg.sort,productCount=_useProductSliderWidg.productCount,swiperProps=_useProductSliderWidg.swiperProps,productItemProps=_useProductSliderWidg.productItemProps,isPreview=_useProductSliderWidg.isPreview;var _useWidgetProducts=useWidgetProducts({type:productsSearchType,value:productsSearchValue,limit:productCount,sort:sort}),results=_useWidgetProducts.results;var theme=useTheme();var productIds=useMemo(function(){return results===null||results===void 0?void 0:results.map(function(result){return result.id;});},[results]);if(!productIds||!productIds.length){return null;}return React.createElement(ProductSlider,_extends({productIds:productIds,scope:"widgets",productItemProps:productItemProps,slidesPerView:2.3// Improves interaction with the slider in the CMS preview iframe
5
- },isPreview?{touchStartPreventDefault:true}:{},{breakpoints:_defineProperty(_defineProperty(_defineProperty({},theme.breakpoints.values.sm,{slidesPerView:3.3}),theme.breakpoints.values.md,{slidesPerView:4.3}),theme.breakpoints.values.lg,{slidesPerView:5.3})},swiperProps));};export default ProductSliderWidget;
@@ -1,28 +0,0 @@
1
- import _camelCase from"lodash/camelCase";import{useMemo}from'react';import{useWidget}from'@shopgate/engage/page/hooks';/**
2
- * @typedef {Object} ProductSliderWidgetProducts
3
- * @property {"searchTerm" | "brand" | "category" | "itemNumbers"} productSelectorType
4
- * Source type for the product list.
5
- * @property {string} [productsSearchTerm] A search term to filter products by.
6
- * @property {string} [productsBrand] A brand to filter products by.
7
- * @property {string} [productsCategory] A category to filter products by.
8
- * @property {string} [productsItemNumbers] A comma-separated list of item numbers
9
- * to filter products by.
10
- */ /**
11
- * @typedef {Object} ProductSliderWidgetConfig
12
- * @property {ProductSliderWidgetProducts} products The products configuration for the widget.
13
- * @property {number} productCount The number of products to display in the widget.
14
- * @property {"relevance" | "priceDesc" | "priceAsc"} sort Sort order for the products.
15
- * @property {boolean} [showName] Whether to display product names.
16
- * @property {boolean} [showPrice] Whether to display product prices.
17
- * @property {boolean} [showRating] Whether to display product ratings.
18
- * @property {boolean} [slideAutomatic] Whether the slider should automatically slide.
19
- * @property {boolean} [endlessSlider] Whether the slider should loop endlessly.
20
- * @property {number} [sliderSpeed] The speed (in ms) for the slider autoplay.
21
- * @property {boolean} [isPreview] Whether the widget is in preview mode.
22
- */ /**
23
- * @typedef {ReturnType< typeof import('@shopgate/engage/page/hooks')
24
- * .useWidget<ProductSliderWidgetConfig> >} UseWidgetReturnType
25
- */ // eslint-disable-next-line valid-jsdoc
26
- /**
27
- * Hook to access the Product Slider widget configuration.
28
- */export var useProductSliderWidget=function useProductSliderWidget(){/** @type {UseWidgetReturnType} */var _useWidget=useWidget(),config=_useWidget.config,isPreview=_useWidget.isPreview;var products=config.products,productCount=config.productCount,sort=config.sort,_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$slideAutomati=config.slideAutomatic,slideAutomatic=_config$slideAutomati===void 0?true:_config$slideAutomati,_config$endlessSlider=config.endlessSlider,endlessSlider=_config$endlessSlider===void 0?true:_config$endlessSlider,_config$sliderSpeed=config.sliderSpeed,sliderSpeed=_config$sliderSpeed===void 0?7000:_config$sliderSpeed;var productSelectorType=products.productSelectorType,productsBrand=products.productsBrand,productsCategory=products.productsCategory,productsItemNumbers=products.productsItemNumbers,productsSearchTerm=products.productsSearchTerm;var value=useMemo(function(){switch(productSelectorType){case'brand':return productsBrand;case'category':return productsCategory;case'itemNumbers':return productsItemNumbers.split(',').map(function(item){return item.trim();});case'searchTerm':default:return productsSearchTerm;}},[productSelectorType,productsBrand,productsCategory,productsItemNumbers,productsSearchTerm]);var swiperProps=useMemo(function(){return{autoplay:slideAutomatic,delay:sliderSpeed,loop:endlessSlider};},[slideAutomatic,sliderSpeed,endlessSlider]);var productItemProps=useMemo(function(){return{hideName:!showName,hidePrice:!showPrice,hideRating:!showRating};},[showName,showPrice,showRating]);return{productsSearchType:productSelectorType,productsSearchValue:value,sort:_camelCase(sort),productCount:productCount,swiperProps:swiperProps,productItemProps:productItemProps,isPreview:isPreview};};
@@ -1 +0,0 @@
1
- export{default}from"./ProductSlider";
@@ -1 +0,0 @@
1
- export{default as PlaceholderWidget}from"./Placeholder";export{default as ProductListWidget}from"./ProductList";export{default as CategoryListWidget}from"./CategoryList";export{default as HtmlWidget}from"./HTML";export{default as ProductSliderWidget}from"./ProductSlider";export{default as HeadlineWidget}from"./Headline";
@@ -1,20 +0,0 @@
1
- {
2
- "@shopgate/widgetsInternal/Placeholder": {
3
- "path": "@shopgate/engage/page/widgets/Placeholder"
4
- },
5
- "@shopgate/widgets/productListWidget": {
6
- "path": "@shopgate/engage/page/widgets/ProductList"
7
- },
8
- "@shopgate/widgets/categoryListWidget": {
9
- "path": "@shopgate/engage/page/widgets/CategoryList"
10
- },
11
- "@shopgate/widgets/productSliderWidget": {
12
- "path": "@shopgate/engage/page/widgets/ProductSlider"
13
- },
14
- "@shopgate/widgets/htmlWidget": {
15
- "path": "@shopgate/engage/page/widgets/HTML"
16
- },
17
- "@shopgate/widgets/headlineWidget": {
18
- "path": "@shopgate/engage/page/widgets/Headline"
19
- }
20
- }
@@ -1,8 +0,0 @@
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,memo}from'react';import PropTypes from'prop-types';import{MapPriceHint,OrderQuantityHint,EffectivityDates,Swatches,AVAILABILITY_STATE_OK,AVAILABILITY_STATE_ALERT,getProductRoute}from'@shopgate/engage/product';import{hasNewServices as checkHasNewServices,i18n}from'@shopgate/engage/core/helpers';import{Availability,Link}from'@shopgate/engage/components';import{StockInfoLists}from'@shopgate/engage/locations/components';import{makeStyles}from'@shopgate/engage/styles';import ItemName from"../ItemName";import ItemPrice from"../ItemPrice";var useStyles=makeStyles()({root:{lineHeight:1.2,':not(:empty)':{padding:'12px 0 16px'}},quantityHint:{paddingTop:8}});/**
2
- * The Product Grid Item Detail component.
3
- * @param {Object} props The component props.
4
- * @param {Object} props.product The product.
5
- * @param {Object} props.display The display object.
6
- * @param {Object} [props.productListTypeMeta] Optional meta object with data from the product list
7
- * @returns {JSX.Element}
8
- */var ItemDetails=function ItemDetails(_ref){var product=_ref.product,display=_ref.display,productListTypeMeta=_ref.productListTypeMeta;var productId=product.id,_product$name=product.name,name=_product$name===void 0?null:_product$name,_product$stock=product.stock,stock=_product$stock===void 0?null:_product$stock;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var hasNewServices=useMemo(function(){return checkHasNewServices();},[]);if(display&&!display.name&&!display.price&&!display.reviews){return null;}return React.createElement(Link,{className:cx(classes.root,'theme__product-grid__item__item-details'),tabIndex:0,href:getProductRoute(productId),state:_extends({title:product.name},productListTypeMeta)},React.createElement(Swatches,{productId:productId}),React.createElement(ItemName,{display:display,productId:productId,name:name}),React.createElement(MapPriceHint,{productId:productId}),React.createElement(OrderQuantityHint,{productId:productId,className:classes.quantityHint}),React.createElement(EffectivityDates,{productId:productId}),hasNewServices&&React.createElement(React.Fragment,null,React.createElement(Availability,{state:!stock||stock.orderable?AVAILABILITY_STATE_OK:AVAILABILITY_STATE_ALERT,text:i18n.text('product.available.not'),showWhenAvailable:false}),React.createElement(StockInfoLists,{product:product})),React.createElement(ItemPrice,{product:product,display:display}));};ItemDetails.defaultProps={display:null,productListTypeMeta:null};export default memo(ItemDetails);
@@ -1 +0,0 @@
1
- function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import React from'react';import{shallow}from'enzyme';import{hasNewServices}from'@shopgate/engage/core/helpers';import{Availability}from'@shopgate/engage/components';import{StockInfoLists}from'@shopgate/engage/locations/components';import ItemDetails from"./index";jest.mock('@shopgate/engage/product',function(){return{MapPriceHint:function MapPriceHint(){return null;},OrderQuantityHint:function OrderQuantityHint(){return null;},EffectivityDates:function EffectivityDates(){return null;},Swatches:function Swatches(){return null;},AVAILABILITY_STATE_OK:'AVAILABILITY_STATE_OK',AVAILABILITY_STATE_ALERT:'AVAILABILITY_STATE_ALERT',getProductRoute:jest.fn(function(productId){return"link-to-product/".concat(productId);})};});jest.mock('@shopgate/engage/locations/components',function(){return{StockInfoLists:function StockInfoLists(){return null;}};});jest.mock('@shopgate/engage/core/helpers',function(){return{hasNewServices:jest.fn().mockReturnValue(false),i18n:{text:function text(str){return str;}}};});jest.mock('@shopgate/engage/components');jest.mock('@shopgate/engage/core',function(){return{isIOSTheme:jest.fn().mockReturnValue(true),hasWebBridge:jest.fn().mockReturnValue(false),i18n:{text:function text(_text){return _text;}}};});jest.mock("../ItemName");jest.mock("../ItemPrice");describe('<ItemDetails />',function(){var props={product:{id:'1234',name:'Foo',price:{}}};var display={name:false,price:false,reviews:false};it('should render with minimal props',function(){var wrapper=shallow(React.createElement(ItemDetails,props));expect(wrapper).toMatchSnapshot();expect(wrapper.find(Availability).exists()).toBe(false);expect(wrapper.find(StockInfoLists).exists()).toBe(false);});it('should render additional components with new services',function(){hasNewServices.mockReturnValueOnce(true);var wrapper=shallow(React.createElement(ItemDetails,props));expect(wrapper).toMatchSnapshot();expect(wrapper.find(Availability).exists()).toBe(true);expect(wrapper.find(StockInfoLists).exists()).toBe(true);});it('should not render with display props set',function(){var wrapper=shallow(React.createElement(ItemDetails,_extends({},props,{display:display})));expect(wrapper).toBeEmptyRender();});});
@@ -1,5 +0,0 @@
1
- import React,{memo,useMemo}from'react';import PropTypes from'prop-types';import{SurroundPortals,DiscountBadge}from'@shopgate/engage/components';import{PRODUCT_ITEM_DISCOUNT}from'@shopgate/engage/category';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()({root:{minWidth:40}});/**
2
- * The item discount component
3
- * @param {Object} props The component props.
4
- * @returns {JSX.Element|null}
5
- */var ItemDiscount=function ItemDiscount(_ref){var productId=_ref.productId,discount=_ref.discount;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var portalProps=useMemo(function(){return{productId:productId};},[productId]);if(!discount){return null;}return React.createElement("div",{className:cx(classes.root,'theme__product-grid__item__item-discount')},React.createElement(SurroundPortals,{portalName:PRODUCT_ITEM_DISCOUNT,portalProps:portalProps},React.createElement(DiscountBadge,{text:"-".concat(discount,"%")})));};ItemDiscount.defaultProps={discount:null};export default memo(ItemDiscount);
@@ -1,5 +0,0 @@
1
- import React,{memo,useMemo}from'react';import PropTypes from'prop-types';import{useSelector}from'react-redux';import{SurroundPortals,FavoritesButton}from'@shopgate/engage/components';import{PRODUCT_ITEM_FAVORITES_BUTTON}from'@shopgate/engage/category';import{isRelativeProductOnList}from'@shopgate/engage/favorites';import{getLoadWishlistOnAppStartEnabled}from'@shopgate/engage/core';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()({root:{position:'absolute',top:0,right:16,left:'auto',transform:'translate3d(0, -50%, 0)'}});/**
2
- * The item favorites button component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX.Element}
5
- */var ItemFavoritesButton=function ItemFavoritesButton(_ref){var productId=_ref.productId;var _useStyles=useStyles(),classes=_useStyles.classes;var loadWishlistOnAppStartEnabled=useSelector(getLoadWishlistOnAppStartEnabled);var isOnWishlist=useSelector(function(state){return isRelativeProductOnList(state,{productId:productId});});var isFavorite=useMemo(function(){return!loadWishlistOnAppStartEnabled?false:isOnWishlist;},[isOnWishlist,loadWishlistOnAppStartEnabled]);var portalProps=useMemo(function(){return{productId:productId};},[productId]);return React.createElement(SurroundPortals,{portalName:PRODUCT_ITEM_FAVORITES_BUTTON,portalProps:portalProps},React.createElement("div",{className:classes.root,"data-test-id":"favorites"},React.createElement(FavoritesButton,{active:isFavorite,productId:productId,noShadow:true,removeWithRelatives:true})));};export default memo(ItemFavoritesButton);
@@ -1 +0,0 @@
1
- import React from'react';import{shallow}from'enzyme';import{combineReducers}from'redux';import{Provider}from'react-redux';import{createMockStore}from'@shopgate/pwa-common/store';import favorites from'@shopgate/pwa-common-commerce/favorites/reducers';import ItemFavoritesButton from"./index";jest.mock('@shopgate/engage/components');var store=createMockStore(combineReducers({favorites:favorites}));describe('<ItemFavoritesButton />',function(){it('should not render when its not a favorite',function(){var wrapper=shallow(React.createElement(Provider,{store:store},React.createElement(ItemFavoritesButton,{productId:"1234"})));expect(wrapper).toMatchSnapshot();});it('should render if its a favorite',function(){var wrapper=shallow(React.createElement(Provider,{store:store},React.createElement(ItemFavoritesButton,{productId:"1234",isFavorite:true})));expect(wrapper).toMatchSnapshot();});});
@@ -1,5 +0,0 @@
1
- import React,{useMemo,memo}from'react';import PropTypes from'prop-types';import{SurroundPortals}from'@shopgate/engage/components';import{PRODUCT_ITEM_IMAGE}from'@shopgate/engage/category/constants';import{getProductImageSettings,ProductImage}from'@shopgate/engage/product';var _getProductImageSetti=getProductImageSettings(),gridResolutions=_getProductImageSetti.ListImage;/**
2
- * The item image component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX.Element}
5
- */var ItemImage=function ItemImage(_ref){var productId=_ref.productId,name=_ref.name,imageUrl=_ref.imageUrl;var portalProps=useMemo(function(){return{productId:productId};},[productId]);return React.createElement(SurroundPortals,{portalName:PRODUCT_ITEM_IMAGE,portalProps:portalProps},React.createElement(ProductImage,{alt:name,src:imageUrl,resolutions:gridResolutions,itemProp:"image"}));};ItemImage.defaultProps={imageUrl:null,name:null};export default memo(ItemImage);
@@ -1 +0,0 @@
1
- import React from'react';import{shallow}from'enzyme';import ItemImage from"./index";jest.mock('@shopgate/engage/components',function(){return{ProductImage:function ProductImage(){return null;}};});describe('<ItemImage />',function(){it('should render',function(){var wrapper=shallow(React.createElement(ItemImage,{productId:"1234",imageUrl:"http://www.google.com",name:"FooBar"}));expect(wrapper).toMatchSnapshot();});});
@@ -1,5 +0,0 @@
1
- import React,{memo,useMemo}from'react';import PropTypes from'prop-types';import{PRODUCT_ITEM_NAME,PRODUCT_ITEM_NAME_BEFORE,PRODUCT_ITEM_NAME_AFTER}from'@shopgate/engage/category/constants';import{Portal}from'@shopgate/engage/components';import{ProductName}from'@shopgate/engage/product';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()({root:{fontWeight:'500',lineHeight:1.15,marginTop:1,wordBreak:['keep-all','break-word'],hyphens:'auto'}});/**
2
- * The item name component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX.Element|null}
5
- */var ItemName=function ItemName(_ref){var display=_ref.display,productId=_ref.productId,name=_ref.name;var _useStyles=useStyles(),classes=_useStyles.classes,cx=_useStyles.cx;var portalProps=useMemo(function(){return{productId:productId,display:display};},[display,productId]);if(display&&!display.name){return React.createElement(React.Fragment,null,React.createElement(Portal,{name:PRODUCT_ITEM_NAME_BEFORE,props:portalProps}),React.createElement(Portal,{name:PRODUCT_ITEM_NAME_AFTER,props:portalProps}));}return React.createElement(ProductName,{name:name,className:cx(classes.root,'theme__product-grid__item__item-name'),portalName:PRODUCT_ITEM_NAME,portalProps:portalProps,testId:"Productname: ".concat(name)});};ItemName.defaultProps={display:null,name:null};export default memo(ItemName);
@@ -1 +0,0 @@
1
- import React from'react';import{shallow}from'enzyme';import ItemName from"./index";jest.mock('@shopgate/engage/product',function(){return{ProductName:function ProductName(){return null;}};});var props={productId:'1234',name:'Foo'};describe('<ItemName />',function(){it('should render with minimal props',function(){var wrapper=shallow(React.createElement(ItemName,props));expect(wrapper).toMatchSnapshot();});});
@@ -1,5 +0,0 @@
1
- import React,{memo,useMemo}from'react';import PropTypes from'prop-types';import{SurroundPortals}from'@shopgate/engage/components';import{PRODUCT_ITEM_PRICE}from'@shopgate/engage/category';import{ProductGridPrice}from'@shopgate/engage/product';/**
2
- * The item price component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX.Element|null}
5
- */var ItemPrice=function ItemPrice(_ref){var display=_ref.display,product=_ref.product;var productId=product.id;var portalProps=useMemo(function(){return{productId:productId,location:'productGrid'};},[productId]);if(display&&!display.price){return null;}return React.createElement(SurroundPortals,{portalName:PRODUCT_ITEM_PRICE,portalProps:portalProps},React.createElement(ProductGridPrice,{product:product}));};ItemPrice.defaultProps={display:null};export default memo(ItemPrice);
@@ -1 +0,0 @@
1
- function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import React from'react';import{shallow}from'enzyme';import ItemPrice from"./index";jest.mock('@shopgate/engage/product',function(){return{ProductGridPrice:function ProductGridPrice(){return null;}};});jest.mock('@shopgate/engage/components',function(){return{Portal:function Portal(_ref){var children=_ref.children;return children;}};});jest.mock('@shopgate/engage/category',function(){return{PRODUCT_ITEM_PRICE:'PRODUCT_ITEM_PRICE',PRODUCT_ITEM_PRICE_AFTER:'PRODUCT_ITEM_PRICE_AFTER',PRODUCT_ITEM_PRICE_BEFORE:'PRODUCT_ITEM_PRICE_BEFORE'};});var props={product:{id:'1234',price:{}}};var display={price:false};describe('<ItemPrice />',function(){it('should render with minimal props',function(){var wrapper=shallow(React.createElement(ItemPrice,props));expect(wrapper).toMatchSnapshot();});it('should not render with display props set',function(){var wrapper=shallow(React.createElement(ItemPrice,_extends({},props,{display:display})));expect(wrapper).toBeEmptyRender();});});
@@ -1,7 +0,0 @@
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,{memo}from'react';import PropTypes from'prop-types';import{isBeta}from'@shopgate/engage/core';import{getProductRoute,FeaturedMedia,ProductBadges}from'@shopgate/engage/product';import{Link}from'@shopgate/engage/components';import{useProductListType}from'@shopgate/engage/product/hooks';import{themeConfig}from'@shopgate/engage';import{makeStyles}from'@shopgate/engage/styles';import ItemImage from"./components/ItemImage";import ItemDiscount from"./components/ItemDiscount";import ItemFavoritesButton from"./components/ItemFavoritesButton";import ItemDetails from"./components/ItemDetails";var colors=themeConfig.colors;var useStyles=makeStyles()(function(theme,_ref){var display=_ref.display;return{root:{position:'relative',display:'flex',flexDirection:'column',background:colors.light,height:'100%'},itemDetails:_extends({position:'relative'},display&&!display.name&&!display.price&&!display.reviews&&{paddingBottom:30})};});/**
2
- * The Product Grid Item component.
3
- * @param {Object} props The component props.
4
- * @param {Object} props.product The product.
5
- * @param {Object} props.display The display object.
6
- * @return {JSX.Element}
7
- */var Item=function Item(_ref2){var product=_ref2.product,display=_ref2.display;var _useStyles=useStyles({display:display}),classes=_useStyles.classes,cx=_useStyles.cx;var _useProductListType=useProductListType(),meta=_useProductListType.meta;return React.createElement("div",{className:cx(classes.root,'theme__product-grid__item')},React.createElement(Link,{role:"none",href:getProductRoute(product.id),state:_extends({title:product.name},meta)},isBeta()&&product.featuredMedia?React.createElement(FeaturedMedia,{type:product.featuredMedia.type,url:product.featuredMedia.url}):React.createElement(ItemImage,{productId:product.id,name:product.name,imageUrl:product.featuredImageBaseUrl})),React.createElement(ProductBadges,{location:"productGrid",productId:product.id},React.createElement(ItemDiscount,{productId:product.id,discount:product.price.discount||null})),React.createElement("div",{className:classes.itemDetails},React.createElement(ItemDetails,{product:product,display:display,productListTypeMeta:meta}),React.createElement(ItemFavoritesButton,{productId:product.id})));};Item.defaultProps={display:null};export default memo(Item);
@@ -1,5 +0,0 @@
1
- import React from'react';import PropTypes from'prop-types';import{Grid,SurroundPortals}from'@shopgate/engage/components';import{PRODUCT_ITEM}from'@shopgate/engage/category';import{ProductListEntryProvider}from'@shopgate/engage/product';import Item from"../Item";/**
2
- * The Product Grid Iterator component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX}
5
- */var Iterator=function Iterator(props){var portalProps={productId:props.id};var id=props.id,display=props.display;return React.createElement(Grid.Item,{key:id,"data-test-id":props.name,className:"theme__product-grid__item__container"},React.createElement(ProductListEntryProvider,{productId:props.id},React.createElement(SurroundPortals,{portalName:PRODUCT_ITEM,portalProps:portalProps},React.createElement(Item,{product:props,display:display}))));};Iterator.defaultProps={display:null,name:null};export default Iterator;
@@ -1,5 +0,0 @@
1
- import React from'react';import PropTypes from'prop-types';import{Grid}from'@shopgate/engage/components';import{makeStyles}from'@shopgate/engage/styles';var useStyles=makeStyles()(function(theme,_ref){var columns=_ref.columns;return{root:{padding:'0 16px',':not(:empty)':{marginTop:16},display:'grid',gridGap:'0 16px',gridTemplateColumns:"repeat(".concat(columns,", 1fr)")}};});/**
2
- * The product grid layout component.
3
- * @param {Object} props The component props.
4
- * @returns {JSX}
5
- */var Layout=function Layout(_ref2){var children=_ref2.children,columns=_ref2.columns,className=_ref2.className;var _useStyles=useStyles({columns:columns}),classes=_useStyles.classes,cx=_useStyles.cx;return React.createElement(Grid,{wrap:true,className:cx(classes.root,className,'theme__product-grid'),"data-test-id":"productGrid"},children);};Layout.defaultProps={className:null,children:null};export default Layout;
@@ -1,22 +0,0 @@
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,{useContext}from'react';import PropTypes from'prop-types';import{ViewContext,InfiniteContainer,LoadingIndicator}from'@shopgate/engage/components';import{ProductListTypeProvider}from'@shopgate/engage/product';import{ITEMS_PER_LOAD}from'@shopgate/engage/core/constants';import{useResponsiveValue}from'@shopgate/engage/styles';import Iterator from"./components/Iterator";import Layout from"./components/Layout";export var WIDGET_ID='@shopgate/engage/product/ProductGrid';/**
2
- * The Product Grid component.
3
- * @param {Object} props The component props.
4
- * @param {Array} props.products The list of products to display.
5
- * @param {string} props.scope Optional scope of the component. Will be used as subType property of
6
- * the ProductListTypeContext and is intended as a description in which "context" the component is
7
- * used.
8
- * @param {Object} props.meta Optional metadata for the product list type context.
9
- * @param {Object} props.flags The flags object.
10
- * @param {boolean} props.flags.name Whether to display product names.
11
- * @param {boolean} props.flags.price Whether to display product prices.
12
- * @param {boolean} props.flags.reviews Whether to display rating stars.
13
- * @param {boolean} props.infiniteLoad Whether the grid should support infinite loading.
14
- * @param {Function} props.handleGetProducts Callback function that's invoked to load more products
15
- * when infinite loading is enabled.
16
- * @param {number} props.totalProductCount The total number of products. Needed when infinite
17
- * loading is enabled.
18
- * @param {string} props.requestHash The hash for the current request. Needed when infinite loading
19
- * is enabled
20
- * @param {string} props.className Optional class name for the grid container
21
- * @returns {JSX.Element}
22
- */var ProductGrid=function ProductGrid(_ref){var flags=_ref.flags,infiniteLoad=_ref.infiniteLoad,handleGetProducts=_ref.handleGetProducts,products=_ref.products,totalProductCount=_ref.totalProductCount,requestHash=_ref.requestHash,scope=_ref.scope,meta=_ref.meta,className=_ref.className;var _useContext=useContext(ViewContext),getContentRef=_useContext.getContentRef;var columns=useResponsiveValue({xs:2,md:4});if(!infiniteLoad){return React.createElement(Layout,{columns:columns,className:className},React.createElement(ProductListTypeProvider,{type:"productGrid",subType:scope,meta:meta},products.map(function(product){return React.createElement(Iterator,_extends({display:flags,id:product.id,key:product.id},product));})));}return React.createElement(ProductListTypeProvider,{type:"productGrid",subType:scope,meta:meta},React.createElement(InfiniteContainer,{containerRef:getContentRef(),wrapper:function wrapper(props){return React.createElement(Layout,_extends({columns:columns,className:className},props));},iterator:Iterator,loader:handleGetProducts,items:products,columns:columns,loadingIndicator:React.createElement(LoadingIndicator,null),totalItems:totalProductCount,initialLimit:ITEMS_PER_LOAD,limit:ITEMS_PER_LOAD,requestHash:requestHash,enablePromiseBasedLoading:true}));};ProductGrid.defaultProps={flags:null,handleGetProducts:function handleGetProducts(){},infiniteLoad:true,products:null,requestHash:null,totalProductCount:null,scope:null,meta:null,className:null};export default ProductGrid;
@@ -1 +0,0 @@
1
- import React from'react';import{mount}from'enzyme';import ProductGrid from'.';global.console.error=jest.fn();jest.mock('@shopgate/engage/core',function(){return{hasWebBridge:jest.fn(function(){return false;}),isIOSTheme:jest.fn(function(){return false;}),withForwardedRef:jest.fn(),withCurrentProduct:jest.fn(),useWidgetSettings:jest.fn().mockReturnValue({})};});jest.mock('@shopgate/engage/components',function(){var _jest$requireActual=jest.requireActual('@shopgate/engage/components/View/context'),ViewContext=_jest$requireActual.ViewContext;return{ViewContext:ViewContext,InfiniteContainer:function InfiniteContainer(){return null;},Grid:function Grid(){return null;}};});jest.mock("./components/Iterator",function(){return function Iterator(){return null;};});jest.mock('@shopgate/engage/product',function(){return{ProductListTypeProvider:function ProductListTypeProvider(_ref){var children=_ref.children;return children;},ProductListEntryProvider:function ProductListEntryProvider(_ref2){var children=_ref2.children;return children;}};});describe('<ProductGrid />',function(){it('should render with the InfiniteContainer',function(){var wrapper=mount(React.createElement(ProductGrid,{products:[]}));expect(wrapper).toMatchSnapshot();expect(wrapper.find('InfiniteContainer').exists()).toBe(true);expect(wrapper.find('Layout').exists()).toBe(false);});it('should render the original layout',function(){var wrapper=mount(React.createElement(ProductGrid,{infiniteLoad:false,products:[]}));expect(wrapper).toMatchSnapshot();expect(wrapper.find('InfiniteContainer').exists()).toBe(false);expect(wrapper.find('Layout').exists()).toBe(true);});});
@@ -1,23 +0,0 @@
1
- // Import the Color constructor from the color.js package
2
- import Color from'color';/**
3
- * Converts any valid input color to an RGBA CSS string.
4
- * If the input color already contains an alpha channel (< 1), that alpha is preserved.
5
- * Otherwise, the provided `opacity` is applied.
6
- *
7
- * @param {string} inputColor any CSS‐valid color string (hex, rgb(), hsl(), etc.)
8
- * @param {number} [opacity=1] fallback alpha (0–1) to use if `inputColor` has no alpha
9
- * @returns {string} "rgba(r, g, b, a)" string
10
- *
11
- * @example
12
- * toRgba('#ff0000') // → "rgba(255, 0, 0, 1)"
13
- * toRgba('#ff0000', 0.5) // → "rgba(255, 0, 0, 0.5)"
14
- * toRgba('rgba(10,20,30,0.2)', 0.9) // → "rgba(10, 20, 30, 0.2)"
15
- * toRgba('hsl(120, 100%, 50%)') // → "rgba(0, 255, 0, 1)"
16
- * toRgba('blue', 0.3) // → "rgba(0, 0, 255, 0.3)"
17
- */export function colorToRgba(inputColor){var opacity=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1;// Parse the input into a Color instance
18
- var parsed=Color(inputColor);// Extract the alpha channel from the parsed color (default is 1 if none was provided)
19
- var inputAlpha=parsed.alpha();// Determine which alpha to use:
20
- // - If the parsed color already had alpha < 1, keep that.
21
- // - Otherwise, use the provided opacity value.
22
- var finalAlpha=inputAlpha<1?inputAlpha:opacity;// Set the computed alpha and return as "rgba(r, g, b, a)" string
23
- return parsed.alpha(finalAlpha).rgb().string();}
package/styles/index.d.ts DELETED
@@ -1,17 +0,0 @@
1
- export * from './helpers';
2
- export {
3
- ThemeProvider,
4
- createTheme,
5
- useActiveBreakpoint,
6
- useMediaQuery,
7
- useResponsiveValue,
8
- useTheme,
9
- Theme,
10
- } from './theme';
11
- export {
12
- makeStyles,
13
- withStyles,
14
- tss,
15
- GlobalStyles,
16
- keyframes,
17
- } from './tss';
@@ -1,114 +0,0 @@
1
- export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
2
- export const keys: Breakpoint[];
3
-
4
- export interface Breakpoints {
5
- keys: Breakpoint[];
6
- /**
7
- * Each breakpoint (a key) matches with a fixed screen width (a value).
8
- * @default
9
- * {
10
- * // extra-small
11
- * xs: 0,
12
- * // small
13
- * sm: 600,
14
- * // medium
15
- * md: 900,
16
- * // large
17
- * lg: 1200,
18
- * // extra-large
19
- * xl: 1536,
20
- * }
21
- */
22
- values: { [key in Breakpoint]: number };
23
- /**
24
- * @param key - A breakpoint key (`xs`, `sm`, etc.) or a screen width number in px.
25
- * @returns A media query string which matches screen widths greater than the screen size given by the breakpoint key (inclusive).
26
- * @example
27
- * ```js
28
- * const styles = (theme) => ({
29
- * root: {
30
- * backgroundColor: 'blue',
31
- * // Matches "md" and above
32
- * [theme.breakpoints.up('md')]: {
33
- * backgroundColor: 'red',
34
- * }
35
- * }
36
- * })
37
- * ```
38
- */
39
- up: (key: Breakpoint | number) => string;
40
- /**
41
- * @param key - A breakpoint key (`xs`, `sm`, etc.) or a screen width number in px.
42
- * @returns A media query string which matches screen widths less than the screen size given by the breakpoint key (exclusive).
43
- * @example
44
- * ```js
45
- * const styles = (theme) => ({
46
- * root: {
47
- * backgroundColor: 'blue',
48
- * // Matches "xs" and "sm"
49
- * [theme.breakpoints.down('md')]: {
50
- * backgroundColor: 'red',
51
- * }
52
- * }
53
- * })
54
- * ```
55
- */
56
- down: (key: Breakpoint | number) => string;
57
- /**
58
- * @param start - A breakpoint key (`xs`, `sm`, etc.) or a screen width number in px.
59
- * @param end - A breakpoint key (`xs`, `sm`, etc.) or a screen width number in px.
60
- * @returns A media query string which matches screen widths greater than
61
- * the screen size given by the breakpoint key in the first argument (inclusive) and less than the screen size given by the breakpoint key in the second argument (exclusive).
62
- * @example
63
- * ```js
64
- * const styles = (theme) => ({
65
- * root: {
66
- * backgroundColor: 'blue',
67
- * // Matches "sm" and "md"
68
- * [theme.breakpoints.between('sm', 'lg')]: {
69
- * backgroundColor: 'red',
70
- * }
71
- * }
72
- * })
73
- * ```
74
- */
75
- between: (start: Breakpoint | number, end: Breakpoint | number) => string;
76
- /**
77
- * @param key - A breakpoint key (`xs`, `sm`, etc.) or a screen width number in px.
78
- * @returns A media query string which matches screen widths starting from
79
- * the screen size given by the breakpoint key (inclusive) and stopping at the screen size given by the next breakpoint key (exclusive).
80
- * @example
81
- * ```js
82
- * const styles = (theme) => ({
83
- * root: {
84
- * backgroundColor: 'blue',
85
- * // Matches "sm"
86
- * [theme.breakpoints.only('sm')]: {
87
- * backgroundColor: 'red',
88
- * }
89
- * }
90
- * })
91
- * ```
92
- */
93
- only: (key: Breakpoint) => string;
94
- /**
95
- * @param key - A breakpoint key (`xs`, `sm`, etc.).
96
- * @returns A media query string which matches screen widths stopping at
97
- * the screen size given by the breakpoint key (exclusive) and starting at the screen size given by the next breakpoint key (inclusive).
98
- * @example
99
- * ```js
100
- * const styles = (theme) => ({
101
- * root: {
102
- * backgroundColor: 'blue',
103
- * // Matches "xs", "md", "lg", and "xl"
104
- * [theme.breakpoints.not('sm')]: {
105
- * backgroundColor: 'red',
106
- * }
107
- * }
108
- * })
109
- * ```
110
- */
111
- not: (key: Breakpoint) => string;
112
- }
113
-
114
- export default function createBreakpoints(): Breakpoints;
@@ -1,41 +0,0 @@
1
- function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _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);}/* eslint-disable valid-jsdoc */ // Possible breakpoints for responsive design
2
- /** @type {import('./createBreakpoints').Breakpoint[]} */export var breakpointKeys=['xs','sm','md','lg','xl'];/**
3
- * Sorts an object of breakpoints by their numeric values in ascending order.
4
- *
5
- * This is useful in responsive design systems to ensure breakpoints
6
- * are applied in the correct order.
7
- *
8
- * @param {Object.<string, number>} values - An object where keys are breakpoint names
9
- * (e.g., 'xs', 'sm', 'md') and values are numeric pixel values.
10
- * @returns {Object.<string, number>} A new object with the same key-value pairs, sorted by
11
- * ascending numeric values.
12
- *
13
- * @example
14
- * const breakpoints = { md: 960, xs: 0, sm: 600 };
15
- * const sorted = sortBreakpointsValues(breakpoints);
16
- * console.log(sorted); // { xs: 0, sm: 600, md: 960 }
17
- */var sortBreakpointsValues=function sortBreakpointsValues(values){var breakpointsAsArray=Object.keys(values).map(function(key){return{key:key,val:values[key]};})||[];breakpointsAsArray.sort(function(breakpoint1,breakpoint2){return breakpoint1.val-breakpoint2.val;});return breakpointsAsArray.reduce(function(acc,obj){return _extends({},acc,_defineProperty({},obj.key,obj.val));},{});};var unit='px';var step=5;/**
18
- * Creates a set of media query functions based on the provided breakpoints.
19
- */var createBreakpoints=function createBreakpoints(){/** @type {import('./createBreakpoints').Breakpoints['values]} */var values={// Extra small – all mobile phones
20
- xs:0,// Small – large phones in landscape
21
- sm:480,// Medium – tablets
22
- md:768,// Large – small laptops
23
- lg:1024,// Extra large – desktops
24
- xl:1280};var sortedValues=sortBreakpointsValues(values);var keys=Object.keys(sortedValues);/**
25
- * @param {import('./createBreakpoints').Breakpoint | number} key Breakpoint key or pixel value
26
- * @returns {string} A media query string for the specified breakpoint
27
- */function up(key){var value=typeof values[key]==='number'?values[key]:key;return"@media (min-width:".concat(value).concat(unit,")");}/**
28
- * @param {import('./createBreakpoints').Breakpoint | number} key Breakpoint key or pixel value
29
- * @returns {string} A media query string for the specified breakpoint
30
- */function down(key){/** @type {number} */var value=typeof values[key]==='number'?values[key]:key;return"@media (max-width:".concat(value-step/100).concat(unit,")");}/**
31
- * @param {import('./createBreakpoints').Breakpoint | number} start Breakpoint key or pixel value
32
- * @param {import('./createBreakpoints').Breakpoint | number} end Breakpoint key or pixel value
33
- * @returns {string} A media query string for the specified breakpoint
34
- */function between(start,end){var endIndex=keys.indexOf(end);return"@media (min-width:".concat(typeof values[start]==='number'?values[start]:start).concat(unit,") and ")+"(max-width:".concat((endIndex!==-1&&typeof values[keys[endIndex]]==='number'?values[keys[endIndex]]:end)-step/100).concat(unit,")");}/**
35
- * @param {import('./createBreakpoints').Breakpoint} key Breakpoint key or pixel value
36
- * @returns {string} A media query string for the specified breakpoint
37
- */function only(key){if(keys.indexOf(key)+1<keys.length){return between(key,keys[keys.indexOf(key)+1]);}return up(key);}/**
38
- * @param {import('./createBreakpoints').Breakpoint} key Breakpoint key or pixel value
39
- * @returns {string} A media query string for the specified breakpoint
40
- */function not(key){// handle first and last key separately, for better readability
41
- var keyIndex=keys.indexOf(key);if(keyIndex===0){return up(keys[1]);}if(keyIndex===keys.length-1){return down(keys[keyIndex]);}return between(key,keys[keys.indexOf(key)+1]).replace('@media','@media not all and');}return{keys:keys,values:sortedValues,up:up,down:down,between:between,only:only,not:not};};export default createBreakpoints;/* eslint-enable valid-jsdoc */
@@ -1,36 +0,0 @@
1
- type ColorPartialKeys =
2
- | 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
3
- | 'A100' | 'A200' | 'A400' | 'A700';
4
-
5
- type ColorPartial = Record<ColorPartialKeys, string>;
6
-
7
-
8
- interface TypeText {
9
- primary: string;
10
- secondary: string;
11
- tertiary: string;
12
- }
13
-
14
- interface BasePaletteColor {
15
- main: string;
16
- }
17
-
18
- interface PaletteColorWithContrast extends PaletteColor {
19
- contrast: string;
20
- }
21
-
22
- type PaletteColor<WithContrast extends boolean = false> =
23
- BasePaletteColor & (WithContrast extends true ? { contrast: string } : {});
24
-
25
- export interface Palette {
26
- primary: PaletteColor<true>;
27
- secondary: PaletteColor<true>;
28
- error: PaletteColor;
29
- warning: PaletteColor;
30
- success: PaletteColor;
31
- cta: PaletteColor<true>;
32
- text: TypeText;
33
- grey: ColorPartial;
34
- }
35
-
36
- export default function createPalette(): Palette;