@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.
Files changed (75) hide show
  1. package/dist/algolia/algolia-active-categories.js +2 -2
  2. package/dist/breadcrumbs/breadcrumb.js +4 -4
  3. package/dist/buttons/button/button.d.ts +5 -2
  4. package/dist/buttons/button/button.js +22 -11
  5. package/dist/buttons/icon-button/icon-button.d.ts +6 -3
  6. package/dist/buttons/icon-button/icon-button.js +12 -5
  7. package/dist/buttons/link/link.d.ts +2 -0
  8. package/dist/buttons/link/link.js +13 -9
  9. package/dist/cards/category-card/category-card.d.ts +3 -1
  10. package/dist/cards/category-card/category-card.js +4 -4
  11. package/dist/cards/orderline-card/orderline-card.js +2 -2
  12. package/dist/cards/product-card/connected-product-card.d.ts +2 -0
  13. package/dist/cards/product-card/product-card.d.ts +3 -1
  14. package/dist/cards/product-card/product-card.js +3 -3
  15. package/dist/collapsables/show-all/show-all.js +2 -2
  16. package/dist/country-selector/connected-country-selector.d.ts +6 -6
  17. package/dist/exports.d.ts +2 -3
  18. package/dist/filters/active-filters/active-filters.js +2 -2
  19. package/dist/footer/connected-footer.d.ts +3 -1
  20. package/dist/footer/connected-footer.js +2 -2
  21. package/dist/footer/footer.js +6 -6
  22. package/dist/global-search/search-result-panel/sections/no-search.js +2 -2
  23. package/dist/global-search/search-result-panel/sections/with-results.js +2 -2
  24. package/dist/header/buttons/account/connected-account-button.js +2 -2
  25. package/dist/header/buttons/cart/connected-cart-button.js +2 -2
  26. package/dist/header/buttons/favorites/connected-favorites-button.js +2 -2
  27. package/dist/header/buttons/search/search-button.js +2 -2
  28. package/dist/header/connected-header.d.ts +2 -1
  29. package/dist/header/connected-header.js +3 -4
  30. package/dist/header/header.d.ts +2 -1
  31. package/dist/header/header.js +2 -2
  32. package/dist/header/link-list/navigation-link-list.js +3 -3
  33. package/dist/header/sonic-logo/sonic-logo.js +2 -3
  34. package/dist/index.js +2 -3
  35. package/dist/lists/menu-list/menu-list-header.js +2 -2
  36. package/dist/lists/menu-list/menu-list-item.js +2 -2
  37. package/dist/modals/signin/sign-in-dialog.js +2 -2
  38. package/dist/navigation/cart-icon/cart-icon.js +1 -1
  39. package/dist/notifications/announcements/announcement.js +2 -2
  40. package/dist/notifications/announcements/connected-announcement-list.d.ts +3 -1
  41. package/dist/notifications/announcements/connected-announcement-list.js +2 -2
  42. package/dist/pages/account/components/sign-in-form/sign-in-form.js +1 -2
  43. package/dist/pages/account/create-account-page/create-account-page.js +2 -2
  44. package/dist/pages/checkout/cart-page/cart-page.js +4 -6
  45. package/dist/pages/checkout/layouts/checkout-page-layout/checkout-page-layout.js +1 -1
  46. package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +3 -3
  47. package/dist/pages/checkout/shipping-page/components/currency-change-dialog.js +2 -2
  48. package/dist/pages/checkout/shipping-page/components/readonly-address.js +3 -3
  49. package/dist/pages/product/components/product-overview.d.ts +2 -0
  50. package/dist/pages/product/components/product-overview.js +1 -1
  51. package/dist/pages/product/product-listing-page/no-results/no-results.js +2 -2
  52. package/dist/pages/product/product-listing-page/product-listing-page-category-carousel/product-listing-page-category-carousel.js +1 -1
  53. package/dist/pages/product/product-listing-page/product-listing-product-overview/product-listing-product-overview.js +1 -1
  54. package/dist/promos/promo-banner/promo-banner.js +2 -2
  55. package/dist/promos/promo-card/promo-card.js +2 -2
  56. package/dist/shared/hooks/use-watch-css-property.js +1 -1
  57. package/dist/shared/routing/route-provider.d.ts +4 -3
  58. package/dist/shared/routing/route-provider.js +4 -2
  59. package/dist/shared/routing/route-utils.d.ts +4 -0
  60. package/dist/shared/routing/route-utils.js +8 -0
  61. package/dist/shared/routing/types.d.ts +7 -0
  62. package/dist/shared/routing/use-route-link-element.d.ts +1 -0
  63. package/dist/shared/routing/use-route-link-element.js +11 -0
  64. package/dist/shared/routing/with-routing.d.ts +3 -6
  65. package/dist/shared/routing/with-routing.js +6 -6
  66. package/dist/shared/utils/css.js +53 -0
  67. package/dist/shared/utils/price.d.ts +1 -1
  68. package/dist/styles.css +190 -188
  69. package/package.json +1 -1
  70. package/dist/shared/routing/route-button.d.ts +0 -1
  71. package/dist/shared/routing/route-button.js +0 -7
  72. package/dist/shared/routing/route-icon-button.d.ts +0 -1
  73. package/dist/shared/routing/route-icon-button.js +0 -7
  74. package/dist/shared/routing/route-link.d.ts +0 -1
  75. 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(RouteIconButton, { className: className, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(CartIcon, { "aria-label": t('Shopping cart'), count: count }) }));
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(RouteIconButton, { className: className, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(FavoriteIcon, { "aria-label": t('Favorites') }) }));
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(RouteIconButton, { "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" }) }));
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 { jsxs, Fragment, jsx } from 'react/jsx-runtime';
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 (jsxs(Fragment, { children: [jsx(ConnectedAnnouncementList, {}), jsx(Header, { links: data?.header ?? [], sticky: true })] }));
9
+ return (jsx(Header, { className: className, links: data?.header ?? [], sticky: true }));
11
10
  }
12
11
 
13
12
  export { ConnectedHeader };
@@ -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;
@@ -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(RouteLink, { "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));
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(RouteLink, { className: styles.link, href: link.url, children: link.title }) }, link.key));
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
- const Tag = href ? RouteLink : 'div';
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(RouteLink, { href: href, children: [children, jsx(GlyphsArrowBlackCapsRightIcon, { className: styles['icon'], role: "presentation" })] })), !href && children] }));
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(RouteLink, { "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'] }))] }));
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(RouteButton, { withArrow: true, color: "primary", href: `${signInUrl}?returnUrl=${encodeURIComponent(location.pathname + location.search)}`, onClick: () => onOpenChange(false), variant: "solid", children: jsx(FormattedMessage, { id: "sign in" }) }), jsx(RouteButton, { 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') })] }) }));
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": "cartIconCount", icon: jsx(SolidCartIcon, { role: "presentation" }) }));
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(RouteLink, { 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, {}) })] }) }));
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
 
@@ -1 +1,3 @@
1
- export declare function ConnectedAnnouncementList(): import("react/jsx-runtime").JSX.Element | null;
1
+ export declare function ConnectedAnnouncementList({ className, }: {
2
+ className?: string;
3
+ }): import("react/jsx-runtime").JSX.Element | null;
@@ -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(RouteLink, { "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') }) }))] }));
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(RouteButton, { 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(RouteButton, { 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." }) }) })] }));
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(RouteButton, { withArrow: true, "data-test-selector": "checkoutShippingCartTotalContinueButton", href: "/CheckoutShipping", children: jsx(FormattedMessage, { id: "Start checkout" }) })),
85
- secondary: (jsx(RouteButton, { color: "secondary", "data-test-selector": "saveCartForLaterButton", href: isAuthenticated ? undefined : PATHS.SIGN_IN, onClick: () => {
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-height');
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(RouteButton, { withArrow: true, "data-test-selector": "checkoutReviewAndSubmit_continueShopping", href: "/", children: jsx(FormattedMessage, { id: "Continue shopping" }) })),
56
- secondary: (jsxs(Fragment, { children: [cart.canSaveOrder && (jsx(RouteButton, { color: "secondary", onClick: () => {
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(RouteLink, { 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." })] }) }));
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(RouteLink, { color: "secondary", href: PATHS.ACCOUNT_ADDRESSES, isDisabled: isLoading, children: [jsx(FormattedMessage, { id: "Edit billing address" }), " >"] }) }), jsxs(CheckoutPageSectionContent, { children: [billTo && (jsx(AddressInfoDisplay, { address: {
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(RouteLink, { 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: {
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(RouteButton, { withArrow: true, "data-test-selector": "buttonContinueShopping", href: "/", size: "md", children: jsx(FormattedMessage, { id: "Continue shopping" }) }) })] }));
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(RouteLink, { className: clsx(styles['promo-banner'], styles[variant]), href: href, tabIndex: 0, children: jsx(Image, { fit: "cover", image: image, title: image.altText }) }));
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(RouteLink, { className: styles['promo-card'], href: href, onClick: onClick, children: jsx(Image, { className: styles.image, fit: "cover", image: image, title: image.altText }) }) }));
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 = getComputedStyle?.(document.body).getPropertyValue(property);
13
+ const propertyValue = getCssPropertyValue(property);
14
14
  setValue(propertyValue);
15
15
  });
16
16
  mutationObserver.observe(document.body, {