@sonic-equipment/ui 201.0.0 → 203.0.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/breadcrumbs/breadcrumb.js +7 -16
- package/dist/breadcrumbs/breadcrumb.module.css.js +1 -1
- package/dist/buttons/add-to-cart-button/add-to-cart-button.d.ts +1 -1
- package/dist/buttons/add-to-cart-button/add-to-cart-button.js +12 -13
- package/dist/buttons/button/button.js +1 -2
- package/dist/buttons/icon-button/icon-button.js +1 -2
- package/dist/buttons/link/link.js +1 -2
- package/dist/collapsables/accordion/accordion-item.js +6 -5
- package/dist/collapsables/accordion/accordion.module.css.js +1 -1
- package/dist/cookies/client-cookie-context.d.ts +3 -0
- package/dist/cookies/client-cookie-context.js +30 -0
- package/dist/cookies/cookie-context.d.ts +2 -0
- package/dist/cookies/cookie-context.js +6 -0
- package/dist/cookies/cookie-provider.d.ts +6 -0
- package/dist/cookies/cookie-provider.js +10 -0
- package/dist/cookies/readonly-cookie-reader.d.ts +2 -0
- package/dist/cookies/readonly-cookie-reader.js +18 -0
- package/dist/cookies/types.d.ts +14 -0
- package/dist/cookies/types.js +7 -0
- package/dist/{shared/hooks → cookies}/use-cookie.d.ts +1 -2
- package/dist/cookies/use-cookie.js +30 -0
- package/dist/country-select/hooks/use-countries.js +1 -1
- package/dist/country-selector/connected-country-selector.js +1 -1
- package/dist/country-selector/use-countries-languages.js +3 -11
- package/dist/exports.d.ts +8 -1
- package/dist/header/buttons/account/connected-account-button.js +1 -8
- package/dist/index.js +10 -3
- package/dist/media/image-grid/images-grid.d.ts +2 -1
- package/dist/media/image-grid/images-grid.js +2 -2
- package/dist/media/image-lightbox/image-lightbox.d.ts +2 -1
- package/dist/media/image-lightbox/image-lightbox.js +2 -2
- package/dist/pages/account/components/create-account-form/create-account-form.js +1 -1
- package/dist/pages/account/create-account-page/create-account-page.js +5 -3
- package/dist/pages/account/layouts/sign-in-page-layout/sign-in-page-layout.d.ts +2 -1
- package/dist/pages/account/layouts/sign-in-page-layout/sign-in-page-layout.js +2 -4
- package/dist/pages/account/sign-in-page/sign-in-page.js +2 -2
- package/dist/pages/checkout/cart-page/cart-page.js +1 -1
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +1 -1
- package/dist/pages/my-sonic/widgets/connected-bill-to-address-widget.js +2 -1
- package/dist/pages/my-sonic/widgets/connected-ship-to-address-widget.js +2 -1
- package/dist/pages/product/product-details-page/components/product-details-images/product-detail-images.js +1 -3
- package/dist/pages/product/product-details-page/components/product-details-images/product-detail-images.module.css.js +1 -1
- package/dist/pages/product/product-details-page/product-details.js +5 -1
- package/dist/pages/product/product-listing-page/no-results/no-results.js +3 -1
- package/dist/shared/api/storefront/hooks/cart/use-fetch-current-cart-with-atp.js +6 -4
- package/dist/shared/api/storefront/hooks/product/use-mark-product-as-viewed.d.ts +5 -3
- package/dist/shared/api/storefront/hooks/product/use-mark-product-as-viewed.js +4 -8
- package/dist/shared/api/storefront/services/website-service.js +9 -0
- package/dist/shared/hooks/use-debounced-callback.d.ts +5 -1
- package/dist/shared/hooks/use-debounced-callback.js +10 -10
- package/dist/shared/providers/react-query-container.d.ts +8 -3
- package/dist/shared/providers/react-query-container.js +4 -4
- package/dist/shared/routing/route-context.d.ts +2 -0
- package/dist/shared/routing/route-context.js +6 -0
- package/dist/shared/routing/route-provider.d.ts +1 -0
- package/dist/shared/routing/route-provider.js +7 -8
- package/dist/shared/routing/types.d.ts +2 -1
- package/dist/shared/routing/use-location.d.ts +3 -3
- package/dist/shared/routing/use-location.js +5 -5
- package/dist/shared/routing/use-navigate.js +4 -7
- package/dist/shared/routing/use-paths.js +4 -5
- package/dist/shared/routing/use-route-link-element.d.ts +1 -1
- package/dist/shared/routing/use-route-link-element.js +5 -6
- package/dist/shared/routing/use-route-link.d.ts +1 -1
- package/dist/shared/routing/use-route-link.js +1 -0
- package/dist/shared/routing/use-router.d.ts +1 -0
- package/dist/shared/routing/use-router.js +13 -0
- package/dist/shared/routing/with-routing.d.ts +1 -0
- package/dist/shared/routing/with-routing.js +2 -1
- package/dist/sidebar/sidebar-provider.js +0 -2
- package/dist/styles.css +31 -1
- package/package.json +1 -1
- package/dist/shared/hooks/use-cookie.js +0 -34
|
@@ -2,7 +2,8 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
import { ImageType } from '../../../../shared/model/image';
|
|
3
3
|
export interface SignInPageLayoutProps {
|
|
4
4
|
children?: ReactNode;
|
|
5
|
+
'data-test-selector': string;
|
|
5
6
|
fullHeight?: boolean;
|
|
6
7
|
image?: ImageType;
|
|
7
8
|
}
|
|
8
|
-
export declare function SignInPageLayout({ children, fullHeight, image, }: SignInPageLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SignInPageLayout({ children, 'data-test-selector': dataTestSelector, fullHeight, image, }: SignInPageLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import clsx from 'clsx';
|
|
4
|
-
import { useIsBreakpoint } from '../../../../shared/hooks/use-is-breakpoint.js';
|
|
5
4
|
import { Image } from '../../../../media/image/image.js';
|
|
6
5
|
import { SIGN_IN_PAGE_BACKGROUND_IMAGE } from './sign-in-page-background-image.js';
|
|
7
6
|
import styles from './sign-in-page-layout.module.css.js';
|
|
8
7
|
|
|
9
|
-
function SignInPageLayout({ children, fullHeight, image = SIGN_IN_PAGE_BACKGROUND_IMAGE, }) {
|
|
10
|
-
|
|
11
|
-
return (jsxs("div", { className: clsx(styles['sign-in-page-layout'], fullHeight && styles['full-height']), children: [jsx("section", { className: styles.main, children: children }), isLg && (jsx("div", { className: styles.side, children: jsx("div", { className: styles.image, children: jsx(Image, { image: image, title: "" }) }) }))] }));
|
|
8
|
+
function SignInPageLayout({ children, 'data-test-selector': dataTestSelector, fullHeight, image = SIGN_IN_PAGE_BACKGROUND_IMAGE, }) {
|
|
9
|
+
return (jsxs("div", { className: clsx(styles['sign-in-page-layout'], fullHeight && styles['full-height']), "data-test-selector": dataTestSelector, children: [jsx("section", { className: styles.main, children: children }), jsx("div", { className: styles.side, children: jsx("div", { className: styles.image, children: jsx(Image, { image: image, title: "" }) }) })] }));
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
export { SignInPageLayout };
|
|
@@ -37,7 +37,7 @@ function SignInPage({ returnUrl } = {}) {
|
|
|
37
37
|
navigate(returnUrl || paths.HOME, { reload: true });
|
|
38
38
|
};
|
|
39
39
|
const allowGuestSignIn = returnUrl === paths.CHECKOUT_SHIPPING;
|
|
40
|
-
const createAccountPath = `${paths.ACCOUNT_CREATE}${returnUrl ? `?returnUrl=${returnUrl}` : ''}`;
|
|
40
|
+
const createAccountPath = `${paths.ACCOUNT_CREATE}${returnUrl ? `?returnUrl=${encodeURIComponent(returnUrl)}` : ''}`;
|
|
41
41
|
const onSubmit = ({ data }) => {
|
|
42
42
|
resetSignIn();
|
|
43
43
|
resetCreateGuest();
|
|
@@ -57,7 +57,7 @@ function SignInPage({ returnUrl } = {}) {
|
|
|
57
57
|
const onRecoverPasswordDialogOpen = () => {
|
|
58
58
|
setRecoverPasswordDialogOpen(true);
|
|
59
59
|
};
|
|
60
|
-
return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(SignInForm, { allowGuestSignIn: allowGuestSignIn, createAccountPath: createAccountPath, errorType: errorType, initialEmail: session?.isGuest ? '' : session?.email, initialRememberMe: session?.rememberMe, isDisabled: !session || isSuccess, isLoading: isLoading, isPendingGuestSignIn: isPendingCreateGuest, isPendingUserSignIn: isPendingSignIn, onRecoverPasswordDialogOpen: onRecoverPasswordDialogOpen, onSubmit: onSubmit }) }), jsx(RecoverPasswordDialog, { isOpen: isRecoverPasswordDialogOpen, onOpenChange: isOpen => setRecoverPasswordDialogOpen(isOpen) })] }));
|
|
60
|
+
return (jsxs(Fragment, { children: [jsx(SignInPageLayout, { fullHeight: true, "data-test-selector": "signInPage", children: jsx(SignInForm, { allowGuestSignIn: allowGuestSignIn, createAccountPath: createAccountPath, errorType: errorType, initialEmail: session?.isGuest ? '' : session?.email, initialRememberMe: session?.rememberMe, isDisabled: !session || isSuccess, isLoading: isLoading, isPendingGuestSignIn: isPendingCreateGuest, isPendingUserSignIn: isPendingSignIn, onRecoverPasswordDialogOpen: onRecoverPasswordDialogOpen, onSubmit: onSubmit }) }), jsx(RecoverPasswordDialog, { isOpen: isRecoverPasswordDialogOpen, onOpenChange: isOpen => setRecoverPasswordDialogOpen(isOpen) })] }));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export { SignInPage };
|
|
@@ -82,7 +82,7 @@ function CartContent({ cartLines }) {
|
|
|
82
82
|
if (!currencyCode)
|
|
83
83
|
throw new Error(`Currency code not found for symbol ${currentCart.currencySymbol}`);
|
|
84
84
|
return (jsx(CheckoutPageLayout, { actions: {
|
|
85
|
-
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", href:
|
|
85
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", href: paths.CHECKOUT_SHIPPING, children: jsx(FormattedMessage, { id: "Start checkout" }) })),
|
|
86
86
|
secondary: isAuthenticated ? (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", onClick: () => {
|
|
87
87
|
saveCartForLater.mutate({ cart: currentCart });
|
|
88
88
|
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })) : (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", href: paths.SIGN_IN, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })),
|
|
@@ -51,7 +51,7 @@ function OrderConfirmationPageContent({ cart, }) {
|
|
|
51
51
|
label: t('Order confirmation'),
|
|
52
52
|
},
|
|
53
53
|
], "data-test-selector": "orderConfirmationPage", title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
|
|
54
|
-
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href:
|
|
54
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href: paths.HOME, children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
|
|
55
55
|
secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(Button, { color: "secondary", onClick: () => {
|
|
56
56
|
saveCartForLater.mutate({ cart });
|
|
57
57
|
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })), jsx(PrintButton, {})] })),
|
|
@@ -9,7 +9,8 @@ import { AddressDataCard } from './components/address-data-card.js';
|
|
|
9
9
|
|
|
10
10
|
function ConnectedBillToAddressWidget({ billToId = 'current', } = {}) {
|
|
11
11
|
const paths = usePaths();
|
|
12
|
-
const {
|
|
12
|
+
const { pathname, search } = useLocation();
|
|
13
|
+
const href = `${pathname}${search}`;
|
|
13
14
|
const editAddressUrl = `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/${billToId}?returnUrl=${encodeURIComponent(href)}`;
|
|
14
15
|
const { data: billToAddress, error, isLoading, } = useFetchBillToAddress({ billToId });
|
|
15
16
|
return (jsx(AddressDataCard, { actions: [
|
|
@@ -9,7 +9,8 @@ import { AddressDataCard } from './components/address-data-card.js';
|
|
|
9
9
|
|
|
10
10
|
function ConnectedShipToAddressWidget({ billToId = 'current', shipToId = 'current', } = {}) {
|
|
11
11
|
const paths = usePaths();
|
|
12
|
-
const {
|
|
12
|
+
const { pathname, search } = useLocation();
|
|
13
|
+
const href = `${pathname}${search}`;
|
|
13
14
|
const editAddressUrl = `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/${billToId}${paths.ACCOUNT_EDIT_SHIP_TO_ADDRESS}/${shipToId}?returnUrl=${encodeURIComponent(href)}`;
|
|
14
15
|
const createAddressUrl = `${paths.ACCOUNT_EDIT_BILL_TO_ADDRESS}/${billToId}${paths.ACCOUNT_EDIT_SHIP_TO_ADDRESS}/new?returnUrl=${encodeURIComponent(href)}`;
|
|
15
16
|
const { data: shipToAddress, error, isLoading, } = useFetchShipToAddress({
|
|
@@ -6,7 +6,6 @@ import { ImageLightbox } from '../../../../../media/image-lightbox/image-lightbo
|
|
|
6
6
|
import { ZoomImage } from '../../../../../media/zoom-image/zoom-image.js';
|
|
7
7
|
import { Modal } from '../../../../../modals/modal/modal.js';
|
|
8
8
|
import { useDisclosure } from '../../../../../shared/hooks/use-disclosure.js';
|
|
9
|
-
import { useIsBreakpoint } from '../../../../../shared/hooks/use-is-breakpoint.js';
|
|
10
9
|
import styles from './product-detail-images.module.css.js';
|
|
11
10
|
|
|
12
11
|
const MAX_IMAGES = 5;
|
|
@@ -16,7 +15,6 @@ function ProductDetailImages({ images }) {
|
|
|
16
15
|
const [scrollPercentage, setScrollPercentage] = useState(0);
|
|
17
16
|
const { isOpen: isOpenModal, open: openModal, toggle: toggleModal, } = useDisclosure();
|
|
18
17
|
const { close: closeZoom, isOpen: isOpenZoom, open: openZoom, } = useDisclosure();
|
|
19
|
-
const isXl = useIsBreakpoint('xl');
|
|
20
18
|
if (images.length > MAX_IMAGES) {
|
|
21
19
|
images = images.slice(0, MAX_IMAGES);
|
|
22
20
|
}
|
|
@@ -29,7 +27,7 @@ function ProductDetailImages({ images }) {
|
|
|
29
27
|
setScrollPercentage(scrollPercentage);
|
|
30
28
|
openZoom();
|
|
31
29
|
}
|
|
32
|
-
return (jsxs(Fragment, { children: [
|
|
30
|
+
return (jsxs(Fragment, { children: [jsx(ImagesGrid, { className: styles['images-grid'], images: images, onSelectImage: (image, _index) => handleOpenImage(image) }), isOpenModal && (jsx(Modal, { hasCloseButton: true, isDismissable: true, isFullScreen: true, isKeyboardDismissDisabled: false, isOpen: isOpenModal, onOpenChange: toggleModal, shouldCloseOnInteractOutside: false, children: jsx("div", { className: styles['image-lightbox-modal'], children: jsx(ImageLightbox, { images: images, initialSelectedIndex: selectedImageIndex, onZoom: onZoom, variant: "lg" }) }) })), jsx(ImageLightbox, { className: styles['image-lightbox'], images: images, onZoom: onZoom }), isOpenZoom && (jsx(ZoomImage, { currentImage: images[selectedZoomImageIndex], isZoomed: isOpenZoom, onClose: closeZoom, scrollFromTopPercentage: scrollPercentage }))] }));
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
export { ProductDetailImages };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var styles = {"image-lightbox-modal":"product-detail-images-module-ERzjA"};
|
|
1
|
+
var styles = {"image-lightbox-modal":"product-detail-images-module-ERzjA","images-grid":"product-detail-images-module-cdIHn","image-lightbox":"product-detail-images-module-0udrk"};
|
|
2
2
|
|
|
3
3
|
export { styles as default };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { useEffect } from 'react';
|
|
3
4
|
import { ConnectedProductCard } from '../../../cards/product-card/connected-product-card.js';
|
|
4
5
|
import { CardCarousel } from '../../../carousel/card-carousel/card-carousel.js';
|
|
5
6
|
import { ProductUSPCarousel } from '../../../carousel/usp-carousel/product-usp-carousel.js';
|
|
@@ -15,7 +16,10 @@ import { ProductDetailsRecentlyViewedSection } from './components/product-detail
|
|
|
15
16
|
|
|
16
17
|
function ProductDetails({ data, priceComponent, }) {
|
|
17
18
|
const { breadCrumb, included, page, product, usps } = data;
|
|
18
|
-
|
|
19
|
+
const { mutate } = useMarkProductAsRecentlyViewed();
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
mutate({ productId: product.id });
|
|
22
|
+
}, [mutate, product]);
|
|
19
23
|
useDataLayer({
|
|
20
24
|
event: {
|
|
21
25
|
event: 'view_item',
|
|
@@ -3,12 +3,14 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
import { Button } from '../../../../buttons/button/button.js';
|
|
4
4
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
5
5
|
import { useIsBreakpoint } from '../../../../shared/hooks/use-is-breakpoint.js';
|
|
6
|
+
import { usePaths } from '../../../../shared/routing/use-paths.js';
|
|
6
7
|
import { Heading } from '../../../../typography/heading/heading.js';
|
|
7
8
|
import styles from './no-results.module.css.js';
|
|
8
9
|
|
|
9
10
|
function NoResults({ content, title }) {
|
|
11
|
+
const paths = usePaths();
|
|
10
12
|
const isLg = useIsBreakpoint('lg');
|
|
11
|
-
return (jsxs("div", { className: styles['no-results'], children: [jsx(Heading, { bold: false, className: styles.title, size: isLg ? 's' : 'xs', tag: "h2", children: title }), jsx("p", { className: styles.body, children: content }), jsx("div", { className: styles.buttons, children: jsx(Button, { withArrow: true, "data-test-selector": "buttonContinueShopping", href:
|
|
13
|
+
return (jsxs("div", { className: styles['no-results'], children: [jsx(Heading, { bold: false, className: styles.title, size: isLg ? 's' : 'xs', tag: "h2", children: title }), jsx("p", { className: styles.body, children: content }), jsx("div", { className: styles.buttons, children: jsx(Button, { withArrow: true, "data-test-selector": "buttonContinueShopping", href: paths.HOME, size: "md", children: jsx(FormattedMessage, { id: "Continue shopping" }) }) })] }));
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export { NoResults };
|
|
@@ -12,10 +12,12 @@ function useFetchCurrentCartWithAtp({ forceRecalculation = true, select = cartMo
|
|
|
12
12
|
select(atp
|
|
13
13
|
? {
|
|
14
14
|
...cartResult.data,
|
|
15
|
-
cartLines: cartResult.data.cartLines?.map(line =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
cartLines: cartResult.data.cartLines?.map(line => {
|
|
16
|
+
const matchingAtp = atp.find(a => a.productCode === line.erpNumber);
|
|
17
|
+
if (!matchingAtp)
|
|
18
|
+
return line;
|
|
19
|
+
return { ...line, atp: matchingAtp };
|
|
20
|
+
}),
|
|
19
21
|
}
|
|
20
22
|
: cartResult.data),
|
|
21
23
|
error: cartResult.error || error,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
productId
|
|
3
|
-
}
|
|
1
|
+
interface MarkProductAsRecentlyViewedParams {
|
|
2
|
+
productId: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function useMarkProductAsRecentlyViewed(): import("@tanstack/react-query").UseMutationResult<void, Error, MarkProductAsRecentlyViewedParams, unknown>;
|
|
5
|
+
export {};
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import { useQueryClient,
|
|
1
|
+
import { useQueryClient, useMutation } from '@tanstack/react-query';
|
|
2
2
|
import { markProductAsRecentlyViewed } from '../../services/product-service.js';
|
|
3
3
|
|
|
4
|
-
function useMarkProductAsRecentlyViewed(
|
|
4
|
+
function useMarkProductAsRecentlyViewed() {
|
|
5
5
|
const queryClient = useQueryClient();
|
|
6
|
-
return
|
|
7
|
-
|
|
8
|
-
gcTime: 0,
|
|
9
|
-
queryFn: () => {
|
|
6
|
+
return useMutation({
|
|
7
|
+
mutationFn: async ({ productId }) => {
|
|
10
8
|
markProductAsRecentlyViewed({ productId: productId });
|
|
11
9
|
queryClient.invalidateQueries({
|
|
12
10
|
queryKey: ['products', 'recently-viewed'],
|
|
13
11
|
});
|
|
14
12
|
},
|
|
15
|
-
queryKey: ['mark-product-as-recently-viewed', productId],
|
|
16
|
-
staleTime: 0,
|
|
17
13
|
});
|
|
18
14
|
}
|
|
19
15
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { config } from '../../../../config.js';
|
|
2
2
|
import { request } from '../../../fetch/request.js';
|
|
3
|
+
import { TIME } from '../../../utils/time.js';
|
|
3
4
|
|
|
4
5
|
async function fetchCountriesLanguages() {
|
|
5
6
|
const { body } = await request({
|
|
7
|
+
next: {
|
|
8
|
+
revalidate: 1 * TIME.DAY,
|
|
9
|
+
tags: ['countries-languages'],
|
|
10
|
+
},
|
|
6
11
|
url: `${config.SHOP_API_URL}/api/v1/websites/current?expand=languages%2Ccountries`,
|
|
7
12
|
});
|
|
8
13
|
return {
|
|
@@ -12,6 +17,10 @@ async function fetchCountriesLanguages() {
|
|
|
12
17
|
}
|
|
13
18
|
async function fetchCountriesWithLanguages() {
|
|
14
19
|
const { body } = await request({
|
|
20
|
+
next: {
|
|
21
|
+
revalidate: 1 * TIME.DAY,
|
|
22
|
+
tags: ['countries-languages'],
|
|
23
|
+
},
|
|
15
24
|
url: `${config.SHOP_API_URL}/api/v1/custom/countrylanguage`,
|
|
16
25
|
});
|
|
17
26
|
return body;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface DebouncedCallback<T extends (...args: any[]) => any> {
|
|
2
|
+
(...args: Parameters<T>): Promise<ReturnType<T>>;
|
|
3
|
+
cancel: VoidFunction;
|
|
4
|
+
}
|
|
5
|
+
export declare function useDebouncedCallback<T extends (...args: any[]) => any>(func: T, delay: number): DebouncedCallback<T>;
|
|
@@ -4,16 +4,16 @@ import { useRef, useCallback } from 'react';
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
5
|
function useDebouncedCallback(func, delay) {
|
|
6
6
|
const timeoutId = useRef();
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
const debounced = (...args) => new Promise(resolve => {
|
|
8
|
+
if (typeof window === 'undefined')
|
|
9
|
+
return resolve(func(...args));
|
|
10
|
+
clearTimeout(timeoutId.current);
|
|
11
|
+
timeoutId.current = setTimeout(() => {
|
|
12
|
+
resolve(func(...args));
|
|
13
|
+
}, delay);
|
|
14
|
+
});
|
|
15
|
+
debounced.cancel = () => clearTimeout(timeoutId.current);
|
|
16
|
+
return useCallback(debounced, [delay, func]);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export { useDebouncedCallback };
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
3
|
+
export declare const globalQueryClient: QueryClient;
|
|
4
|
+
export declare function ReactQueryContainer({ children, enableDevTools, queryClient, }: {
|
|
5
|
+
children: ReactNode | ((args: {
|
|
6
|
+
queryClient: QueryClient;
|
|
7
|
+
}) => ReactNode | ReactElement);
|
|
4
8
|
enableDevTools?: boolean;
|
|
9
|
+
queryClient?: QueryClient;
|
|
5
10
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
|
|
5
5
|
import { environment } from '../utils/environment.js';
|
|
6
6
|
import { TIME } from '../utils/time.js';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const globalQueryClient = new QueryClient({
|
|
9
9
|
defaultOptions: {
|
|
10
10
|
queries: {
|
|
11
11
|
/* Set gcTime and staleTime to 0 to disable react query cache */
|
|
@@ -15,8 +15,8 @@ const queryClient = new QueryClient({
|
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
});
|
|
18
|
-
function ReactQueryContainer({ children, enableDevTools = environment !== 'production', }) {
|
|
19
|
-
return (jsxs(QueryClientProvider, { client: queryClient, children: [enableDevTools && jsx(ReactQueryDevtools, { initialIsOpen: false }), children] }));
|
|
18
|
+
function ReactQueryContainer({ children, enableDevTools = environment !== 'production', queryClient = globalQueryClient, }) {
|
|
19
|
+
return (jsxs(QueryClientProvider, { client: queryClient, children: [enableDevTools && jsx(ReactQueryDevtools, { initialIsOpen: false }), children instanceof Function ? children({ queryClient }) : children] }));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export { ReactQueryContainer };
|
|
22
|
+
export { ReactQueryContainer, globalQueryClient };
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { RouteContext } from './route-context.js';
|
|
5
5
|
|
|
6
|
-
function RouteProvider({ children, Link
|
|
7
|
-
|
|
6
|
+
function RouteProvider({ children, Link, navigate, paths, url, }) {
|
|
7
|
+
const value = useMemo(() => ({
|
|
8
8
|
Link,
|
|
9
9
|
navigate,
|
|
10
10
|
paths,
|
|
11
11
|
url,
|
|
12
|
-
});
|
|
13
|
-
return jsx(
|
|
12
|
+
}), [Link, navigate, paths, url]);
|
|
13
|
+
return jsx(RouteContext.Provider, { value: value, children: children });
|
|
14
14
|
}
|
|
15
|
-
const FallbackRouteLink = withRouting('a');
|
|
16
15
|
|
|
17
16
|
export { RouteProvider };
|
|
@@ -18,12 +18,13 @@ export interface Paths {
|
|
|
18
18
|
REVIEW_AND_SUBMIT: string;
|
|
19
19
|
SIGN_IN: string;
|
|
20
20
|
}
|
|
21
|
-
export interface
|
|
21
|
+
export interface RouteContextValue {
|
|
22
22
|
Link?: ElementType<RouteLinkElementProps>;
|
|
23
23
|
navigate: NavigateFunction;
|
|
24
24
|
paths: Paths;
|
|
25
25
|
url: {
|
|
26
26
|
basePathname?: string;
|
|
27
|
+
href: string;
|
|
27
28
|
pathname: string;
|
|
28
29
|
search: string;
|
|
29
30
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import qs from 'query-string';
|
|
2
2
|
export declare function useLocation(): {
|
|
3
3
|
basePathname: string | undefined;
|
|
4
|
-
fullPathname: string
|
|
4
|
+
fullPathname: string;
|
|
5
5
|
href: string;
|
|
6
|
-
pathname: string
|
|
6
|
+
pathname: string;
|
|
7
7
|
query: qs.ParsedQuery<string>;
|
|
8
|
-
search: string
|
|
8
|
+
search: string;
|
|
9
9
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import qs from 'query-string';
|
|
2
|
-
import {
|
|
3
|
+
import { useRouter } from './use-router.js';
|
|
3
4
|
|
|
4
5
|
function useLocation() {
|
|
5
|
-
const
|
|
6
|
-
const { url: { basePathname, pathname, search }, } = routeState || { url: {} };
|
|
6
|
+
const { url: { basePathname, href, pathname, search }, } = useRouter();
|
|
7
7
|
const query = qs.parse(search || '');
|
|
8
8
|
return {
|
|
9
9
|
basePathname,
|
|
10
10
|
fullPathname: pathname,
|
|
11
|
-
href
|
|
12
|
-
pathname: pathname
|
|
11
|
+
href,
|
|
12
|
+
pathname: pathname.replace(new RegExp(`^${basePathname}`), ''),
|
|
13
13
|
query,
|
|
14
14
|
search,
|
|
15
15
|
};
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useRef, useCallback } from 'react';
|
|
3
|
-
import { useGlobalState } from '../providers/global-state-provider.js';
|
|
4
3
|
import { useOnNavigate } from './use-on-navigate.js';
|
|
4
|
+
import { useRouter } from './use-router.js';
|
|
5
5
|
|
|
6
6
|
function useNavigate() {
|
|
7
7
|
const isNavigatingRef = useRef(false);
|
|
8
|
-
const
|
|
8
|
+
const routeState = useRouter();
|
|
9
9
|
const trigger = useOnNavigate(() => {
|
|
10
10
|
isNavigatingRef.current = false;
|
|
11
11
|
});
|
|
12
|
-
if (!state) {
|
|
13
|
-
throw new Error('RouteProvider not found');
|
|
14
|
-
}
|
|
15
12
|
const navigate = useCallback((href, options) => {
|
|
16
13
|
trigger(href, options);
|
|
17
14
|
isNavigatingRef.current = true;
|
|
18
|
-
return
|
|
19
|
-
}, [
|
|
15
|
+
return routeState.navigate(href, options);
|
|
16
|
+
}, [routeState, trigger]);
|
|
20
17
|
return { isNavigating: isNavigatingRef.current, navigate };
|
|
21
18
|
}
|
|
22
19
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRouter } from './use-router.js';
|
|
2
3
|
|
|
3
4
|
function usePaths() {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
throw new Error('usePaths must be used within a RouteProvider context');
|
|
7
|
-
return routeState.paths;
|
|
5
|
+
const { paths } = useRouter();
|
|
6
|
+
return paths;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
export { usePaths };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function useRouteLinkElement(): React.ElementType<import("./types").RouteLinkElementProps
|
|
1
|
+
export declare function useRouteLinkElement(): React.ElementType<import("./types").RouteLinkElementProps>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRouter } from './use-router.js';
|
|
3
|
+
import { FallbackRouteLink } from './with-routing.js';
|
|
2
4
|
|
|
3
5
|
function useRouteLinkElement() {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
throw new Error('RouteProvider not found');
|
|
7
|
-
}
|
|
8
|
-
return state.Link;
|
|
6
|
+
const { Link } = useRouter();
|
|
7
|
+
return Link || FallbackRouteLink;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
export { useRouteLinkElement };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NavigateOptions } from './types';
|
|
2
2
|
export declare function useRouteLink(): {
|
|
3
|
-
RouteLinkElement: React.ElementType<import("./types").RouteLinkElementProps
|
|
3
|
+
RouteLinkElement: React.ElementType<import("./types").RouteLinkElementProps>;
|
|
4
4
|
getRouteLinkProps: (href: string, route?: NavigateOptions) => {
|
|
5
5
|
href: string;
|
|
6
6
|
onNavigate: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useRouter(): import("./types").RouteContextValue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { RouteContext } from './route-context.js';
|
|
4
|
+
|
|
5
|
+
function useRouter() {
|
|
6
|
+
const context = useContext(RouteContext);
|
|
7
|
+
if (!context) {
|
|
8
|
+
throw new Error('useRouter must be used within a RouteProvider');
|
|
9
|
+
}
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { useRouter };
|
|
@@ -5,3 +5,4 @@ export interface WithRoutingProps {
|
|
|
5
5
|
route?: NavigateOptions;
|
|
6
6
|
}
|
|
7
7
|
export declare function withRouting(component: ElementType<RouteLinkElementProps>): React.FunctionComponent<RouteLinkElementProps>;
|
|
8
|
+
export declare const FallbackRouteLink: React.FunctionComponent<RouteLinkElementProps>;
|
|
@@ -41,8 +41,6 @@ function SidebarProvider({ children }) {
|
|
|
41
41
|
const { close, isDocked, isOpen, transition } = state;
|
|
42
42
|
return (jsxs("div", { className: clsx(styles['sidebar-container'], {
|
|
43
43
|
[styles['transition']]: transition,
|
|
44
|
-
[styles['docked']]: isDocked,
|
|
45
|
-
[styles['open']]: isOpen,
|
|
46
44
|
}), children: [jsx(SidebarDetectBreakpoint, {}), children, jsx(BackgroundOverlay, { isOpen: isDocked && isOpen, onClick: close })] }));
|
|
47
45
|
}
|
|
48
46
|
|
package/dist/styles.css
CHANGED
|
@@ -479,7 +479,7 @@ html {
|
|
|
479
479
|
grid-template-rows: 1fr;
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
-
.accordion-module-9WvAH .accordion-module-lf9d-:has(.accordion-module--Rwpb[disabled]) {
|
|
482
|
+
.accordion-module-9WvAH .accordion-module-lf9d-:has(.accordion-module--Rwpb[disabled]):not(.accordion-module-RnNRT) {
|
|
483
483
|
border-color: var(--color-brand-light-gray);
|
|
484
484
|
}
|
|
485
485
|
|
|
@@ -2218,6 +2218,21 @@ html {
|
|
|
2218
2218
|
content: '/';
|
|
2219
2219
|
margin-inline: 10px;
|
|
2220
2220
|
}
|
|
2221
|
+
.breadcrumb-module-CQGse .breadcrumb-module-hxhDY.breadcrumb-module-ToeDB {
|
|
2222
|
+
display: flex;
|
|
2223
|
+
}
|
|
2224
|
+
.breadcrumb-module-CQGse .breadcrumb-module-hxhDY.breadcrumb-module-np5GK {
|
|
2225
|
+
display: none;
|
|
2226
|
+
}
|
|
2227
|
+
@media (width >= 768px) {
|
|
2228
|
+
.breadcrumb-module-CQGse .breadcrumb-module-hxhDY.breadcrumb-module-ToeDB {
|
|
2229
|
+
display: none;
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
.breadcrumb-module-CQGse .breadcrumb-module-hxhDY.breadcrumb-module-np5GK {
|
|
2233
|
+
display: flex;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2221
2236
|
@media (width < 768px) {
|
|
2222
2237
|
.breadcrumb-module-CQGse .breadcrumb-module-hxhDY::after {
|
|
2223
2238
|
display: none;
|
|
@@ -3369,6 +3384,7 @@ html {
|
|
|
3369
3384
|
|
|
3370
3385
|
.product-card-module-pLaiB .product-card-module-XzunM {
|
|
3371
3386
|
z-index: var(--z-top);
|
|
3387
|
+
margin: 0;
|
|
3372
3388
|
grid-area: sku;
|
|
3373
3389
|
justify-self: start;
|
|
3374
3390
|
-webkit-user-select: all;
|
|
@@ -8555,6 +8571,20 @@ button.swiper-pagination-bullet {
|
|
|
8555
8571
|
padding: 64px 48px;
|
|
8556
8572
|
}
|
|
8557
8573
|
|
|
8574
|
+
.product-detail-images-module-cdIHn {
|
|
8575
|
+
display: none;
|
|
8576
|
+
}
|
|
8577
|
+
|
|
8578
|
+
@media (width >= 1024px) {
|
|
8579
|
+
.product-detail-images-module-0udrk {
|
|
8580
|
+
display: none;
|
|
8581
|
+
}
|
|
8582
|
+
|
|
8583
|
+
.product-detail-images-module-cdIHn {
|
|
8584
|
+
display: grid;
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
|
|
8558
8588
|
.product-details-panel-module-MXfPm {
|
|
8559
8589
|
display: flex;
|
|
8560
8590
|
flex-direction: column;
|