@faststore/core 3.38.3 → 3.40.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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +18 -21
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +10 -10
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/41.js +1 -0
- package/.next/server/chunks/674.js +1 -1
- package/.next/server/chunks/{9380.js → 7348.js} +1 -1
- package/.next/server/chunks/8112.js +1 -1
- package/.next/server/functions-config-manifest.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.js +1 -1
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.js +1 -1
- package/.next/server/pages/500.js.nft.json +1 -1
- package/.next/server/pages/[...slug].js +1 -1
- package/.next/server/pages/[...slug].js.nft.json +1 -1
- package/.next/server/pages/[slug]/p.js +1 -1
- package/.next/server/pages/[slug]/p.js.nft.json +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/account/profile.js +1 -1
- package/.next/server/pages/account/profile.js.nft.json +1 -1
- package/.next/server/pages/account.js +1 -1
- package/.next/server/pages/account.js.nft.json +1 -1
- package/.next/server/pages/api/graphql.js +1 -1
- package/.next/server/pages/api/graphql.js.nft.json +1 -1
- package/.next/server/pages/api/health/live.js.nft.json +1 -1
- package/.next/server/pages/api/health/ready.js.nft.json +1 -1
- package/.next/server/pages/api/preview.js.nft.json +1 -1
- package/.next/server/pages/checkout.js +1 -1
- package/.next/server/pages/checkout.js.nft.json +1 -1
- package/.next/server/pages/en-US/404.html +2 -2
- package/.next/server/pages/en-US/500.html +2 -2
- package/.next/server/pages/en-US/checkout.html +2 -2
- package/.next/server/pages/en-US/login.html +2 -2
- package/.next/server/pages/en-US/s.html +2 -2
- package/.next/server/pages/en-US.html +2 -2
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/login.js +1 -1
- package/.next/server/pages/login.js.nft.json +1 -1
- package/.next/server/pages/s.js +1 -1
- package/.next/server/pages/s.js.nft.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/static/chunks/{1552.b5a073e7ac834965.js → 1552.e7cece605fc2e1cd.js} +1 -1
- package/.next/static/chunks/{4349-24e224a3b1307f65.js → 4349-6fc936580b772e67.js} +1 -1
- package/.next/static/chunks/{4625-07284599f239c05b.js → 4625-c277826e300c23b7.js} +1 -1
- package/.next/static/chunks/4774.907a71a04126d57c.js +1 -0
- package/.next/static/chunks/ProductShelf.0b5a71a93bca3148.js +1 -0
- package/.next/static/chunks/ProductTiles.a75612c0bcf990d6.js +1 -0
- package/.next/static/chunks/pages/account-963cd6d42498ff28.js +1 -0
- package/.next/static/chunks/{webpack-827d211260f776ab.js → webpack-071462ed32bcb285.js} +1 -1
- package/.next/static/sCq3tiaobInU11Xb5y64T/_buildManifest.js +1 -0
- package/.next/trace +109 -108
- package/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-test.log +6 -5
- package/CHANGELOG.md +12 -0
- package/package.json +2 -2
- package/src/components/product/ProductGrid/ProductGrid.tsx +67 -40
- package/src/components/ui/ProductGallery/ProductGalleryPage.tsx +1 -0
- package/src/pages/account/index.tsx +26 -35
- package/src/sdk/analytics/hooks/useViewItemListEvent.ts +39 -26
- package/src/sdk/product/ProductSentinel.tsx +60 -0
- package/src/sdk/product/viewItemListQueue.ts +31 -0
- package/src/sdk/search/Sentinel.tsx +3 -29
- package/.next/server/chunks/2032.js +0 -1
- package/.next/static/D9Rlow6eCZi7BCEu9o7_O/_buildManifest.js +0 -1
- package/.next/static/chunks/3143.1aaec7f4a9e83b8d.js +0 -1
- package/.next/static/chunks/ProductShelf.e80131dfc337fae6.js +0 -1
- package/.next/static/chunks/ProductTiles.413c061cf10578b4.js +0 -1
- package/.next/static/chunks/pages/account-32bc9db3fea9b0c4.js +0 -1
- /package/.next/static/{D9Rlow6eCZi7BCEu9o7_O → sCq3tiaobInU11Xb5y64T}/_ssgManifest.js +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.
|
|
2
|
+
> @faststore/core@3.39.0 prebuild /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> na run partytown && na run generate
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @faststore/core@3.
|
|
6
|
+
> @faststore/core@3.39.0 partytown /home/runner/work/faststore/faststore/packages/core
|
|
7
7
|
> partytown copylib ./public/~partytown
|
|
8
8
|
|
|
9
9
|
Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
|
|
10
10
|
|
|
11
|
-
> @faststore/core@3.
|
|
11
|
+
> @faststore/core@3.39.0 generate /home/runner/work/faststore/faststore/packages/core
|
|
12
12
|
> na run generate:schema && na run generate:codegen && na run format:generated
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
> @faststore/core@3.
|
|
15
|
+
> @faststore/core@3.39.0 generate:schema /home/runner/work/faststore/faststore/packages/core
|
|
16
16
|
> tsx src/server/generator/generateGraphQLSchemaFile.ts
|
|
17
17
|
|
|
18
18
|
Schema GraphQL file generated successfully
|
|
19
19
|
|
|
20
|
-
> @faststore/core@3.
|
|
20
|
+
> @faststore/core@3.39.0 generate:codegen /home/runner/work/faststore/faststore/packages/core
|
|
21
21
|
> graphql-codegen
|
|
22
22
|
|
|
23
23
|
[STARTED] Parse Configuration
|
|
@@ -37,11 +37,11 @@ Running lifecycle hook "afterStart" scripts...
|
|
|
37
37
|
[CLI] Loading Documents
|
|
38
38
|
[CLI] Generating output
|
|
39
39
|
|
|
40
|
-
> @faststore/core@3.
|
|
40
|
+
> @faststore/core@3.39.0 format:generated /home/runner/work/faststore/faststore/packages/core
|
|
41
41
|
> prettier --write "@generated/**/*.{ts,js,tsx,jsx,json}" --loglevel error
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
> @faststore/core@3.
|
|
44
|
+
> @faststore/core@3.39.0 build /home/runner/work/faststore/faststore/packages/core
|
|
45
45
|
> next build
|
|
46
46
|
|
|
47
47
|
⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
|
|
@@ -71,13 +71,13 @@ Route (pages) Size First Load JS
|
|
|
71
71
|
├ └ css/b1806cbafd0c1f81.css 3.06 kB
|
|
72
72
|
├ /_app 0 B 92.4 kB
|
|
73
73
|
├ ● /[...slug] 2.34 kB 133 kB
|
|
74
|
-
├ ● /[slug]/p 35.
|
|
74
|
+
├ ● /[slug]/p 35.6 kB 156 kB
|
|
75
75
|
├ ├ css/a3ca6a9b63f657be.css 5.75 kB
|
|
76
76
|
├ ├ css/62a5153ac7061286.css 6.11 kB
|
|
77
77
|
├ └ css/b5bf49598c8f8b66.css 16.1 kB
|
|
78
78
|
├ ○ /404 1.48 kB 122 kB
|
|
79
79
|
├ ● /500 1.48 kB 122 kB
|
|
80
|
-
├ λ /account
|
|
80
|
+
├ λ /account 240 B 92.6 kB
|
|
81
81
|
├ λ /account/profile 1.34 kB 122 kB
|
|
82
82
|
├ └ css/249b9deaabc0d32d.css 2.51 kB
|
|
83
83
|
├ λ /api/graphql 0 B 92.4 kB
|
|
@@ -91,7 +91,7 @@ Route (pages) Size First Load JS
|
|
|
91
91
|
├ chunks/framework-807b0f81cbc129f0.js 45.4 kB
|
|
92
92
|
├ chunks/main-5569625b3fdd6741.js 33.1 kB
|
|
93
93
|
├ chunks/pages/_app-012e51403727ae6a.js 10.4 kB
|
|
94
|
-
├ chunks/webpack-
|
|
94
|
+
├ chunks/webpack-071462ed32bcb285.js 3.59 kB
|
|
95
95
|
└ css/0a57ee6c7a57788c.css 3.49 kB
|
|
96
96
|
|
|
97
97
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
> @faststore/core@3.
|
|
2
|
+
> @faststore/core@3.39.0 test /home/runner/work/faststore/faststore/packages/core
|
|
3
3
|
> jest
|
|
4
4
|
|
|
5
|
-
PASS test/
|
|
6
|
-
PASS test/
|
|
5
|
+
PASS test/server/cms/global.test.ts (24.343 s)
|
|
6
|
+
PASS test/utils/multipleTemplates.test.ts (25.211 s)
|
|
7
7
|
PASS test/server/cms/index.test.ts
|
|
8
|
-
PASS test/server/index.test.ts (28.
|
|
8
|
+
PASS test/server/index.test.ts (28.944 s)
|
|
9
|
+
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
|
|
9
10
|
|
|
10
11
|
Test Suites: 4 passed, 4 total
|
|
11
12
|
Tests: 22 passed, 22 total
|
|
12
13
|
Snapshots: 0 total
|
|
13
|
-
Time:
|
|
14
|
+
Time: 30.228 s
|
|
14
15
|
Ran all test suites.
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.40.0](https://github.com/vtex/faststore/compare/v3.39.0...v3.40.0) (2025-04-11)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- GA `view_item_list` event only when item is in viewport of `ProductGallery` ([#2771](https://github.com/vtex/faststore/issues/2771)) ([16a4efa](https://github.com/vtex/faststore/commit/16a4efa23b7459a4327df0bc994b96c15f44ee5e))
|
|
11
|
+
|
|
12
|
+
# [3.39.0](https://github.com/vtex/faststore/compare/v3.38.3...v3.39.0) (2025-04-11)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- MyAccount redirects using SSR - SFS-2440 ([#2782](https://github.com/vtex/faststore/issues/2782)) ([6f92f41](https://github.com/vtex/faststore/commit/6f92f41e647298734bcc0f503810845c1558fd6f))
|
|
17
|
+
|
|
6
18
|
## 3.38.3 (2025-04-11)
|
|
7
19
|
|
|
8
20
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.40.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "vtex/faststore",
|
|
6
6
|
"browserslist": "supports es6-module and not dead",
|
|
@@ -105,5 +105,5 @@
|
|
|
105
105
|
"ts-jest": "29.1.1",
|
|
106
106
|
"typescript": "5.3.2"
|
|
107
107
|
},
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "be8308dc73b997370c8c1aac56682362acfe58c0"
|
|
109
109
|
}
|
|
@@ -10,6 +10,7 @@ import { memo } from 'react'
|
|
|
10
10
|
import ViewportObserver from 'src/components/cms/ViewportObserver'
|
|
11
11
|
import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext'
|
|
12
12
|
import useScreenResize from 'src/sdk/ui/useScreenResize'
|
|
13
|
+
import ProductSentinel from 'src/sdk/product/ProductSentinel'
|
|
13
14
|
|
|
14
15
|
interface Props {
|
|
15
16
|
/**
|
|
@@ -35,6 +36,10 @@ interface Props {
|
|
|
35
36
|
* Determine if the current page is the first page.
|
|
36
37
|
*/
|
|
37
38
|
firstPage?: number
|
|
39
|
+
/**
|
|
40
|
+
* Title for the `ProductGrid` component that will be send to GA events.
|
|
41
|
+
*/
|
|
42
|
+
title?: string
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
function ProductGrid({
|
|
@@ -48,6 +53,7 @@ function ProductGrid({
|
|
|
48
53
|
sponsoredLabel,
|
|
49
54
|
} = {},
|
|
50
55
|
firstPage,
|
|
56
|
+
title,
|
|
51
57
|
}: Props) {
|
|
52
58
|
const { isMobile } = useScreenResize()
|
|
53
59
|
const { __experimentalProductCard: ProductCard } =
|
|
@@ -67,36 +73,19 @@ function ProductGrid({
|
|
|
67
73
|
<>
|
|
68
74
|
{products.slice(0, 2).map(({ node: product }, idx) => (
|
|
69
75
|
<UIProductGridItem key={`${product.id}`}>
|
|
70
|
-
<
|
|
71
|
-
aspectRatio={aspectRatio}
|
|
72
|
-
imgProps={{
|
|
73
|
-
width: 150,
|
|
74
|
-
height: 150,
|
|
75
|
-
sizes: '30vw',
|
|
76
|
-
loading: 'eager',
|
|
77
|
-
}}
|
|
78
|
-
{...ProductCard.props}
|
|
79
|
-
bordered={bordered ?? ProductCard.props.bordered}
|
|
80
|
-
showDiscountBadge={
|
|
81
|
-
showDiscountBadge ?? ProductCard.props.showDiscountBadge
|
|
82
|
-
}
|
|
76
|
+
<ProductSentinel
|
|
83
77
|
product={product}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</UIProductGridItem>
|
|
89
|
-
))}
|
|
90
|
-
<ViewportObserver sectionName="UIProductGrid-out-viewport">
|
|
91
|
-
{products.slice(2).map(({ node: product }, idx) => (
|
|
92
|
-
<UIProductGridItem key={`${product.id}`}>
|
|
78
|
+
title={title}
|
|
79
|
+
page={page}
|
|
80
|
+
pageSize={pageSize}
|
|
81
|
+
>
|
|
93
82
|
<ProductCard.Component
|
|
94
83
|
aspectRatio={aspectRatio}
|
|
95
84
|
imgProps={{
|
|
96
85
|
width: 150,
|
|
97
86
|
height: 150,
|
|
98
87
|
sizes: '30vw',
|
|
99
|
-
loading: '
|
|
88
|
+
loading: 'eager',
|
|
100
89
|
}}
|
|
101
90
|
{...ProductCard.props}
|
|
102
91
|
bordered={bordered ?? ProductCard.props.bordered}
|
|
@@ -108,6 +97,37 @@ function ProductGrid({
|
|
|
108
97
|
taxesConfiguration={taxesConfiguration}
|
|
109
98
|
sponsoredLabel={sponsoredLabel}
|
|
110
99
|
/>
|
|
100
|
+
</ProductSentinel>
|
|
101
|
+
</UIProductGridItem>
|
|
102
|
+
))}
|
|
103
|
+
<ViewportObserver sectionName="UIProductGrid-out-viewport">
|
|
104
|
+
{products.slice(2).map(({ node: product }, idx) => (
|
|
105
|
+
<UIProductGridItem key={`${product.id}`}>
|
|
106
|
+
<ProductSentinel
|
|
107
|
+
product={product}
|
|
108
|
+
title={title}
|
|
109
|
+
page={page}
|
|
110
|
+
pageSize={pageSize}
|
|
111
|
+
>
|
|
112
|
+
<ProductCard.Component
|
|
113
|
+
aspectRatio={aspectRatio}
|
|
114
|
+
imgProps={{
|
|
115
|
+
width: 150,
|
|
116
|
+
height: 150,
|
|
117
|
+
sizes: '30vw',
|
|
118
|
+
loading: 'lazy',
|
|
119
|
+
}}
|
|
120
|
+
{...ProductCard.props}
|
|
121
|
+
bordered={bordered ?? ProductCard.props.bordered}
|
|
122
|
+
showDiscountBadge={
|
|
123
|
+
showDiscountBadge ?? ProductCard.props.showDiscountBadge
|
|
124
|
+
}
|
|
125
|
+
product={product}
|
|
126
|
+
index={pageSize * page + idx + 1}
|
|
127
|
+
taxesConfiguration={taxesConfiguration}
|
|
128
|
+
sponsoredLabel={sponsoredLabel}
|
|
129
|
+
/>
|
|
130
|
+
</ProductSentinel>
|
|
111
131
|
</UIProductGridItem>
|
|
112
132
|
))}
|
|
113
133
|
</ViewportObserver>
|
|
@@ -116,24 +136,31 @@ function ProductGrid({
|
|
|
116
136
|
<>
|
|
117
137
|
{products.map(({ node: product }, idx) => (
|
|
118
138
|
<UIProductGridItem key={`${product.id}`}>
|
|
119
|
-
<
|
|
120
|
-
aspectRatio={aspectRatio}
|
|
121
|
-
imgProps={{
|
|
122
|
-
width: 150,
|
|
123
|
-
height: 150,
|
|
124
|
-
sizes: '30vw',
|
|
125
|
-
loading: idx === 0 ? 'eager' : 'lazy',
|
|
126
|
-
}}
|
|
127
|
-
{...ProductCard.props}
|
|
128
|
-
bordered={bordered ?? ProductCard.props.bordered}
|
|
129
|
-
showDiscountBadge={
|
|
130
|
-
showDiscountBadge ?? ProductCard.props.showDiscountBadge
|
|
131
|
-
}
|
|
139
|
+
<ProductSentinel
|
|
132
140
|
product={product}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
title={title}
|
|
142
|
+
page={page}
|
|
143
|
+
pageSize={pageSize}
|
|
144
|
+
>
|
|
145
|
+
<ProductCard.Component
|
|
146
|
+
aspectRatio={aspectRatio}
|
|
147
|
+
imgProps={{
|
|
148
|
+
width: 150,
|
|
149
|
+
height: 150,
|
|
150
|
+
sizes: '30vw',
|
|
151
|
+
loading: idx === 0 ? 'eager' : 'lazy',
|
|
152
|
+
}}
|
|
153
|
+
{...ProductCard.props}
|
|
154
|
+
bordered={bordered ?? ProductCard.props.bordered}
|
|
155
|
+
showDiscountBadge={
|
|
156
|
+
showDiscountBadge ?? ProductCard.props.showDiscountBadge
|
|
157
|
+
}
|
|
158
|
+
product={product}
|
|
159
|
+
index={pageSize * page + idx + 1}
|
|
160
|
+
taxesConfiguration={taxesConfiguration}
|
|
161
|
+
sponsoredLabel={sponsoredLabel}
|
|
162
|
+
/>
|
|
163
|
+
</ProductSentinel>
|
|
137
164
|
</UIProductGridItem>
|
|
138
165
|
))}
|
|
139
166
|
</>
|
|
@@ -1,44 +1,35 @@
|
|
|
1
|
-
import { NextSeo } from 'next-seo'
|
|
2
|
-
import type { ComponentType } from 'react'
|
|
3
|
-
import { useEffect } from 'react'
|
|
4
|
-
import RenderSections from 'src/components/cms/RenderSections'
|
|
5
|
-
import { default as GLOBAL_COMPONENTS } from 'src/components/cms/global/Components'
|
|
6
|
-
import CUSTOM_COMPONENTS from 'src/customizations/src/components'
|
|
7
1
|
import storeConfig from 'discovery.config'
|
|
8
|
-
import {
|
|
9
|
-
getServerSideProps,
|
|
10
|
-
type MyAccountProps,
|
|
11
|
-
} from 'src/experimental/myAccountSeverSideProps'
|
|
12
|
-
import { useRouter } from 'next/router'
|
|
13
2
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
3
|
+
import type { GetServerSideProps, NextPage } from 'next'
|
|
4
|
+
|
|
5
|
+
const MyAccountRedirectPage: NextPage = () => {
|
|
6
|
+
return null
|
|
18
7
|
}
|
|
19
8
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
export const getServerSideProps: GetServerSideProps = async ({ query }) => {
|
|
10
|
+
if (storeConfig.experimental.enableFaststoreMyAccount) {
|
|
11
|
+
return {
|
|
12
|
+
redirect: {
|
|
13
|
+
destination: '/account/profile',
|
|
14
|
+
permanent: false,
|
|
15
|
+
},
|
|
27
16
|
}
|
|
28
|
-
}
|
|
17
|
+
}
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
<RenderSections
|
|
32
|
-
globalSections={globalSections.sections}
|
|
33
|
-
components={COMPONENTS}
|
|
34
|
-
>
|
|
35
|
-
<NextSeo noindex nofollow />
|
|
19
|
+
const searchParams = new URLSearchParams()
|
|
36
20
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
21
|
+
for (const key in query) {
|
|
22
|
+
const value = query[key]
|
|
23
|
+
const values = Array.isArray(value) ? value : [value]
|
|
24
|
+
values.forEach((v) => v && searchParams.append(key, v))
|
|
25
|
+
}
|
|
41
26
|
|
|
42
|
-
|
|
27
|
+
return {
|
|
28
|
+
redirect: {
|
|
29
|
+
destination: `${storeConfig.accountUrl}?${searchParams.toString()}`,
|
|
30
|
+
permanent: false,
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
43
34
|
|
|
44
|
-
export default
|
|
35
|
+
export default MyAccountRedirectPage
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback } from 'react'
|
|
1
|
+
import { useCallback, useRef } from 'react'
|
|
2
2
|
import type { CurrencyCode, ViewItemListEvent } from '@faststore/sdk'
|
|
3
3
|
|
|
4
4
|
import { useSession } from 'src/sdk/session'
|
|
@@ -7,12 +7,16 @@ import type { ProductSummary_ProductFragment } from '@generated/graphql'
|
|
|
7
7
|
import type { AnalyticsItem } from '../types'
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
|
-
products
|
|
10
|
+
products?: Array<{ node: ProductSummary_ProductFragment }>
|
|
11
11
|
title: string
|
|
12
12
|
page: number
|
|
13
13
|
pageSize: number
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
type ProductsFallbackProps = {
|
|
17
|
+
products?: Array<{ node: ProductSummary_ProductFragment }>
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
export const useViewItemListEvent = ({
|
|
17
21
|
products,
|
|
18
22
|
title,
|
|
@@ -23,31 +27,40 @@ export const useViewItemListEvent = ({
|
|
|
23
27
|
currency: { code },
|
|
24
28
|
} = useSession()
|
|
25
29
|
|
|
26
|
-
const sendViewItemListEvent = useCallback(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
product.
|
|
42
|
-
product.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
const sendViewItemListEvent = useCallback(
|
|
31
|
+
(productsFallback?: ProductsFallbackProps) => {
|
|
32
|
+
const items = products?.length ? products : productsFallback?.products
|
|
33
|
+
|
|
34
|
+
if (!items || items.length === 0) {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
import('@faststore/sdk').then(({ sendAnalyticsEvent }) => {
|
|
39
|
+
sendAnalyticsEvent<ViewItemListEvent<AnalyticsItem>>({
|
|
40
|
+
name: 'view_item_list',
|
|
41
|
+
params: {
|
|
42
|
+
item_list_name: title,
|
|
43
|
+
item_list_id: title,
|
|
44
|
+
items: items.map(({ node: product }, index) => ({
|
|
45
|
+
item_id: product.isVariantOf.productGroupID,
|
|
46
|
+
item_name: product.isVariantOf.name,
|
|
47
|
+
item_brand: product.brand.name,
|
|
48
|
+
item_variant: product.sku,
|
|
49
|
+
price: product.offers.offers[0].price,
|
|
50
|
+
index: page * pageSize + index + 1,
|
|
51
|
+
discount:
|
|
52
|
+
product.offers.offers[0].listPrice -
|
|
53
|
+
product.offers.offers[0].price,
|
|
54
|
+
currency: code as CurrencyCode,
|
|
55
|
+
item_variant_name: product.name,
|
|
56
|
+
product_reference_id: product.gtin,
|
|
57
|
+
})),
|
|
58
|
+
},
|
|
59
|
+
})
|
|
48
60
|
})
|
|
49
|
-
}
|
|
50
|
-
|
|
61
|
+
},
|
|
62
|
+
[code, products, title, page, pageSize]
|
|
63
|
+
)
|
|
51
64
|
|
|
52
65
|
return { sendViewItemListEvent }
|
|
53
66
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useEffect, type PropsWithChildren } from 'react'
|
|
2
|
+
import { useInView } from 'react-intersection-observer'
|
|
3
|
+
|
|
4
|
+
import type { ProductSummary_ProductFragment } from '@generated/graphql'
|
|
5
|
+
|
|
6
|
+
import { useViewItemListEvent } from '../analytics/hooks/useViewItemListEvent'
|
|
7
|
+
import { queueViewItemList } from './viewItemListQueue'
|
|
8
|
+
|
|
9
|
+
interface ProductSentinelProps {
|
|
10
|
+
/**
|
|
11
|
+
* Title for the `ProductSentinel` component.
|
|
12
|
+
*/
|
|
13
|
+
title: string
|
|
14
|
+
/**
|
|
15
|
+
* Product listed on the grid.
|
|
16
|
+
*/
|
|
17
|
+
product: ProductSummary_ProductFragment
|
|
18
|
+
/**
|
|
19
|
+
* The page's number that the Product is being rendered.
|
|
20
|
+
*/
|
|
21
|
+
page: number
|
|
22
|
+
/**
|
|
23
|
+
* Quantity of products listed by page.
|
|
24
|
+
*/
|
|
25
|
+
pageSize: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Use this component to add a boundary between Products to send the right view_item_list event to GA in ProductGallery
|
|
30
|
+
*/
|
|
31
|
+
export function ProductSentinel({
|
|
32
|
+
product,
|
|
33
|
+
title,
|
|
34
|
+
page,
|
|
35
|
+
pageSize,
|
|
36
|
+
children,
|
|
37
|
+
}: PropsWithChildren<ProductSentinelProps>) {
|
|
38
|
+
const { ref, inView } = useInView()
|
|
39
|
+
|
|
40
|
+
const { sendViewItemListEvent } = useViewItemListEvent({
|
|
41
|
+
title,
|
|
42
|
+
page,
|
|
43
|
+
pageSize,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (inView) {
|
|
48
|
+
queueViewItemList({ product, sendViewItemListEvent })
|
|
49
|
+
}
|
|
50
|
+
}, [inView, product])
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
// minHeight to avoid the layout shift when the sentinel is not in view, '15.225rem' is the min value from the Product Card
|
|
54
|
+
<div ref={ref} style={{ minHeight: '15.225rem' }}>
|
|
55
|
+
{children}
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default ProductSentinel
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ProductSummary_ProductFragment } from '@generated/graphql'
|
|
2
|
+
|
|
3
|
+
const sentItems = new Set<string>()
|
|
4
|
+
let pendingItems: { node: ProductSummary_ProductFragment }[] = []
|
|
5
|
+
let debounceTimeout: NodeJS.Timeout | null = null
|
|
6
|
+
|
|
7
|
+
type QueueViewItemListProps = {
|
|
8
|
+
product: ProductSummary_ProductFragment
|
|
9
|
+
sendViewItemListEvent: (props: {
|
|
10
|
+
products: Array<{ node: ProductSummary_ProductFragment }>
|
|
11
|
+
}) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function queueViewItemList({
|
|
15
|
+
product,
|
|
16
|
+
sendViewItemListEvent,
|
|
17
|
+
}: QueueViewItemListProps) {
|
|
18
|
+
if (sentItems.has(product.id)) return
|
|
19
|
+
|
|
20
|
+
sentItems.add(product.id)
|
|
21
|
+
pendingItems.push({ node: product })
|
|
22
|
+
|
|
23
|
+
if (debounceTimeout) clearTimeout(debounceTimeout)
|
|
24
|
+
|
|
25
|
+
debounceTimeout = setTimeout(() => {
|
|
26
|
+
if (pendingItems.length > 0) {
|
|
27
|
+
sendViewItemListEvent({ products: pendingItems })
|
|
28
|
+
pendingItems = []
|
|
29
|
+
}
|
|
30
|
+
}, 300)
|
|
31
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useSearch } from '@faststore/sdk'
|
|
2
|
-
import { useEffect,
|
|
2
|
+
import { useEffect, type PropsWithChildren } from 'react'
|
|
3
3
|
import { useInView } from 'react-intersection-observer'
|
|
4
4
|
import type { NextRouter } from 'next/router'
|
|
5
5
|
import { useRouter } from 'next/router'
|
|
@@ -7,7 +7,6 @@ import { useRouter } from 'next/router'
|
|
|
7
7
|
import type { ProductSummary_ProductFragment } from '@generated/graphql'
|
|
8
8
|
|
|
9
9
|
import useScreenResize from 'src/sdk/ui/useScreenResize'
|
|
10
|
-
import { useViewItemListEvent } from '../analytics/hooks/useViewItemListEvent'
|
|
11
10
|
|
|
12
11
|
interface SentinelProps {
|
|
13
12
|
page: number
|
|
@@ -39,24 +38,11 @@ const replacePagination = (page: string, router: NextRouter) => {
|
|
|
39
38
|
* Also, this component's name is kind of curious. Wikipedia calls is Page Break(https://en.wikipedia.org/wiki/Page_break)
|
|
40
39
|
* however all codes I've seen online use Sentinel
|
|
41
40
|
*/
|
|
42
|
-
function Sentinel({
|
|
43
|
-
page,
|
|
44
|
-
pageSize,
|
|
45
|
-
products,
|
|
46
|
-
title,
|
|
47
|
-
children,
|
|
48
|
-
}: PropsWithChildren<SentinelProps>) {
|
|
41
|
+
function Sentinel({ page, children }: PropsWithChildren<SentinelProps>) {
|
|
49
42
|
const router = useRouter()
|
|
50
43
|
const { pages } = useSearch()
|
|
51
44
|
const { isMobile } = useScreenResize()
|
|
52
45
|
const { ref, inView } = useInView({ threshold: isMobile ? 0.3 : 0.7 })
|
|
53
|
-
const { sendViewItemListEvent } = useViewItemListEvent({
|
|
54
|
-
products,
|
|
55
|
-
title,
|
|
56
|
-
page,
|
|
57
|
-
pageSize,
|
|
58
|
-
})
|
|
59
|
-
const viewedRef = useRef(false)
|
|
60
46
|
|
|
61
47
|
useEffect(() => {
|
|
62
48
|
// Only replace pagination state when infinite scroll
|
|
@@ -64,19 +50,7 @@ function Sentinel({
|
|
|
64
50
|
if (inView && pages.length > 1) {
|
|
65
51
|
replacePagination(page.toString(), router)
|
|
66
52
|
}
|
|
67
|
-
|
|
68
|
-
if (inView && !viewedRef.current && products.length) {
|
|
69
|
-
sendViewItemListEvent()
|
|
70
|
-
viewedRef.current = true
|
|
71
|
-
}
|
|
72
|
-
}, [
|
|
73
|
-
pages.length,
|
|
74
|
-
inView,
|
|
75
|
-
page,
|
|
76
|
-
router,
|
|
77
|
-
sendViewItemListEvent,
|
|
78
|
-
products.length,
|
|
79
|
-
])
|
|
53
|
+
}, [pages.length, inView, page])
|
|
80
54
|
|
|
81
55
|
return <div ref={ref}>{children}</div>
|
|
82
56
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=2032,exports.ids=[2032],exports.modules={52032:(e,i,t)=>{t.d(i,{m:()=>useViewItemListEvent});var r=t(16689),s=t(84355);let useViewItemListEvent=({products:e,title:i,page:n,pageSize:a})=>{let{currency:{code:m}}=(0,s.kP)(),o=(0,r.useCallback)(()=>{Promise.all([t.e(2880),t.e(1153)]).then(t.bind(t,81153)).then(({sendAnalyticsEvent:t})=>{t({name:"view_item_list",params:{item_list_name:i,item_list_id:i,items:e.map(({node:e},i)=>({item_id:e.isVariantOf.productGroupID,item_name:e.isVariantOf.name,item_brand:e.brand.name,item_variant:e.sku,price:e.offers.offers[0].price,index:n*a+i+1,discount:e.offers.offers[0].listPrice-e.offers.offers[0].price,currency:m,item_variant_name:e.name,product_reference_id:e.gtin}))}})})},[m,e,i,n,a]);return{sendViewItemListEvent:o}}}};
|
|
@@ -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-d36123e232b889d8.js"],"/404":[s,c,a,t,"static/chunks/pages/404-8e61ea158e7b314c.js"],"/500":[s,c,a,t,"static/chunks/pages/500-68f51177e64de6e7.js"],"/_error":["static/chunks/pages/_error-f432276d5ac8f150.js"],"/account":[s,c,a,"static/chunks/pages/account-32bc9db3fea9b0c4.js"],"/account/profile":[s,c,a,"static/css/249b9deaabc0d32d.css","static/chunks/pages/account/profile-1fdb500de8f12b3a.js"],"/checkout":[s,c,a,"static/chunks/pages/checkout-0dfe0dc9cee443ba.js"],"/login":[s,c,a,t,"static/chunks/pages/login-b59ea5561defc0d4.js"],"/s":[s,c,a,e,i,t,"static/chunks/pages/s-ffb46af7067b79b1.js"],"/[slug]/p":[s,"static/chunks/5259-90f7ef92cf24e49a.js",c,a,"static/chunks/7498-49bf89838314b503.js","static/css/a3ca6a9b63f657be.css","static/css/62a5153ac7061286.css","static/chunks/4349-24e224a3b1307f65.js","static/css/b5bf49598c8f8b66.css","static/chunks/pages/[slug]/p-2e02254149cef33d.js"],"/[...slug]":[s,c,a,e,i,"static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js"],sortedPages:["/","/404","/500","/_app","/_error","/account","/account/profile","/checkout","/login","/s","/[slug]/p","/[...slug]"]}}("static/chunks/6167-ecb49640dcb9d566.js","static/css/b0c0e0632c5d7f52.css","static/chunks/6335-2bf379c0870c440e.js","static/css/2980acad3f8e1028.css","static/css/2841bab51b99dd53.css","static/chunks/4625-07284599f239c05b.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3143],{3143:function(e,r,t){t.r(r),t.d(r,{default:function(){return w}});var n=t(4424),i=t(9115),o=t(1347),s=t(3125),a=t(4194),c=t(143),d=t(6220),u=t(6259),l=t(1549);function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,n)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){(0,n.Z)(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}var p=(0,a.memo)(function(e){var{products:r,page:t,pageSize:n,productCard:{showDiscountBadge:a,bordered:p,taxesConfiguration:h,sponsoredLabel:f}={},firstPage:v}=e,{isMobile:g}=(0,u.Z)(),{__experimentalProductCard:b}=(0,d.r3)();return(0,l.jsx)(s.Z,{aspectRatio:1,loading:0===r.length,children:(0,l.jsx)(i.Z,{children:g&&v===t?(0,l.jsxs)(l.Fragment,{children:[r.slice(0,2).map((e,r)=>{var{node:i}=e;return(0,l.jsx)(o.Z,{children:(0,l.jsx)(b.Component,_objectSpread(_objectSpread({aspectRatio:1,imgProps:{width:150,height:150,sizes:"30vw",loading:"eager"}},b.props),{},{bordered:null!=p?p:b.props.bordered,showDiscountBadge:null!=a?a:b.props.showDiscountBadge,product:i,index:n*t+r+1,taxesConfiguration:h,sponsoredLabel:f}))},"".concat(i.id))}),(0,l.jsx)(c.Z,{sectionName:"UIProductGrid-out-viewport",children:r.slice(2).map((e,r)=>{var{node:i}=e;return(0,l.jsx)(o.Z,{children:(0,l.jsx)(b.Component,_objectSpread(_objectSpread({aspectRatio:1,imgProps:{width:150,height:150,sizes:"30vw",loading:"lazy"}},b.props),{},{bordered:null!=p?p:b.props.bordered,showDiscountBadge:null!=a?a:b.props.showDiscountBadge,product:i,index:n*t+r+1,taxesConfiguration:h,sponsoredLabel:f}))},"".concat(i.id))})})]}):(0,l.jsx)(l.Fragment,{children:r.map((e,r)=>{var{node:i}=e;return(0,l.jsx)(o.Z,{children:(0,l.jsx)(b.Component,_objectSpread(_objectSpread({aspectRatio:1,imgProps:{width:150,height:150,sizes:"30vw",loading:0===r?"eager":"lazy"}},b.props),{},{bordered:null!=p?p:b.props.bordered,showDiscountBadge:null!=a?a:b.props.showDiscountBadge,product:i,index:n*t+r+1,taxesConfiguration:h,sponsoredLabel:f}))},"".concat(i.id))})})})})}),h=t(9029),f=t(6410),v=t(4444),g=t(2032),replacePagination=(e,r)=>{var t=new URL(window.location.href);t.searchParams.get("page")!==e&&(t.searchParams.set("page",e),r.replace(t,void 0,{shallow:!0,scroll:!1}))},search_Sentinel=function(e){var{page:r,pageSize:t,products:n,title:i,children:o}=e,s=(0,v.useRouter)(),{pages:c}=(0,h.R)(),{isMobile:d}=(0,u.Z)(),{ref:p,inView:b}=(0,f.YD)({threshold:d?.3:.7}),{sendViewItemListEvent:w}=(0,g.m)({products:n,title:i,page:r,pageSize:t}),y=(0,a.useRef)(!1);return(0,a.useEffect)(()=>{b&&c.length>1&&replacePagination(r.toString(),s),b&&!y.current&&n.length&&(w(),y.current=!0)},[c.length,b,r,s,w,n.length]),(0,l.jsx)("div",{ref:p,children:o})},b=t(2125),w=(0,a.memo)(function(e){var r,t,n,{page:i,title:o,productCard:s,itemsPerPage:a,firstPage:c}=e,{data:d}=(0,b.__)(i),u=null!==(r=null==d?void 0:null===(t=d.search)||void 0===t?void 0:null===(n=t.products)||void 0===n?void 0:n.edges)&&void 0!==r?r:[];return(0,l.jsx)(search_Sentinel,{products:u,page:i,pageSize:a,title:o,children:(0,l.jsx)(p,{products:u,page:i,pageSize:a,productCard:s,firstPage:c})})})},2032:function(e,r,t){t.d(r,{m:function(){return useViewItemListEvent}});var n=t(4194),i=t(4355),useViewItemListEvent=e=>{var{products:r,title:o,page:s,pageSize:a}=e,{currency:{code:c}}=(0,i.kP)();return{sendViewItemListEvent:(0,n.useCallback)(()=>{t.e(7195).then(t.bind(t,1153)).then(e=>{var{sendAnalyticsEvent:t}=e;t({name:"view_item_list",params:{item_list_name:o,item_list_id:o,items:r.map((e,r)=>{var{node:t}=e;return{item_id:t.isVariantOf.productGroupID,item_name:t.isVariantOf.name,item_brand:t.brand.name,item_variant:t.sku,price:t.offers.offers[0].price,index:s*a+r+1,discount:t.offers.offers[0].listPrice-t.offers.offers[0].price,currency:c,item_variant_name:t.name,product_reference_id:t.gtin}})}})})},[c,r,o,s,a])}}},6410:function(e,r,t){t.d(r,{YD:function(){return useInView},df:function(){return d}});var n=t(4194);function _extends(){return(_extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}function _setPrototypeOf(e,r){return(_setPrototypeOf=Object.setPrototypeOf||function(e,r){return e.__proto__=r,e})(e,r)}var i=new Map,o=new WeakMap,s=0,a=void 0;function observe(e,r,t,n){if(void 0===t&&(t={}),void 0===n&&(n=a),void 0===window.IntersectionObserver&&void 0!==n){var c=e.getBoundingClientRect();return r(n,{isIntersecting:n,target:e,intersectionRatio:"number"==typeof t.threshold?t.threshold:0,time:0,boundingClientRect:c,intersectionRect:c,rootBounds:c}),function(){}}var d=function(e){var r=Object.keys(e).sort().filter(function(r){return void 0!==e[r]}).map(function(r){var t;return r+"_"+("root"===r?(t=e.root)?(o.has(t)||(s+=1,o.set(t,s.toString())),o.get(t)):"0":e[r])}).toString(),t=i.get(r);if(!t){var n,a=new Map,c=new IntersectionObserver(function(r){r.forEach(function(r){var t,i=r.isIntersecting&&n.some(function(e){return r.intersectionRatio>=e});e.trackVisibility&&void 0===r.isVisible&&(r.isVisible=i),null==(t=a.get(r.target))||t.forEach(function(e){e(i,r)})})},e);n=c.thresholds||(Array.isArray(e.threshold)?e.threshold:[e.threshold||0]),t={id:r,observer:c,elements:a},i.set(r,t)}return t}(t),u=d.id,l=d.observer,p=d.elements,h=p.get(e)||[];return p.has(e)||p.set(e,h),h.push(r),l.observe(e),function(){h.splice(h.indexOf(r),1),0===h.length&&(p.delete(e),l.unobserve(e)),0===p.size&&(l.disconnect(),i.delete(u))}}var c=["children","as","triggerOnce","threshold","root","rootMargin","onChange","skip","trackVisibility","delay","initialInView","fallbackInView"];function isPlainChildren(e){return"function"!=typeof e.children}var d=function(e){function InView(r){var t;return(t=e.call(this,r)||this).node=null,t._unobserveCb=null,t.handleNode=function(e){!t.node||(t.unobserve(),e||t.props.triggerOnce||t.props.skip||t.setState({inView:!!t.props.initialInView,entry:void 0})),t.node=e||null,t.observeNode()},t.handleChange=function(e,r){e&&t.props.triggerOnce&&t.unobserve(),isPlainChildren(t.props)||t.setState({inView:e,entry:r}),t.props.onChange&&t.props.onChange(e,r)},t.state={inView:!!r.initialInView,entry:void 0},t}InView.prototype=Object.create(e.prototype),InView.prototype.constructor=InView,_setPrototypeOf(InView,e);var r=InView.prototype;return r.componentDidUpdate=function(e){(e.rootMargin!==this.props.rootMargin||e.root!==this.props.root||e.threshold!==this.props.threshold||e.skip!==this.props.skip||e.trackVisibility!==this.props.trackVisibility||e.delay!==this.props.delay)&&(this.unobserve(),this.observeNode())},r.componentWillUnmount=function(){this.unobserve(),this.node=null},r.observeNode=function(){if(this.node&&!this.props.skip){var e=this.props,r=e.threshold,t=e.root,n=e.rootMargin,i=e.trackVisibility,o=e.delay,s=e.fallbackInView;this._unobserveCb=observe(this.node,this.handleChange,{threshold:r,root:t,rootMargin:n,trackVisibility:i,delay:o},s)}},r.unobserve=function(){this._unobserveCb&&(this._unobserveCb(),this._unobserveCb=null)},r.render=function(){if(!isPlainChildren(this.props)){var e=this.state,r=e.inView,t=e.entry;return this.props.children({inView:r,entry:t,ref:this.handleNode})}var i=this.props,o=i.children,s=i.as,a=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(i,c);return n.createElement(s||"div",_extends({ref:this.handleNode},a),o)},InView}(n.Component);function useInView(e){var r=void 0===e?{}:e,t=r.threshold,i=r.delay,o=r.trackVisibility,s=r.rootMargin,a=r.root,c=r.triggerOnce,d=r.skip,u=r.initialInView,l=r.fallbackInView,p=n.useRef(),h=n.useState({inView:!!u}),f=h[0],v=h[1],g=n.useCallback(function(e){void 0!==p.current&&(p.current(),p.current=void 0),!d&&e&&(p.current=observe(e,function(e,r){v({inView:e,entry:r}),r.isIntersecting&&c&&p.current&&(p.current(),p.current=void 0)},{root:a,rootMargin:s,threshold:t,trackVisibility:o,delay:i},l))},[Array.isArray(t)?t.toString():t,a,s,c,d,o,l,i]);(0,n.useEffect)(function(){p.current||!f.entry||c||d||v({inView:!!u})});var b=[g,f.inView,f.entry];return b.ref=b[0],b.inView=b[1],b.entry=b[2],b}d.displayName="InView",d.defaultProps={threshold:0,triggerOnce:!1,initialInView:!1}},9115:function(e,r,t){var n=t(4194);let i=(0,n.forwardRef)(function({testId:e="fs-product-grid",children:r,...t},i){return n.createElement("ul",{ref:i,"data-fs-product-grid":!0,...t},r)});r.Z=i},1347:function(e,r,t){var n=t(4194);let i=(0,n.forwardRef)(function({testId:e="fs-product-grid-item",children:r,...t},i){return n.createElement("li",{ref:i,"data-fs-product-grid-item":!0,...t},r)});r.Z=i}}]);
|