@salesforce/retail-react-app 1.0.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/.eslintignore +7 -0
  2. package/.eslintrc.js +25 -0
  3. package/.prettierignore +4 -0
  4. package/.prettierrc.yaml +7 -0
  5. package/CHANGELOG.md +173 -0
  6. package/LICENSE +14 -0
  7. package/README.md +48 -0
  8. package/app/assets/svg/account.svg +3 -0
  9. package/app/assets/svg/alert.svg +3 -0
  10. package/app/assets/svg/basket.svg +3 -0
  11. package/app/assets/svg/brand-logo.svg +10 -0
  12. package/app/assets/svg/cc-amex.svg +7 -0
  13. package/app/assets/svg/cc-cvv.svg +8 -0
  14. package/app/assets/svg/cc-discover.svg +14 -0
  15. package/app/assets/svg/cc-mastercard.svg +8 -0
  16. package/app/assets/svg/cc-visa.svg +11 -0
  17. package/app/assets/svg/check-circle.svg +3 -0
  18. package/app/assets/svg/check.svg +3 -0
  19. package/app/assets/svg/chevron-down.svg +3 -0
  20. package/app/assets/svg/chevron-left.svg +3 -0
  21. package/app/assets/svg/chevron-right.svg +3 -0
  22. package/app/assets/svg/chevron-up.svg +3 -0
  23. package/app/assets/svg/close.svg +3 -0
  24. package/app/assets/svg/dashboard.svg +4 -0
  25. package/app/assets/svg/figma-logo.svg +14 -0
  26. package/app/assets/svg/file.svg +3 -0
  27. package/app/assets/svg/filter.svg +3 -0
  28. package/app/assets/svg/flag-ca.svg +5 -0
  29. package/app/assets/svg/flag-cn.svg +19 -0
  30. package/app/assets/svg/flag-fr.svg +19 -0
  31. package/app/assets/svg/flag-gb.svg +16 -0
  32. package/app/assets/svg/flag-it.svg +29 -0
  33. package/app/assets/svg/flag-jp.svg +10 -0
  34. package/app/assets/svg/flag-us.svg +7 -0
  35. package/app/assets/svg/github-logo.svg +40 -0
  36. package/app/assets/svg/hamburger.svg +8 -0
  37. package/app/assets/svg/heart-solid.svg +7 -0
  38. package/app/assets/svg/heart.svg +3 -0
  39. package/app/assets/svg/info.svg +3 -0
  40. package/app/assets/svg/like.svg +4 -0
  41. package/app/assets/svg/location.svg +3 -0
  42. package/app/assets/svg/lock.svg +3 -0
  43. package/app/assets/svg/paypal.svg +19 -0
  44. package/app/assets/svg/plug.svg +3 -0
  45. package/app/assets/svg/plus.svg +3 -0
  46. package/app/assets/svg/receipt.svg +3 -0
  47. package/app/assets/svg/search.svg +8 -0
  48. package/app/assets/svg/signout.svg +3 -0
  49. package/app/assets/svg/social-facebook.svg +3 -0
  50. package/app/assets/svg/social-instagram.svg +3 -0
  51. package/app/assets/svg/social-pinterest.svg +4 -0
  52. package/app/assets/svg/social-twitter.svg +3 -0
  53. package/app/assets/svg/social-youtube.svg +3 -0
  54. package/app/assets/svg/user.svg +3 -0
  55. package/app/assets/svg/visibility-off.svg +5 -0
  56. package/app/assets/svg/visibility.svg +3 -0
  57. package/app/components/_app/index.jsx +401 -0
  58. package/app/components/_app/index.test.js +85 -0
  59. package/app/components/_app/partials/above-header.jsx +10 -0
  60. package/app/components/_app-config/index.jsx +125 -0
  61. package/app/components/_app-config/index.test.js +77 -0
  62. package/app/components/_error/index.jsx +142 -0
  63. package/app/components/_error/index.test.js +25 -0
  64. package/app/components/action-card/index.jsx +75 -0
  65. package/app/components/address-display/index.jsx +30 -0
  66. package/app/components/basic-tile/index.jsx +65 -0
  67. package/app/components/basic-tile/index.test.js +23 -0
  68. package/app/components/breadcrumb/index.jsx +67 -0
  69. package/app/components/breadcrumb/index.test.js +30 -0
  70. package/app/components/confirmation-modal/index.jsx +111 -0
  71. package/app/components/confirmation-modal/index.test.js +98 -0
  72. package/app/components/drawer-menu/index.jsx +405 -0
  73. package/app/components/drawer-menu/index.test.js +33 -0
  74. package/app/components/dynamic-image/index.jsx +56 -0
  75. package/app/components/field/index.jsx +161 -0
  76. package/app/components/footer/index.jsx +269 -0
  77. package/app/components/footer/index.test.js +22 -0
  78. package/app/components/forms/address-fields.jsx +49 -0
  79. package/app/components/forms/credit-card-fields.jsx +149 -0
  80. package/app/components/forms/form-action-buttons.jsx +55 -0
  81. package/app/components/forms/login-fields.jsx +31 -0
  82. package/app/components/forms/password-requirements.jsx +99 -0
  83. package/app/components/forms/post-checkout-registration-fields.jsx +43 -0
  84. package/app/components/forms/profile-fields.jsx +36 -0
  85. package/app/components/forms/promo-code-fields.jsx +43 -0
  86. package/app/components/forms/registration-fields.jsx +42 -0
  87. package/app/components/forms/reset-password-fields.jsx +31 -0
  88. package/app/components/forms/state-province-options.jsx +75 -0
  89. package/app/components/forms/update-password-fields.jsx +49 -0
  90. package/app/components/forms/useAddressFields.jsx +196 -0
  91. package/app/components/forms/useCreditCardFields.jsx +146 -0
  92. package/app/components/forms/useLoginFields.jsx +52 -0
  93. package/app/components/forms/useProfileFields.jsx +95 -0
  94. package/app/components/forms/usePromoCodeFields.jsx +39 -0
  95. package/app/components/forms/useRegistrationFields.jsx +136 -0
  96. package/app/components/forms/useResetPasswordFields.jsx +40 -0
  97. package/app/components/forms/useUpdatePasswordFields.jsx +89 -0
  98. package/app/components/header/index.jsx +290 -0
  99. package/app/components/header/index.test.js +217 -0
  100. package/app/components/hero/index.jsx +84 -0
  101. package/app/components/hero/index.test.js +40 -0
  102. package/app/components/icons/index.jsx +158 -0
  103. package/app/components/icons/index.test.js +20 -0
  104. package/app/components/image-gallery/index.jsx +176 -0
  105. package/app/components/image-gallery/index.test.js +485 -0
  106. package/app/components/item-variant/index.jsx +33 -0
  107. package/app/components/item-variant/item-attributes.jsx +107 -0
  108. package/app/components/item-variant/item-image.jsx +73 -0
  109. package/app/components/item-variant/item-name.jsx +28 -0
  110. package/app/components/item-variant/item-price.jsx +117 -0
  111. package/app/components/link/index.jsx +32 -0
  112. package/app/components/link/index.test.js +72 -0
  113. package/app/components/links-list/index.jsx +89 -0
  114. package/app/components/links-list/index.test.js +62 -0
  115. package/app/components/list-menu/index.jsx +280 -0
  116. package/app/components/list-menu/index.test.js +44 -0
  117. package/app/components/loading-spinner/index.jsx +46 -0
  118. package/app/components/locale-selector/index.jsx +124 -0
  119. package/app/components/locale-selector/index.test.js +37 -0
  120. package/app/components/locale-text/index.jsx +97 -0
  121. package/app/components/locale-text/index.test.js +36 -0
  122. package/app/components/login/index.jsx +96 -0
  123. package/app/components/nested-accordion/index.jsx +185 -0
  124. package/app/components/nested-accordion/index.test.js +98 -0
  125. package/app/components/offline-banner/index.jsx +40 -0
  126. package/app/components/offline-banner/index.test.js +15 -0
  127. package/app/components/offline-boundary/index.jsx +104 -0
  128. package/app/components/offline-boundary/index.test.js +123 -0
  129. package/app/components/order-summary/index.jsx +331 -0
  130. package/app/components/page-action-placeholder/index.jsx +50 -0
  131. package/app/components/pagination/index.jsx +134 -0
  132. package/app/components/pagination/index.test.js +25 -0
  133. package/app/components/product-item/index.jsx +146 -0
  134. package/app/components/product-item/index.test.js +38 -0
  135. package/app/components/product-scroller/index.jsx +172 -0
  136. package/app/components/product-scroller/index.test.js +98 -0
  137. package/app/components/product-tile/index.jsx +195 -0
  138. package/app/components/product-tile/index.test.js +96 -0
  139. package/app/components/product-view/index.jsx +538 -0
  140. package/app/components/product-view/index.test.js +224 -0
  141. package/app/components/product-view-modal/index.jsx +48 -0
  142. package/app/components/product-view-modal/index.test.js +72 -0
  143. package/app/components/promo-code/index.jsx +162 -0
  144. package/app/components/promo-popover/index.jsx +83 -0
  145. package/app/components/quantity-picker/index.jsx +58 -0
  146. package/app/components/radio-card/index.jsx +75 -0
  147. package/app/components/recommended-products/index.jsx +227 -0
  148. package/app/components/register/index.jsx +114 -0
  149. package/app/components/reset-password/index.jsx +87 -0
  150. package/app/components/responsive/index.jsx +29 -0
  151. package/app/components/scroll-to-top/index.jsx +24 -0
  152. package/app/components/scroll-to-top/index.test.js +46 -0
  153. package/app/components/search/index.jsx +279 -0
  154. package/app/components/search/index.test.js +127 -0
  155. package/app/components/search/partials/recent-searches.jsx +76 -0
  156. package/app/components/search/partials/search-suggestions.jsx +45 -0
  157. package/app/components/search/partials/suggestions.jsx +43 -0
  158. package/app/components/section/index.jsx +68 -0
  159. package/app/components/seo/index.jsx +33 -0
  160. package/app/components/social-icons/index.jsx +101 -0
  161. package/app/components/social-icons/index.test.js +30 -0
  162. package/app/components/swatch-group/index.jsx +77 -0
  163. package/app/components/swatch-group/index.test.js +136 -0
  164. package/app/components/swatch-group/swatch.jsx +94 -0
  165. package/app/components/toggle-card/index.jsx +97 -0
  166. package/app/components/with-registration/index.jsx +58 -0
  167. package/app/components/with-registration/index.test.js +85 -0
  168. package/app/constants.js +109 -0
  169. package/app/contexts/index.js +92 -0
  170. package/app/hooks/einstein-mock-data.js +916 -0
  171. package/app/hooks/index.js +17 -0
  172. package/app/hooks/use-add-to-cart-modal.js +344 -0
  173. package/app/hooks/use-add-to-cart-modal.test.js +625 -0
  174. package/app/hooks/use-auth-modal.js +337 -0
  175. package/app/hooks/use-auth-modal.test.js +365 -0
  176. package/app/hooks/use-currency.js +20 -0
  177. package/app/hooks/use-currency.test.js +41 -0
  178. package/app/hooks/use-current-basket.js +39 -0
  179. package/app/hooks/use-current-customer.js +29 -0
  180. package/app/hooks/use-derived-product.js +77 -0
  181. package/app/hooks/use-derived-product.test.js +69 -0
  182. package/app/hooks/use-einstein.js +512 -0
  183. package/app/hooks/use-einstein.test.js +224 -0
  184. package/app/hooks/use-intersection-observer.js +64 -0
  185. package/app/hooks/use-limit-urls.js +31 -0
  186. package/app/hooks/use-limit-urls.test.js +40 -0
  187. package/app/hooks/use-multi-site.js +36 -0
  188. package/app/hooks/use-multi-site.test.js +53 -0
  189. package/app/hooks/use-navigation.js +37 -0
  190. package/app/hooks/use-navigation.test.js +109 -0
  191. package/app/hooks/use-page-urls.js +35 -0
  192. package/app/hooks/use-page-urls.test.js +39 -0
  193. package/app/hooks/use-pdp-search-params.js +16 -0
  194. package/app/hooks/use-pdp-search-params.test.js +52 -0
  195. package/app/hooks/use-previous.js +17 -0
  196. package/app/hooks/use-product-view-modal.js +93 -0
  197. package/app/hooks/use-product-view-modal.test.js +172 -0
  198. package/app/hooks/use-search-params.js +96 -0
  199. package/app/hooks/use-search-params.test.js +91 -0
  200. package/app/hooks/use-sort-urls.js +33 -0
  201. package/app/hooks/use-sort-urls.test.js +42 -0
  202. package/app/hooks/use-toast.js +68 -0
  203. package/app/hooks/use-toast.test.js +58 -0
  204. package/app/hooks/use-variant.js +32 -0
  205. package/app/hooks/use-variant.test.js +81 -0
  206. package/app/hooks/use-variation-attributes.js +138 -0
  207. package/app/hooks/use-variation-attributes.test.js +119 -0
  208. package/app/hooks/use-variation-params.js +31 -0
  209. package/app/hooks/use-variation-params.test.js +73 -0
  210. package/app/hooks/use-wish-list.js +42 -0
  211. package/app/main.jsx +14 -0
  212. package/app/mocks/basket-with-suit.js +146 -0
  213. package/app/mocks/empty-basket.js +39 -0
  214. package/app/mocks/mock-data.js +5632 -0
  215. package/app/mocks/product-set-winter-lookM.js +1224 -0
  216. package/app/mocks/searchResults.js +144 -0
  217. package/app/mocks/variant-750518699578M.js +434 -0
  218. package/app/page-designer/README.md +102 -0
  219. package/app/page-designer/assets/image-tile/index.jsx +51 -0
  220. package/app/page-designer/assets/image-tile/index.test.js +30 -0
  221. package/app/page-designer/assets/image-with-text/index.jsx +140 -0
  222. package/app/page-designer/assets/image-with-text/index.test.js +38 -0
  223. package/app/page-designer/assets/index.js +9 -0
  224. package/app/page-designer/index.js +10 -0
  225. package/app/page-designer/layouts/carousel/index.jsx +222 -0
  226. package/app/page-designer/layouts/carousel/index.test.js +43 -0
  227. package/app/page-designer/layouts/index.js +14 -0
  228. package/app/page-designer/layouts/mobileGrid1r1c/index.jsx +36 -0
  229. package/app/page-designer/layouts/mobileGrid1r1c/index.test.js +35 -0
  230. package/app/page-designer/layouts/mobileGrid2r1c/index.jsx +37 -0
  231. package/app/page-designer/layouts/mobileGrid2r1c/index.test.js +47 -0
  232. package/app/page-designer/layouts/mobileGrid2r2c/index.jsx +37 -0
  233. package/app/page-designer/layouts/mobileGrid2r2c/index.test.js +71 -0
  234. package/app/page-designer/layouts/mobileGrid2r3c/index.jsx +37 -0
  235. package/app/page-designer/layouts/mobileGrid2r3c/index.test.js +95 -0
  236. package/app/page-designer/layouts/mobileGrid3r1c/index.jsx +37 -0
  237. package/app/page-designer/layouts/mobileGrid3r1c/index.test.js +59 -0
  238. package/app/page-designer/layouts/mobileGrid3r2c/index.jsx +37 -0
  239. package/app/page-designer/layouts/mobileGrid3r2c/index.test.js +95 -0
  240. package/app/page-designer/utils.js +14 -0
  241. package/app/pages/account/addresses.jsx +382 -0
  242. package/app/pages/account/addresses.test.js +120 -0
  243. package/app/pages/account/constant.js +57 -0
  244. package/app/pages/account/index.jsx +237 -0
  245. package/app/pages/account/index.test.js +188 -0
  246. package/app/pages/account/order-detail.jsx +397 -0
  247. package/app/pages/account/order-history.jsx +264 -0
  248. package/app/pages/account/orders.jsx +30 -0
  249. package/app/pages/account/orders.test.js +95 -0
  250. package/app/pages/account/profile.jsx +357 -0
  251. package/app/pages/account/wishlist/index.jsx +195 -0
  252. package/app/pages/account/wishlist/index.mock.js +1481 -0
  253. package/app/pages/account/wishlist/index.test.js +56 -0
  254. package/app/pages/account/wishlist/partials/wishlist-primary-action.jsx +170 -0
  255. package/app/pages/account/wishlist/partials/wishlist-primary-action.mock.js +1623 -0
  256. package/app/pages/account/wishlist/partials/wishlist-primary-action.test.js +99 -0
  257. package/app/pages/account/wishlist/partials/wishlist-secondary-button-group.jsx +120 -0
  258. package/app/pages/account/wishlist/partials/wishlist-secondary-button-group.test.js +391 -0
  259. package/app/pages/cart/index.jsx +476 -0
  260. package/app/pages/cart/index.test.js +481 -0
  261. package/app/pages/cart/partials/cart-cta.jsx +46 -0
  262. package/app/pages/cart/partials/cart-secondary-button-group.jsx +135 -0
  263. package/app/pages/cart/partials/cart-secondary-button-group.test.js +103 -0
  264. package/app/pages/cart/partials/cart-skeleton.jsx +93 -0
  265. package/app/pages/cart/partials/cart-title.jsx +27 -0
  266. package/app/pages/cart/partials/empty-cart.jsx +86 -0
  267. package/app/pages/checkout/confirmation.jsx +541 -0
  268. package/app/pages/checkout/confirmation.mock.js +450 -0
  269. package/app/pages/checkout/confirmation.test.js +114 -0
  270. package/app/pages/checkout/index.jsx +169 -0
  271. package/app/pages/checkout/index.test.js +582 -0
  272. package/app/pages/checkout/partials/cc-radio-group.jsx +122 -0
  273. package/app/pages/checkout/partials/checkout-footer.jsx +140 -0
  274. package/app/pages/checkout/partials/checkout-footer.test.js +16 -0
  275. package/app/pages/checkout/partials/checkout-header.jsx +54 -0
  276. package/app/pages/checkout/partials/checkout-header.test.js +16 -0
  277. package/app/pages/checkout/partials/checkout-skeleton.jsx +52 -0
  278. package/app/pages/checkout/partials/contact-info.jsx +251 -0
  279. package/app/pages/checkout/partials/contact-info.test.js +43 -0
  280. package/app/pages/checkout/partials/payment-form.jsx +97 -0
  281. package/app/pages/checkout/partials/payment.jsx +276 -0
  282. package/app/pages/checkout/partials/shipping-address-selection.jsx +377 -0
  283. package/app/pages/checkout/partials/shipping-address.jsx +132 -0
  284. package/app/pages/checkout/partials/shipping-options.jsx +232 -0
  285. package/app/pages/checkout/util/checkout-context.js +94 -0
  286. package/app/pages/home/data.js +134 -0
  287. package/app/pages/home/index.jsx +301 -0
  288. package/app/pages/home/index.test.js +23 -0
  289. package/app/pages/login/index.jsx +123 -0
  290. package/app/pages/login/index.test.js +229 -0
  291. package/app/pages/login-redirect/index.jsx +23 -0
  292. package/app/pages/login-redirect/index.test.js +16 -0
  293. package/app/pages/page-not-found/index.jsx +90 -0
  294. package/app/pages/page-not-found/index.test.js +31 -0
  295. package/app/pages/product-detail/index.jsx +394 -0
  296. package/app/pages/product-detail/index.mock.js +197 -0
  297. package/app/pages/product-detail/index.test.js +162 -0
  298. package/app/pages/product-detail/partials/information-accordion.jsx +121 -0
  299. package/app/pages/product-list/index.jsx +735 -0
  300. package/app/pages/product-list/index.test.js +180 -0
  301. package/app/pages/product-list/partials/above-page-header.jsx +10 -0
  302. package/app/pages/product-list/partials/checkbox-refinements.jsx +41 -0
  303. package/app/pages/product-list/partials/checkbox-refinements.test.js +53 -0
  304. package/app/pages/product-list/partials/color-refinements.jsx +88 -0
  305. package/app/pages/product-list/partials/empty-results.jsx +118 -0
  306. package/app/pages/product-list/partials/link-refinements.jsx +38 -0
  307. package/app/pages/product-list/partials/page-header.jsx +42 -0
  308. package/app/pages/product-list/partials/radio-refinements.jsx +60 -0
  309. package/app/pages/product-list/partials/refinements.jsx +144 -0
  310. package/app/pages/product-list/partials/selected-refinements.jsx +100 -0
  311. package/app/pages/product-list/partials/size-refinements.jsx +55 -0
  312. package/app/pages/registration/index.jsx +87 -0
  313. package/app/pages/registration/index.test.jsx +132 -0
  314. package/app/pages/reset-password/index.jsx +112 -0
  315. package/app/pages/reset-password/index.test.jsx +141 -0
  316. package/app/request-processor.js +118 -0
  317. package/app/request-processor.test.js +23 -0
  318. package/app/routes.jsx +111 -0
  319. package/app/routes.test.js +13 -0
  320. package/app/ssr.js +70 -0
  321. package/app/static/ico/favicon.ico +0 -0
  322. package/app/static/img/global/app-icon-192.png +0 -0
  323. package/app/static/img/global/app-icon-512.png +0 -0
  324. package/app/static/img/global/apple-touch-icon.png +0 -0
  325. package/app/static/img/hero.png +0 -0
  326. package/app/static/manifest.json +19 -0
  327. package/app/static/robots.txt +2 -0
  328. package/app/theme/components/base/accordion.js +21 -0
  329. package/app/theme/components/base/alert.js +17 -0
  330. package/app/theme/components/base/badge.js +25 -0
  331. package/app/theme/components/base/button.js +77 -0
  332. package/app/theme/components/base/checkbox.js +30 -0
  333. package/app/theme/components/base/container.js +17 -0
  334. package/app/theme/components/base/drawer.js +26 -0
  335. package/app/theme/components/base/formLabel.js +13 -0
  336. package/app/theme/components/base/icon.js +13 -0
  337. package/app/theme/components/base/input.js +44 -0
  338. package/app/theme/components/base/modal.js +11 -0
  339. package/app/theme/components/base/popover.js +61 -0
  340. package/app/theme/components/base/radio.js +33 -0
  341. package/app/theme/components/base/select.js +15 -0
  342. package/app/theme/components/base/skeleton.js +12 -0
  343. package/app/theme/components/base/tooltip.js +19 -0
  344. package/app/theme/components/project/_app.js +25 -0
  345. package/app/theme/components/project/breadcrumb.js +25 -0
  346. package/app/theme/components/project/checkout-footer.js +35 -0
  347. package/app/theme/components/project/drawer-menu.js +66 -0
  348. package/app/theme/components/project/footer.js +84 -0
  349. package/app/theme/components/project/header.js +84 -0
  350. package/app/theme/components/project/image-gallery.js +59 -0
  351. package/app/theme/components/project/links-list.js +43 -0
  352. package/app/theme/components/project/list-menu.js +91 -0
  353. package/app/theme/components/project/locale-selector.js +42 -0
  354. package/app/theme/components/project/nested-accordion.js +26 -0
  355. package/app/theme/components/project/offline-banner.js +25 -0
  356. package/app/theme/components/project/pagination.js +22 -0
  357. package/app/theme/components/project/product-tile.js +32 -0
  358. package/app/theme/components/project/social-icons.js +52 -0
  359. package/app/theme/components/project/swatch-group.js +115 -0
  360. package/app/theme/foundations/colors.js +170 -0
  361. package/app/theme/foundations/gradients.js +9 -0
  362. package/app/theme/foundations/layerStyles.js +41 -0
  363. package/app/theme/foundations/shadows.js +9 -0
  364. package/app/theme/foundations/sizes.js +18 -0
  365. package/app/theme/foundations/space.js +9 -0
  366. package/app/theme/foundations/styles.js +21 -0
  367. package/app/theme/index.js +104 -0
  368. package/app/utils/cc-utils.js +112 -0
  369. package/app/utils/cc-utils.test.js +41 -0
  370. package/app/utils/image-groups-utils.js +62 -0
  371. package/app/utils/image-groups-utils.test.js +65 -0
  372. package/app/utils/locale.js +78 -0
  373. package/app/utils/locale.test.js +112 -0
  374. package/app/utils/password-utils.js +21 -0
  375. package/app/utils/phone-utils.js +22 -0
  376. package/app/utils/phone-utils.test.js +15 -0
  377. package/app/utils/product-utils.js +35 -0
  378. package/app/utils/product-utils.test.js +51 -0
  379. package/app/utils/responsive-image.js +198 -0
  380. package/app/utils/responsive-image.test.js +170 -0
  381. package/app/utils/routes-utils.js +111 -0
  382. package/app/utils/routes-utils.test.js +291 -0
  383. package/app/utils/site-utils.js +222 -0
  384. package/app/utils/site-utils.test.js +376 -0
  385. package/app/utils/test-utils.js +257 -0
  386. package/app/utils/url.js +291 -0
  387. package/app/utils/url.test.js +421 -0
  388. package/app/utils/utils.js +201 -0
  389. package/app/utils/utils.test.js +182 -0
  390. package/babel.config.js +7 -0
  391. package/cache-hash-config.json +8 -0
  392. package/config/default.js +64 -0
  393. package/config/mocks/default.js +131 -0
  394. package/config/sites.js +78 -0
  395. package/jest-setup.js +191 -0
  396. package/jest.config.js +50 -0
  397. package/jsconfig.json +13 -0
  398. package/package.json +105 -0
  399. package/scripts/extract-default-messages.js +92 -0
  400. package/tests/lighthouserc.js +37 -0
  401. package/translations/README.md +127 -0
  402. package/translations/compiled/de-DE.json +3212 -0
  403. package/translations/compiled/en-GB.json +3212 -0
  404. package/translations/compiled/en-US.json +3212 -0
  405. package/translations/compiled/en-XA.json +6948 -0
  406. package/translations/compiled/es-MX.json +3216 -0
  407. package/translations/compiled/fr-FR.json +3216 -0
  408. package/translations/compiled/it-IT.json +3188 -0
  409. package/translations/compiled/ja-JP.json +3200 -0
  410. package/translations/compiled/ko-KR.json +3180 -0
  411. package/translations/compiled/pt-BR.json +3220 -0
  412. package/translations/compiled/zh-CN.json +3212 -0
  413. package/translations/compiled/zh-TW.json +3208 -0
  414. package/translations/de-DE.json +1417 -0
  415. package/translations/en-GB.json +1417 -0
  416. package/translations/en-US.json +1417 -0
  417. package/translations/es-MX.json +1417 -0
  418. package/translations/fr-FR.json +1417 -0
  419. package/translations/it-IT.json +1417 -0
  420. package/translations/ja-JP.json +1417 -0
  421. package/translations/ko-KR.json +1417 -0
  422. package/translations/pt-BR.json +1417 -0
  423. package/translations/zh-CN.json +1417 -0
  424. package/translations/zh-TW.json +1417 -0
  425. package/worker/main.js +36 -0
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import React from 'react'
9
+ import PropTypes from 'prop-types'
10
+ import {Box, Flex, Heading, Stack, Image} from '@chakra-ui/react'
11
+
12
+ const Hero = ({title, img, actions, ...props}) => {
13
+ const {src, alt} = img
14
+
15
+ return (
16
+ <Box
17
+ marginBottom={{base: 0, md: 10}}
18
+ height={{lg: 'xl'}}
19
+ position={{lg: 'relative'}}
20
+ {...props}
21
+ >
22
+ <Stack
23
+ align={'center'}
24
+ spacing={{base: 8, md: 10}}
25
+ paddingTop={{base: 12, md: 10}}
26
+ paddingBottom={{base: 6, md: 10}}
27
+ direction={{base: 'column', lg: 'row'}}
28
+ >
29
+ <Stack flex={1} spacing={{base: 5, md: 8}}>
30
+ <Heading
31
+ as="h1"
32
+ fontSize={{base: '4xl', md: '5xl', lg: '6xl'}}
33
+ maxWidth={{base: '75%', md: '50%', lg: 'md'}}
34
+ >
35
+ {title}
36
+ </Heading>
37
+
38
+ {actions && <Box width={{base: 'full', lg: 'inherit'}}>{actions}</Box>}
39
+ </Stack>
40
+ <Flex
41
+ flex={1}
42
+ justify={'center'}
43
+ align={'center'}
44
+ position={'relative'}
45
+ width={'full'}
46
+ paddingTop={{base: 4, lg: 0}}
47
+ >
48
+ <Box position={'relative'} width={{base: 'full', md: '80%', lg: 'full'}}>
49
+ <Image
50
+ fit={'cover'}
51
+ align={'center'}
52
+ width={'100%'}
53
+ height={'100%'}
54
+ src={src}
55
+ alt={alt}
56
+ />
57
+ </Box>
58
+ </Flex>
59
+ </Stack>
60
+ </Box>
61
+ )
62
+ }
63
+
64
+ Hero.displayName = 'Hero'
65
+
66
+ Hero.propTypes = {
67
+ /**
68
+ * Hero component image
69
+ */
70
+ img: PropTypes.shape({
71
+ src: PropTypes.string,
72
+ alt: PropTypes.string
73
+ }),
74
+ /**
75
+ * Hero component main title
76
+ */
77
+ title: PropTypes.string,
78
+ /**
79
+ * Call to action component(s)
80
+ */
81
+ actions: PropTypes.element
82
+ }
83
+
84
+ export default Hero
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import {fireEvent} from '@testing-library/react'
9
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
10
+ import Hero from '@salesforce/retail-react-app/app/components/hero/index'
11
+
12
+ test('Hero renders without errors', () => {
13
+ const data = {
14
+ title: 'title',
15
+ actions: undefined,
16
+ img: {
17
+ src: 'src',
18
+ alt: 'alt'
19
+ }
20
+ }
21
+ const {getByText} = renderWithProviders(<Hero {...data} />)
22
+ expect(getByText(/title/i)).toBeInTheDocument()
23
+ })
24
+
25
+ test('Hero renders actions and event handlers', () => {
26
+ const onClick = jest.fn()
27
+ const data = {
28
+ title: 'title',
29
+ actions: <button data-testid="button" onClick={onClick}></button>,
30
+ img: {
31
+ src: 'src',
32
+ alt: 'alt'
33
+ }
34
+ }
35
+ const {getByTestId} = renderWithProviders(<Hero {...data} />)
36
+ const button = getByTestId('button')
37
+ expect(button).toBeInTheDocument()
38
+ fireEvent.click(button)
39
+ expect(onClick).toHaveBeenCalledTimes(1)
40
+ })
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React, {forwardRef} from 'react'
8
+ import {Icon, useTheme} from '@chakra-ui/react'
9
+
10
+ // Our own SVG imports. These will be extracted to a single sprite sheet by the
11
+ // svg-sprite-loader webpack plugin at build time and injected in the <body> tag
12
+ // during SSR.
13
+ // NOTE: Another solution would be to use `require-context.macro` package to accomplish
14
+ // importing icon svg's.
15
+ import '@salesforce/retail-react-app/app/assets/svg/alert.svg'
16
+ import '@salesforce/retail-react-app/app/assets/svg/account.svg'
17
+ import '@salesforce/retail-react-app/app/assets/svg/basket.svg'
18
+ import '@salesforce/retail-react-app/app/assets/svg/check.svg'
19
+ import '@salesforce/retail-react-app/app/assets/svg/check-circle.svg'
20
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-up.svg'
21
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-down.svg'
22
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-right.svg'
23
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-left.svg'
24
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-right.svg'
25
+ import '@salesforce/retail-react-app/app/assets/svg/chevron-up.svg'
26
+ import '@salesforce/retail-react-app/app/assets/svg/dashboard.svg'
27
+ import '@salesforce/retail-react-app/app/assets/svg/figma-logo.svg'
28
+ import '@salesforce/retail-react-app/app/assets/svg/filter.svg'
29
+ import '@salesforce/retail-react-app/app/assets/svg/file.svg'
30
+ import '@salesforce/retail-react-app/app/assets/svg/flag-ca.svg'
31
+ import '@salesforce/retail-react-app/app/assets/svg/flag-us.svg'
32
+ import '@salesforce/retail-react-app/app/assets/svg/flag-gb.svg'
33
+ import '@salesforce/retail-react-app/app/assets/svg/flag-fr.svg'
34
+ import '@salesforce/retail-react-app/app/assets/svg/flag-it.svg'
35
+ import '@salesforce/retail-react-app/app/assets/svg/flag-cn.svg'
36
+ import '@salesforce/retail-react-app/app/assets/svg/flag-jp.svg'
37
+ import '@salesforce/retail-react-app/app/assets/svg/github-logo.svg'
38
+ import '@salesforce/retail-react-app/app/assets/svg/hamburger.svg'
39
+ import '@salesforce/retail-react-app/app/assets/svg/info.svg'
40
+ import '@salesforce/retail-react-app/app/assets/svg/social-facebook.svg'
41
+ import '@salesforce/retail-react-app/app/assets/svg/social-instagram.svg'
42
+ import '@salesforce/retail-react-app/app/assets/svg/social-twitter.svg'
43
+ import '@salesforce/retail-react-app/app/assets/svg/social-youtube.svg'
44
+ import '@salesforce/retail-react-app/app/assets/svg/like.svg'
45
+ import '@salesforce/retail-react-app/app/assets/svg/lock.svg'
46
+ import '@salesforce/retail-react-app/app/assets/svg/plug.svg'
47
+ import '@salesforce/retail-react-app/app/assets/svg/plus.svg'
48
+ import '@salesforce/retail-react-app/app/assets/svg/receipt.svg'
49
+ import '@salesforce/retail-react-app/app/assets/svg/search.svg'
50
+ import '@salesforce/retail-react-app/app/assets/svg/signout.svg'
51
+ import '@salesforce/retail-react-app/app/assets/svg/user.svg'
52
+ import '@salesforce/retail-react-app/app/assets/svg/visibility.svg'
53
+ import '@salesforce/retail-react-app/app/assets/svg/visibility-off.svg'
54
+ import '@salesforce/retail-react-app/app/assets/svg/heart.svg'
55
+ import '@salesforce/retail-react-app/app/assets/svg/heart-solid.svg'
56
+ import '@salesforce/retail-react-app/app/assets/svg/close.svg'
57
+
58
+ // For non-square SVGs, we can use the symbol data from the import to set the
59
+ // proper viewBox attribute on the Icon wrapper.
60
+ import AmexSymbol from '@salesforce/retail-react-app/app/assets/svg/cc-amex.svg'
61
+ import BrandLogoSymbol from '@salesforce/retail-react-app/app/assets/svg/brand-logo.svg'
62
+ import CVVSymbol from '@salesforce/retail-react-app/app/assets/svg/cc-cvv.svg'
63
+ import DiscoverSymbol from '@salesforce/retail-react-app/app/assets/svg/cc-discover.svg'
64
+ import LocationSymbol from '@salesforce/retail-react-app/app/assets/svg/location.svg'
65
+ import MastercardSymbol from '@salesforce/retail-react-app/app/assets/svg/cc-mastercard.svg'
66
+ import PaypalSymbol from '@salesforce/retail-react-app/app/assets/svg/paypal.svg'
67
+ import SocialPinterestSymbol from '@salesforce/retail-react-app/app/assets/svg/social-pinterest.svg'
68
+ import VisaSymbol from '@salesforce/retail-react-app/app/assets/svg/cc-visa.svg'
69
+
70
+ // TODO: We're hardcoding the `viewBox` for these imported SVGs temporarily as the
71
+ // SVG loader plugin is not properly providing us the symbol data on the client side.
72
+ AmexSymbol.viewBox = AmexSymbol.viewBox || '0 0 38 22'
73
+ BrandLogoSymbol.viewBox = BrandLogoSymbol.viewBox || '0 0 46 32'
74
+ CVVSymbol.viewBox = CVVSymbol.viewBox || '0 0 41 24'
75
+ DiscoverSymbol.viewBox = DiscoverSymbol.viewBox || '0 0 38 22'
76
+ LocationSymbol.viewBox = LocationSymbol.viewBox || '0 0 16 21'
77
+ MastercardSymbol.viewBox = MastercardSymbol.viewBox || '0 0 38 22'
78
+ PaypalSymbol.viewBox = PaypalSymbol.viewBox || '0 0 80 20'
79
+ SocialPinterestSymbol.viewBox = SocialPinterestSymbol.viewBox || '0 0 21 20'
80
+ VisaSymbol.viewBox = VisaSymbol.viewBox || '0 0 38 22'
81
+
82
+ /**
83
+ * A helper for creating a Chakra-wrapped icon from our own SVG imports via sprite sheet.
84
+ * @param {string} name - the filename of the imported svg (does not include extension)
85
+ */
86
+ /* istanbul ignore next */
87
+ const icon = (name, passProps) => {
88
+ const displayName = name
89
+ .toLowerCase()
90
+ .replace(/(?:^|[\s-/])\w/g, (match) => match.toUpperCase())
91
+ .replace(/-/g, '')
92
+ const component = forwardRef((props, ref) => {
93
+ const theme = useTheme()
94
+ const baseStyle = theme?.components?.Icon?.baseStyle
95
+ return (
96
+ <Icon ref={ref} {...baseStyle} {...passProps} {...props}>
97
+ <use role="presentation" xlinkHref={`#${name}`} />
98
+ </Icon>
99
+ )
100
+ })
101
+ component.displayName = `${displayName}Icon`
102
+ return component
103
+ }
104
+
105
+ // Export Chakra icon components that use our SVG sprite symbol internally
106
+ // For non-square SVGs, we can use the symbol data from the import to set the
107
+ // proper viewBox attribute on the Icon wrapper.
108
+ export const AmexIcon = icon('cc-amex', {viewBox: AmexSymbol.viewBox})
109
+ export const AlertIcon = icon('alert')
110
+ export const AccountIcon = icon('account')
111
+ export const BrandLogo = icon('brand-logo', {viewBox: BrandLogoSymbol.viewBox})
112
+ export const BasketIcon = icon('basket')
113
+ export const CheckIcon = icon('check')
114
+ export const CheckCircleIcon = icon('check-circle')
115
+ export const ChevronDownIcon = icon('chevron-down')
116
+ export const ChevronLeftIcon = icon('chevron-left')
117
+ export const ChevronRightIcon = icon('chevron-right')
118
+ export const ChevronUpIcon = icon('chevron-up')
119
+ export const CVVIcon = icon('cc-cvv', {viewBox: CVVSymbol.viewBox})
120
+ export const DashboardIcon = icon('dashboard')
121
+ export const DiscoverIcon = icon('cc-discover', {viewBox: DiscoverSymbol.viewBox})
122
+ export const FigmaLogo = icon('figma-logo')
123
+ export const FilterIcon = icon('filter')
124
+ export const FileIcon = icon('file')
125
+ export const FlagCAIcon = icon('flag-ca')
126
+ export const FlagUSIcon = icon('flag-us')
127
+ export const FlagGBIcon = icon('flag-gb')
128
+ export const FlagFRIcon = icon('flag-fr')
129
+ export const FlagITIcon = icon('flag-it')
130
+ export const FlagCNIcon = icon('flag-cn')
131
+ export const FlagJPIcon = icon('flag-jp')
132
+ export const GithubLogo = icon('github-logo')
133
+ export const HamburgerIcon = icon('hamburger')
134
+ export const InfoIcon = icon('info')
135
+ export const LikeIcon = icon('like')
136
+ export const LockIcon = icon('lock')
137
+ export const LocationIcon = icon('location')
138
+ export const PaypalIcon = icon('paypal', {viewBox: PaypalSymbol.viewBox})
139
+ export const PlugIcon = icon('plug')
140
+ export const PlusIcon = icon('plus')
141
+ export const MastercardIcon = icon('cc-mastercard', {viewBox: MastercardSymbol.viewBox})
142
+ export const ReceiptIcon = icon('receipt')
143
+ export const SearchIcon = icon('search')
144
+ export const SocialFacebookIcon = icon('social-facebook')
145
+ export const SocialInstagramIcon = icon('social-instagram')
146
+ export const SocialPinterestIcon = icon('social-pinterest', {
147
+ viewBox: SocialPinterestSymbol.viewBox
148
+ })
149
+ export const SocialTwitterIcon = icon('social-twitter')
150
+ export const SocialYoutubeIcon = icon('social-youtube')
151
+ export const SignoutIcon = icon('signout')
152
+ export const UserIcon = icon('user')
153
+ export const VisaIcon = icon('cc-visa', {viewBox: VisaSymbol.viewBox})
154
+ export const VisibilityIcon = icon('visibility')
155
+ export const VisibilityOffIcon = icon('visibility-off')
156
+ export const HeartIcon = icon('heart')
157
+ export const HeartSolidIcon = icon('heart-solid')
158
+ export const CloseIcon = icon('close')
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ import React from 'react'
8
+ import {within} from '@testing-library/dom'
9
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
10
+ import * as Icons from '@salesforce/retail-react-app/app/components/icons/index'
11
+
12
+ test('renders svg icons with Chakra Icon component', () => {
13
+ renderWithProviders(<Icons.CheckIcon />)
14
+ const svg = document.querySelector('.chakra-icon')
15
+ const use = within(svg).getByRole('presentation')
16
+ expect(svg).toBeInTheDocument()
17
+ expect(use).toBeInTheDocument()
18
+ expect(svg).toHaveAttribute('viewBox', '0 0 24 24')
19
+ expect(use).toHaveAttribute('xlink:href', '#check')
20
+ })
@@ -0,0 +1,176 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ import React, {useState, useMemo, useEffect} from 'react'
9
+ import PropTypes from 'prop-types'
10
+ import {useLocation} from 'react-router-dom'
11
+
12
+ // Chakra Components
13
+ import {
14
+ AspectRatio,
15
+ Box,
16
+ Img,
17
+ Flex,
18
+
19
+ // Hooks
20
+ Skeleton as ChakraSkeleton,
21
+ ListItem,
22
+ List,
23
+ useMultiStyleConfig
24
+ } from '@chakra-ui/react'
25
+ import {findImageGroupBy} from '@salesforce/retail-react-app/app/utils/image-groups-utils'
26
+ import DynamicImage from '@salesforce/retail-react-app/app/components/dynamic-image'
27
+
28
+ const EnterKeyNumber = 13
29
+
30
+ const LARGE = 'large'
31
+ const SMALL = 'small'
32
+
33
+ /**
34
+ * The skeleton representation of the image gallery component. Use this component while
35
+ * you are waiting for product data to be returnd from the server.
36
+ */
37
+ export const Skeleton = ({size}) => {
38
+ const styles = useMultiStyleConfig('ImageGallery', {size})
39
+
40
+ return (
41
+ <Box data-testid="sf-image-gallery-skeleton">
42
+ <Flex flexDirection="column">
43
+ <AspectRatio ratio={1} {...styles.heroImageSkeleton}>
44
+ <ChakraSkeleton />
45
+ </AspectRatio>
46
+ <Flex>
47
+ {new Array(4).fill(0).map((_, index) => (
48
+ <AspectRatio ratio={1} {...styles.thumbnailImageSkeleton} key={index}>
49
+ <ChakraSkeleton />
50
+ </AspectRatio>
51
+ ))}
52
+ </Flex>
53
+ </Flex>
54
+ </Box>
55
+ )
56
+ }
57
+
58
+ Skeleton.propTypes = {
59
+ size: PropTypes.bool
60
+ }
61
+
62
+ /**
63
+ * The image gallery displays a hero image and thumbnails below it. You can control which
64
+ * image groups that are use by passing in the current selected variation values.
65
+ */
66
+ const ImageGallery = ({imageGroups = [], selectedVariationAttributes = {}, size, lazy = false}) => {
67
+ const [selectedIndex, setSelectedIndex] = useState(0)
68
+ const styles = useMultiStyleConfig('ImageGallery', {size})
69
+ const location = useLocation()
70
+
71
+ // Get the 'hero' image for the current variation.
72
+ const heroImageGroup = useMemo(
73
+ () =>
74
+ findImageGroupBy(imageGroups, {
75
+ viewType: LARGE,
76
+ selectedVariationAttributes
77
+ }),
78
+ [selectedVariationAttributes]
79
+ )
80
+
81
+ useEffect(() => {
82
+ // reset the selected index when location search changes
83
+ setSelectedIndex(0)
84
+ }, [location.search])
85
+
86
+ // Get a memoized image group used for the thumbnails. We use the `useMemo` hook
87
+ // so we don't have to waste time filtering the image groups each render if the
88
+ // selected variation attributes haven't changed.
89
+ const thumbnailImageGroup = useMemo(
90
+ () =>
91
+ findImageGroupBy(imageGroups, {
92
+ viewType: SMALL,
93
+ selectedVariationAttributes
94
+ }),
95
+ [selectedVariationAttributes]
96
+ )
97
+
98
+ const heroImage = heroImageGroup?.images?.[selectedIndex]
99
+ const thumbnailImages = thumbnailImageGroup?.images || []
100
+ const loadingStrategy = lazy ? 'lazy' : 'eager'
101
+
102
+ const heroImageMaxWidth = styles.heroImage.maxWidth[3] // in px
103
+
104
+ return (
105
+ <Flex direction="column">
106
+ {heroImage && (
107
+ <Box {...styles.heroImageGroup}>
108
+ <AspectRatio {...styles.heroImage} ratio={1}>
109
+ <DynamicImage
110
+ src={`${heroImage.disBaseLink || heroImage.link}[?sw={width}&q=60]`}
111
+ widths={{
112
+ base: '100vw',
113
+ lg: heroImageMaxWidth
114
+ }}
115
+ imageProps={{
116
+ alt: heroImage.alt,
117
+ loading: loadingStrategy
118
+ }}
119
+ />
120
+ </AspectRatio>
121
+ </Box>
122
+ )}
123
+
124
+ <List display={'flex'} flexWrap={'wrap'}>
125
+ {thumbnailImages.map((image, index) => {
126
+ const selected = index === selectedIndex
127
+ return (
128
+ <ListItem
129
+ {...styles.thumbnailImageItem}
130
+ tabIndex={0}
131
+ key={index}
132
+ data-testid="image-gallery-thumbnails"
133
+ onKeyDown={(e) => {
134
+ if (e.keyCode === EnterKeyNumber) {
135
+ return setSelectedIndex(index)
136
+ }
137
+ }}
138
+ onClick={() => setSelectedIndex(index)}
139
+ borderColor={`${selected ? 'black' : ''}`}
140
+ borderWidth={`${selected ? '1px' : 0}`}
141
+ >
142
+ <AspectRatio ratio={1}>
143
+ <Img
144
+ alt={image.alt}
145
+ src={image.disBaseLink || image.link}
146
+ loading={loadingStrategy}
147
+ />
148
+ </AspectRatio>
149
+ </ListItem>
150
+ )
151
+ })}
152
+ </List>
153
+ </Flex>
154
+ )
155
+ }
156
+
157
+ ImageGallery.propTypes = {
158
+ /**
159
+ * The images array to be rendered
160
+ */
161
+ imageGroups: PropTypes.array,
162
+ /**
163
+ * The current selected variation values
164
+ */
165
+ selectedVariationAttributes: PropTypes.object,
166
+ /**
167
+ * Size of the Image gallery, this will be used to determined the max width from styles
168
+ */
169
+ size: PropTypes.string,
170
+ /**
171
+ * Determines whether the image will be lazy loaded or not
172
+ */
173
+ lazy: PropTypes.bool
174
+ }
175
+
176
+ export default ImageGallery