@faststore/core 3.5.1 → 3.7.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 (178) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +27 -26
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/eslint/.cache_1gneedd +1 -1
  6. package/.next/cache/webpack/client-production/0.pack +0 -0
  7. package/.next/cache/webpack/client-production/index.pack +0 -0
  8. package/.next/cache/webpack/server-production/0.pack +0 -0
  9. package/.next/cache/webpack/server-production/index.pack +0 -0
  10. package/.next/next-minimal-server.js.nft.json +1 -1
  11. package/.next/next-server.js.nft.json +1 -1
  12. package/.next/prerender-manifest.js +1 -1
  13. package/.next/prerender-manifest.json +1 -1
  14. package/.next/react-loadable-manifest.json +36 -36
  15. package/.next/routes-manifest.json +1 -1
  16. package/.next/server/chunks/1153.js +1 -1
  17. package/.next/server/chunks/1163.js +2 -2
  18. package/.next/server/chunks/1377.js +1 -1
  19. package/.next/server/chunks/2082.js +3 -3
  20. package/.next/server/chunks/2245.js +1 -1
  21. package/.next/server/chunks/2295.js +1 -1
  22. package/.next/server/chunks/2552.js +1 -1
  23. package/.next/server/chunks/2710.js +1 -1
  24. package/.next/server/chunks/2880.js +1 -1
  25. package/.next/server/chunks/2918.js +2 -2
  26. package/.next/server/chunks/3157.js +1 -1
  27. package/.next/server/chunks/319.js +1 -1
  28. package/.next/server/chunks/3202.js +1 -1
  29. package/.next/server/chunks/371.js +1 -1
  30. package/.next/server/chunks/3716.js +2 -2
  31. package/.next/server/chunks/3779.js +1 -1
  32. package/.next/server/chunks/3922.js +1 -1
  33. package/.next/server/chunks/4012.js +1 -1
  34. package/.next/server/chunks/4222.js +1 -1
  35. package/.next/server/chunks/4358.js +1 -1
  36. package/.next/server/chunks/4451.js +1 -1
  37. package/.next/server/chunks/5110.js +1 -1
  38. package/.next/server/chunks/5156.js +1 -1
  39. package/.next/server/chunks/5284.js +1 -1
  40. package/.next/server/chunks/5342.js +1 -1
  41. package/.next/server/chunks/5380.js +1 -1
  42. package/.next/server/chunks/5430.js +1 -1
  43. package/.next/server/chunks/5476.js +1 -1
  44. package/.next/server/chunks/5484.js +1 -1
  45. package/.next/server/chunks/5671.js +1 -1
  46. package/.next/server/chunks/5754.js +2 -2
  47. package/.next/server/chunks/6198.js +1 -0
  48. package/.next/server/chunks/6335.js +1 -1
  49. package/.next/server/chunks/64.js +1 -1
  50. package/.next/server/chunks/6414.js +1 -1
  51. package/.next/server/chunks/6859.js +3 -3
  52. package/.next/server/chunks/7169.js +1 -1
  53. package/.next/server/chunks/7228.js +1 -1
  54. package/.next/server/chunks/7468.js +1 -1
  55. package/.next/server/chunks/7675.js +1 -1
  56. package/.next/server/chunks/7986.js +1 -1
  57. package/.next/server/chunks/8096.js +1 -1
  58. package/.next/server/chunks/8640.js +1 -1
  59. package/.next/server/chunks/8724.js +1 -1
  60. package/.next/server/chunks/8737.js +1 -1
  61. package/.next/server/chunks/8857.js +1 -1
  62. package/.next/server/chunks/9088.js +1 -1
  63. package/.next/server/chunks/9160.js +1 -1
  64. package/.next/server/chunks/9369.js +1 -1
  65. package/.next/server/chunks/9410.js +1 -1
  66. package/.next/server/chunks/945.js +1 -1
  67. package/.next/server/chunks/9570.js +1 -1
  68. package/.next/server/chunks/9572.js +49 -3
  69. package/.next/server/chunks/983.js +1 -1
  70. package/.next/server/chunks/9844.js +1 -1
  71. package/.next/server/chunks/ButtonSignIn.js +1 -1
  72. package/.next/server/chunks/Dropdown.js +1 -1
  73. package/.next/server/chunks/DropdownButton.js +1 -1
  74. package/.next/server/chunks/DropdownItem.js +1 -1
  75. package/.next/server/chunks/DropdownMenu.js +1 -1
  76. package/.next/server/chunks/FilterSkeleton.js +1 -1
  77. package/.next/server/chunks/ScrollToTopButton.js +1 -1
  78. package/.next/server/chunks/UIBannerText.js +1 -1
  79. package/.next/server/middleware-build-manifest.js +1 -1
  80. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  81. package/.next/server/pages/404.js +1 -1
  82. package/.next/server/pages/404.js.nft.json +1 -1
  83. package/.next/server/pages/500.js +1 -1
  84. package/.next/server/pages/500.js.nft.json +1 -1
  85. package/.next/server/pages/[...slug].js +1 -1
  86. package/.next/server/pages/[...slug].js.nft.json +1 -1
  87. package/.next/server/pages/[slug]/p.js +1 -1
  88. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  89. package/.next/server/pages/_app.js +1 -1
  90. package/.next/server/pages/_app.js.nft.json +1 -1
  91. package/.next/server/pages/_document.js +1 -1
  92. package/.next/server/pages/_document.js.nft.json +1 -1
  93. package/.next/server/pages/_error.js +1 -1
  94. package/.next/server/pages/_error.js.nft.json +1 -1
  95. package/.next/server/pages/account.js +1 -1
  96. package/.next/server/pages/account.js.nft.json +1 -1
  97. package/.next/server/pages/api/graphql.js +1 -1
  98. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  99. package/.next/server/pages/api/health/live.js +1 -1
  100. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  101. package/.next/server/pages/api/health/ready.js +1 -1
  102. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  103. package/.next/server/pages/api/preview.js +1 -1
  104. package/.next/server/pages/api/preview.js.nft.json +1 -1
  105. package/.next/server/pages/checkout.js +1 -1
  106. package/.next/server/pages/checkout.js.nft.json +1 -1
  107. package/.next/server/pages/en-US/404.html +1 -1
  108. package/.next/server/pages/en-US/404.json +1 -1
  109. package/.next/server/pages/en-US/500.html +1 -1
  110. package/.next/server/pages/en-US/500.json +1 -1
  111. package/.next/server/pages/en-US/account.html +1 -1
  112. package/.next/server/pages/en-US/account.json +1 -1
  113. package/.next/server/pages/en-US/checkout.html +1 -1
  114. package/.next/server/pages/en-US/checkout.json +1 -1
  115. package/.next/server/pages/en-US/login.html +1 -1
  116. package/.next/server/pages/en-US/login.json +1 -1
  117. package/.next/server/pages/en-US/s.html +1 -1
  118. package/.next/server/pages/en-US/s.json +1 -1
  119. package/.next/server/pages/en-US.html +1 -1
  120. package/.next/server/pages/en-US.json +1 -1
  121. package/.next/server/pages/index.js +1 -1
  122. package/.next/server/pages/index.js.nft.json +1 -1
  123. package/.next/server/pages/login.js +1 -1
  124. package/.next/server/pages/login.js.nft.json +1 -1
  125. package/.next/server/pages/s.js +1 -1
  126. package/.next/server/pages/s.js.nft.json +1 -1
  127. package/.next/server/pages-manifest.json +1 -1
  128. package/.next/static/chunks/1550-a6207993ae890714.js +1 -0
  129. package/.next/static/chunks/2552.9070ea604ee3c214.js +1 -0
  130. package/.next/static/chunks/2599-67df8c38c483737b.js +1 -0
  131. package/.next/static/chunks/3285.419d379c827c993d.js +1 -0
  132. package/.next/static/chunks/6379-e49fe5643b85d5b5.js +1 -0
  133. package/.next/static/chunks/7498-791ad2ef2c9fc716.js +1 -0
  134. package/.next/static/chunks/BannerNewsletter.29403e046f34b6c1.js +1 -0
  135. package/.next/static/chunks/BannerText.24939a8013e30e18.js +1 -0
  136. package/.next/static/chunks/CartSidebar.71febd97344a7b4c.js +1 -0
  137. package/.next/static/chunks/ProductShelf.d40d1e693c5a302b.js +1 -0
  138. package/.next/static/chunks/RegionModal.cec6e7d1faeeae2d.js +1 -0
  139. package/.next/static/chunks/Toast.0e3d2c547b67cf60.js +1 -0
  140. package/.next/static/chunks/pages/[slug]/p-c005eeb4788692e7.js +1 -0
  141. package/.next/static/chunks/webpack-0d0b6c5bc10dfaad.js +1 -0
  142. package/.next/static/css/d92839440872e246.css +1 -0
  143. package/.next/static/wTXZLYjYfhhubsnCUqtpc/_buildManifest.js +1 -0
  144. package/.next/trace +98 -98
  145. package/.turbo/turbo-build.log +4 -4
  146. package/.turbo/turbo-lint.log +1 -1
  147. package/.turbo/turbo-test.log +5 -5
  148. package/@generated/gql.ts +18 -2
  149. package/@generated/graphql.ts +157 -0
  150. package/@generated/persisted-documents.json +1 -0
  151. package/@generated/schema.graphql +2 -0
  152. package/CHANGELOG.md +10 -0
  153. package/cms/faststore/sections.json +193 -406
  154. package/package.json +5 -5
  155. package/src/components/sections/ProductDetails/DefaultComponents.ts +9 -1
  156. package/src/components/sections/ProductDetails/ProductDetails.tsx +46 -3
  157. package/src/components/sections/ProductDetails/section.module.scss +39 -3
  158. package/src/components/ui/SKUMatrix/SKUMatrixSidebar.tsx +132 -0
  159. package/src/sdk/cart/useBuyButton.ts +41 -20
  160. package/src/sdk/product/useAllVariantProducts.ts +114 -0
  161. package/src/typings/overrides.ts +21 -5
  162. package/.next/server/chunks/463.js +0 -1
  163. package/.next/static/6ZNleGM8J-r36JTXegNEr/_buildManifest.js +0 -1
  164. package/.next/static/chunks/1550-b2d0f274d1db008a.js +0 -1
  165. package/.next/static/chunks/2552.35321485d927aa08.js +0 -1
  166. package/.next/static/chunks/299.c58d37a55fab85ad.js +0 -1
  167. package/.next/static/chunks/6379-fc541ff2f12fab06.js +0 -1
  168. package/.next/static/chunks/9638-24a86482d4a4b434.js +0 -1
  169. package/.next/static/chunks/BannerNewsletter.96d85bb5fbde1d76.js +0 -1
  170. package/.next/static/chunks/BannerText.f58f1afdd622dd6c.js +0 -1
  171. package/.next/static/chunks/CartSidebar.33f111ff908118cf.js +0 -1
  172. package/.next/static/chunks/ProductShelf.58b9c11d0b9d412c.js +0 -1
  173. package/.next/static/chunks/RegionModal.8d2c6065d8aaf911.js +0 -1
  174. package/.next/static/chunks/Toast.9ad46e15a6444bd6.js +0 -1
  175. package/.next/static/chunks/pages/[slug]/p-b5e429fbf8e96d36.js +0 -1
  176. package/.next/static/chunks/webpack-712cba50a8ffee1b.js +0 -1
  177. package/.next/static/css/9718991cd57978e9.css +0 -1
  178. /package/.next/static/{6ZNleGM8J-r36JTXegNEr → wTXZLYjYfhhubsnCUqtpc}/_ssgManifest.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "3.5.1",
3
+ "version": "3.7.0",
4
4
  "license": "MIT",
5
5
  "repository": "vtex/faststore",
6
6
  "browserslist": "supports es6-module and not dead",
@@ -43,12 +43,12 @@
43
43
  "@envelop/graphql-jit": "^8.0.3",
44
44
  "@envelop/parser-cache": "^6.0.2",
45
45
  "@envelop/validation-cache": "^6.0.2",
46
- "@faststore/api": "^3.5.0",
47
- "@faststore/components": "^3.5.0",
46
+ "@faststore/api": "^3.7.0",
47
+ "@faststore/components": "^3.7.0",
48
48
  "@faststore/graphql-utils": "^3.5.0",
49
49
  "@faststore/lighthouse": "^3.5.0",
50
50
  "@faststore/sdk": "^3.5.0",
51
- "@faststore/ui": "^3.5.0",
51
+ "@faststore/ui": "^3.7.0",
52
52
  "@graphql-codegen/cli": "5.0.2",
53
53
  "@graphql-codegen/client-preset": "4.2.6",
54
54
  "@graphql-codegen/typescript": "4.0.7",
@@ -128,5 +128,5 @@
128
128
  "node": "18.19.0",
129
129
  "yarn": "1.19.1"
130
130
  },
131
- "gitHead": "63d97909ce64bf874209853f0c94030eeaa2ce22"
131
+ "gitHead": "b692b179d39c24f590083cc0a1fdaaa779aa6dd9"
132
132
  }
@@ -9,13 +9,17 @@ import {
9
9
  QuantitySelector as UIQuantitySelector,
10
10
  ImageGalleryViewer as UIImageGalleryViewer,
11
11
  ImageGallery as UIImageGallery,
12
+ SKUMatrix as UISKUMatrix,
13
+ SKUMatrixSidebar as UISKUMatrixSidebar,
14
+ SKUMatrixTrigger as UISKUMatrixTrigger,
12
15
  } from '@faststore/ui'
13
16
 
14
17
  import LocalImageGallery from 'src/components/ui/ImageGallery'
15
18
  import LocalShippingSimulation from 'src/components/ui/ShippingSimulation/ShippingSimulation'
16
19
  import { Image } from 'src/components/ui/Image'
17
20
  import LocalNotAvailableButton from 'src/components/product/NotAvailableButton'
18
- import LocalProductDescription from 'src/components/ui/ProductDescription'
21
+ import LocalSKUMatrixSidebar from 'src/components/ui/SKUMatrix/SKUMatrixSidebar'
22
+ import LocalProductDescription from 'src/components/ui/ProductDescription/ProductDescription'
19
23
  import { ProductDetailsSettings as LocalProductDetailsSettings } from 'src/components/ui/ProductDetails'
20
24
 
21
25
  export const ProductDetailsDefaultComponents = {
@@ -29,9 +33,13 @@ export const ProductDetailsDefaultComponents = {
29
33
  ShippingSimulation: UIShippingSimulation,
30
34
  ImageGallery: UIImageGallery,
31
35
  ImageGalleryViewer: UIImageGalleryViewer,
36
+ SKUMatrix: UISKUMatrix,
37
+ SKUMatrixTrigger: UISKUMatrixTrigger,
38
+ SKUMatrixSidebar: UISKUMatrixSidebar,
32
39
  __experimentalImageGalleryImage: Image,
33
40
  __experimentalImageGallery: LocalImageGallery,
34
41
  __experimentalShippingSimulation: LocalShippingSimulation,
42
+ __experimentalSKUMatrixSidebar: LocalSKUMatrixSidebar,
35
43
  __experimentalNotAvailableButton: LocalNotAvailableButton,
36
44
  __experimentalProductDescription: LocalProductDescription,
37
45
  __experimentalProductDetailsSettings: LocalProductDetailsSettings,
@@ -55,6 +55,21 @@ export interface ProductDetailsProps {
55
55
  usePriceWithTaxes?: boolean
56
56
  taxesLabel?: string
57
57
  }
58
+ skuMatrix?: {
59
+ shouldDisplaySKUMatrix?: boolean
60
+ triggerButtonLabel: string
61
+ separatorButtonsText: string
62
+ columns: {
63
+ name: string
64
+ additionalColumns: Array<{ label: string; value: string }>
65
+ availability: {
66
+ label: string
67
+ stockDisplaySettings: 'showAvailability' | 'showStockQuantity'
68
+ }
69
+ price: number
70
+ quantitySelector: number
71
+ }
72
+ }
58
73
  }
59
74
 
60
75
  function ProductDetails({
@@ -74,6 +89,7 @@ function ProductDetails({
74
89
  initiallyExpanded: productDescriptionInitiallyExpanded,
75
90
  displayDescription: shouldDisplayProductDescription,
76
91
  },
92
+ skuMatrix,
77
93
  notAvailableButton: { title: notAvailableButtonTitle },
78
94
  quantitySelector,
79
95
  taxesConfiguration,
@@ -81,17 +97,19 @@ function ProductDetails({
81
97
  const {
82
98
  DiscountBadge,
83
99
  ProductTitle,
100
+ SKUMatrix,
101
+ SKUMatrixTrigger,
84
102
  __experimentalImageGallery: ImageGallery,
85
103
  __experimentalShippingSimulation: ShippingSimulation,
86
104
  __experimentalNotAvailableButton: NotAvailableButton,
87
105
  __experimentalProductDescription: ProductDescription,
88
106
  __experimentalProductDetailsSettings: ProductDetailsSettings,
107
+ __experimentalSKUMatrixSidebar: SKUMatrixSidebar,
89
108
  } = useOverrideComponents<'ProductDetails'>()
90
109
  const { currency } = useSession()
91
110
  const context = usePDP()
92
111
  const { product, isValidating } = context?.data
93
112
  const [quantity, setQuantity] = useState(1)
94
-
95
113
  if (!product) {
96
114
  throw new Error('NotFound')
97
115
  }
@@ -104,7 +122,11 @@ function ProductDetails({
104
122
  brand,
105
123
  isVariantOf,
106
124
  description,
107
- isVariantOf: { name, productGroupID: productId },
125
+ isVariantOf: {
126
+ name,
127
+ productGroupID: productId,
128
+ skuVariants: { slugsMap },
129
+ },
108
130
  image: productImages,
109
131
  offers: {
110
132
  offers: [{ availability, price, listPrice, listPriceWithTaxes, seller }],
@@ -213,6 +235,27 @@ function ProductDetails({
213
235
  isValidating={isValidating}
214
236
  taxesConfiguration={taxesConfiguration}
215
237
  />
238
+
239
+ {skuMatrix?.shouldDisplaySKUMatrix &&
240
+ Object.keys(slugsMap).length > 1 && (
241
+ <>
242
+ <div data-fs-product-details-settings-separator>
243
+ {skuMatrix.separatorButtonsText}
244
+ </div>
245
+
246
+ <SKUMatrix.Component>
247
+ <SKUMatrixTrigger.Component disabled={isValidating}>
248
+ {skuMatrix.triggerButtonLabel}
249
+ </SKUMatrixTrigger.Component>
250
+
251
+ <SKUMatrixSidebar.Component
252
+ formatter={useFormattedPrice}
253
+ columns={skuMatrix.columns}
254
+ overlayProps={{ className: styles.section }}
255
+ />
256
+ </SKUMatrix.Component>
257
+ </>
258
+ )}
216
259
  </section>
217
260
 
218
261
  {!outOfStock && (
@@ -277,7 +320,7 @@ export const fragment = gql(`
277
320
  isVariantOf {
278
321
  name
279
322
  productGroupID
280
- skuVariants {
323
+ skuVariants {
281
324
  activeVariations
282
325
  slugsMap
283
326
  availableVariations
@@ -1,9 +1,13 @@
1
1
  @layer components {
2
2
  .section {
3
3
  // Taxes label
4
- --fs-product-details-taxes-label-color : var(--fs-color-info-text);
5
- --fs-product-details-taxes-text-size : var(--fs-text-size-tiny);
6
- --fs-product-details-taxes-text-weight : var(--fs-text-weight-regular);
4
+ --fs-product-details-taxes-label-color : var(--fs-color-info-text);
5
+ --fs-product-details-taxes-text-size : var(--fs-text-size-tiny);
6
+ --fs-product-details-taxes-text-weight : var(--fs-text-weight-regular);
7
+
8
+ // Separator colors
9
+ --fs-product-details-separator-color : var(--fs-color-neutral-2);
10
+ --fs-product-details-separator-color-text : var(--fs-color-text-light);
7
11
 
8
12
  margin-top: 0;
9
13
 
@@ -29,11 +33,43 @@
29
33
  @import "@faststore/ui/src/components/organisms/ShippingSimulation/styles.scss";
30
34
  @import "@faststore/ui/src/components/organisms/ImageGallery/styles.scss";
31
35
  @import "@faststore/ui/src/components/organisms/ProductDetails/styles.scss";
36
+ @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
37
+ @import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss";
32
38
 
33
39
  [data-fs-product-details-taxes-label] {
34
40
  font-size: var(--fs-product-details-taxes-text-size);
35
41
  font-weight: var(--fs-product-details-taxes-text-weight);
36
42
  color: var(--fs-product-details-taxes-label-color);
37
43
  }
44
+
45
+ [data-fs-product-details-settings-separator] {
46
+ position: relative;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: space-between;
50
+ color: var(--fs-product-details-separator-color-text);
51
+
52
+ &::after {
53
+ display: inline-block;
54
+ width: 45%;
55
+ height: 1px;
56
+ content: "";
57
+ background-color: var(--fs-product-details-separator-color);
58
+ }
59
+
60
+ &::before {
61
+ display: inline-block;
62
+ width: 45%;
63
+ height: 1px;
64
+ content: "";
65
+ background-color: var(--fs-product-details-separator-color);
66
+ }
67
+ }
68
+
69
+ [data-fs-sku-matrix] {
70
+ > [data-fs-button] {
71
+ width: 100%;
72
+ }
73
+ }
38
74
  }
39
75
  }
@@ -0,0 +1,132 @@
1
+ import type { SKUMatrixSidebarProps as UISKUMatrixSidebarProps } from '@faststore/ui'
2
+ import {
3
+ SKUMatrixSidebar as UISKUMatrixSidebar,
4
+ useSKUMatrix,
5
+ } from '@faststore/ui'
6
+ import { gql } from '@generated/gql'
7
+ import { useBuyButton } from 'src/sdk/cart/useBuyButton'
8
+ import { usePDP } from 'src/sdk/overrides/PageProvider'
9
+ import { useAllVariantProducts } from 'src/sdk/product/useAllVariantProducts'
10
+
11
+ interface SKUMatrixProps extends UISKUMatrixSidebarProps {}
12
+
13
+ function SKUMatrixSidebar(props: SKUMatrixProps) {
14
+ const {
15
+ data: { product },
16
+ } = usePDP()
17
+
18
+ const { allVariantProducts, isOpen, setAllVariantProducts } = useSKUMatrix()
19
+ const { isValidating } = useAllVariantProducts(
20
+ product.id,
21
+ isOpen,
22
+ setAllVariantProducts
23
+ )
24
+
25
+ const {
26
+ gtin,
27
+ unitMultiplier,
28
+ brand,
29
+ additionalProperty,
30
+ isVariantOf,
31
+ offers: {
32
+ offers: [{ seller }],
33
+ },
34
+ } = product
35
+
36
+ const buyButtonProps = allVariantProducts
37
+ .filter((item) => item.selectedCount)
38
+ .map((item) => {
39
+ const {
40
+ offers: {
41
+ offers: [{ price, priceWithTaxes, listPrice, listPriceWithTaxes }],
42
+ },
43
+ } = item
44
+
45
+ return {
46
+ id: item.id,
47
+ price,
48
+ priceWithTaxes,
49
+ listPrice,
50
+ listPriceWithTaxes,
51
+ seller,
52
+ quantity: item.selectedCount,
53
+ itemOffered: {
54
+ sku: item.id,
55
+ name: item.name,
56
+ gtin,
57
+ image: [item.image],
58
+ brand,
59
+ isVariantOf: {
60
+ ...isVariantOf,
61
+ skuVariants: {
62
+ ...isVariantOf.skuVariants,
63
+ activeVariations: item.specifications,
64
+ },
65
+ },
66
+ additionalProperty,
67
+ unitMultiplier,
68
+ },
69
+ }
70
+ })
71
+
72
+ const buyProps = useBuyButton(buyButtonProps)
73
+
74
+ return (
75
+ <UISKUMatrixSidebar
76
+ buyProps={buyProps}
77
+ title={product.isVariantOf.name ?? ''}
78
+ loading={isValidating}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ export const fragment = gql(`
85
+ fragment ProductSKUMatrixSidebarFragment_product on StoreProduct {
86
+ id: productID
87
+ isVariantOf {
88
+ name
89
+ productGroupID
90
+ skuVariants {
91
+ activeVariations
92
+ slugsMap
93
+ availableVariations
94
+ allVariantProducts {
95
+ sku
96
+ name
97
+ image {
98
+ url
99
+ alternateName
100
+ }
101
+ offers {
102
+ highPrice
103
+ lowPrice
104
+ lowPriceWithTaxes
105
+ offerCount
106
+ priceCurrency
107
+ offers {
108
+ listPrice
109
+ listPriceWithTaxes
110
+ sellingPrice
111
+ priceCurrency
112
+ price
113
+ priceWithTaxes
114
+ priceValidUntil
115
+ itemCondition
116
+ availability
117
+ quantity
118
+ }
119
+ }
120
+ additionalProperty {
121
+ propertyID
122
+ value
123
+ name
124
+ valueReference
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ `)
131
+
132
+ export default SKUMatrixSidebar
@@ -8,12 +8,14 @@ import { useUI } from '@faststore/ui'
8
8
  import { useSession } from '../session'
9
9
  import { cartStore } from './index'
10
10
 
11
- export const useBuyButton = (item: CartItem | null) => {
11
+ export const useBuyButton = (item: CartItem | CartItem[] | null) => {
12
12
  const { openCart } = useUI()
13
13
  const {
14
14
  currency: { code },
15
15
  } = useSession()
16
16
 
17
+ const itemIsArray = Array.isArray(item)
18
+
17
19
  const onClick = useCallback(
18
20
  (e: React.MouseEvent<HTMLButtonElement>) => {
19
21
  e.preventDefault()
@@ -22,6 +24,33 @@ export const useBuyButton = (item: CartItem | null) => {
22
24
  return
23
25
  }
24
26
 
27
+ const value = itemIsArray
28
+ ? item.reduce((sum, item) => (sum += item.price * item.quantity), 0)
29
+ : item.price * item.quantity
30
+
31
+ function generatedItem(item: CartItem) {
32
+ return {
33
+ item_id: item.itemOffered.isVariantOf.productGroupID,
34
+ item_name: item.itemOffered.isVariantOf.name,
35
+ item_brand: item.itemOffered.brand.name,
36
+ item_variant: item.itemOffered.sku,
37
+ quantity: item.quantity,
38
+ price: item.price,
39
+ discount: item.listPrice - item.price,
40
+ currency: code as CurrencyCode,
41
+ item_variant_name: item.itemOffered.name,
42
+ product_reference_id: item.itemOffered.gtin,
43
+ }
44
+ }
45
+
46
+ function getItems() {
47
+ if (!itemIsArray) {
48
+ return [generatedItem(item)]
49
+ }
50
+
51
+ return item.map(generatedItem)
52
+ }
53
+
25
54
  import('@faststore/sdk').then(({ sendAnalyticsEvent }) => {
26
55
  sendAnalyticsEvent<AddToCartEvent<AnalyticsItem>>({
27
56
  name: 'add_to_cart',
@@ -29,35 +58,27 @@ export const useBuyButton = (item: CartItem | null) => {
29
58
  currency: code as CurrencyCode,
30
59
  // TODO: In the future, we can explore more robust ways of
31
60
  // calculating the value (gift items, discounts, etc.).
32
- value: item.price * item.quantity,
33
- items: [
34
- {
35
- item_id: item.itemOffered.isVariantOf.productGroupID,
36
- item_name: item.itemOffered.isVariantOf.name,
37
- item_brand: item.itemOffered.brand.name,
38
- item_variant: item.itemOffered.sku,
39
- quantity: item.quantity,
40
- price: item.price,
41
- discount: item.listPrice - item.price,
42
- currency: code as CurrencyCode,
43
- item_variant_name: item.itemOffered.name,
44
- product_reference_id: item.itemOffered.gtin,
45
- },
46
- ],
61
+ value,
62
+ items: getItems(),
47
63
  },
48
64
  })
49
65
  })
50
66
 
51
- cartStore.addItem(item)
67
+ itemIsArray
68
+ ? item.forEach((value) => cartStore.addItem(value))
69
+ : cartStore.addItem(item)
70
+
52
71
  openCart()
53
72
  },
54
- [code, item, openCart]
73
+ [code, item, openCart, itemIsArray]
55
74
  )
56
75
 
57
76
  return {
58
77
  onClick,
59
78
  'data-testid': 'buy-button',
60
- 'data-sku': item?.itemOffered.sku,
61
- 'data-seller': item?.seller.identifier,
79
+ 'data-sku': itemIsArray ? 'sku-matrix-sidebar' : item?.itemOffered.sku,
80
+ 'data-seller': itemIsArray
81
+ ? item[0]?.seller.identifier
82
+ : item?.seller.identifier,
62
83
  }
63
84
  }
@@ -0,0 +1,114 @@
1
+ import { useMemo } from 'react'
2
+
3
+ import { gql } from '@generated'
4
+ import type {
5
+ ClientAllVariantProductsQueryQuery,
6
+ ClientProductQueryQueryVariables,
7
+ } from '@generated/graphql'
8
+
9
+ import { useQuery } from '../graphql/useQuery'
10
+ import { useSession } from '../session'
11
+
12
+ const query = gql(`
13
+ query ClientAllVariantProductsQuery($locator: [IStoreSelectedFacet!]!) {
14
+ product(locator: $locator) {
15
+ ...ProductSKUMatrixSidebarFragment_product
16
+ }
17
+ }
18
+ `)
19
+
20
+ type FormattedVariantProduct = {
21
+ id: string
22
+ name: string
23
+ image: {
24
+ url: string
25
+ alternateName: string
26
+ }
27
+ inventory: number
28
+ selectedCount: number
29
+ availability: string
30
+ offers: ClientAllVariantProductsQueryQuery['product']['isVariantOf']['skuVariants']['allVariantProducts'][0]['offers']
31
+ price: number
32
+ listPrice: number
33
+ priceWithTaxes: number
34
+ listPriceWithTaxes: number
35
+ specifications: Record<string, string>
36
+ }
37
+
38
+ export const useAllVariantProducts = <
39
+ T extends ClientAllVariantProductsQueryQuery
40
+ >(
41
+ productID: string,
42
+ enabled: boolean,
43
+ processResponse: (data: FormattedVariantProduct[]) => void,
44
+ fallbackData?: T
45
+ ) => {
46
+ const { channel, locale } = useSession()
47
+ const variables = useMemo(() => {
48
+ if (!channel) {
49
+ throw new Error(
50
+ `useAllVariantProducts: 'channel' from session is an empty string.`
51
+ )
52
+ }
53
+
54
+ return {
55
+ locator: [
56
+ { key: 'id', value: productID },
57
+ { key: 'channel', value: channel },
58
+ { key: 'locale', value: locale },
59
+ ],
60
+ }
61
+ }, [channel, locale, productID])
62
+
63
+ return useQuery<FormattedVariantProduct[], ClientProductQueryQueryVariables>(
64
+ query,
65
+ variables,
66
+ {
67
+ fallbackData,
68
+ revalidateOnMount: true,
69
+ doNotRun: !enabled,
70
+ onSuccess: (data: ClientAllVariantProductsQueryQuery) => {
71
+ const formattedData =
72
+ data.product.isVariantOf.skuVariants.allVariantProducts.map(
73
+ (item) => {
74
+ const specifications = item.additionalProperty.reduce<{
75
+ [key: string]: any
76
+ }>(
77
+ (acc, prop) => ({
78
+ ...acc,
79
+ [prop.name.toLowerCase()]: prop.value,
80
+ }),
81
+ {}
82
+ )
83
+
84
+ const outOfStock =
85
+ item.offers.offers[0].availability ===
86
+ 'https://schema.org/OutOfStock'
87
+
88
+ return {
89
+ id: item.sku,
90
+ name: item.name,
91
+ image: {
92
+ url: item.image[0].url,
93
+ alternateName: item.image[0].alternateName,
94
+ },
95
+ inventory: item.offers.offers[0].quantity,
96
+ availability: outOfStock ? 'outOfStock' : 'available',
97
+ price: item.offers.offers[0].price,
98
+ listPrice: item.offers.offers[0].listPrice,
99
+ priceWithTaxes: item.offers.offers[0].priceWithTaxes,
100
+ listPriceWithTaxes: item.offers.offers[0].listPriceWithTaxes,
101
+ specifications,
102
+ offers: item.offers,
103
+ selectedCount: 0,
104
+ }
105
+ }
106
+ )
107
+
108
+ processResponse(
109
+ formattedData.sort((a, b) => a.name.localeCompare(b.name))
110
+ )
111
+ },
112
+ }
113
+ )
114
+ }
@@ -39,6 +39,9 @@ import type {
39
39
  ShippingSimulationProps,
40
40
  SkeletonProps,
41
41
  SkuSelectorProps,
42
+ SKUMatrixProps,
43
+ SKUMatrixTriggerProps,
44
+ SKUMatrixSidebarProps,
42
45
  } from '@faststore/ui'
43
46
 
44
47
  import type {
@@ -81,10 +84,10 @@ export type SectionOverride = {
81
84
  export type OverrideComponentsForSection<
82
85
  Section extends SectionsOverrides[keyof SectionsOverrides]['Section']
83
86
  > = {
84
- // The first 'extends' condition is used to filter out sections that don't have overrides (typed 'never')
85
- [K in keyof SectionsOverrides as SectionsOverrides[K] extends {
86
- Section: never
87
- }
87
+ // The first 'extends' condition is used to filter out sections that don't have overrides (typed 'never')
88
+ [K in keyof SectionsOverrides as SectionsOverrides[K] extends {
89
+ Section: never
90
+ }
88
91
  ? never
89
92
  : // In the second 'extends' condition, we check if the section matches the one we're looking for
90
93
  SectionsOverrides[K] extends {
@@ -269,12 +272,25 @@ export type SectionsOverrides = {
269
272
  ImageGalleryViewerProps,
270
273
  ImageGalleryViewerProps
271
274
  >
275
+ SKUMatrix: ComponentOverrideDefinition<SKUMatrixProps, SKUMatrixProps>
276
+ SKUMatrixTrigger: ComponentOverrideDefinition<
277
+ SKUMatrixTriggerProps,
278
+ SKUMatrixTriggerProps
279
+ >
280
+ SKUMatrixSidebar: ComponentOverrideDefinition<
281
+ SKUMatrixSidebarProps,
282
+ SKUMatrixSidebarProps
283
+ >
272
284
  __experimentalImageGalleryImage: ComponentOverrideDefinition<any, any>
273
285
  __experimentalImageGallery: ComponentOverrideDefinition<any, any>
274
286
  __experimentalShippingSimulation: ComponentOverrideDefinition<any, any>
275
287
  __experimentalNotAvailableButton: ComponentOverrideDefinition<any, any>
276
288
  __experimentalProductDescription: ComponentOverrideDefinition<any, any>
277
- __experimentalProductDetailsSettings: ComponentOverrideDefinition<any, any>
289
+ __experimentalSKUMatrixSidebar: ComponentOverrideDefinition<any, any>
290
+ __experimentalProductDetailsSettings: ComponentOverrideDefinition<
291
+ any,
292
+ any
293
+ >
278
294
  }
279
295
  }
280
296
  ProductGallery: {
@@ -1 +0,0 @@
1
- "use strict";exports.id=463,exports.ids=[463],exports.modules={6476:(e,t,a)=>{a.d(t,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var l=a(6689),r=a.n(l),n=a(3339);let __WEBPACK_DEFAULT_EXPORT__=function({testId:e="fs-buy-button",icon:t,children:a,...l}){return r().createElement(n.Z,{"data-fs-buy-button":!0,icon:t,iconPosition:"left","data-testid":e,...l},a)}},7876:(e,t,a)=>{a.d(t,{Z:()=>o});var l=a(6689),r=a.n(l),n=a(3024);let i=(0,l.forwardRef)(function({title:e,label:t,refTag:a="Ref.: ",refNumber:l,testId:i="fs-product-title",ratingValue:o,...s},c){return r().createElement("header",{ref:c,"data-fs-product-title":!0,"data-testid":i,...s},r().createElement("div",{"data-fs-product-title-header":!0},e,!!t&&t),(l||o)&&r().createElement("div",{"data-fs-product-title-addendum":!0},o&&r().createElement(n.Z,{value:o}),l&&r().createElement(r().Fragment,null,a," ",l)))}),o=i},6693:(e,t,a)=>{a.d(t,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var l=a(6689),r=a.n(l),n=a(7041),i=a(2614),o=a(2256);let __WEBPACK_DEFAULT_EXPORT__=({max:e,min:t=1,unitMultiplier:a=1,useUnitMultiplier:s,initial:c,disabled:u=!1,onChange:d,onValidateBlur:m,testId:f="fs-quantity-selector",...g})=>{let[E,h]=(0,l.useState)(c??t),[p,_]=(0,l.useState)(E*a),roundUpQuantityIfNeeded=e=>s?Math.ceil(e/a)*a:e,b=E===t,y=E===e,changeQuantity=e=>{let t=validateQuantityBounds(E+e);d?.(t),h(t),_(t*a)};function validateQuantityBounds(l){let r=t?Math.max(l,t):l;return e?Math.min(r,s?e*a:e):r}return(0,l.useEffect)(()=>{c&&h(c)},[c]),r().createElement("div",{"data-fs-quantity-selector":u?"disabled":"true","data-testid":f,...g},r().createElement(n.Z,{"data-quantity-selector-button":"left",icon:r().createElement(i.Z,{name:"Minus",width:16,height:16,weight:"bold"}),"aria-label":"Decrement Quantity","aria-controls":"quantity-selector-input",disabled:b||u,onClick:()=>changeQuantity(-1),testId:`${f}-left-button`,size:"small"}),r().createElement(o.Z,{"data-quantity-selector-input":!0,id:"quantity-selector-input","aria-label":"Quantity",value:s?p:E,onChange:e=>{let t=e.target.value.replace(/\D/g,"");h(Number(t))},onBlur:function(){let l=validateQuantityBounds(E),r=roundUpQuantityIfNeeded(l),n=e??(t?Math.max(E,t):E),i=E>n||E<t;i&&m?.(t,n,r),h(()=>(_(r),d?.(r/a),r/a))},onInput:e=>{let t=e.currentTarget;t.value=t.value.replace(/\D/g,"")},disabled:u}),r().createElement(n.Z,{"data-quantity-selector-button":"right","aria-controls":"quantity-selector-input","aria-label":"Increment Quantity",disabled:y||u,icon:r().createElement(i.Z,{name:"Plus",width:16,height:16,weight:"bold"}),onClick:()=>changeQuantity(1),testId:`${f}-right-button`,size:"small"}))}},5136:(e,t,a)=>{a.d(t,{Z:()=>c});var l=a(6689),r=a.n(l),n=a(1953),i=a(727),o=a(5450);let getImageName=e=>{let t=new URL(e).pathname,a=t.split("/").slice(-1)[0];return a},useDefineVariant=(e,t)=>(0,l.useMemo)(()=>{if(t)return t;let a=e.every(e=>e.hexColor);if(a)return"color";let l=e[0]?.src&&getImageName(e[0].src);if(l&&1===e.length)return"image";let r=e.every(e=>{if(!e.src)return!0;let t=getImageName(e.src);return t===l});return r?"label":"image"},[e,t]),useSkuSlug=(e,t,a,r)=>{let n=(0,l.useCallback)(l=>{if(r)return{getItemHrefProp:r};let n=`/${function(e,t,a){let l=Object.entries(t).flat().join("-");if(l in e)return e[l];let r=Object.keys(e),n=`${a}-${t[a]}`,i=r.filter(e=>e.includes(n)),o=i.length>1?function(e,t){let[a,l]=t.split("-");return e.find(e=>{let t=function(e){let t={},a=e.split("-");for(let e=0;e<a.length;e+=2){let l=a[e].trim(),r=a[e+1]?a[e+1].trim():"";t[l]=r}return t}(e);return t[a]===l})}(i,n):i[0];return e[o??r[0]]}(t,{...e,[a]:l.value},a)}/p`;return n},[e,r,t,a]);return{getItemHref:n}},ImageComponentFallback=({src:e,alt:t,...a})=>r().createElement("img",{src:e,alt:t,...a}),s=(0,l.forwardRef)(function({availableVariations:e,skuPropertyName:t,testId:a,activeVariations:l,linkProps:s,slugsMap:c,getItemHref:u,ImageComponent:d=ImageComponentFallback,variant:m,...f},g){let E=l[t],h=e[t],p=useDefineVariant(h,m),{getItemHref:_}=useSkuSlug(l,c,t,u);return r().createElement("div",{ref:g,"data-fs-sku-selector":!0,"data-testid":a,"data-fs-sku-selector-variant":p,...f},t&&r().createElement(n.Z,{"data-fs-sku-selector-title":!0},t,": ",r().createElement("strong",null,E)),r().createElement("ul",{"data-fs-sku-selector-list":!0},h.map((e,a)=>r().createElement("li",{key:String(a),title:e.label,"data-fs-sku-selector-option":!0,"data-fs-sku-selector-disabled":e.disabled,"data-fs-sku-selector-checked":e.value===l[t]},r().createElement(i.Z,{"data-fs-sku-selector-option-link":!0,href:_(e),...s},r().createElement(o.Z,{text:e.label})),"label"===p&&r().createElement("span",null,e.value),"image"===p&&d&&r().createElement("span",null,r().createElement(d,{src:e.src??"",alt:e.alt??"","data-fs-sku-selector-option-image":!0})),"color"===p&&r().createElement("span",null,r().createElement("div",{"data-fs-sku-selector-option-color":!0,title:e.value,style:{"--data-fs-sku-selector-option-color-bkg-color":e.hexColor}}))))))}),c=s},7336:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(6689),r=a.n(l);let n=(0,l.forwardRef)(function({children:e,variant:t="colored",testId:a="fs-table",...l},n){return r().createElement("div",{"data-fs-table":!0},r().createElement("table",{ref:n,"data-fs-table-content":!0,"data-fs-table-variant":t,"data-testid":a,...l},e))}),i=n},9336:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(6689),r=a.n(l);let n=(0,l.forwardRef)(function({children:e,testId:t="fs-table-body",...a},l){return r().createElement("tbody",{ref:l,"data-testid":t,"data-fs-table-body":!0,...a},e)}),i=n},4256:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(6689),r=a.n(l);let n=(0,l.forwardRef)(function({scope:e,align:t,children:a,variant:l="data",testId:n="fs-table-cell",...i},o){return r().createElement("header"===l?"th":"td",{ref:o,"data-fs-table-cell":l,"data-fs-table-cell-align":t,"data-testid":n,scope:e,...i},a)}),i=n},4236:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(6689),r=a.n(l);let n=(0,l.forwardRef)(function({children:e,testId:t="fs-table-row",...a},l){return r().createElement("tr",{ref:l,"data-fs-table-row":!0,"data-testid":t,...a},e)}),i=n},165:(e,t,a)=>{a.d(t,{Z:()=>o});var l=a(6689),r=a.n(l),n=a(9362);let i=(0,l.forwardRef)(function({images:e,children:t,ImageComponent:a,selectedImageIdx:l,setSelectedImageIdx:i,testId:o="fs-image-gallery",...s},c){let u=e.length>1;return r().createElement("section",{ref:c,"data-fs-image-gallery":u?"with-selector":"without-selector","data-testid":o,...s},t,u&&r().createElement(n.Z,{images:e,onSelect:i,currentImageIdx:l,ImageComponent:a}))}),o=i},9362:(e,t,a)=>{a.d(t,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var l=a(6689),r=a.n(l),n=a(9785),i=a(7041),o=a(2614),s=a(3339);let moveScroll=(e,t)=>{e&&(e.scrollHeight>e.clientHeight?(e.style.overflow="auto",window.requestAnimationFrame(()=>e.scrollTo({top:t,behavior:"smooth"})),setTimeout(()=>e.style.overflow="hidden",2e3)):e.scrollLeft+=t)},hasScroll=e=>!!e&&(e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth),__WEBPACK_DEFAULT_EXPORT__=function({images:e,onSelect:t,ImageComponent:a,currentImageIdx:c,testId:u="fs-image-gallery-selector","aria-label":d="Product Images",navigationButtonLeftAriaLabel:m="Backward slide image selector",navigationButtonRightAriaLabel:f="Forward slide image selector"}){let g=(0,l.useRef)(null),E=hasScroll(g.current),[h,p]=(0,l.useState)(!0),[_,b]=(0,l.useState)(!0),y=(0,l.useCallback)((t,a)=>{0===t&&p(a),t===e.length-1&&b(a)},[e.length]);return r().createElement("section",{"data-fs-image-gallery-selector":!0,"data-testid":u,"aria-label":d},E&&!h&&r().createElement("div",{"data-fs-image-gallery-selector-control":!0},r().createElement(i.Z,{"data-fs-image-gallery-selector-control-button":!0,"aria-label":m,icon:r().createElement(o.Z,{name:"ArrowLeft"}),onClick:()=>moveScroll(g.current,-400)})),r().createElement("div",{"data-fs-image-gallery-selector-elements":!0,ref:g},e.map((l,i)=>r().createElement(n.InView,{key:i,onChange:e=>y(i,e)},r().createElement(s.Z,{key:i,"aria-label":`${l.alternateName} - Image ${i+1} of ${e.length}`,onClick:()=>t(i),"data-fs-image-gallery-selector-thumbnail":i===c?"selected":"true"},r().createElement(a,{url:l.url??"",loading:0===i?"eager":"lazy",alternateName:l.alternateName??""}))))),E&&!_&&r().createElement("div",{"data-fs-image-gallery-selector-control":!0},r().createElement(i.Z,{"data-fs-image-gallery-selector-control-button":!0,"aria-label":f,icon:r().createElement(o.Z,{name:"ArrowLeft"}),onClick:()=>moveScroll(g.current,400)})))}},1431:(e,t,a)=>{a.d(t,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var l=a(6689),r=a.n(l);let __WEBPACK_DEFAULT_EXPORT__=({children:e})=>r().createElement(r().Fragment,null,e)},8878:(e,t,a)=>{a.d(t,{Z:()=>__WEBPACK_DEFAULT_EXPORT__});var l=a(6689),r=a.n(l),n=a(3779),i=a(727),o=a(2614),s=a(7336),c=a(9336),u=a(4236),d=a(4256),m=a(9767);let __WEBPACK_DEFAULT_EXPORT__=function({testId:e="fs-shipping-simulation",formatter:t,title:a="Shipping",inputLabel:l="Postal Code",optionsLabel:f="Shipping options",idkPostalCodeLinkProps:g,onInput:E,onSubmit:h,onClear:p,location:_,options:b=[],displayClearButton:y=!1,errorMessage:v,postalCode:Z,...k}){let w=!!b&&b.length>0;return r().createElement("section",{"data-fs-shipping-simulation":!0,"data-fs-shipping-simulation-empty":w?"false":"true","data-testid":e,...k},r().createElement("h2",{"data-fs-shipping-simulation-title":!0},a),r().createElement(n.Z,{actionable:!0,error:v,id:`${e}-input-field`,label:l,value:Z,onInput:e=>E?.(e),onSubmit:()=>h?.(),onClear:()=>p?.(),displayClearButton:y}),r().createElement(i.Z,{href:"/","data-fs-shipping-simulation-link":!0,size:"small",...g},g?.children??r().createElement(r().Fragment,null,"I don't know my Postal Code",r().createElement(o.Z,{name:"ArrowSquareOut",width:20,height:20}))),w&&r().createElement(r().Fragment,null,r().createElement("header",{"data-fs-shipping-simulation-header":!0},r().createElement("h3",{"data-fs-shipping-simulation-subtitle":!0},f),r().createElement("p",{"data-fs-shipping-simulation-location":!0},_)),r().createElement(s.Z,null,r().createElement(c.Z,null,b.map(e=>r().createElement(u.Z,{key:e.carrier},r().createElement(d.Z,{align:"left"},e.carrier),r().createElement(d.Z,null,e.localizedEstimates),r().createElement(d.Z,{align:"right"},e.price&&r().createElement(m.Z,{formatter:t,value:e.price,SRText:"price"}))))))))}}};
@@ -1 +0,0 @@
1
- self.__BUILD_MANIFEST=function(s,c,a,t,e,i){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":[s,c,a,"static/css/b1806cbafd0c1f81.css","static/chunks/pages/index-ad532cf8840c5d3f.js"],"/404":[s,c,a,t,"static/chunks/pages/404-358f6795222bf991.js"],"/500":[s,c,a,t,"static/chunks/pages/500-7adc48c3231ccee1.js"],"/_error":["static/chunks/pages/_error-85cabf0d7a5ea2f2.js"],"/account":[s,c,a,"static/chunks/pages/account-9db0ef5c4174c7dd.js"],"/checkout":[s,c,a,"static/chunks/pages/checkout-abaa6374ae946641.js"],"/login":[s,c,a,t,"static/chunks/pages/login-8d2eb8db226d6363.js"],"/s":[s,c,a,e,i,t,"static/chunks/pages/s-ba5734fbe496d9af.js"],"/[slug]/p":[s,c,a,"static/chunks/9638-24a86482d4a4b434.js","static/css/bf1560439df2c1a1.css","static/css/e3ff5d95518a5c79.css","static/chunks/6379-fc541ff2f12fab06.js","static/css/9718991cd57978e9.css","static/chunks/pages/[slug]/p-b5e429fbf8e96d36.js"],"/[...slug]":[s,c,a,e,i,"static/chunks/pages/[...slug]-0203b74377537f7d.js"],sortedPages:["/","/404","/500","/_app","/_error","/account","/checkout","/login","/s","/[slug]/p","/[...slug]"]}}("static/chunks/6941-6223429b182b7109.js","static/css/93d239c461485bdf.css","static/chunks/1550-b2d0f274d1db008a.js","static/css/2980acad3f8e1028.css","static/css/6e34c6c07086e3df.css","static/chunks/4501-7857a5a8218d9f58.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();