@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,77 @@
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 {render, waitFor} from '@testing-library/react'
9
+ import AppConfig from '@salesforce/retail-react-app/app/components/_app-config/index.jsx'
10
+
11
+ import {CorrelationIdProvider} from '@salesforce/pwa-kit-react-sdk/ssr/universal/contexts'
12
+ import {uuidv4} from '@salesforce/pwa-kit-react-sdk/utils/uuidv4.client'
13
+ import {StaticRouter} from 'react-router-dom'
14
+
15
+ import mockConfig from '@salesforce/retail-react-app/config/mocks/default'
16
+ import {rest} from 'msw'
17
+ import {registerUserToken} from '@salesforce/retail-react-app/app/utils/test-utils'
18
+
19
+ describe('AppConfig', () => {
20
+ beforeAll(() => {
21
+ jest.spyOn(window.localStorage, 'setItem')
22
+ global.fetch = jest.fn().mockImplementation(() => mockConfig.mockFetchOCAPISessions)
23
+ })
24
+
25
+ beforeEach(() => {
26
+ window.localStorage.setItem.mockClear()
27
+
28
+ global.server.use(
29
+ rest.post('*/oauth2/token', (req, res, ctx) =>
30
+ res(
31
+ ctx.delay(0),
32
+ ctx.json({
33
+ customer_id: 'customerid',
34
+ access_token: registerUserToken,
35
+ refresh_token: 'testrefeshtoken',
36
+ usid: 'testusid',
37
+ enc_user_id: 'testEncUserId',
38
+ id_token: 'testIdToken'
39
+ })
40
+ )
41
+ )
42
+ )
43
+ })
44
+
45
+ afterAll(() => {
46
+ window.localStorage.setItem.mockRestore()
47
+ global.fetch.mockClear()
48
+ delete global.fetch
49
+ })
50
+
51
+ test('renders', async () => {
52
+ const locals = {
53
+ appConfig: mockConfig.app
54
+ }
55
+ const {container} = render(
56
+ <StaticRouter>
57
+ <CorrelationIdProvider correlationId={() => uuidv4()}>
58
+ <AppConfig locals={locals} />
59
+ </CorrelationIdProvider>
60
+ </StaticRouter>
61
+ )
62
+ expect(container).toBeDefined()
63
+
64
+ // Wait for access token to be saved
65
+ // Otherwise, the test would end prematurely before our component has finished its business
66
+ // (for example: commerce-sdk-react Provider needs to finish its useEffect for `auth.ready()`)
67
+ await waitFor(() => {
68
+ expect(window.localStorage.setItem).toHaveBeenCalled()
69
+ })
70
+ })
71
+
72
+ test('AppConfig static methods behave as expected', () => {
73
+ expect(AppConfig.restore()).toBeUndefined()
74
+ expect(AppConfig.restore({frozen: 'any values here'})).toBeUndefined()
75
+ expect(AppConfig.freeze()).toBeUndefined()
76
+ })
77
+ })
@@ -0,0 +1,142 @@
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 PropTypes from 'prop-types'
9
+ import {Helmet} from 'react-helmet'
10
+ import {Box, Button, Flex, Heading, IconButton, Stack, Text} from '@chakra-ui/react'
11
+
12
+ import {BrandLogo, FileIcon} from '@salesforce/retail-react-app/app/components/icons'
13
+ import {useHistory} from 'react-router-dom'
14
+
15
+ // <Error> is rendered when:
16
+ //
17
+ // 1. A user requests a page that is not routable from `app/routes.jsx`.
18
+ // 2. A routed component throws an error in `getProps()`.
19
+ // 3. A routed component throws an error in `render()`.
20
+ //
21
+ // It must not throw an error. Keep it as simple as possible.
22
+
23
+ const Error = (props) => {
24
+ const {message, stack} = props
25
+ const history = useHistory()
26
+
27
+ const title = "This page isn't working"
28
+ return (
29
+ <Flex id="sf-app" flex={1} direction="column" minWidth={'375px'}>
30
+ <Helmet>
31
+ <title>{title}</title>
32
+ </Helmet>
33
+ <Box as="header" width="full" boxShadow="base" backgroundColor="white">
34
+ <Box
35
+ maxWidth="container.xxxl"
36
+ marginLeft="auto"
37
+ marginRight="auto"
38
+ px={[4, 4, 6, 8]}
39
+ paddingTop={[1, 1, 2, 4]}
40
+ paddingBottom={[3, 3, 2, 4]}
41
+ >
42
+ <IconButton
43
+ aria-label="logo"
44
+ icon={<BrandLogo width={[8, 8, 8, 12]} height={[6, 6, 6, 8]} />}
45
+ marginBottom={[1, 1, 2, 0]}
46
+ variant="unstyled"
47
+ onClick={() => history.push('/')}
48
+ />
49
+ </Box>
50
+ </Box>
51
+ <Box
52
+ as="main"
53
+ id="app-main"
54
+ role="main"
55
+ layerStyle="page"
56
+ padding={{lg: 8, md: 6, sm: 0, base: 0}}
57
+ flex={1}
58
+ >
59
+ <Flex
60
+ direction={'column'}
61
+ justify="center"
62
+ px={{base: 4, md: 6, lg: 50}}
63
+ py={{base: 20, md: 24}}
64
+ >
65
+ <Flex align="center" direction="column">
66
+ <FileIcon boxSize={['30px', '32px']} mb={8} />
67
+ <Heading as="h2" fontSize={['xl', '2xl', '2xl', '3xl']} mb={2}>
68
+ {title}
69
+ </Heading>
70
+ <Box maxWidth="440px" marginBottom={8}>
71
+ <Text align="center">
72
+ An error has occurred. Try refreshing the page or if you need
73
+ immediate help please contact support.
74
+ </Text>
75
+ {message && (
76
+ <Box
77
+ as="pre"
78
+ mt={4}
79
+ fontSize="sm"
80
+ background="gray.50"
81
+ borderColor="gray.200"
82
+ borderStyle="solid"
83
+ borderWidth="1px"
84
+ overflow="auto"
85
+ padding={4}
86
+ >
87
+ {message}
88
+ </Box>
89
+ )}
90
+ </Box>
91
+ <Stack direction={['column', 'row']} spacing={4} width={['100%', 'auto']}>
92
+ <Button
93
+ variant="outline"
94
+ bg="white"
95
+ as="a"
96
+ borderColor={'gray.200'}
97
+ target="_blank"
98
+ href="https://help.salesforce.com/s/support"
99
+ >
100
+ Contact Support
101
+ </Button>
102
+ <Button onClick={() => window.location.reload()}>
103
+ Refresh the page
104
+ </Button>
105
+ </Stack>
106
+ </Flex>
107
+ {stack && (
108
+ <Box marginTop={20}>
109
+ <Text fontWeight="bold" fontSize="md">
110
+ Stack Trace
111
+ </Text>
112
+ <Box
113
+ as="pre"
114
+ mt={4}
115
+ fontSize="sm"
116
+ background="gray.50"
117
+ borderColor="gray.200"
118
+ borderStyle="solid"
119
+ borderWidth="1px"
120
+ overflow="auto"
121
+ padding={4}
122
+ >
123
+ {stack}
124
+ </Box>
125
+ </Box>
126
+ )}
127
+ </Flex>
128
+ </Box>
129
+ </Flex>
130
+ )
131
+ }
132
+
133
+ Error.propTypes = {
134
+ // JavaScript error stack trace: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack
135
+ stack: PropTypes.string,
136
+ // HTTP status code: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
137
+ status: PropTypes.number,
138
+ // A description of the error, if available
139
+ message: PropTypes.string
140
+ }
141
+
142
+ export default Error
@@ -0,0 +1,25 @@
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 {screen} from '@testing-library/react'
9
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
10
+ import Error from '@salesforce/retail-react-app/app/components/_error/index'
11
+
12
+ test('Error renders without errors', () => {
13
+ expect(renderWithProviders(<Error />)).toBeDefined()
14
+ })
15
+
16
+ test('Error status 500', () => {
17
+ renderWithProviders(<Error status={500} />)
18
+ expect(screen.getByRole('heading', {level: 2})).toHaveTextContent("This page isn't working")
19
+ })
20
+
21
+ test('Error status 500 with stack trace', () => {
22
+ renderWithProviders(<Error status={500} stack={'Stack trace error message'} />)
23
+ expect(screen.getByRole('heading', {level: 2})).toHaveTextContent("This page isn't working")
24
+ expect(screen.getByText(/stack trace error message/i)).toBeInTheDocument()
25
+ })
@@ -0,0 +1,75 @@
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, {useState} from 'react'
8
+ import PropTypes from 'prop-types'
9
+ import {Stack, Box, Button} from '@chakra-ui/react'
10
+ import {FormattedMessage} from 'react-intl'
11
+ import LoadingSpinner from '@salesforce/retail-react-app/app/components/loading-spinner'
12
+
13
+ /**
14
+ * Renders a card-style box with optional edit and remove buttons. Used for
15
+ * lists of addresses, payment methods, or any other list-type content.
16
+ * The provided `onRemove` callback triggers a loading spinner internally
17
+ * if given a promise.
18
+ */
19
+ const ActionCard = ({children, onEdit, onRemove, ...props}) => {
20
+ const [showLoading, setShowLoading] = useState(false)
21
+
22
+ const handleRemove = async () => {
23
+ setShowLoading(true)
24
+ try {
25
+ return await Promise.resolve(onRemove())
26
+ } finally {
27
+ setShowLoading(false)
28
+ }
29
+ }
30
+
31
+ return (
32
+ <Box
33
+ spacing={4}
34
+ p={4}
35
+ position="relative"
36
+ border="1px solid"
37
+ borderColor="gray.100"
38
+ borderRadius="base"
39
+ {...props}
40
+ >
41
+ {showLoading && <LoadingSpinner />}
42
+ <Stack spacing={3}>
43
+ <Box>{children}</Box>
44
+ <Stack direction="row" spacing={4}>
45
+ {onEdit && (
46
+ <Button onClick={onEdit} variant="link" size="sm">
47
+ <FormattedMessage defaultMessage="Edit" id="action_card.action.edit" />
48
+ </Button>
49
+ )}
50
+ {onRemove && (
51
+ <Button variant="link" size="sm" colorScheme="red" onClick={handleRemove}>
52
+ <FormattedMessage
53
+ defaultMessage="Remove"
54
+ id="action_card.action.remove"
55
+ />
56
+ </Button>
57
+ )}
58
+ </Stack>
59
+ </Stack>
60
+ </Box>
61
+ )
62
+ }
63
+
64
+ ActionCard.propTypes = {
65
+ /** Callback fired on edit */
66
+ onEdit: PropTypes.func,
67
+
68
+ /** Callback fired on remove click (if promise, will toggle loading spinner) */
69
+ onRemove: PropTypes.func,
70
+
71
+ /** Content rendered in card */
72
+ children: PropTypes.node
73
+ }
74
+
75
+ export default ActionCard
@@ -0,0 +1,30 @@
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 PropTypes from 'prop-types'
9
+ import {Box, Text} from '@chakra-ui/react'
10
+
11
+ const AddressDisplay = ({address}) => {
12
+ return (
13
+ <Box>
14
+ <Text>
15
+ {address.firstName} {address.lastName}
16
+ </Text>
17
+ <Text>{address.address1}</Text>
18
+ <Text>
19
+ {address.city}, {address.stateCode} {address.postalCode}
20
+ </Text>
21
+ <Text>{address.countryCode}</Text>
22
+ </Box>
23
+ )
24
+ }
25
+
26
+ AddressDisplay.propTypes = {
27
+ address: PropTypes.object
28
+ }
29
+
30
+ export default AddressDisplay
@@ -0,0 +1,65 @@
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, Img, Text, AspectRatio, useTheme} from '@chakra-ui/react'
11
+ import {Link} from 'react-router-dom'
12
+
13
+ import {ChevronRightIcon} from '@salesforce/retail-react-app/app/components/icons'
14
+
15
+ /**
16
+ * BasicTile component is used on content pages like home page.
17
+ * This component is used to promote categories, it consistents
18
+ * of an image and a category title link.
19
+ */
20
+ const BasicTile = ({img, href, title, ...props}) => {
21
+ const {src, alt} = img
22
+ const theme = useTheme()
23
+ return (
24
+ <Box {...props}>
25
+ <Box paddingBottom="4">
26
+ <Link to={href}>
27
+ <AspectRatio ratio={3 / 4}>
28
+ <Img
29
+ alt={alt}
30
+ src={src}
31
+ borderRadius="base"
32
+ bgGradient={theme.gradients.imageBackground}
33
+ />
34
+ </AspectRatio>
35
+ </Link>
36
+ </Box>
37
+ <Box>
38
+ <Link to={href}>
39
+ <Text
40
+ fontWeight="bold"
41
+ _hover={{
42
+ textDecoration: 'underline'
43
+ }}
44
+ >
45
+ {title}
46
+ <ChevronRightIcon />
47
+ </Text>
48
+ </Link>
49
+ </Box>
50
+ </Box>
51
+ )
52
+ }
53
+
54
+ BasicTile.displayName = 'BasicTile'
55
+
56
+ BasicTile.propTypes = {
57
+ href: PropTypes.string.isRequired,
58
+ img: PropTypes.shape({
59
+ src: PropTypes.string,
60
+ alt: PropTypes.string
61
+ }).isRequired,
62
+ title: PropTypes.string.isRequired
63
+ }
64
+
65
+ export default BasicTile
@@ -0,0 +1,23 @@
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 {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
9
+ import BasicTile from '@salesforce/retail-react-app/app/components/basic-tile/index'
10
+
11
+ test('BasicTile renders without errors', () => {
12
+ const data = {
13
+ title: 'title',
14
+ href: '/category/womens-outfits',
15
+ img: {
16
+ src: 'src',
17
+ alt: 'alt'
18
+ }
19
+ }
20
+ const {getByText} = renderWithProviders(<BasicTile {...data} />)
21
+
22
+ expect(getByText('title')).toBeInTheDocument()
23
+ })
@@ -0,0 +1,67 @@
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 {Link as RouteLink} from 'react-router-dom'
11
+ import {useIntl} from 'react-intl'
12
+
13
+ // Components
14
+ import {
15
+ Breadcrumb as ChakraBreadcrumb,
16
+ BreadcrumbItem as ChakraBreadcrumbItem,
17
+ BreadcrumbLink as ChakraBreadcrumbLink,
18
+ // Hooks
19
+ useStyleConfig
20
+ } from '@chakra-ui/react'
21
+
22
+ // Icons
23
+ import {ChevronRightIcon} from '@salesforce/retail-react-app/app/components/icons'
24
+
25
+ // Others
26
+ import {categoryUrlBuilder} from '@salesforce/retail-react-app/app/utils/url'
27
+
28
+ /**
29
+ * A simplification of the Chakra `Breadcrumb` component for our project needs. Given
30
+ * a list of categories, display a breadcrumb and it's items.
31
+ */
32
+ const Breadcrumb = ({categories, ...rest}) => {
33
+ const intl = useIntl()
34
+ const styles = useStyleConfig('Breadcrumb')
35
+
36
+ return (
37
+ <ChakraBreadcrumb
38
+ className="sf-breadcrumb"
39
+ {...styles.container}
40
+ separator={<ChevronRightIcon {...styles.icon} />}
41
+ {...rest}
42
+ >
43
+ {categories.map((category) => (
44
+ <ChakraBreadcrumbItem key={category.id} data-testid="sf-crumb-item">
45
+ <ChakraBreadcrumbLink
46
+ as={RouteLink}
47
+ to={categoryUrlBuilder(category, intl.locale)}
48
+ {...styles.linkTest}
49
+ >
50
+ {category.name}
51
+ </ChakraBreadcrumbLink>
52
+ </ChakraBreadcrumbItem>
53
+ ))}
54
+ </ChakraBreadcrumb>
55
+ )
56
+ }
57
+
58
+ Breadcrumb.displayName = 'Breadcrumb'
59
+
60
+ Breadcrumb.propTypes = {
61
+ /**
62
+ * The categories to be displayed in this breadcrumb.
63
+ */
64
+ categories: PropTypes.array
65
+ }
66
+
67
+ export default Breadcrumb
@@ -0,0 +1,30 @@
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 Breadcrumb from '@salesforce/retail-react-app/app/components/breadcrumb/index'
9
+ import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
10
+
11
+ const mockCategories = [
12
+ {
13
+ id: 1,
14
+ name: 'Category 1'
15
+ },
16
+ {
17
+ id: 2,
18
+ name: 'Category 2'
19
+ },
20
+ {
21
+ id: 3,
22
+ name: 'Category 3'
23
+ }
24
+ ]
25
+
26
+ test('Renders Breadcrum', () => {
27
+ const {getAllByTestId} = renderWithProviders(<Breadcrumb categories={mockCategories} />)
28
+
29
+ expect(getAllByTestId('sf-crumb-item')).toHaveLength(mockCategories.length)
30
+ })
@@ -0,0 +1,111 @@
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 {noop} from '@salesforce/retail-react-app/app/utils/utils'
9
+ import {
10
+ Button,
11
+ AlertDialog,
12
+ AlertDialogBody,
13
+ AlertDialogFooter,
14
+ AlertDialogHeader,
15
+ AlertDialogContent,
16
+ AlertDialogOverlay,
17
+ Text
18
+ } from '@chakra-ui/react'
19
+
20
+ import PropTypes from 'prop-types'
21
+ import {CONFIRMATION_DIALOG_DEFAULT_CONFIG} from '@salesforce/retail-react-app/app/pages/account/constant'
22
+ import {useIntl} from 'react-intl'
23
+
24
+ const ConfirmationModal = ({
25
+ dialogTitle = CONFIRMATION_DIALOG_DEFAULT_CONFIG.dialogTitle,
26
+ confirmationMessage = CONFIRMATION_DIALOG_DEFAULT_CONFIG.confirmationMessage,
27
+ primaryActionLabel = CONFIRMATION_DIALOG_DEFAULT_CONFIG.primaryActionLabel,
28
+ alternateActionLabel = CONFIRMATION_DIALOG_DEFAULT_CONFIG.alternateActionLabel,
29
+ onPrimaryAction = noop,
30
+ onAlternateAction = noop,
31
+ ...props
32
+ }) => {
33
+ const {formatMessage} = useIntl()
34
+
35
+ const handleConfirmClick = () => {
36
+ onPrimaryAction()
37
+ props.onClose()
38
+ }
39
+
40
+ const handleAlternateActionClick = () => {
41
+ onAlternateAction()
42
+ props.onClose()
43
+ }
44
+
45
+ return (
46
+ <AlertDialog
47
+ isOpen={props.isOpen}
48
+ isCentered
49
+ onClose={handleAlternateActionClick}
50
+ {...props}
51
+ >
52
+ <AlertDialogOverlay />
53
+ <AlertDialogContent>
54
+ <AlertDialogHeader>{formatMessage(dialogTitle)}</AlertDialogHeader>
55
+ <AlertDialogBody>
56
+ <Text>{formatMessage(confirmationMessage)}</Text>
57
+ </AlertDialogBody>
58
+
59
+ <AlertDialogFooter>
60
+ <Button variant="ghost" mr={3} onClick={handleAlternateActionClick}>
61
+ {formatMessage(alternateActionLabel)}
62
+ </Button>
63
+ <Button variant="solid" onClick={handleConfirmClick}>
64
+ {formatMessage(primaryActionLabel)}
65
+ </Button>
66
+ </AlertDialogFooter>
67
+ </AlertDialogContent>
68
+ </AlertDialog>
69
+ )
70
+ }
71
+
72
+ ConfirmationModal.propTypes = {
73
+ /**
74
+ * Prop to check if modal is open
75
+ */
76
+ isOpen: PropTypes.bool.isRequired,
77
+ /**
78
+ * Callback invoked to open the modal
79
+ */
80
+ onOpen: PropTypes.func.isRequired,
81
+ /**
82
+ * Callback invoked to close the modal
83
+ */
84
+ onClose: PropTypes.func.isRequired,
85
+ /**
86
+ * Text to be displayed as modal header
87
+ */
88
+ dialogTitle: PropTypes.object,
89
+ /**
90
+ * Text to display in confirmation modal prompting user to pick an action
91
+ */
92
+ confirmationMessage: PropTypes.object,
93
+ /**
94
+ * Button Label for primary action in confirmation modal
95
+ */
96
+ primaryActionLabel: PropTypes.object,
97
+ /**
98
+ * Button Label for alternate or secondary action in confirmation modal
99
+ */
100
+ alternateActionLabel: PropTypes.object,
101
+ /**
102
+ * Action to execute if user selects primary action
103
+ */
104
+ onPrimaryAction: PropTypes.func,
105
+ /**
106
+ * Action to execute if user selects alternate or secondary action
107
+ */
108
+ onAlternateAction: PropTypes.func
109
+ }
110
+
111
+ export default ConfirmationModal