@sonic-equipment/ui 168.0.0 → 170.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/algolia/algolia-active-categories.js +2 -2
- package/dist/breadcrumbs/breadcrumb.js +4 -4
- package/dist/buttons/button/button.d.ts +5 -2
- package/dist/buttons/button/button.js +22 -11
- package/dist/buttons/icon-button/icon-button.d.ts +6 -3
- package/dist/buttons/icon-button/icon-button.js +12 -5
- package/dist/buttons/link/link.d.ts +2 -0
- package/dist/buttons/link/link.js +13 -9
- package/dist/cards/category-card/category-card.d.ts +3 -1
- package/dist/cards/category-card/category-card.js +4 -4
- package/dist/cards/orderline-card/orderline-card.js +2 -2
- package/dist/cards/product-card/connected-product-card.d.ts +2 -0
- package/dist/cards/product-card/product-card.d.ts +3 -1
- package/dist/cards/product-card/product-card.js +3 -3
- package/dist/collapsables/show-all/show-all.js +2 -2
- package/dist/country-selector/connected-country-selector.d.ts +6 -6
- package/dist/exports.d.ts +2 -3
- package/dist/filters/active-filters/active-filters.js +2 -2
- package/dist/footer/connected-footer.d.ts +3 -1
- package/dist/footer/connected-footer.js +2 -2
- package/dist/footer/footer.js +6 -6
- package/dist/global-search/search-result-panel/sections/no-search.js +2 -2
- package/dist/global-search/search-result-panel/sections/with-results.js +2 -2
- package/dist/header/buttons/account/connected-account-button.js +2 -2
- package/dist/header/buttons/cart/connected-cart-button.js +2 -2
- package/dist/header/buttons/favorites/connected-favorites-button.js +2 -2
- package/dist/header/buttons/search/search-button.js +2 -2
- package/dist/header/connected-header.d.ts +2 -1
- package/dist/header/connected-header.js +3 -4
- package/dist/header/header.d.ts +2 -1
- package/dist/header/header.js +2 -2
- package/dist/header/link-list/navigation-link-list.js +3 -3
- package/dist/header/sonic-logo/sonic-logo.js +2 -3
- package/dist/index.js +2 -3
- package/dist/lists/menu-list/menu-list-header.js +2 -2
- package/dist/lists/menu-list/menu-list-item.js +2 -2
- package/dist/modals/signin/sign-in-dialog.js +2 -2
- package/dist/navigation/cart-icon/cart-icon.js +1 -1
- package/dist/notifications/announcements/announcement.js +2 -2
- package/dist/notifications/announcements/connected-announcement-list.d.ts +3 -1
- package/dist/notifications/announcements/connected-announcement-list.js +2 -2
- package/dist/pages/account/components/sign-in-form/sign-in-form.js +1 -2
- package/dist/pages/account/create-account-page/create-account-page.js +2 -2
- package/dist/pages/checkout/cart-page/cart-page.js +4 -6
- package/dist/pages/checkout/layouts/checkout-page-layout/checkout-page-layout.js +1 -1
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +3 -3
- package/dist/pages/checkout/shipping-page/components/currency-change-dialog.js +2 -2
- package/dist/pages/checkout/shipping-page/components/readonly-address.js +3 -3
- package/dist/pages/product/components/product-overview.d.ts +2 -0
- package/dist/pages/product/components/product-overview.js +1 -1
- package/dist/pages/product/product-listing-page/no-results/no-results.js +2 -2
- package/dist/pages/product/product-listing-page/product-listing-page-category-carousel/product-listing-page-category-carousel.js +1 -1
- package/dist/pages/product/product-listing-page/product-listing-product-overview/product-listing-product-overview.js +1 -1
- package/dist/promos/promo-banner/promo-banner.js +2 -2
- package/dist/promos/promo-card/promo-card.js +2 -2
- package/dist/shared/hooks/use-watch-css-property.js +1 -1
- package/dist/shared/routing/route-provider.d.ts +4 -3
- package/dist/shared/routing/route-provider.js +4 -2
- package/dist/shared/routing/route-utils.d.ts +4 -0
- package/dist/shared/routing/route-utils.js +8 -0
- package/dist/shared/routing/types.d.ts +7 -0
- package/dist/shared/routing/use-route-link-element.d.ts +1 -0
- package/dist/shared/routing/use-route-link-element.js +11 -0
- package/dist/shared/routing/with-routing.d.ts +3 -6
- package/dist/shared/routing/with-routing.js +6 -6
- package/dist/shared/utils/css.js +53 -0
- package/dist/shared/utils/price.d.ts +1 -1
- package/dist/styles.css +190 -188
- package/package.json +1 -1
- package/dist/shared/routing/route-button.d.ts +0 -1
- package/dist/shared/routing/route-button.js +0 -7
- package/dist/shared/routing/route-icon-button.d.ts +0 -1
- package/dist/shared/routing/route-icon-button.js +0 -7
- package/dist/shared/routing/route-link.d.ts +0 -1
- package/dist/shared/routing/route-link.js +0 -7
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { IconButton } from '../../../buttons/icon-button/icon-button.js';
|
|
3
4
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
4
5
|
import { CartIcon } from '../../../navigation/cart-icon/cart-icon.js';
|
|
5
6
|
import { useFetchCurrentCartCount } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-count.js';
|
|
6
|
-
import { RouteIconButton } from '../../../shared/routing/route-icon-button.js';
|
|
7
7
|
|
|
8
8
|
function ConnectedCartButton({ className, 'data-test-selector': dataTestSelector, href, onClick, }) {
|
|
9
9
|
const count = useFetchCurrentCartCount();
|
|
10
10
|
const t = useFormattedMessage();
|
|
11
|
-
return (jsx(
|
|
11
|
+
return (jsx(IconButton, { className: className, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(CartIcon, { "aria-label": t('Shopping cart'), count: count }) }));
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export { ConnectedCartButton };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { IconButton } from '../../../buttons/icon-button/icon-button.js';
|
|
3
4
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
4
5
|
import { FavoriteIcon } from '../../../navigation/favorite-icon/favorite-icon.js';
|
|
5
|
-
import { RouteIconButton } from '../../../shared/routing/route-icon-button.js';
|
|
6
6
|
|
|
7
7
|
function ConnectedFavoritesButton({ className, 'data-test-selector': dataTestSelector, href, onClick, }) {
|
|
8
8
|
const t = useFormattedMessage();
|
|
9
9
|
// TODO: add a count of total favorites
|
|
10
|
-
return (jsx(
|
|
10
|
+
return (jsx(IconButton, { className: className, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(FavoriteIcon, { "aria-label": t('Favorites') }) }));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export { ConnectedFavoritesButton };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { IconButton } from '../../../buttons/icon-button/icon-button.js';
|
|
3
4
|
import { StrokeSearchIcon } from '../../../icons/stroke/stroke-search-icon.js';
|
|
4
5
|
import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
5
|
-
import { RouteIconButton } from '../../../shared/routing/route-icon-button.js';
|
|
6
6
|
|
|
7
7
|
function SearchButton({ 'aria-controls': ariaControls, 'data-test-selector': dataTestSelector, isActive, onActiveChange, }) {
|
|
8
8
|
const t = useFormattedMessage();
|
|
9
|
-
return (jsx(
|
|
9
|
+
return (jsx(IconButton, { "aria-controls": ariaControls, "aria-expanded": typeof isActive === 'boolean' ? isActive : undefined, "aria-label": t('Search'), "data-test-selector": dataTestSelector, onClick: () => onActiveChange(!isActive), children: jsx(StrokeSearchIcon, { role: "presentation" }) }));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export { SearchButton };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NavigationLinkSource } from '../shared/api/bff/services/bff-service';
|
|
2
|
-
export declare function ConnectedHeader({ source }: {
|
|
2
|
+
export declare function ConnectedHeader({ className, source, }: {
|
|
3
|
+
className?: string;
|
|
3
4
|
source: NavigationLinkSource;
|
|
4
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useCultureCode } from '../intl/use-culture-code.js';
|
|
3
|
-
import { ConnectedAnnouncementList } from '../notifications/announcements/connected-announcement-list.js';
|
|
4
3
|
import { useFetchNavigationLinks } from '../shared/api/bff/hooks/use-fetch-navigation-links.js';
|
|
5
4
|
import { Header } from './header.js';
|
|
6
5
|
|
|
7
|
-
function ConnectedHeader({ source }) {
|
|
6
|
+
function ConnectedHeader({ className, source, }) {
|
|
8
7
|
const cultureCode = useCultureCode();
|
|
9
8
|
const { data } = useFetchNavigationLinks({ cultureCode, source });
|
|
10
|
-
return (
|
|
9
|
+
return (jsx(Header, { className: className, links: data?.header ?? [], sticky: true }));
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export { ConnectedHeader };
|
package/dist/header/header.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NavigationLink } from '../shared/api/bff/model/bff.model';
|
|
2
2
|
export interface HeaderProps {
|
|
3
|
+
className?: string;
|
|
3
4
|
links: NavigationLink[];
|
|
4
5
|
sticky?: boolean;
|
|
5
6
|
}
|
|
6
|
-
export declare function Header({ links, sticky }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function Header({ className, links, sticky }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/header/header.js
CHANGED
|
@@ -22,7 +22,7 @@ import { NavigationLinkList } from './link-list/navigation-link-list.js';
|
|
|
22
22
|
import { SonicLogo } from './sonic-logo/sonic-logo.js';
|
|
23
23
|
import styles from './header.module.css.js';
|
|
24
24
|
|
|
25
|
-
function Header({ links, sticky }) {
|
|
25
|
+
function Header({ className, links, sticky }) {
|
|
26
26
|
const [activeSubmenu, setActiveSubmenu] = useState();
|
|
27
27
|
const t = useFormattedMessage();
|
|
28
28
|
const isXl = useIsBreakpoint('xl');
|
|
@@ -65,7 +65,7 @@ function Header({ links, sticky }) {
|
|
|
65
65
|
if (activeSubmenu)
|
|
66
66
|
setDesktopNavigationOpen(true);
|
|
67
67
|
}, [activeSubmenu, setDesktopNavigationOpen]);
|
|
68
|
-
return (jsxs(Fragment, { children: [jsx("header", { ref: headerRef, className: clsx(styles['header'], sticky && styles['sticky']), children: jsx(HeaderLayout, { hamburgerButton: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", isActive: mobileNavigationOpen, onActiveChange: toggleMobileNavigation }), hasDrawersOpen: hasDrawersOpen, logo: jsx(SonicLogo, { href: PATHS.HOME, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeSubmenu, links: links, onSubmenuToggle: link => toggleActiveSubmenu(link) }), navigationActions: jsxs(Fragment, { children: [jsx(ConnectedAccountButton, { href: PATHS.ACCOUNT }), jsx(ConnectedFavoritesButton, { href: PATHS.FAVORITES }), jsx(ConnectedCartButton, { href: PATHS.CART })] }), search: jsx(SearchButton, { "aria-controls": "global-search", isActive: searchOpen, onActiveChange: toggleSearch }) }) }), jsx(SearchDrawer, { groupId: searchGroupId, instanceId: searchInstanceId }), !isXl && (jsx(MobileNavigationDrawer, { groupId: mobileNavigationDrawer.groupId, instanceId: mobileNavigationDrawer.instanceId, links: links })), isXl && (jsx(DesktopNavigationDrawer, { groupId: desktopNavigationDrawer.groupId, instanceId: desktopNavigationDrawer.instanceId, onClosed: () => setActiveSubmenu(undefined), submenu: activeSubmenu }))] }));
|
|
68
|
+
return (jsxs(Fragment, { children: [jsx("header", { ref: headerRef, className: clsx(styles['header'], sticky && styles['sticky'], className), children: jsx(HeaderLayout, { hamburgerButton: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", isActive: mobileNavigationOpen, onActiveChange: toggleMobileNavigation }), hasDrawersOpen: hasDrawersOpen, logo: jsx(SonicLogo, { href: PATHS.HOME, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeSubmenu, links: links, onSubmenuToggle: link => toggleActiveSubmenu(link) }), navigationActions: jsxs(Fragment, { children: [jsx(ConnectedAccountButton, { href: PATHS.ACCOUNT }), jsx(ConnectedFavoritesButton, { href: PATHS.FAVORITES }), jsx(ConnectedCartButton, { href: PATHS.CART })] }), search: jsx(SearchButton, { "aria-controls": "global-search", isActive: searchOpen, onActiveChange: toggleSearch }) }) }), jsx(SearchDrawer, { groupId: searchGroupId, instanceId: searchInstanceId }), !isXl && (jsx(MobileNavigationDrawer, { groupId: mobileNavigationDrawer.groupId, instanceId: mobileNavigationDrawer.instanceId, links: links })), isXl && (jsx(DesktopNavigationDrawer, { groupId: desktopNavigationDrawer.groupId, instanceId: desktopNavigationDrawer.instanceId, onClosed: () => setActiveSubmenu(undefined), submenu: activeSubmenu }))] }));
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export { Header };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Link } from '../../buttons/link/link.js';
|
|
2
3
|
import { GlyphsChevronsBoldDownIcon } from '../../icons/glyph/glyphs-chevrons-bold-down-icon.js';
|
|
3
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
4
4
|
import styles from './navigation-link-list.module.css.js';
|
|
5
5
|
|
|
6
6
|
function NavigationLinkList({ activeLink, links, onSubmenuToggle, }) {
|
|
7
7
|
return (jsx("ul", { className: styles['navigation-link-list'], children: links.map(link => {
|
|
8
8
|
if (link.links && link.links.length > 0) {
|
|
9
|
-
return (jsx("li", { className: activeLink === link ? styles['active'] : undefined, children: jsxs(
|
|
9
|
+
return (jsx("li", { className: activeLink === link ? styles['active'] : undefined, children: jsxs(Link, { "aria-controls": `panels-${link.key}`, "aria-expanded": activeLink === link, className: styles.link, onClick: () => onSubmenuToggle(link), target: link.openInNewTab ? '_blank' : undefined, children: [link.title, jsx(GlyphsChevronsBoldDownIcon, { className: styles.chevron })] }) }, link.key));
|
|
10
10
|
}
|
|
11
|
-
return (jsx("li", { children: jsx(
|
|
11
|
+
return (jsx("li", { children: jsx(Link, { className: styles.link, href: link.url, children: link.title }) }, link.key));
|
|
12
12
|
}) }));
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
+
import { Link } from '../../buttons/link/link.js';
|
|
3
4
|
import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
4
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
5
5
|
import styles from './sonic-logo.module.css.js';
|
|
6
6
|
|
|
7
7
|
function SonicLogo({ className, href, title }) {
|
|
8
8
|
const t = useFormattedMessage();
|
|
9
|
-
|
|
10
|
-
return (jsx(Tag, { className: clsx(styles.wrapper, className), href: href, title: title, children: jsx("svg", { "aria-label": t('Sonic Equipment'), className: styles['sonic-logo'], viewBox: "0 0 100 24", xmlns: "http://www.w3.org/2000/svg", children: jsxs("g", { fill: "none", fillRule: "evenodd", children: [jsx("path", { className: styles.letters, d: "M11.87 8.65c1.815 0 3.286 1.482 3.286 3.311 0 6.595-5.325 11.962-11.87 11.962C1.471 23.923 0 22.44 0 20.612c0-1.766 1.372-3.21 3.1-3.307l.186-.005c2.848 0 5.179-2.277 5.293-5.12l.005-.219c0-1.829 1.471-3.311 3.286-3.311zm0-8.65c1.815 0 3.286 1.483 3.286 3.311 0 1.766-1.371 3.21-3.1 3.307l-.186.005c-2.849 0-5.178 2.277-5.293 5.118l-.004.22c0 1.829-1.472 3.311-3.287 3.311C1.472 15.272 0 13.79 0 11.961 0 5.366 5.325 0 11.87 0zm6.155 12.016c0 6.596 5.325 11.963 11.87 11.963 6.545 0 11.87-5.367 11.87-11.963 0-6.595-5.325-11.96-11.87-11.96-6.545 0-11.87 5.365-11.87 11.96zm6.572 0c0-2.943 2.376-5.338 5.298-5.338 2.92 0 5.297 2.395 5.297 5.338 0 2.945-2.376 5.34-5.297 5.34-2.922 0-5.298-2.395-5.298-5.34zM82.251 3.56c-4.628 4.663-4.628 12.251 0 16.915 4.628 4.663 12.158 4.663 16.786 0a3.33 3.33 0 0 0 .001-4.683 3.268 3.268 0 0 0-4.501-.138l-.146.138a5.278 5.278 0 0 1-7.494 0c-2.064-2.081-2.064-5.468.001-7.549a5.275 5.275 0 0 1 7.313-.174l.18.173a3.268 3.268 0 0 0 4.647 0 3.33 3.33 0 0 0 0-4.684c-4.63-4.663-12.16-4.662-16.787.002zm-12.868-.13v17.148c0 1.828 1.47 3.311 3.285 3.311 1.816 0 3.287-1.483 3.287-3.311V3.429c0-1.829-1.471-3.312-3.287-3.312-1.815 0-3.285 1.483-3.285 3.312zM48.063.075c-1.814 0-3.285 1.483-3.285 3.311V20.69c0 1.828 1.471 3.311 3.286 3.311s3.286-1.483 3.286-3.311V6.698h2.95c2.92 0 5.297 2.394 5.297 5.338v8.653c0 1.828 1.471 3.311 3.286 3.311s3.286-1.483 3.286-3.311v-8.653C66.17 5.44 60.844.075 54.3.075h-6.235z" }), jsx("path", { className: styles.dot, d: "M35.27 12.017c0 2.991-2.406 5.416-5.375 5.416-2.97 0-5.376-2.425-5.376-5.416 0-2.992 2.407-5.417 5.376-5.417 2.969 0 5.375 2.425 5.375 5.417" })] }) }) }));
|
|
9
|
+
return (jsx(Link, { className: clsx(styles.wrapper, className), href: href, title: title, children: jsx("svg", { "aria-label": t('Sonic Equipment'), className: styles['sonic-logo'], viewBox: "0 0 100 24", xmlns: "http://www.w3.org/2000/svg", children: jsxs("g", { fill: "none", fillRule: "evenodd", children: [jsx("path", { className: styles.letters, d: "M11.87 8.65c1.815 0 3.286 1.482 3.286 3.311 0 6.595-5.325 11.962-11.87 11.962C1.471 23.923 0 22.44 0 20.612c0-1.766 1.372-3.21 3.1-3.307l.186-.005c2.848 0 5.179-2.277 5.293-5.12l.005-.219c0-1.829 1.471-3.311 3.286-3.311zm0-8.65c1.815 0 3.286 1.483 3.286 3.311 0 1.766-1.371 3.21-3.1 3.307l-.186.005c-2.849 0-5.178 2.277-5.293 5.118l-.004.22c0 1.829-1.472 3.311-3.287 3.311C1.472 15.272 0 13.79 0 11.961 0 5.366 5.325 0 11.87 0zm6.155 12.016c0 6.596 5.325 11.963 11.87 11.963 6.545 0 11.87-5.367 11.87-11.963 0-6.595-5.325-11.96-11.87-11.96-6.545 0-11.87 5.365-11.87 11.96zm6.572 0c0-2.943 2.376-5.338 5.298-5.338 2.92 0 5.297 2.395 5.297 5.338 0 2.945-2.376 5.34-5.297 5.34-2.922 0-5.298-2.395-5.298-5.34zM82.251 3.56c-4.628 4.663-4.628 12.251 0 16.915 4.628 4.663 12.158 4.663 16.786 0a3.33 3.33 0 0 0 .001-4.683 3.268 3.268 0 0 0-4.501-.138l-.146.138a5.278 5.278 0 0 1-7.494 0c-2.064-2.081-2.064-5.468.001-7.549a5.275 5.275 0 0 1 7.313-.174l.18.173a3.268 3.268 0 0 0 4.647 0 3.33 3.33 0 0 0 0-4.684c-4.63-4.663-12.16-4.662-16.787.002zm-12.868-.13v17.148c0 1.828 1.47 3.311 3.285 3.311 1.816 0 3.287-1.483 3.287-3.311V3.429c0-1.829-1.471-3.312-3.287-3.312-1.815 0-3.285 1.483-3.285 3.312zM48.063.075c-1.814 0-3.285 1.483-3.285 3.311V20.69c0 1.828 1.471 3.311 3.286 3.311s3.286-1.483 3.286-3.311V6.698h2.95c2.92 0 5.297 2.394 5.297 5.338v8.653c0 1.828 1.471 3.311 3.286 3.311s3.286-1.483 3.286-3.311v-8.653C66.17 5.44 60.844.075 54.3.075h-6.235z" }), jsx("path", { className: styles.dot, d: "M35.27 12.017c0 2.991-2.406 5.416-5.375 5.416-2.97 0-5.376-2.425-5.376-5.416 0-2.992 2.407-5.417 5.376-5.417 2.969 0 5.375 2.425 5.375 5.417" })] }) }) }));
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export { SonicLogo };
|
package/dist/index.js
CHANGED
|
@@ -349,13 +349,12 @@ export { CartProvider, useCartEvents } from './shared/providers/cart-provider.js
|
|
|
349
349
|
export { FavoriteProvider, useFavorite, useFavoriteProduct } from './shared/providers/favorite-provider.js';
|
|
350
350
|
export { GlobalStateProvider, GlobalStateProviderContext, useGlobalState } from './shared/providers/global-state-provider.js';
|
|
351
351
|
export { ReactQueryContainer } from './shared/providers/react-query-container.js';
|
|
352
|
-
export { RouteButton } from './shared/routing/route-button.js';
|
|
353
|
-
export { RouteIconButton } from './shared/routing/route-icon-button.js';
|
|
354
|
-
export { RouteLink } from './shared/routing/route-link.js';
|
|
355
352
|
export { RouteProvider } from './shared/routing/route-provider.js';
|
|
353
|
+
export { buildHref } from './shared/routing/route-utils.js';
|
|
356
354
|
export { useBasePath } from './shared/routing/use-base-path.js';
|
|
357
355
|
export { useNavigate } from './shared/routing/use-navigate.js';
|
|
358
356
|
export { useOnNavigate } from './shared/routing/use-on-navigate.js';
|
|
357
|
+
export { useRouteLinkElement } from './shared/routing/use-route-link-element.js';
|
|
359
358
|
export { withRouting } from './shared/routing/with-routing.js';
|
|
360
359
|
export { ensureArray } from './shared/utils/array.js';
|
|
361
360
|
export { breakpoints, getCurrentBreakpoints } from './shared/utils/breakpoints.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Link } from '../../buttons/link/link.js';
|
|
2
3
|
import { GlyphsArrowBlackCapsRightIcon } from '../../icons/glyph/glyphs-arrow-blackcaps-right-icon.js';
|
|
3
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
4
4
|
import styles from './menu-list.module.css.js';
|
|
5
5
|
|
|
6
6
|
function MenuListHeader({ children, href }) {
|
|
7
|
-
return (jsxs("h2", { className: styles['menu-list-header'], children: [href && (jsxs(
|
|
7
|
+
return (jsxs("h2", { className: styles['menu-list-header'], children: [href && (jsxs(Link, { href: href, children: [children, jsx(GlyphsArrowBlackCapsRightIcon, { className: styles['icon'], role: "presentation" })] })), !href && children] }));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export { MenuListHeader };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import clsx from 'clsx';
|
|
4
|
+
import { Link } from '../../buttons/link/link.js';
|
|
4
5
|
import { GlyphsChevronsSlimRightIcon } from '../../icons/glyph/glyphs-chevrons-slim-right-icon.js';
|
|
5
6
|
import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
6
7
|
import { Image } from '../../media/image/image.js';
|
|
7
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
8
8
|
import styles from './menu-list.module.css.js';
|
|
9
9
|
|
|
10
10
|
function MenuListItem({ 'aria-controls': ariaControls, badge, children, hasChildren, href, image, isSelected, onClick, openInNewTab, }) {
|
|
11
11
|
const t = useFormattedMessage();
|
|
12
|
-
return (jsxs("li", { "aria-owns": ariaControls, className: clsx(styles['menu-list-item'], isSelected && styles['selected'], hasChildren && styles['has-children']), children: [image && (jsx("span", { className: styles['image'], role: "presentation", children: jsx(Image, { fit: "contain", image: image, title: "" }) })), badge && jsx("span", { className: styles['badge'], children: badge }), jsx(
|
|
12
|
+
return (jsxs("li", { "aria-owns": ariaControls, className: clsx(styles['menu-list-item'], isSelected && styles['selected'], hasChildren && styles['has-children']), children: [image && (jsx("span", { className: styles['image'], role: "presentation", children: jsx(Image, { fit: "contain", image: image, title: "" }) })), badge && jsx("span", { className: styles['badge'], children: badge }), jsx(Link, { "aria-controls": ariaControls, "aria-expanded": ariaControls && isSelected, "aria-haspopup": hasChildren ? 'true' : undefined, className: styles['label'], href: href, onClick: onClick, role: hasChildren ? 'menuitem' : undefined, target: openInNewTab ? '_blank' : undefined, children: children }), hasChildren && (jsx(GlyphsChevronsSlimRightIcon, { "aria-description": `(${t('Submenu')})`, className: styles['icon'] }))] }));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { MenuListItem };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { Button } from '../../buttons/button/button.js';
|
|
3
4
|
import { SolidOkayIcon } from '../../icons/solid/solid-okay-icon.js';
|
|
4
5
|
import { FormattedMessage } from '../../intl/formatted-message.js';
|
|
5
6
|
import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
6
7
|
import { IconList, IconListItem } from '../../lists/icon-list/icon-list.js';
|
|
7
8
|
import { useFavorite } from '../../shared/providers/favorite-provider.js';
|
|
8
|
-
import { RouteButton } from '../../shared/routing/route-button.js';
|
|
9
9
|
import { Dialog } from '../dialog/dialog.js';
|
|
10
10
|
|
|
11
11
|
const getLocation = () => typeof window === 'undefined' ? undefined : window.location;
|
|
@@ -15,7 +15,7 @@ function SignInDialog({ isOpen, onOpenChange }) {
|
|
|
15
15
|
const location = getLocation();
|
|
16
16
|
if (!location)
|
|
17
17
|
return null;
|
|
18
|
-
return (jsx(Dialog, { isDismissable: true, footer: jsxs(Fragment, { children: [jsx(
|
|
18
|
+
return (jsx(Dialog, { isDismissable: true, footer: jsxs(Fragment, { children: [jsx(Button, { withArrow: true, color: "primary", href: `${signInUrl}?returnUrl=${encodeURIComponent(location.pathname + location.search)}`, onClick: () => onOpenChange(false), variant: "solid", children: jsx(FormattedMessage, { id: "sign in" }) }), jsx(Button, { color: "secondary", href: `${signInUrl}?returnUrl=${encodeURIComponent(location.pathname + location.search)}`, onClick: () => onOpenChange(false), variant: "outline", children: jsx(FormattedMessage, { id: "create account" }) })] }), isOpen: isOpen, onOpenChange: onOpenChange, title: t('Shop more efficiently and quicker with a favorites list'), children: jsxs(IconList, { children: [jsx(IconListItem, { icon: jsx(SolidOkayIcon, { fill: "var(--color-status-available)" }), text: t('Easily add your favorite products') }), jsx(IconListItem, { icon: jsx(SolidOkayIcon, { fill: "var(--color-status-available)" }), text: t('Your favorites are available on multiple devices') }), jsx(IconListItem, { icon: jsx(SolidOkayIcon, { fill: "var(--color-status-available)" }), text: t('Share your favorite list with others') })] }) }));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export { SignInDialog };
|
|
@@ -7,7 +7,7 @@ import { useFormattedMessage } from '../../intl/use-formatted-message.js';
|
|
|
7
7
|
|
|
8
8
|
function CartIcon({ 'aria-label': ariaLabel, count }) {
|
|
9
9
|
const t = useFormattedMessage();
|
|
10
|
-
return (jsx(IconWithBadge, { "aria-label": ariaLabel, badge: count && count > 0 ? (jsx(Badge, { "aria-label": count && count > 0 ? `(${t('Number of products')})` : undefined, count: count })) : undefined, "data-test-selector": "
|
|
10
|
+
return (jsx(IconWithBadge, { "aria-label": ariaLabel, badge: count && count > 0 ? (jsx(Badge, { "aria-label": count && count > 0 ? `(${t('Number of products')})` : undefined, count: count })) : undefined, "data-test-selector": "cartIcon", icon: jsx(SolidCartIcon, { role: "presentation" }) }));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export { CartIcon };
|
|
@@ -3,6 +3,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import { IconButton } from '../../buttons/icon-button/icon-button.js';
|
|
6
|
+
import { Link } from '../../buttons/link/link.js';
|
|
6
7
|
import { GlyphsArrowSemiBoldRightIcon } from '../../icons/glyph/glyphs-arrow-semibold-right-icon.js';
|
|
7
8
|
import { SolidAttentionIcon } from '../../icons/solid/solid-attention-icon.js';
|
|
8
9
|
import { SolidEventIcon } from '../../icons/solid/solid-event-icon.js';
|
|
@@ -12,7 +13,6 @@ import { SolidNoticeIcon } from '../../icons/solid/solid-notice-icon.js';
|
|
|
12
13
|
import { SolidSaleIcon } from '../../icons/solid/solid-sale-icon.js';
|
|
13
14
|
import { SolidTagIcon } from '../../icons/solid/solid-tag-icon.js';
|
|
14
15
|
import { StrokeCloseboxIcon } from '../../icons/stroke/stroke-closebox-icon.js';
|
|
15
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
16
16
|
import { multiRef } from '../../shared/utils/refs.js';
|
|
17
17
|
import styles from './announcement.module.css.js';
|
|
18
18
|
|
|
@@ -27,7 +27,7 @@ const iconMap = {
|
|
|
27
27
|
};
|
|
28
28
|
const Announcement = forwardRef(({ announcement: { href, id, subType, text, title, type }, className, onDismiss, }, ref) => {
|
|
29
29
|
return (jsx("div", { ref: multiRef(ref), className: clsx(styles.announcement, styles[type], styles[subType], className), role: "listitem", children: jsxs("div", { className: styles.wrapper, children: [jsx("div", { className: styles.icon, role: "presentation", children: iconMap[subType] }), jsxs("div", { className: styles.content, children: [jsx("h2", { className: styles.title, children: title }), text &&
|
|
30
|
-
(href ? (jsxs(
|
|
30
|
+
(href ? (jsxs(Link, { className: styles.link, href: href, children: [text, jsx(GlyphsArrowSemiBoldRightIcon, {})] })) : (jsx("p", { className: styles.text, children: text })))] }), jsx(IconButton, { className: styles.close, color: "current-color", onClick: () => onDismiss?.(id), children: jsx(StrokeCloseboxIcon, {}) })] }) }));
|
|
31
31
|
});
|
|
32
32
|
Announcement.displayName = 'Announcement';
|
|
33
33
|
|
|
@@ -6,7 +6,7 @@ import { useFetchAnnouncements } from '../../shared/api/bff/hooks/use-fetch-anno
|
|
|
6
6
|
import { useLocalStorage } from '../../shared/hooks/use-local-storage.js';
|
|
7
7
|
import { AnnouncementList } from './announcement-list.js';
|
|
8
8
|
|
|
9
|
-
function ConnectedAnnouncementList() {
|
|
9
|
+
function ConnectedAnnouncementList({ className, }) {
|
|
10
10
|
const cultureCode = useCultureCode();
|
|
11
11
|
const { data: announcements, error } = useFetchAnnouncements({
|
|
12
12
|
cultureCode,
|
|
@@ -16,7 +16,7 @@ function ConnectedAnnouncementList() {
|
|
|
16
16
|
const filteredAnnouncements = announcements?.filter(({ id }) => !dismissedIds.includes(id));
|
|
17
17
|
if (!filteredAnnouncements)
|
|
18
18
|
return null;
|
|
19
|
-
return (jsx(AnnouncementList, { announcements: filteredAnnouncements, onDismiss: id => setDismissedIds(dismissedIds => [...dismissedIds, id]), sticky: true }));
|
|
19
|
+
return (jsx(AnnouncementList, { announcements: filteredAnnouncements, className: className, onDismiss: id => setDismissedIds(dismissedIds => [...dismissedIds, id]), sticky: true }));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export { ConnectedAnnouncementList };
|
|
@@ -10,7 +10,6 @@ import { TextField } from '../../../../forms/text-field/text-field.js';
|
|
|
10
10
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
11
11
|
import { validateEmail } from '../../../../shared/model/address.js';
|
|
12
12
|
import { voidFunction } from '../../../../shared/model/defaults.js';
|
|
13
|
-
import { RouteLink } from '../../../../shared/routing/route-link.js';
|
|
14
13
|
import { Heading } from '../../../../typography/heading/heading.js';
|
|
15
14
|
import styles from './sign-in-form.module.css.js';
|
|
16
15
|
|
|
@@ -60,7 +59,7 @@ function SignInForm({ allowGuestSignIn = false, createAccountPath, errorType, in
|
|
|
60
59
|
// form header
|
|
61
60
|
const header = (jsx(Heading, { "data-test-selector": "pageTitle", italic: true, size: "m", tag: "h1", uppercase: true, children: title }));
|
|
62
61
|
// form footer
|
|
63
|
-
const footer = (jsxs(Fragment, { children: [jsx(FormSegment, { isFloating: true, children: jsx(SwitchField, { defaultSelected: initialRememberMe, isDisabled: isDisabled, name: "rememberMe", value: "true", children: t('Remember me') }) }), jsx(FormSegment, { children: jsx(Button, { "data-test-selector": "signIn_submit", isDisabled: isDisabled, isLoading: isPendingUserSignIn && t('Signing in…'), type: "submit", withArrow: true, children: t('sign in') }) }), jsxs(FormSegment, { children: [jsx("p", { className: styles['footer-options'], children: jsx(Link, { color: "primary", "data-test-selector": "signIn_forgotPassword", hasUnderline: true, isDisabled: isDisabled, onClick: onRecoverPasswordDialogOpen, children: t('Forgot password?') }) }), jsx("p", { className: styles['footer-options'], children: jsxs(Fragment, { children: [t('New user?'), ' ', jsx(
|
|
62
|
+
const footer = (jsxs(Fragment, { children: [jsx(FormSegment, { isFloating: true, children: jsx(SwitchField, { defaultSelected: initialRememberMe, isDisabled: isDisabled, name: "rememberMe", value: "true", children: t('Remember me') }) }), jsx(FormSegment, { children: jsx(Button, { "data-test-selector": "signIn_submit", isDisabled: isDisabled, isLoading: isPendingUserSignIn && t('Signing in…'), type: "submit", withArrow: true, children: t('sign in') }) }), jsxs(FormSegment, { children: [jsx("p", { className: styles['footer-options'], children: jsx(Link, { color: "primary", "data-test-selector": "signIn_forgotPassword", hasUnderline: true, isDisabled: isDisabled, onClick: onRecoverPasswordDialogOpen, children: t('Forgot password?') }) }), jsx("p", { className: styles['footer-options'], children: jsxs(Fragment, { children: [t('New user?'), ' ', jsx(Link, { "data-test-selector": "signInCreateNewAccount_createNewAccount", hasUnderline: true, href: createAccountPath, isDisabled: isDisabled, children: t('create account') })] }) })] }), allowGuestSignIn && (jsx(FormSegment, { children: jsx(Button, { color: "secondary", "data-test-selector": "continueAsGuest", isDisabled: isDisabled, isLoading: isPendingGuestSignIn && t('Signing in…'), isValidating: false, name: GUEST_SIGN_IN_BUTTON_NAME, type: "submit", value: "true", variant: "outline", children: t('Or continue as guest') }) }))] }));
|
|
64
63
|
return (jsx(Form, { autoComplete: true, className: styles['sign-in-form'], errorMessage: errorMessage, footer: footer, header: header, onSubmit: handleSubmit, title: title, children: jsxs(FormSegmentGroup, { children: [jsx(FormSegment, { children: jsx(TextField, { autoComplete: "username", "data-test-selector": "signIn_userName", defaultValue: initialEmail, inputMode: "email", isDisabled: isDisabled, isRequired: true, label: t('Email'), name: "email", showLabel: true, type: "email", validate: value => {
|
|
65
64
|
if (!value)
|
|
66
65
|
return value;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
|
+
import { Button } from '../../../buttons/button/button.js';
|
|
4
5
|
import { FormattedMessage } from '../../../intl/formatted-message.js';
|
|
5
6
|
import { Dialog } from '../../../modals/dialog/dialog.js';
|
|
6
7
|
import { useCreateAccount } from '../../../shared/api/storefront/hooks/authentication/use-create-account.js';
|
|
7
8
|
import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
|
|
8
9
|
import { ExistingAccountError } from '../../../shared/api/storefront/services/authentication-service.js';
|
|
9
|
-
import { RouteButton } from '../../../shared/routing/route-button.js';
|
|
10
10
|
import { useNavigate } from '../../../shared/routing/use-navigate.js';
|
|
11
11
|
import { Page } from '../../components/page/page.js';
|
|
12
12
|
import { LoadingPage } from '../../loading-page/loading-page.js';
|
|
@@ -40,7 +40,7 @@ function CreateAccountPage({ returnUrl } = {}) {
|
|
|
40
40
|
navigate(continuePath, { reload: true });
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
|
-
return (jsxs(Page, { fluid: true, fullHeight: true, "data-test-selector": "createAccountPage", children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(
|
|
43
|
+
return (jsxs(Page, { fluid: true, fullHeight: true, "data-test-selector": "createAccountPage", children: [jsx(SignInPageLayout, { fullHeight: true, children: jsx(CreateAccountForm, { errorType: errorType, isDisabled: isDisabled, isPendingCreateAccount: isPendingCreateAccount, onSubmit: onSubmit }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: continuePath, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isSuccess && !isReturnToShipping, title: "Account created", children: jsx("p", { children: jsx(FormattedMessage, { id: "Your new Sonic Equipment account was succesfully created. You should receive an email soon with further instructions on how to activate this account. If you do not receive this email, please contact Customer Support." }) }) }), jsx(Dialog, { footer: jsx(Button, { color: "primary", href: `${PATHS.SIGN_IN}${returnUrl ? `?returnUrl=${continuePath}` : ''}`, route: { reload: true }, size: "md", withArrow: true, children: jsx(FormattedMessage, { id: "Continue to sign in" }) }), hasCloseButton: false, isDismissable: false, isKeyboardDismissDisabled: true, isOpen: isExistingAccount, title: "Existing account", children: jsx("p", { children: jsx(FormattedMessage, { id: "The email address you entered is already associated with an existing account. Please sign in to this account or contact Customer Support." }) }) })] }));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export { CreateAccountPage };
|
|
@@ -14,8 +14,8 @@ import { useIsAuthenticated } from '../../../shared/api/storefront/hooks/authent
|
|
|
14
14
|
import { useDeleteCartLineById } from '../../../shared/api/storefront/hooks/cart/use-delete-cart-line-by-id.js';
|
|
15
15
|
import { useDeleteCurrentCart } from '../../../shared/api/storefront/hooks/cart/use-delete-current-cart.js';
|
|
16
16
|
import { useSaveCartForLater } from '../../../shared/api/storefront/hooks/cart/use-save-cart-for-later.js';
|
|
17
|
-
import { RouteButton } from '../../../shared/routing/route-button.js';
|
|
18
17
|
import { useToast } from '../../../toast/use-toast.js';
|
|
18
|
+
import { Button } from '../../../buttons/button/button.js';
|
|
19
19
|
import { useFetchCurrentCartLinesWithAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-lines-with-atp.js';
|
|
20
20
|
import { useFetchCurrentCartWithAtp } from '../../../shared/api/storefront/hooks/cart/use-fetch-current-cart-with-atp.js';
|
|
21
21
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
@@ -81,12 +81,10 @@ function CartContent({ cartLines }) {
|
|
|
81
81
|
if (!currencyCode)
|
|
82
82
|
throw new Error(`Currency code not found for symbol ${currentCart.currencySymbol}`);
|
|
83
83
|
return (jsx(CheckoutPageLayout, { actions: {
|
|
84
|
-
primary: (jsx(
|
|
85
|
-
secondary: (jsx(
|
|
86
|
-
if (!isAuthenticated)
|
|
87
|
-
return;
|
|
84
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", href: "/CheckoutShipping", children: jsx(FormattedMessage, { id: "Start checkout" }) })),
|
|
85
|
+
secondary: isAuthenticated ? (jsx(Button, { color: "secondary", "data-test-selector": "saveCartForLaterButton", onClick: () => {
|
|
88
86
|
saveCartForLater.mutate({ cart: currentCart });
|
|
89
|
-
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })),
|
|
87
|
+
}, 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" }) })),
|
|
90
88
|
}, mobileSummary: jsx(CartTotalsSummary, { currencyCode: currencyCode, totalAmount: currentCart.orderGrandTotal }), overview: jsx(CartTotals, { currencyCode: currencyCode, shippingCost: currentCart.shippingAndHandling, subtotal: currentCart.orderSubTotal, tax: currentCart.totalTax, total: currentCart.orderGrandTotal, vatPercentage: cartLines[0]?.pricing?.vatRate || 0 }), children: jsx(OrderLineList, { onRemoveAll: () => deleteCurrentCart.mutate(), children: cartLines.map(cartLine => (jsx(ConnectedOrderLineCard, { deliveryDate: cartLine.atp?.date, href: cartLine.productUri, image: {
|
|
91
89
|
fit: 'contain',
|
|
92
90
|
image: {
|
|
@@ -12,7 +12,7 @@ function CheckoutPageLayout({ actions, children, mobileSummary, overview, }) {
|
|
|
12
12
|
const isXXL = useIsBreakpoint('xxl');
|
|
13
13
|
const topRef = useRef(null);
|
|
14
14
|
const bottomRef = useRef(null);
|
|
15
|
-
const headerHeight = useWatchCssProperty('--header-
|
|
15
|
+
const headerHeight = useWatchCssProperty('--header-bottom');
|
|
16
16
|
const isScrolledBeyond = useIsScrolledBeyondElement(bottomRef.current || undefined);
|
|
17
17
|
const observables = useMemo(() => [
|
|
18
18
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { Button } from '../../../buttons/button/button.js';
|
|
3
4
|
import { PrintButton } from '../../../buttons/print-button/print-button.js';
|
|
4
5
|
import { OrderLineCard } from '../../../cards/orderline-card/orderline-card.js';
|
|
5
6
|
import { CartTotals } from '../../../cart-totals/cart-totals.js';
|
|
@@ -10,7 +11,6 @@ import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
|
|
|
10
11
|
import { OrderLineList } from '../../../lists/orderline-list/orderline-list.js';
|
|
11
12
|
import { useSaveCartForLater } from '../../../shared/api/storefront/hooks/cart/use-save-cart-for-later.js';
|
|
12
13
|
import { getCurrencyCodeBySymbol } from '../../../shared/model/currency.js';
|
|
13
|
-
import { RouteButton } from '../../../shared/routing/route-button.js';
|
|
14
14
|
import { formatDateToLocaleString } from '../../../shared/utils/date.js';
|
|
15
15
|
import { ensureNumber } from '../../../shared/utils/number.js';
|
|
16
16
|
import { useToast } from '../../../toast/use-toast.js';
|
|
@@ -52,8 +52,8 @@ function OrderConfirmationPageContent({ cart, }) {
|
|
|
52
52
|
label: t('Order confirmation'),
|
|
53
53
|
},
|
|
54
54
|
], "data-test-selector": "orderConfirmationPage", title: t('Order confirmation'), children: jsx(CheckoutPageLayout, { actions: {
|
|
55
|
-
primary: (jsx(
|
|
56
|
-
secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(
|
|
55
|
+
primary: (jsx(Button, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href: "/", children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
|
|
56
|
+
secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(Button, { color: "secondary", onClick: () => {
|
|
57
57
|
saveCartForLater.mutate({ cart });
|
|
58
58
|
}, variant: "outline", children: jsx(FormattedMessage, { id: "Save order" }) })), jsx(PrintButton, {})] })),
|
|
59
59
|
}, overview: jsx(CartTotals, { currencyCode: currencyCode, fulfillmentMethod: cart.fulfillmentMethod, orderNumber: cart.orderNumber, shippingCost: cart.shippingAndHandling, subtotal: cart.orderSubTotal, tax: cart.totalTax, total: cart.orderGrandTotal, vatPercentage: cart.cartLines?.[0]?.pricing?.vatRate }), children: jsxs("div", { children: [jsx(CheckoutPageSection, { hasBorder: false, title: t('General'), children: jsx(CheckoutPageSectionContent, { children: jsxs("div", { className: styles['general-order-info'], children: [cart.orderDate && (jsx(InfoDisplay, { id: "order-date", label: t('Order date'), value: formatDateToLocaleString(new Date(cart.orderDate), cultureCode) })), cart.requestedDeliveryDateDisplay && (jsx(InfoDisplay, { id: "requested-delivery-date", label: t('Requested delivery date'), value: formatDateToLocaleString(new Date(cart.requestedDeliveryDateDisplay.toString()), cultureCode) })), cart.poNumber && (jsx(InfoDisplay, { id: "po-number", label: t('PO Number'), value: cart.poNumber }))] }) }) }), jsx(CheckoutPageSection, { hasBorder: false, title: t('Billing and shipping information'), children: jsx(CheckoutPageSectionContent, { children: jsx(BillingAndInvoiceInformation, { billToAddress: {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { Link } from '../../../../buttons/link/link.js';
|
|
3
4
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
4
5
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
5
6
|
import { Dialog } from '../../../../modals/dialog/dialog.js';
|
|
6
|
-
import { RouteLink } from '../../../../shared/routing/route-link.js';
|
|
7
7
|
import { PATHS } from '../../../paths.js';
|
|
8
8
|
|
|
9
9
|
function CurrencyChangeDialog({ isOpen, onOpenChange, onSubmit, }) {
|
|
10
10
|
const t = useFormattedMessage();
|
|
11
|
-
return (jsx(Dialog, { "data-test-selector": "currencyChangeDialog", isOpen: isOpen, onOpenChange: onOpenChange, onSubmit: onSubmit, shouldCloseOnInteractOutside: true, submitLabel: "Continue", title: t('Currency Change'), children: jsxs("p", { children: [jsx(FormattedMessage, { id: "You selected a country where we invoice in a different currency. This will result in your cart being converted to the new currency. If you would like to review your order, " }), jsx(
|
|
11
|
+
return (jsx(Dialog, { "data-test-selector": "currencyChangeDialog", isOpen: isOpen, onOpenChange: onOpenChange, onSubmit: onSubmit, shouldCloseOnInteractOutside: true, submitLabel: "Continue", title: t('Currency Change'), children: jsxs("p", { children: [jsx(FormattedMessage, { id: "You selected a country where we invoice in a different currency. This will result in your cart being converted to the new currency. If you would like to review your order, " }), jsx(Link, { hasUnderline: true, color: "secondary", href: PATHS.CART, onClick: onSubmit, children: jsx(FormattedMessage, { id: "please go back to your cart." }) }), ' ', jsx(FormattedMessage, { id: "If you want to proceed, click the continue button. If you want to change your country, close this message and select a different country." })] }) }));
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export { CurrencyChangeDialog };
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import { Form } from 'react-aria-components';
|
|
4
4
|
import { AddressInfoDisplay } from '../../../../address-info-display/address-info-display.js';
|
|
5
|
+
import { Link } from '../../../../buttons/link/link.js';
|
|
5
6
|
import { Checkbox } from '../../../../forms/checkbox/checkbox.js';
|
|
6
7
|
import { TextField } from '../../../../forms/text-field/text-field.js';
|
|
7
8
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
8
9
|
import { useFormattedMessage } from '../../../../intl/use-formatted-message.js';
|
|
9
|
-
import { RouteLink } from '../../../../shared/routing/route-link.js';
|
|
10
10
|
import { PATHS } from '../../../paths.js';
|
|
11
11
|
import { CheckoutPageSection } from '../../layouts/checkout-page-layout/components/checkout-page-section.js';
|
|
12
12
|
import { CheckoutPageSectionContent } from '../../layouts/checkout-page-layout/components/checkout-page-section-content.js';
|
|
@@ -25,7 +25,7 @@ function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipT
|
|
|
25
25
|
? undefined
|
|
26
26
|
: formData.get('notes')?.toString() || '',
|
|
27
27
|
});
|
|
28
|
-
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(
|
|
28
|
+
}, children: [jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: "Billing address" }), children: [jsx(CheckoutPageSectionLink, { children: jsxs(Link, { color: "secondary", href: PATHS.ACCOUNT_ADDRESSES, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit billing address" }), " >"] }) }), jsxs(CheckoutPageSectionContent, { children: [billTo && (jsx(AddressInfoDisplay, { address: {
|
|
29
29
|
address1: billTo.address1,
|
|
30
30
|
address2: billTo.address2,
|
|
31
31
|
address3: billTo.address3,
|
|
@@ -37,7 +37,7 @@ function ReadOnlyAddresses({ billTo, isLoading, isPickup, notes, onSubmit, shipT
|
|
|
37
37
|
lastName: billTo.lastName,
|
|
38
38
|
phone: billTo.phone,
|
|
39
39
|
postalCode: billTo.postalCode,
|
|
40
|
-
}, "data-test-selector": "billToAddress" })), jsx("div", { className: styles.notes, children: jsx(TextField, { defaultValue: notes, isDisabled: isLoading, isMultiline: true, label: t('Add order notes'), name: "notes", rows: 3, showLabel: true }) })] })] }), jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: isPickup ? 'Pickup address' : 'Shipping address' }), children: [!isPickup && (jsx(CheckoutPageSectionLink, { children: jsxs(
|
|
40
|
+
}, "data-test-selector": "billToAddress" })), jsx("div", { className: styles.notes, children: jsx(TextField, { defaultValue: notes, isDisabled: isLoading, isMultiline: true, label: t('Add order notes'), name: "notes", rows: 3, showLabel: true }) })] })] }), jsxs(CheckoutPageSection, { title: jsx(FormattedMessage, { id: isPickup ? 'Pickup address' : 'Shipping address' }), children: [!isPickup && (jsx(CheckoutPageSectionLink, { children: jsxs(Link, { color: "secondary", href: PATHS.ACCOUNT_ADDRESSES, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit shipping address" }), " >"] }) })), jsx(CheckoutPageSectionContent, { children: isPickup ? (jsx(SonicAddress, {})) : (jsxs(Fragment, { children: [jsx(Checkbox, { className: styles['use-invoice-checkbox'], "data-test-selector": "checkboxUseBillingAddress", isDisabled: true, isSelected: true, children: jsx(FormattedMessage, { id: "Use billing address" }) }), shipTo && (jsx(AddressInfoDisplay, { address: {
|
|
41
41
|
address1: shipTo.address1,
|
|
42
42
|
address2: shipTo.address2,
|
|
43
43
|
address3: shipTo.address3,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ProductHit } from '../../../shared/model/hit';
|
|
2
|
+
import { NavigateOptions } from '../../../shared/routing/types';
|
|
2
3
|
interface ProductOverviewProps {
|
|
3
4
|
ProductHitCard: React.ComponentType<{
|
|
4
5
|
hit: ProductHit;
|
|
6
|
+
route?: NavigateOptions;
|
|
5
7
|
}>;
|
|
6
8
|
}
|
|
7
9
|
export declare function ProductOverview({ ProductHitCard }: ProductOverviewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,7 +14,7 @@ function ProductOverview({ ProductHitCard }) {
|
|
|
14
14
|
const { currentRefinement, nbHits, nbPages } = usePagination();
|
|
15
15
|
const currentPage = currentRefinement + 1;
|
|
16
16
|
const isLastPage = currentPage === nbPages;
|
|
17
|
-
return (jsxs(Fragment, { children: [isLastPage && nbHits > MAX_QUERY_RESULTS && (jsx(Message, { type: "info", children: jsx(FormattedMessage, { id: "You have reached the end of the results, but there may be more articles available. Adjust your filters or search to discover more!" }) })), jsx(ProductOverviewGrid, { isLoading: isLoading, children: hits.map(hit => isProductHit(hit) ? (jsx(ProductHitCard, { hit: hit }, hit.id)) : (jsx(PromoCard, { href: hit.href, image: hit.image }, hit.id))) })] }));
|
|
17
|
+
return (jsxs(Fragment, { children: [isLastPage && nbHits > MAX_QUERY_RESULTS && (jsx(Message, { type: "info", children: jsx(FormattedMessage, { id: "You have reached the end of the results, but there may be more articles available. Adjust your filters or search to discover more!" }) })), jsx(ProductOverviewGrid, { isLoading: isLoading, children: hits.map(hit => isProductHit(hit) ? (jsx(ProductHitCard, { hit: hit, route: { prefetch: true } }, hit.id)) : (jsx(PromoCard, { href: hit.href, image: hit.image }, hit.id))) })] }));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export { ProductOverview };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { Button } from '../../../../buttons/button/button.js';
|
|
3
4
|
import { FormattedMessage } from '../../../../intl/formatted-message.js';
|
|
4
5
|
import { useIsBreakpoint } from '../../../../shared/hooks/use-is-breakpoint.js';
|
|
5
|
-
import { RouteButton } from '../../../../shared/routing/route-button.js';
|
|
6
6
|
import { Heading } from '../../../../typography/heading/heading.js';
|
|
7
7
|
import styles from './no-results.module.css.js';
|
|
8
8
|
|
|
9
9
|
function NoResults({ content, title }) {
|
|
10
10
|
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(
|
|
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: "/", size: "md", children: jsx(FormattedMessage, { id: "Continue shopping" }) }) })] }));
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export { NoResults };
|
|
@@ -16,7 +16,7 @@ function ProductListingPageCategoryCarousel({ currentCategoryPath, }) {
|
|
|
16
16
|
return (jsx(CategoryCarousel, { categoryCards: categories.map((category, index) => (jsx(CategoryCard, { href: category.href, image: {
|
|
17
17
|
image: category.image,
|
|
18
18
|
title: category.name,
|
|
19
|
-
}, title: category.name }, category.href || index))) }));
|
|
19
|
+
}, route: { prefetch: true }, title: category.name }, category.href || index))) }));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export { ProductListingPageCategoryCarousel };
|
|
@@ -23,7 +23,7 @@ function ProductHitCard({ hit }) {
|
|
|
23
23
|
isVatIncluded: hit.isVatIncluded,
|
|
24
24
|
originalPrice: hit.originalPrice,
|
|
25
25
|
price: hit.price,
|
|
26
|
-
}, sku: hit.id, tags: hit.labels, title: hit.name }, hit.storefrontId));
|
|
26
|
+
}, route: { prefetch: true }, sku: hit.id, tags: hit.labels, title: hit.name }, hit.storefrontId));
|
|
27
27
|
}
|
|
28
28
|
function ProductListingProductOverview() {
|
|
29
29
|
return jsx(ProductOverview, { ProductHitCard: ProductHitCard });
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
+
import { Link } from '../../buttons/link/link.js';
|
|
3
4
|
import { Image } from '../../media/image/image.js';
|
|
4
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
5
5
|
import styles from './promo-banner.module.css.js';
|
|
6
6
|
|
|
7
7
|
function PromoBanner({ href, image, variant }) {
|
|
8
|
-
return (jsx(
|
|
8
|
+
return (jsx(Link, { className: clsx(styles['promo-banner'], styles[variant]), href: href, tabIndex: 0, children: jsx(Image, { fit: "cover", image: image, title: image.altText }) }));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export { PromoBanner };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { Link } from '../../buttons/link/link.js';
|
|
3
4
|
import { Image } from '../../media/image/image.js';
|
|
4
|
-
import { RouteLink } from '../../shared/routing/route-link.js';
|
|
5
5
|
import styles from './promo-card.module.css.js';
|
|
6
6
|
|
|
7
7
|
function PromoCard({ href, image, onClick }) {
|
|
8
|
-
return (jsx("div", { className: styles['promo-card-container'], children: jsx(
|
|
8
|
+
return (jsx("div", { className: styles['promo-card-container'], children: jsx(Link, { className: styles['promo-card'], href: href, onClick: onClick, children: jsx(Image, { className: styles.image, fit: "cover", image: image, title: image.altText }) }) }));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export { PromoCard };
|
|
@@ -10,7 +10,7 @@ function useWatchCssProperty(property) {
|
|
|
10
10
|
const mutationObserver = new MutationObserver(() => {
|
|
11
11
|
if (typeof document === 'undefined')
|
|
12
12
|
return;
|
|
13
|
-
const propertyValue =
|
|
13
|
+
const propertyValue = getCssPropertyValue(property);
|
|
14
14
|
setValue(propertyValue);
|
|
15
15
|
});
|
|
16
16
|
mutationObserver.observe(document.body, {
|