@shopify/shop-minis-react 0.3.2 → 0.4.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/dist/components/MinisContainer.js +11 -10
- package/dist/components/MinisContainer.js.map +1 -1
- package/dist/components/atoms/content-wrapper.js.map +1 -1
- package/dist/components/atoms/video-player.js +28 -26
- package/dist/components/atoms/video-player.js.map +1 -1
- package/dist/components/commerce/product-card.js +106 -79
- package/dist/components/commerce/product-card.js.map +1 -1
- package/dist/components/commerce/product-link.js +124 -137
- package/dist/components/commerce/product-link.js.map +1 -1
- package/dist/components/commerce/search.js +20 -20
- package/dist/components/commerce/search.js.map +1 -1
- package/dist/components/ui/sonner.js +3 -1
- package/dist/components/ui/sonner.js.map +1 -1
- package/dist/hooks/content/useContent.js +12 -18
- package/dist/hooks/content/useContent.js.map +1 -1
- package/dist/hooks/navigation/useNavigateWithTransition.js +10 -11
- package/dist/hooks/navigation/useNavigateWithTransition.js.map +1 -1
- package/dist/hooks/product/useCuratedProducts.js +9 -11
- package/dist/hooks/product/useCuratedProducts.js.map +1 -1
- package/dist/hooks/product/usePopularProducts.js +9 -11
- package/dist/hooks/product/usePopularProducts.js.map +1 -1
- package/dist/hooks/product/useProduct.js +11 -17
- package/dist/hooks/product/useProduct.js.map +1 -1
- package/dist/hooks/product/useProductList.js +10 -21
- package/dist/hooks/product/useProductList.js.map +1 -1
- package/dist/hooks/product/useProductLists.js +11 -13
- package/dist/hooks/product/useProductLists.js.map +1 -1
- package/dist/hooks/product/useProductMedia.js +12 -18
- package/dist/hooks/product/useProductMedia.js.map +1 -1
- package/dist/hooks/product/useProductSearch.js +34 -27
- package/dist/hooks/product/useProductSearch.js.map +1 -1
- package/dist/hooks/product/useProductVariants.js +11 -14
- package/dist/hooks/product/useProductVariants.js.map +1 -1
- package/dist/hooks/product/useProducts.js +12 -11
- package/dist/hooks/product/useProducts.js.map +1 -1
- package/dist/hooks/product/useRecommendedProducts.js +11 -13
- package/dist/hooks/product/useRecommendedProducts.js.map +1 -1
- package/dist/hooks/shop/useRecommendedShops.js +11 -13
- package/dist/hooks/shop/useRecommendedShops.js.map +1 -1
- package/dist/hooks/shop/useShop.js +12 -11
- package/dist/hooks/shop/useShop.js.map +1 -1
- package/dist/hooks/user/useBuyerAttributes.js +8 -10
- package/dist/hooks/user/useBuyerAttributes.js.map +1 -1
- package/dist/hooks/user/useCurrentUser.js +7 -9
- package/dist/hooks/user/useCurrentUser.js.map +1 -1
- package/dist/hooks/user/useFollowedShops.js +11 -14
- package/dist/hooks/user/useFollowedShops.js.map +1 -1
- package/dist/hooks/user/useOrders.js +7 -9
- package/dist/hooks/user/useOrders.js.map +1 -1
- package/dist/hooks/user/useRecentProducts.js +11 -13
- package/dist/hooks/user/useRecentProducts.js.map +1 -1
- package/dist/hooks/user/useRecentShops.js +10 -13
- package/dist/hooks/user/useRecentShops.js.map +1 -1
- package/dist/hooks/user/useSavedProducts.js +10 -13
- package/dist/hooks/user/useSavedProducts.js.map +1 -1
- package/dist/index.js +269 -264
- package/dist/index.js.map +1 -1
- package/dist/internal/components/product-review-stars.js +78 -0
- package/dist/internal/components/product-review-stars.js.map +1 -0
- package/dist/internal/reactQuery/MinisQueryProvider.js +11 -0
- package/dist/internal/reactQuery/MinisQueryProvider.js.map +1 -0
- package/dist/internal/reactQuery/queryClient.js +33 -0
- package/dist/internal/reactQuery/queryClient.js.map +1 -0
- package/dist/internal/reactQuery/useShopActionInfiniteQuery.js +52 -0
- package/dist/internal/reactQuery/useShopActionInfiniteQuery.js.map +1 -0
- package/dist/internal/reactQuery/useShopActionQuery.js +37 -0
- package/dist/internal/reactQuery/useShopActionQuery.js.map +1 -0
- package/dist/mocks.js +178 -107
- package/dist/mocks.js.map +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js +45 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js +89 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js +55 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js +198 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js +99 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js +67 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js +39 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js +299 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js +80 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js +215 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js +300 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js +25 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js +76 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js +21 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js +26 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js +176 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js +7 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +17 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js +19 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js +21 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js +18 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +64 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js +13 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js +9 -0
- package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star-half.js +21 -0
- package/dist/shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star-half.js.map +1 -0
- package/dist/shop-minis-react/node_modules/.pnpm/sonner@2.0.5_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/sonner/dist/index.js +4 -4
- package/dist/shop-minis-react/node_modules/.pnpm/sonner@2.0.5_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/sonner/dist/index.js.map +1 -1
- package/package.json +2 -7
- package/src/components/MinisContainer.tsx +6 -3
- package/src/components/atoms/content-wrapper.tsx +1 -1
- package/src/components/atoms/video-player.tsx +7 -0
- package/src/components/commerce/product-card.test.tsx +135 -0
- package/src/components/commerce/product-card.tsx +39 -5
- package/src/components/commerce/product-link.test.tsx +15 -3
- package/src/components/commerce/product-link.tsx +9 -25
- package/src/components/commerce/search.tsx +2 -2
- package/src/components/index.ts +1 -0
- package/src/components/ui/sonner.tsx +2 -2
- package/src/hooks/content/useContent.ts +6 -17
- package/src/hooks/navigation/useNavigateWithTransition.test.ts +46 -7
- package/src/hooks/navigation/useNavigateWithTransition.ts +4 -1
- package/src/hooks/product/useCuratedProducts.ts +4 -6
- package/src/hooks/product/usePopularProducts.ts +4 -6
- package/src/hooks/product/useProduct.ts +6 -17
- package/src/hooks/product/useProductList.ts +4 -19
- package/src/hooks/product/useProductLists.ts +4 -6
- package/src/hooks/product/useProductMedia.ts +6 -17
- package/src/hooks/product/useProductSearch.ts +19 -15
- package/src/hooks/product/useProductVariants.ts +5 -13
- package/src/hooks/product/useProducts.ts +8 -12
- package/src/hooks/product/useRecommendedProducts.ts +4 -6
- package/src/hooks/shop/useRecommendedShops.ts +4 -6
- package/src/hooks/shop/useShop.ts +8 -12
- package/src/hooks/user/useBuyerAttributes.ts +4 -6
- package/src/hooks/user/useCurrentUser.ts +4 -6
- package/src/hooks/user/useFollowedShops.ts +5 -13
- package/src/hooks/user/useOrders.ts +4 -6
- package/src/hooks/user/useRecentProducts.ts +4 -6
- package/src/hooks/user/useRecentShops.ts +5 -13
- package/src/hooks/user/useSavedProducts.ts +5 -13
- package/src/internal/components/product-review-stars.test.tsx +90 -0
- package/src/internal/components/product-review-stars.tsx +113 -0
- package/src/internal/reactQuery/MinisQueryProvider.test.tsx +38 -0
- package/src/internal/reactQuery/MinisQueryProvider.tsx +16 -0
- package/src/internal/reactQuery/index.ts +8 -0
- package/src/internal/reactQuery/queryClient.test.tsx +91 -0
- package/src/internal/reactQuery/queryClient.ts +43 -0
- package/src/internal/reactQuery/useShopActionInfiniteQuery.test.tsx +357 -0
- package/src/internal/reactQuery/useShopActionInfiniteQuery.ts +129 -0
- package/src/internal/reactQuery/useShopActionQuery.test.tsx +184 -0
- package/src/internal/reactQuery/useShopActionQuery.ts +74 -0
- package/src/mocks.ts +10 -2
- package/src/providers/ImagePickerProvider.test.tsx +3 -9
- package/dist/internal/useShopActionsDataFetching.js +0 -79
- package/dist/internal/useShopActionsDataFetching.js.map +0 -1
- package/dist/internal/useShopActionsPaginatedDataFetching.js +0 -96
- package/dist/internal/useShopActionsPaginatedDataFetching.js.map +0 -1
- package/src/hooks/product/useProductSearch.test.ts +0 -470
- package/src/internal/useShopActionsDataFetching.test.ts +0 -465
- package/src/internal/useShopActionsDataFetching.ts +0 -150
- package/src/internal/useShopActionsPaginatedDataFetching.ts +0 -188
- package/src/stories/Accordion.stories.tsx +0 -124
- package/src/stories/AddToCart.stories.tsx +0 -251
- package/src/stories/Alert.stories.tsx +0 -38
- package/src/stories/AlertDialog.stories.tsx +0 -48
- package/src/stories/Avatar.stories.tsx +0 -29
- package/src/stories/Badge.stories.tsx +0 -46
- package/src/stories/Button.stories.tsx +0 -81
- package/src/stories/Card.stories.tsx +0 -40
- package/src/stories/Checkbox.stories.tsx +0 -44
- package/src/stories/FavoriteButton.stories.tsx +0 -58
- package/src/stories/IconButton.stories.tsx +0 -68
- package/src/stories/ImageContentWrapper.stories.tsx +0 -65
- package/src/stories/Input.stories.tsx +0 -44
- package/src/stories/Label.stories.tsx +0 -19
- package/src/stories/List.stories.tsx +0 -64
- package/src/stories/MerchantCard.stories.tsx +0 -127
- package/src/stories/ProductCard.stories.tsx +0 -92
- package/src/stories/ProductLink.stories.tsx +0 -46
- package/src/stories/ProductVariantPrice.stories.tsx +0 -70
- package/src/stories/Progress.stories.tsx +0 -30
- package/src/stories/PullToRefreshList.stories.tsx +0 -122
- package/src/stories/QuantitySelector.stories.tsx +0 -78
- package/src/stories/RadioGroup.stories.tsx +0 -51
- package/src/stories/Search.stories.tsx +0 -37
- package/src/stories/Select.stories.tsx +0 -85
- package/src/stories/Skeleton.stories.tsx +0 -19
- package/src/stories/TextInput.stories.tsx +0 -26
- package/src/stories/Toaster.stories.tsx +0 -46
- package/src/stories/Touchable.stories.tsx +0 -40
- package/src/stories/VideoPlayer.stories.tsx +0 -129
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
ProductCardFavoriteButton,
|
|
21
21
|
ProductCardInfo,
|
|
22
22
|
ProductCardTitle,
|
|
23
|
+
ProductCardReviewStars,
|
|
23
24
|
ProductCardPrice,
|
|
24
25
|
} from './product-card'
|
|
25
26
|
|
|
@@ -174,6 +175,108 @@ describe('ProductCard', () => {
|
|
|
174
175
|
const favoriteButton = screen.getByRole('button')
|
|
175
176
|
expect(favoriteButton).toBeInTheDocument()
|
|
176
177
|
})
|
|
178
|
+
|
|
179
|
+
it('renders review stars when review data is available', () => {
|
|
180
|
+
const product = mockProduct({
|
|
181
|
+
reviewAnalytics: {
|
|
182
|
+
averageRating: 4.5,
|
|
183
|
+
reviewCount: 123,
|
|
184
|
+
},
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
render(<ProductCard product={product} />)
|
|
188
|
+
|
|
189
|
+
// Should show the review stars and count
|
|
190
|
+
expect(screen.getByText('(123)')).toBeInTheDocument()
|
|
191
|
+
|
|
192
|
+
// Check for star elements - ProductReviewStars uses overlay technique with 10 stars total
|
|
193
|
+
const container = screen.getByText('(123)').parentElement
|
|
194
|
+
const stars = container?.querySelectorAll('svg')
|
|
195
|
+
// 5 empty stars + filled stars overlay (4 full + 1 half for 4.5 rating)
|
|
196
|
+
expect(stars).toHaveLength(10)
|
|
197
|
+
|
|
198
|
+
// Verify review count is displayed
|
|
199
|
+
expect(screen.getByText('(123)')).toBeInTheDocument()
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('does not render review stars when review data is missing', () => {
|
|
203
|
+
const product = mockProduct({
|
|
204
|
+
reviewAnalytics: undefined,
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
render(<ProductCard product={product} />)
|
|
208
|
+
|
|
209
|
+
// Should not show review count
|
|
210
|
+
expect(screen.queryByText(/^\(\d+\)$/)).not.toBeInTheDocument()
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('does not render review stars when averageRating is null', () => {
|
|
214
|
+
const product = mockProduct({
|
|
215
|
+
reviewAnalytics: {
|
|
216
|
+
averageRating: null,
|
|
217
|
+
reviewCount: 100,
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
render(<ProductCard product={product} />)
|
|
222
|
+
|
|
223
|
+
// Should not show review count
|
|
224
|
+
expect(screen.queryByText('(100)')).not.toBeInTheDocument()
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('does not render review stars when reviewCount is 0', () => {
|
|
228
|
+
const product = mockProduct({
|
|
229
|
+
reviewAnalytics: {
|
|
230
|
+
averageRating: 4.5,
|
|
231
|
+
reviewCount: 0,
|
|
232
|
+
},
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
render(<ProductCard product={product} />)
|
|
236
|
+
|
|
237
|
+
// Should not show review count
|
|
238
|
+
expect(screen.queryByText('(0)')).not.toBeInTheDocument()
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
it('formats large review counts correctly', () => {
|
|
242
|
+
const product = mockProduct({
|
|
243
|
+
reviewAnalytics: {
|
|
244
|
+
averageRating: 4.0,
|
|
245
|
+
reviewCount: 1500,
|
|
246
|
+
},
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
render(<ProductCard product={product} />)
|
|
250
|
+
|
|
251
|
+
// Should format as 1K
|
|
252
|
+
expect(screen.getByText('(1K)')).toBeInTheDocument()
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('does not show review stars in non-default variants', () => {
|
|
256
|
+
const product = mockProduct({
|
|
257
|
+
reviewAnalytics: {
|
|
258
|
+
averageRating: 4.5,
|
|
259
|
+
reviewCount: 123,
|
|
260
|
+
},
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
const {rerender} = render(
|
|
264
|
+
<ProductCard product={product} variant="priceOverlay" />
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
// Should not show review stars in priceOverlay variant
|
|
268
|
+
expect(screen.queryByText('(123)')).not.toBeInTheDocument()
|
|
269
|
+
|
|
270
|
+
rerender(<ProductCard product={product} variant="compact" />)
|
|
271
|
+
|
|
272
|
+
// Should not show review stars in compact variant
|
|
273
|
+
expect(screen.queryByText('(123)')).not.toBeInTheDocument()
|
|
274
|
+
|
|
275
|
+
rerender(<ProductCard product={product} variant="default" />)
|
|
276
|
+
|
|
277
|
+
// Should show review stars in default variant
|
|
278
|
+
expect(screen.getByText('(123)')).toBeInTheDocument()
|
|
279
|
+
})
|
|
177
280
|
})
|
|
178
281
|
|
|
179
282
|
describe('Interactions', () => {
|
|
@@ -357,6 +460,38 @@ describe('ProductCard', () => {
|
|
|
357
460
|
expect(screen.getByText('$99.99')).toBeInTheDocument()
|
|
358
461
|
})
|
|
359
462
|
|
|
463
|
+
it('allows ProductCardReviewStars in custom composition', () => {
|
|
464
|
+
const product = mockProduct({
|
|
465
|
+
reviewAnalytics: {
|
|
466
|
+
averageRating: 4.2,
|
|
467
|
+
reviewCount: 50,
|
|
468
|
+
},
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
render(
|
|
472
|
+
<ProductCard product={product}>
|
|
473
|
+
<ProductCardContainer>
|
|
474
|
+
<ProductCardImageContainer>
|
|
475
|
+
<ProductCardImage />
|
|
476
|
+
</ProductCardImageContainer>
|
|
477
|
+
<ProductCardInfo>
|
|
478
|
+
<ProductCardTitle />
|
|
479
|
+
<ProductCardReviewStars />
|
|
480
|
+
<ProductCardPrice />
|
|
481
|
+
</ProductCardInfo>
|
|
482
|
+
</ProductCardContainer>
|
|
483
|
+
</ProductCard>
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
// Review stars should be rendered
|
|
487
|
+
expect(screen.getByText('(50)')).toBeInTheDocument()
|
|
488
|
+
|
|
489
|
+
// Check for star elements - ProductReviewStars uses overlay technique
|
|
490
|
+
const container = screen.getByText('(50)').parentElement
|
|
491
|
+
const stars = container?.querySelectorAll('svg')
|
|
492
|
+
expect(stars).toHaveLength(9) // 5 empty + 3 full + 1 half for 3.5 rating
|
|
493
|
+
})
|
|
494
|
+
|
|
360
495
|
it('respects favoriteButtonDisabled in custom composition', () => {
|
|
361
496
|
const product = mockProduct()
|
|
362
497
|
|
|
@@ -5,6 +5,7 @@ import {type Product, type ProductVariant} from '@shopify/shop-minis-platform'
|
|
|
5
5
|
|
|
6
6
|
import {useShopNavigation} from '../../hooks/navigation/useShopNavigation'
|
|
7
7
|
import {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'
|
|
8
|
+
import {ProductReviewStars} from '../../internal/components/product-review-stars'
|
|
8
9
|
import {formatMoney} from '../../lib/formatMoney'
|
|
9
10
|
import {cn} from '../../lib/utils'
|
|
10
11
|
import {Image} from '../atoms/image'
|
|
@@ -25,10 +26,11 @@ interface ProductCardContextValue {
|
|
|
25
26
|
touchable: boolean
|
|
26
27
|
badgeText?: string
|
|
27
28
|
badgeVariant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'none'
|
|
29
|
+
favoriteButtonDisabled: boolean
|
|
30
|
+
reviewsDisabled: boolean
|
|
28
31
|
|
|
29
32
|
// State
|
|
30
33
|
isFavorited: boolean
|
|
31
|
-
isFavoriteButtonDisabled: boolean
|
|
32
34
|
|
|
33
35
|
// Actions
|
|
34
36
|
onClick: () => void
|
|
@@ -194,9 +196,9 @@ function ProductCardFavoriteButton({
|
|
|
194
196
|
className,
|
|
195
197
|
...props
|
|
196
198
|
}: React.ComponentProps<'div'>) {
|
|
197
|
-
const {isFavorited,
|
|
199
|
+
const {isFavorited, favoriteButtonDisabled, onFavoriteToggle} =
|
|
198
200
|
useProductCardContext()
|
|
199
|
-
if (
|
|
201
|
+
if (favoriteButtonDisabled) return null
|
|
200
202
|
|
|
201
203
|
return (
|
|
202
204
|
<div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>
|
|
@@ -213,7 +215,7 @@ function ProductCardInfo({className, ...props}: React.ComponentProps<'div'>) {
|
|
|
213
215
|
|
|
214
216
|
return (
|
|
215
217
|
<div
|
|
216
|
-
data-
|
|
218
|
+
data-testid="product-card-info"
|
|
217
219
|
className={cn('px-1 pt-2 pb-0 space-y-1', className)}
|
|
218
220
|
{...props}
|
|
219
221
|
/>
|
|
@@ -241,6 +243,31 @@ function ProductCardTitle({
|
|
|
241
243
|
)
|
|
242
244
|
}
|
|
243
245
|
|
|
246
|
+
function ProductCardReviewStars({
|
|
247
|
+
className,
|
|
248
|
+
...props
|
|
249
|
+
}: React.ComponentProps<'div'>) {
|
|
250
|
+
const {product, reviewsDisabled} = useProductCardContext()
|
|
251
|
+
const reviewAnalytics = product.reviewAnalytics
|
|
252
|
+
|
|
253
|
+
if (reviewsDisabled || !reviewAnalytics?.averageRating) {
|
|
254
|
+
return null
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<div
|
|
259
|
+
data-slot="product-card-review-stars"
|
|
260
|
+
className={cn('', className)}
|
|
261
|
+
{...props}
|
|
262
|
+
>
|
|
263
|
+
<ProductReviewStars
|
|
264
|
+
averageRating={reviewAnalytics.averageRating}
|
|
265
|
+
reviewCount={reviewAnalytics.reviewCount}
|
|
266
|
+
/>
|
|
267
|
+
</div>
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
|
|
244
271
|
function ProductCardPrice({className}: {className?: string}) {
|
|
245
272
|
const {product, selectedProductVariant} = useProductCardContext()
|
|
246
273
|
|
|
@@ -297,6 +324,8 @@ export interface ProductCardProps {
|
|
|
297
324
|
children?: React.ReactNode
|
|
298
325
|
/** Whether the favorite button is disabled */
|
|
299
326
|
favoriteButtonDisabled?: boolean
|
|
327
|
+
/** Whether review stars are disabled */
|
|
328
|
+
reviewsDisabled?: boolean
|
|
300
329
|
}
|
|
301
330
|
|
|
302
331
|
function ProductCard({
|
|
@@ -310,6 +339,7 @@ function ProductCard({
|
|
|
310
339
|
onFavoriteToggled,
|
|
311
340
|
children,
|
|
312
341
|
favoriteButtonDisabled = false,
|
|
342
|
+
reviewsDisabled = false,
|
|
313
343
|
}: ProductCardProps) {
|
|
314
344
|
const {navigateToProduct} = useShopNavigation()
|
|
315
345
|
const {saveProduct, unsaveProduct} = useSavedProductsActions()
|
|
@@ -377,10 +407,11 @@ function ProductCard({
|
|
|
377
407
|
touchable,
|
|
378
408
|
badgeText,
|
|
379
409
|
badgeVariant,
|
|
410
|
+
favoriteButtonDisabled,
|
|
411
|
+
reviewsDisabled,
|
|
380
412
|
|
|
381
413
|
// State
|
|
382
414
|
isFavorited: isFavoritedLocal,
|
|
383
|
-
isFavoriteButtonDisabled: favoriteButtonDisabled,
|
|
384
415
|
// Actions
|
|
385
416
|
onClick: handleClick,
|
|
386
417
|
onFavoriteToggle: handleFavoriteClick,
|
|
@@ -396,6 +427,7 @@ function ProductCard({
|
|
|
396
427
|
handleClick,
|
|
397
428
|
handleFavoriteClick,
|
|
398
429
|
favoriteButtonDisabled,
|
|
430
|
+
reviewsDisabled,
|
|
399
431
|
]
|
|
400
432
|
)
|
|
401
433
|
|
|
@@ -412,6 +444,7 @@ function ProductCard({
|
|
|
412
444
|
{variant === 'default' && (
|
|
413
445
|
<ProductCardInfo>
|
|
414
446
|
<ProductCardTitle />
|
|
447
|
+
<ProductCardReviewStars />
|
|
415
448
|
<ProductCardPrice />
|
|
416
449
|
</ProductCardInfo>
|
|
417
450
|
)}
|
|
@@ -430,5 +463,6 @@ export {
|
|
|
430
463
|
ProductCardFavoriteButton,
|
|
431
464
|
ProductCardInfo,
|
|
432
465
|
ProductCardTitle,
|
|
466
|
+
ProductCardReviewStars,
|
|
433
467
|
ProductCardPrice,
|
|
434
468
|
}
|
|
@@ -442,10 +442,22 @@ describe('ProductLink', () => {
|
|
|
442
442
|
|
|
443
443
|
render(<ProductLink product={product} />)
|
|
444
444
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
445
|
+
// ProductReviewStars uses overlay technique with specific fill colors
|
|
446
|
+
// Find the star container first to only count star SVGs
|
|
447
|
+
const starContainer = document.querySelector(
|
|
448
|
+
'[data-slot="product-review-stars"]'
|
|
448
449
|
)
|
|
450
|
+
expect(starContainer).toBeInTheDocument()
|
|
451
|
+
|
|
452
|
+
const stars = starContainer?.querySelectorAll('svg') || []
|
|
453
|
+
// For 5 star rating: 5 empty stars + 5 filled stars = 10 total
|
|
454
|
+
expect(stars).toHaveLength(10)
|
|
455
|
+
|
|
456
|
+
// Check that stars are rendered (5 filled stars using var(--grayscale-d100) style)
|
|
457
|
+
const filledStars = Array.from(stars).filter(star => {
|
|
458
|
+
const style = star.getAttribute('style')
|
|
459
|
+
return style?.includes('var(--grayscale-d100)')
|
|
460
|
+
})
|
|
449
461
|
expect(filledStars).toHaveLength(5)
|
|
450
462
|
})
|
|
451
463
|
})
|
|
@@ -2,11 +2,11 @@ import * as React from 'react'
|
|
|
2
2
|
|
|
3
3
|
import {type Product} from '@shopify/shop-minis-platform'
|
|
4
4
|
import {cva, type VariantProps} from 'class-variance-authority'
|
|
5
|
-
import {Star} from 'lucide-react'
|
|
6
5
|
import {Slot as SlotPrimitive} from 'radix-ui'
|
|
7
6
|
|
|
8
7
|
import {useShopNavigation} from '../../hooks/navigation/useShopNavigation'
|
|
9
8
|
import {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'
|
|
9
|
+
import {ProductReviewStars} from '../../internal/components/product-review-stars'
|
|
10
10
|
import {formatMoney} from '../../lib/formatMoney'
|
|
11
11
|
import {cn} from '../../lib/utils'
|
|
12
12
|
import {Touchable} from '../atoms/touchable'
|
|
@@ -183,10 +183,7 @@ function ProductLinkRating({className, ...props}: React.ComponentProps<'div'>) {
|
|
|
183
183
|
return (
|
|
184
184
|
<div
|
|
185
185
|
data-slot="product-link-rating"
|
|
186
|
-
className={cn(
|
|
187
|
-
'flex items-center gap-1 text-xs text-muted-foreground',
|
|
188
|
-
className
|
|
189
|
-
)}
|
|
186
|
+
className={cn('', className)}
|
|
190
187
|
{...props}
|
|
191
188
|
/>
|
|
192
189
|
)
|
|
@@ -233,6 +230,7 @@ export type ProductLinkProps = {
|
|
|
233
230
|
product: Product
|
|
234
231
|
hideFavoriteAction?: boolean
|
|
235
232
|
onClick?: (product: Product) => void
|
|
233
|
+
reviewsDisabled?: boolean
|
|
236
234
|
} & (
|
|
237
235
|
| {
|
|
238
236
|
customAction?: never
|
|
@@ -251,6 +249,7 @@ function ProductLink({
|
|
|
251
249
|
onClick,
|
|
252
250
|
customAction,
|
|
253
251
|
onCustomActionClick,
|
|
252
|
+
reviewsDisabled = false,
|
|
254
253
|
}: ProductLinkProps) {
|
|
255
254
|
const {navigateToProduct} = useShopNavigation()
|
|
256
255
|
const {saveProduct, unsaveProduct} = useSavedProductsActions()
|
|
@@ -354,27 +353,12 @@ function ProductLink({
|
|
|
354
353
|
<ProductLinkInfo layout="horizontal">
|
|
355
354
|
<ProductLinkTitle>{title}</ProductLinkTitle>
|
|
356
355
|
|
|
357
|
-
{
|
|
356
|
+
{averageRating && !reviewsDisabled ? (
|
|
358
357
|
<ProductLinkRating>
|
|
359
|
-
<
|
|
360
|
-
{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
fill={
|
|
364
|
-
i < Math.floor(averageRating!) ? 'currentColor' : 'none'
|
|
365
|
-
}
|
|
366
|
-
className={cn(
|
|
367
|
-
'h-3 w-3',
|
|
368
|
-
i < Math.floor(averageRating!)
|
|
369
|
-
? 'text-primary'
|
|
370
|
-
: 'text-gray-300'
|
|
371
|
-
)}
|
|
372
|
-
/>
|
|
373
|
-
))}
|
|
374
|
-
<span className="text-xs text-gray-600 ml-1">
|
|
375
|
-
({reviewCount})
|
|
376
|
-
</span>
|
|
377
|
-
</div>
|
|
358
|
+
<ProductReviewStars
|
|
359
|
+
averageRating={averageRating}
|
|
360
|
+
reviewCount={reviewCount}
|
|
361
|
+
/>
|
|
378
362
|
</ProductLinkRating>
|
|
379
363
|
) : null}
|
|
380
364
|
|
|
@@ -246,8 +246,8 @@ function Search({
|
|
|
246
246
|
|
|
247
247
|
return (
|
|
248
248
|
<SearchProvider initialQuery={initialQuery}>
|
|
249
|
-
<div className={cn('flex flex-col ', className)}>
|
|
250
|
-
<div className="
|
|
249
|
+
<div className={cn('flex flex-col relative', className)}>
|
|
250
|
+
<div className="absolute top-0 left-0 right-0 p-4 w-full z-20 bg-background">
|
|
251
251
|
<SearchInput placeholder={placeholder} inputProps={inputProps} />
|
|
252
252
|
</div>
|
|
253
253
|
<div className="h-14" />
|
package/src/components/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ export * from './atoms/list'
|
|
|
26
26
|
export * from './atoms/video-player'
|
|
27
27
|
export * from './atoms/text-input'
|
|
28
28
|
export * from './atoms/content-wrapper'
|
|
29
|
+
export * from './atoms/product-variant-price'
|
|
29
30
|
|
|
30
31
|
export * from './ui/accordion'
|
|
31
32
|
export * from './ui/alert'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {useTheme} from 'next-themes'
|
|
2
|
-
import {Toaster as Sonner, ToasterProps} from 'sonner'
|
|
2
|
+
import {Toaster as Sonner, ToasterProps, toast} from 'sonner'
|
|
3
3
|
|
|
4
4
|
const Toaster = ({...props}: ToasterProps) => {
|
|
5
5
|
const {theme = 'system'} = useTheme()
|
|
@@ -20,4 +20,4 @@ const Toaster = ({...props}: ToasterProps) => {
|
|
|
20
20
|
)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export {Toaster}
|
|
23
|
+
export {Toaster, toast}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {useShopActionQuery} from '../../internal/reactQuery'
|
|
3
2
|
import {useShopActions} from '../../internal/useShopActions'
|
|
4
|
-
import {useShopActionsDataFetching} from '../../internal/useShopActionsDataFetching'
|
|
5
3
|
import {
|
|
6
4
|
Content,
|
|
7
5
|
ContentIdentifierInput,
|
|
@@ -27,24 +25,15 @@ export const useContent = (params: UseContentParams): UseContentReturns => {
|
|
|
27
25
|
const {getContent} = useShopActions()
|
|
28
26
|
const {identifiers, skip = false, ...restParams} = params
|
|
29
27
|
|
|
30
|
-
const {data, ...rest} =
|
|
28
|
+
const {data, ...rest} = useShopActionQuery(
|
|
29
|
+
['content', identifiers, restParams],
|
|
31
30
|
getContent,
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
...restParams,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
skip,
|
|
38
|
-
hook: 'useContent',
|
|
39
|
-
}
|
|
31
|
+
{identifiers, ...restParams},
|
|
32
|
+
{skip}
|
|
40
33
|
)
|
|
41
34
|
|
|
42
|
-
const content = useMemo(() => {
|
|
43
|
-
return data ?? null
|
|
44
|
-
}, [data])
|
|
45
|
-
|
|
46
35
|
return {
|
|
47
36
|
...rest,
|
|
48
|
-
content,
|
|
37
|
+
content: data,
|
|
49
38
|
}
|
|
50
39
|
}
|
|
@@ -86,47 +86,59 @@ describe('useNavigateWithTransition', () => {
|
|
|
86
86
|
})
|
|
87
87
|
|
|
88
88
|
it('uses view transition for path navigation', async () => {
|
|
89
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
89
90
|
const {result} = renderHook(() => useNavigateWithTransition())
|
|
90
91
|
|
|
91
92
|
await act(async () => {
|
|
92
93
|
result.current('/new-route')
|
|
94
|
+
await mockTransition.finished
|
|
93
95
|
})
|
|
94
96
|
|
|
95
97
|
expect(document.startViewTransition).toHaveBeenCalled()
|
|
96
98
|
expect(mockNavigate).toHaveBeenCalledWith('/new-route', {
|
|
97
|
-
preventScrollReset: true,
|
|
98
99
|
replace: false,
|
|
99
100
|
})
|
|
101
|
+
expect(scrollToSpy).toHaveBeenCalledWith(0, 0)
|
|
102
|
+
|
|
103
|
+
scrollToSpy.mockRestore()
|
|
100
104
|
})
|
|
101
105
|
|
|
102
106
|
it('uses replace navigation for same route', async () => {
|
|
107
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
103
108
|
const {result} = renderHook(() => useNavigateWithTransition())
|
|
104
109
|
|
|
105
110
|
await act(async () => {
|
|
106
111
|
result.current('/current')
|
|
112
|
+
await mockTransition.finished
|
|
107
113
|
})
|
|
108
114
|
|
|
109
115
|
expect(document.startViewTransition).toHaveBeenCalled()
|
|
110
116
|
expect(mockNavigate).toHaveBeenCalledWith('/current', {
|
|
111
|
-
preventScrollReset: true,
|
|
112
117
|
replace: true,
|
|
113
118
|
})
|
|
119
|
+
expect(scrollToSpy).toHaveBeenCalledWith(0, 0)
|
|
120
|
+
|
|
121
|
+
scrollToSpy.mockRestore()
|
|
114
122
|
})
|
|
115
123
|
|
|
116
124
|
it('merges custom options with defaults', async () => {
|
|
125
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
117
126
|
const {result} = renderHook(() => useNavigateWithTransition())
|
|
118
127
|
|
|
119
128
|
const customOptions = {state: {from: 'test'}, replace: true}
|
|
120
129
|
|
|
121
130
|
await act(async () => {
|
|
122
131
|
result.current('/new-route', customOptions)
|
|
132
|
+
await mockTransition.finished
|
|
123
133
|
})
|
|
124
134
|
|
|
125
135
|
expect(mockNavigate).toHaveBeenCalledWith('/new-route', {
|
|
126
|
-
preventScrollReset: true,
|
|
127
136
|
replace: true,
|
|
128
137
|
state: {from: 'test'},
|
|
129
138
|
})
|
|
139
|
+
expect(scrollToSpy).toHaveBeenCalledWith(0, 0)
|
|
140
|
+
|
|
141
|
+
scrollToSpy.mockRestore()
|
|
130
142
|
})
|
|
131
143
|
|
|
132
144
|
it('removes navigation type attribute after transition completes', async () => {
|
|
@@ -183,14 +195,20 @@ describe('useNavigateWithTransition', () => {
|
|
|
183
195
|
})
|
|
184
196
|
|
|
185
197
|
it('uses view transition for delta navigation', async () => {
|
|
198
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
186
199
|
const {result} = renderHook(() => useNavigateWithTransition())
|
|
187
200
|
|
|
188
201
|
await act(async () => {
|
|
189
202
|
result.current(-1)
|
|
203
|
+
await mockTransition.finished
|
|
190
204
|
})
|
|
191
205
|
|
|
192
206
|
expect(document.startViewTransition).toHaveBeenCalled()
|
|
193
207
|
expect(mockNavigate).toHaveBeenCalledWith(-1)
|
|
208
|
+
// Delta navigation should NOT reset scroll
|
|
209
|
+
expect(scrollToSpy).not.toHaveBeenCalled()
|
|
210
|
+
|
|
211
|
+
scrollToSpy.mockRestore()
|
|
194
212
|
})
|
|
195
213
|
|
|
196
214
|
it('removes attribute after delta navigation transition', async () => {
|
|
@@ -210,14 +228,39 @@ describe('useNavigateWithTransition', () => {
|
|
|
210
228
|
})
|
|
211
229
|
|
|
212
230
|
it('handles positive delta navigation', async () => {
|
|
231
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
213
232
|
const {result} = renderHook(() => useNavigateWithTransition())
|
|
214
233
|
|
|
215
234
|
await act(async () => {
|
|
216
235
|
result.current(1)
|
|
236
|
+
await mockTransition.finished
|
|
217
237
|
})
|
|
218
238
|
|
|
219
239
|
expect(document.startViewTransition).toHaveBeenCalled()
|
|
220
240
|
expect(mockNavigate).toHaveBeenCalledWith(1)
|
|
241
|
+
// Delta navigation should NOT reset scroll
|
|
242
|
+
expect(scrollToSpy).not.toHaveBeenCalled()
|
|
243
|
+
|
|
244
|
+
scrollToSpy.mockRestore()
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
it('does not reset scroll when preventScrollReset is true', async () => {
|
|
248
|
+
const scrollToSpy = vi.spyOn(window, 'scrollTo')
|
|
249
|
+
const {result} = renderHook(() => useNavigateWithTransition())
|
|
250
|
+
|
|
251
|
+
await act(async () => {
|
|
252
|
+
result.current('/new-route', {preventScrollReset: true})
|
|
253
|
+
await mockTransition.finished
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
expect(document.startViewTransition).toHaveBeenCalled()
|
|
257
|
+
expect(mockNavigate).toHaveBeenCalledWith('/new-route', {
|
|
258
|
+
replace: false,
|
|
259
|
+
preventScrollReset: true,
|
|
260
|
+
})
|
|
261
|
+
expect(scrollToSpy).not.toHaveBeenCalled()
|
|
262
|
+
|
|
263
|
+
scrollToSpy.mockRestore()
|
|
221
264
|
})
|
|
222
265
|
})
|
|
223
266
|
|
|
@@ -243,7 +286,6 @@ describe('useNavigateWithTransition', () => {
|
|
|
243
286
|
})
|
|
244
287
|
|
|
245
288
|
expect(mockNavigate).toHaveBeenCalledWith('', {
|
|
246
|
-
preventScrollReset: true,
|
|
247
289
|
replace: false,
|
|
248
290
|
})
|
|
249
291
|
})
|
|
@@ -256,7 +298,6 @@ describe('useNavigateWithTransition', () => {
|
|
|
256
298
|
})
|
|
257
299
|
|
|
258
300
|
expect(mockNavigate).toHaveBeenCalledWith('/', {
|
|
259
|
-
preventScrollReset: true,
|
|
260
301
|
replace: false,
|
|
261
302
|
})
|
|
262
303
|
})
|
|
@@ -269,7 +310,6 @@ describe('useNavigateWithTransition', () => {
|
|
|
269
310
|
})
|
|
270
311
|
|
|
271
312
|
expect(mockNavigate).toHaveBeenCalledWith('/search?q=test&page=2', {
|
|
272
|
-
preventScrollReset: true,
|
|
273
313
|
replace: false,
|
|
274
314
|
})
|
|
275
315
|
})
|
|
@@ -282,7 +322,6 @@ describe('useNavigateWithTransition', () => {
|
|
|
282
322
|
})
|
|
283
323
|
|
|
284
324
|
expect(mockNavigate).toHaveBeenCalledWith('/page#section', {
|
|
285
|
-
preventScrollReset: true,
|
|
286
325
|
replace: false,
|
|
287
326
|
})
|
|
288
327
|
})
|
|
@@ -43,10 +43,13 @@ export function useNavigateWithTransition(): UseNavigateWithTransitionReturns {
|
|
|
43
43
|
if (document.startViewTransition) {
|
|
44
44
|
const transition = document.startViewTransition(() => {
|
|
45
45
|
navigate(to, {
|
|
46
|
-
preventScrollReset: true,
|
|
47
46
|
replace: isSameRoute,
|
|
48
47
|
...options,
|
|
49
48
|
})
|
|
49
|
+
|
|
50
|
+
if (options?.preventScrollReset !== true) {
|
|
51
|
+
window.scrollTo(0, 0)
|
|
52
|
+
}
|
|
50
53
|
})
|
|
51
54
|
|
|
52
55
|
transition.finished
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import {useShopActionInfiniteQuery} from '../../internal/reactQuery'
|
|
1
2
|
import {useShopActions} from '../../internal/useShopActions'
|
|
2
|
-
import {useShopActionsPaginatedDataFetching} from '../../internal/useShopActionsPaginatedDataFetching'
|
|
3
3
|
import {
|
|
4
4
|
Product,
|
|
5
5
|
PaginatedDataHookOptionsBase,
|
|
@@ -25,13 +25,11 @@ export const useCuratedProducts = (
|
|
|
25
25
|
const {getCuratedProducts} = useShopActions()
|
|
26
26
|
const {skip, ...shopActionParams} = params ?? {}
|
|
27
27
|
|
|
28
|
-
const {data, ...rest} =
|
|
28
|
+
const {data, ...rest} = useShopActionInfiniteQuery(
|
|
29
|
+
['curatedProducts', shopActionParams],
|
|
29
30
|
getCuratedProducts,
|
|
30
31
|
shopActionParams,
|
|
31
|
-
{
|
|
32
|
-
skip,
|
|
33
|
-
hook: 'useCuratedProducts',
|
|
34
|
-
}
|
|
32
|
+
{skip}
|
|
35
33
|
)
|
|
36
34
|
|
|
37
35
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import {useShopActionInfiniteQuery} from '../../internal/reactQuery'
|
|
1
2
|
import {useShopActions} from '../../internal/useShopActions'
|
|
2
|
-
import {useShopActionsPaginatedDataFetching} from '../../internal/useShopActionsPaginatedDataFetching'
|
|
3
3
|
import {
|
|
4
4
|
Product,
|
|
5
5
|
PaginatedDataHookOptionsBase,
|
|
@@ -21,13 +21,11 @@ export const usePopularProducts = (
|
|
|
21
21
|
const {getPopularProducts} = useShopActions()
|
|
22
22
|
const {skip, ...shopActionParams} = params ?? {}
|
|
23
23
|
|
|
24
|
-
const {data, ...rest} =
|
|
24
|
+
const {data, ...rest} = useShopActionInfiniteQuery(
|
|
25
|
+
['popularProducts', shopActionParams],
|
|
25
26
|
getPopularProducts,
|
|
26
27
|
shopActionParams,
|
|
27
|
-
{
|
|
28
|
-
skip,
|
|
29
|
-
hook: 'usePopularProducts',
|
|
30
|
-
}
|
|
28
|
+
{skip}
|
|
31
29
|
)
|
|
32
30
|
|
|
33
31
|
return {
|