@sonic-equipment/ui 169.0.0 → 171.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 (113) hide show
  1. package/dist/algolia/algolia-active-categories.js +2 -2
  2. package/dist/algolia/algolia-query-string-routing.js +2 -2
  3. package/dist/breadcrumbs/breadcrumb.js +4 -4
  4. package/dist/buttons/button/button.d.ts +5 -2
  5. package/dist/buttons/button/button.js +19 -11
  6. package/dist/buttons/icon-button/icon-button.d.ts +7 -3
  7. package/dist/buttons/icon-button/icon-button.js +9 -5
  8. package/dist/buttons/link/link.d.ts +2 -0
  9. package/dist/buttons/link/link.js +10 -9
  10. package/dist/cards/category-card/category-card.d.ts +3 -1
  11. package/dist/cards/category-card/category-card.js +4 -4
  12. package/dist/cards/orderline-card/orderline-card.js +2 -2
  13. package/dist/cards/product-card/connected-product-card.d.ts +2 -0
  14. package/dist/cards/product-card/product-card.d.ts +3 -1
  15. package/dist/cards/product-card/product-card.js +3 -3
  16. package/dist/carousel/carousel.js +3 -3
  17. package/dist/carousel/usp-carousel/usp-carousel.js +1 -1
  18. package/dist/collapsables/show-all/show-all.js +2 -2
  19. package/dist/drawer/drawer.d.ts +2 -1
  20. package/dist/drawer/drawer.js +2 -2
  21. package/dist/drawer/use-drawer.js +1 -0
  22. package/dist/exports.d.ts +3 -3
  23. package/dist/filters/active-filters/active-filters.js +2 -2
  24. package/dist/footer/footer.js +6 -6
  25. package/dist/forms/select-field/select-field.js +1 -0
  26. package/dist/global-search/search-result-panel/sections/no-search.js +2 -2
  27. package/dist/global-search/search-result-panel/sections/with-results.js +5 -6
  28. package/dist/header/buttons/account/connected-account-button.js +2 -2
  29. package/dist/header/buttons/cart/connected-cart-button.js +2 -2
  30. package/dist/header/buttons/favorites/connected-favorites-button.js +2 -2
  31. package/dist/header/buttons/search/search-button.js +2 -2
  32. package/dist/header/drawers/desktop-navigation-drawer.js +2 -1
  33. package/dist/header/drawers/mobile-navigation-drawer.js +2 -1
  34. package/dist/header/drawers/search-drawer.js +1 -1
  35. package/dist/header/header.js +1 -1
  36. package/dist/header/link-list/navigation-link-list.d.ts +2 -1
  37. package/dist/header/link-list/navigation-link-list.js +6 -5
  38. package/dist/header/sonic-logo/sonic-logo.d.ts +2 -1
  39. package/dist/header/sonic-logo/sonic-logo.js +4 -4
  40. package/dist/index.js +3 -3
  41. package/dist/lists/menu-list/menu-list-back-button.d.ts +2 -1
  42. package/dist/lists/menu-list/menu-list-back-button.js +2 -2
  43. package/dist/lists/menu-list/menu-list-header.d.ts +2 -1
  44. package/dist/lists/menu-list/menu-list-header.js +3 -3
  45. package/dist/lists/menu-list/menu-list-item.d.ts +2 -1
  46. package/dist/lists/menu-list/menu-list-item.js +3 -3
  47. package/dist/lists/menu-list/menu-list.js +1 -1
  48. package/dist/media/image-lightbox/image-lightbox.js +3 -3
  49. package/dist/modals/signin/sign-in-dialog.js +2 -2
  50. package/dist/navigation/cart-icon/cart-icon.js +1 -1
  51. package/dist/navigation/mobile-navigation/mobile-navigation.js +1 -1
  52. package/dist/navigation/panel-navigation/panel-navigation.d.ts +2 -1
  53. package/dist/navigation/panel-navigation/panel-navigation.js +4 -4
  54. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/modules/free-mode.js +1 -1
  55. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/modules/thumbs.js +1 -1
  56. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/swiper-core.js +30 -15
  57. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/update-on-virtual-data.js +1 -0
  58. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/update-swiper.js +4 -2
  59. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/utils.js +13 -1
  60. package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/swiper-react.js +2 -2
  61. package/dist/notifications/announcements/announcement-list.js +1 -1
  62. package/dist/notifications/announcements/announcement.js +3 -3
  63. package/dist/pages/account/components/sign-in-form/sign-in-form.js +1 -2
  64. package/dist/pages/account/create-account-page/create-account-page.js +2 -2
  65. package/dist/pages/checkout/cart-page/cart-page.js +4 -6
  66. package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +3 -3
  67. package/dist/pages/checkout/payment-page/hooks/use-get-adyen-redirect-result.js +1 -0
  68. package/dist/pages/checkout/shipping-page/components/currency-change-dialog.js +2 -2
  69. package/dist/pages/checkout/shipping-page/components/readonly-address.js +3 -3
  70. package/dist/pages/product/components/product-overview.d.ts +2 -0
  71. package/dist/pages/product/components/product-overview.js +1 -1
  72. package/dist/pages/product/product-listing-page/no-results/no-results.js +2 -2
  73. package/dist/pages/product/product-listing-page/product-listing-page-category-carousel/product-listing-page-category-carousel.js +1 -1
  74. package/dist/pages/product/product-listing-page/product-listing-product-overview/product-listing-product-overview.js +1 -1
  75. package/dist/promos/promo-banner/promo-banner.js +2 -2
  76. package/dist/promos/promo-card/promo-card.js +2 -2
  77. package/dist/shared/api/storefront/hooks/cart/use-fetch-cart-by-id.d.ts +1 -1
  78. package/dist/shared/api/storefront/hooks/cart/use-fetch-current-cart.d.ts +1 -1
  79. package/dist/shared/api/storefront/hooks/website/use-fetch-countries-with-languages.d.ts +1 -1
  80. package/dist/shared/hooks/use-debounced-callback.js +1 -0
  81. package/dist/shared/hooks/use-enable-mobile-zoom.js +1 -0
  82. package/dist/shared/hooks/use-intersection-observer.js +1 -0
  83. package/dist/shared/hooks/use-mutation-observer.js +1 -0
  84. package/dist/shared/hooks/use-resize-observer.js +1 -0
  85. package/dist/shared/routing/route-provider.d.ts +4 -3
  86. package/dist/shared/routing/route-provider.js +4 -2
  87. package/dist/shared/routing/route-utils.d.ts +4 -0
  88. package/dist/shared/routing/route-utils.js +8 -0
  89. package/dist/shared/routing/types.d.ts +8 -0
  90. package/dist/shared/routing/use-route-link-element.d.ts +1 -0
  91. package/dist/shared/routing/use-route-link-element.js +11 -0
  92. package/dist/shared/routing/use-route-link.d.ts +8 -0
  93. package/dist/shared/routing/use-route-link.js +24 -0
  94. package/dist/shared/routing/with-routing.d.ts +3 -6
  95. package/dist/shared/routing/with-routing.js +6 -6
  96. package/dist/shared/utils/price.d.ts +1 -1
  97. package/dist/styles.css +2 -2
  98. package/package.json +45 -45
  99. package/dist/shared/routing/route-button.d.ts +0 -1
  100. package/dist/shared/routing/route-button.js +0 -7
  101. package/dist/shared/routing/route-icon-button.d.ts +0 -1
  102. package/dist/shared/routing/route-icon-button.js +0 -7
  103. package/dist/shared/routing/route-link.d.ts +0 -1
  104. package/dist/shared/routing/route-link.js +0 -7
  105. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/routers/history.js +0 -0
  106. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/stateMappings/simple.js +0 -0
  107. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/utils/documentation.js +0 -0
  108. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/utils/logger.js +0 -0
  109. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/utils/noop.js +0 -0
  110. /package/dist/node_modules/.pnpm/{instantsearch.js@4.78.0_algoliasearch@4.24.0 → instantsearch.js@4.78.3_algoliasearch@4.24.0}/node_modules/instantsearch.js/es/lib/utils/safelyRunOnBrowser.js +0 -0
  111. /package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/modules/navigation.js +0 -0
  112. /package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/create-element-if-not-defined.js +0 -0
  113. /package/dist/node_modules/.pnpm/{swiper@11.2.5 → swiper@11.2.8}/node_modules/swiper/shared/ssr-window.esm.js +0 -0
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { createElement } from 'react';
3
2
  import { jsx, jsxs } from 'react/jsx-runtime';
4
3
  import clsx from 'clsx';
5
4
  import { useAlgoliaInsights } from '../../../algolia/use-algolia-insights.js';
6
5
  import { useAlgoliaSearch } from '../../../algolia/use-algolia-search.js';
6
+ import { Button } from '../../../buttons/button/button.js';
7
7
  import { ConnectedProductCard } from '../../../cards/product-card/connected-product-card.js';
8
8
  import { CardCarousel } from '../../../carousel/card-carousel/card-carousel.js';
9
9
  import { StrokeRecentIcon } from '../../../icons/stroke/stroke-recent-icon.js';
@@ -12,7 +12,6 @@ import { FormattedMessage } from '../../../intl/formatted-message.js';
12
12
  import { useFormattedMessage } from '../../../intl/use-formatted-message.js';
13
13
  import { PromoCard } from '../../../promos/promo-card/promo-card.js';
14
14
  import { isProductHit } from '../../../shared/model/hit.js';
15
- import { RouteButton } from '../../../shared/routing/route-button.js';
16
15
  import { useGlobalSearchDisclosure } from '../../global-search-provider/use-search-disclosure.js';
17
16
  import { Highlight } from '../../search-highlight/highlight.js';
18
17
  import { SearchList } from '../../search-section/search-list.js';
@@ -26,7 +25,7 @@ import styles from './search-content.module.css.js';
26
25
  function WithResults({ isLoading }) {
27
26
  const { state } = useAlgoliaSearch();
28
27
  const { close } = useGlobalSearchDisclosure();
29
- return (jsx("div", { children: jsx(SectionContainer, { buttons: !isLoading && (jsx(RouteButton, { withArrow: true, className: clsx(styles['show-all-button'], buttonStyles.button, buttonStyles.secondary, buttonStyles.outline, buttonStyles.md), href: `/search?keyword=${encodeURIComponent(state.query)}`, onClick: close, children: jsx(FormattedMessage, { id: "See all results" }) })), leftContent: jsx(SuggestionsSection, {}), rightContent: isLoading ? jsx(SearchingSection, {}) : jsx(ProductResultsSection, {}) }) }));
28
+ return (jsx("div", { children: jsx(SectionContainer, { buttons: !isLoading && (jsx(Button, { withArrow: true, className: clsx(styles['show-all-button'], buttonStyles.button, buttonStyles.secondary, buttonStyles.outline, buttonStyles.md), href: `/search?keyword=${encodeURIComponent(state.query)}`, onClick: close, children: jsx(FormattedMessage, { id: "See all results" }) })), leftContent: jsx(SuggestionsSection, {}), rightContent: isLoading ? jsx(SearchingSection, {}) : jsx(ProductResultsSection, {}) }) }));
30
29
  }
31
30
  function SuggestionsSection() {
32
31
  const { autocomplete, categories, querySuggestions, recentSearches } = useAlgoliaSearch();
@@ -56,10 +55,10 @@ function SuggestionsSection() {
56
55
  function ProductHitCard({ autocomplete, hit, index, source, }) {
57
56
  const { close } = useGlobalSearchDisclosure();
58
57
  const { sendAddToCartFromSearchEvent, sendAddToWishListFromSearchEvent, sendProductClickFromSearchEvent, } = useAlgoliaInsights();
59
- return (createElement(ConnectedProductCard, { ...autocomplete.getItemProps({
58
+ return (jsx(ConnectedProductCard, { ...autocomplete.getItemProps({
60
59
  item: hit.hit,
61
60
  source,
62
- }), key: hit.storefrontId, href: hit.storefrontSlug, id: hit.storefrontId, image: {
61
+ }), href: hit.storefrontSlug, id: hit.storefrontId, image: {
63
62
  fit: 'contain',
64
63
  image: hit.image,
65
64
  title: hit.name,
@@ -87,7 +86,7 @@ function ProductHitCard({ autocomplete, hit, index, source, }) {
87
86
  isVatIncluded: hit.isVatIncluded,
88
87
  originalPrice: hit.originalPrice,
89
88
  price: hit.price,
90
- }, sku: hit.id, tags: hit.labels, title: jsx(Highlight, { attribute: "name", hit: hit.hit }) }));
89
+ }, sku: hit.id, tags: hit.labels, title: jsx(Highlight, { attribute: "name", hit: hit.hit }) }, hit.storefrontId));
91
90
  }
92
91
  function ProductResultsSection() {
93
92
  const { autocomplete, products: collection } = useAlgoliaSearch();
@@ -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 { AccountIcon } from '../../../navigation/account-icon/account-icon.js';
5
6
  import { useFetchSession } from '../../../shared/api/storefront/hooks/authentication/use-fetch-session.js';
6
- import { RouteIconButton } from '../../../shared/routing/route-icon-button.js';
7
7
 
8
8
  function ConnectedAccountButton({ className, 'data-test-selector': dataTestSelector, href, onClick, }) {
9
9
  const t = useFormattedMessage();
10
10
  const { data: { isAuthenticated } = {} } = useFetchSession();
11
- return (jsx(RouteIconButton, { className: className, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(AccountIcon, { "aria-label": isAuthenticated ? t('My account') : t('Sign in or create account'), isAuthenticated: isAuthenticated }) }));
11
+ return (jsx(IconButton, { className: className, "data-authenticated": isAuthenticated ? true : false, "data-test-selector": dataTestSelector, href: href, onClick: onClick, children: jsx(AccountIcon, { "aria-label": isAuthenticated ? t('My account') : t('Sign in or create account'), isAuthenticated: isAuthenticated }) }));
12
12
  }
13
13
 
14
14
  export { ConnectedAccountButton };
@@ -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-count": count, "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,10 +1,11 @@
1
+ "use client";
1
2
  import { jsx } from 'react/jsx-runtime';
2
3
  import { Drawer } from '../../drawer/drawer.js';
3
4
  import { PanelNavigation } from '../../navigation/panel-navigation/panel-navigation.js';
4
5
  import styles from './desktop-navigation-drawer.module.css.js';
5
6
 
6
7
  function DesktopNavigationDrawer({ groupId, instanceId, onClosed, submenu, }) {
7
- return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, className: styles['desktop-navigation-drawer'], groupId: groupId, instanceId: instanceId, onClosed: onClosed, position: "top", showUnder: "header", children: submenu && (jsx(PanelNavigation, { header: submenu.url
8
+ return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, className: styles['desktop-navigation-drawer'], "data-test-selector": "desktopNavigationDrawer", groupId: groupId, instanceId: instanceId, onClosed: onClosed, position: "top", showUnder: "header", children: submenu && (jsx(PanelNavigation, { "data-test-selector": "desktopNavigationPanel", header: submenu.url
8
9
  ? { href: submenu.url, title: submenu.title }
9
10
  : submenu.title, id: `panels-${submenu.key}`, links: submenu.links }, submenu.key)) }));
10
11
  }
@@ -1,10 +1,11 @@
1
+ "use client";
1
2
  import { jsx } from 'react/jsx-runtime';
2
3
  import { Drawer } from '../../drawer/drawer.js';
3
4
  import { MobileNavigation } from '../../navigation/mobile-navigation/mobile-navigation.js';
4
5
  import styles from './mobile-navigation-drawer.module.css.js';
5
6
 
6
7
  function MobileNavigationDrawer({ groupId, instanceId, links, }) {
7
- return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, className: styles['mobile-navigation-drawer'], groupId: groupId, instanceId: instanceId, position: "left", showUnder: "announcement", children: ({ close, isOpen }) => (jsx(MobileNavigation, { id: "mobile-navigation", isActive: isOpen, links: links, onActiveChange: close })) }));
8
+ return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, className: styles['mobile-navigation-drawer'], "data-test-selector": "mobileNavigationDrawer", groupId: groupId, instanceId: instanceId, position: "left", showUnder: "announcement", children: ({ close, isOpen }) => (jsx(MobileNavigation, { id: "mobile-navigation", isActive: isOpen, links: links, onActiveChange: close })) }));
8
9
  }
9
10
 
10
11
  export { MobileNavigationDrawer };
@@ -3,7 +3,7 @@ import { Drawer } from '../../drawer/drawer.js';
3
3
  import { SearchRoot } from '../../global-search/global-search.js';
4
4
 
5
5
  function SearchDrawer({ groupId, instanceId }) {
6
- return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, groupId: groupId, instanceId: instanceId, position: "top", showUnder: "header", children: jsx(SearchRoot, {}) }));
6
+ return (jsx(Drawer, { allowCloseOnBackgroundClick: true, showBackgroundOverlay: true, "data-test-selector": "searchDrawer", groupId: groupId, instanceId: instanceId, position: "top", showUnder: "header", children: jsx(SearchRoot, {}) }));
7
7
  }
8
8
 
9
9
  export { SearchDrawer };
@@ -65,7 +65,7 @@ function Header({ className, 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'], 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 }))] }));
68
+ return (jsxs(Fragment, { children: [jsx("header", { ref: headerRef, className: clsx(styles['header'], sticky && styles['sticky'], className), "data-test-selector": "pageHeader", children: jsx(HeaderLayout, { hamburgerButton: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "pageHeaderHamburgerButton", isActive: mobileNavigationOpen, onActiveChange: toggleMobileNavigation }), hasDrawersOpen: hasDrawersOpen, logo: jsx(SonicLogo, { "data-test-selector": "pageHeaderLogo", href: PATHS.HOME, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeSubmenu, "data-test-selector": "pageHeaderMainNavigation", links: links, onSubmenuToggle: link => toggleActiveSubmenu(link) }), navigationActions: jsxs(Fragment, { children: [jsx(ConnectedAccountButton, { "data-test-selector": "pageHeaderAccountButton", href: PATHS.ACCOUNT }), jsx(ConnectedFavoritesButton, { "data-test-selector": "pageHeaderFavoritesButton", href: PATHS.FAVORITES }), jsx(ConnectedCartButton, { "data-test-selector": "pageHeaderCartButton", href: PATHS.CART })] }), search: jsx(SearchButton, { "aria-controls": "global-search", "data-test-selector": "pageHeaderSearchButton", 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,7 +1,8 @@
1
1
  import { NavigationLink } from '../../shared/api/bff/model/bff.model';
2
2
  export interface LinkListProps {
3
3
  activeLink?: NavigationLink;
4
+ 'data-test-selector'?: string;
4
5
  links: NavigationLink[];
5
6
  onSubmenuToggle: (link: NavigationLink) => void;
6
7
  }
7
- export declare function NavigationLinkList({ activeLink, links, onSubmenuToggle, }: LinkListProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector, links, onSubmenuToggle, }: LinkListProps): import("react/jsx-runtime").JSX.Element;
@@ -1,14 +1,15 @@
1
+ "use client";
1
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { Link } from '../../buttons/link/link.js';
2
4
  import { GlyphsChevronsBoldDownIcon } from '../../icons/glyph/glyphs-chevrons-bold-down-icon.js';
3
- import { RouteLink } from '../../shared/routing/route-link.js';
4
5
  import styles from './navigation-link-list.module.css.js';
5
6
 
6
- function NavigationLinkList({ activeLink, links, onSubmenuToggle, }) {
7
- return (jsx("ul", { className: styles['navigation-link-list'], children: links.map(link => {
7
+ function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector, links, onSubmenuToggle, }) {
8
+ return (jsx("ul", { className: styles['navigation-link-list'], "data-test-selector": dataTestSelector, children: links.map(link => {
8
9
  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));
10
+ return (jsx("li", { className: activeLink === link ? styles['active'] : undefined, children: jsxs(Link, { "aria-controls": `panels-${link.key}`, "aria-expanded": activeLink === link, className: styles.link, "data-test-selector": `navigationLink-${link.key}`, onClick: () => onSubmenuToggle(link), target: link.openInNewTab ? '_blank' : undefined, children: [link.title, jsx(GlyphsChevronsBoldDownIcon, { className: styles.chevron, role: "presentation" })] }) }, link.key));
10
11
  }
11
- return (jsx("li", { children: jsx(RouteLink, { className: styles.link, href: link.url, children: link.title }) }, link.key));
12
+ return (jsx("li", { children: jsx(Link, { className: styles.link, href: link.url, children: link.title }) }, link.key));
12
13
  }) }));
13
14
  }
14
15
 
@@ -1,6 +1,7 @@
1
1
  export interface SonicLogoProps {
2
2
  className?: string;
3
+ 'data-test-selector'?: string;
3
4
  href?: string;
4
5
  title?: string;
5
6
  }
6
- export declare function SonicLogo({ className, href, title }: SonicLogoProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function SonicLogo({ className, 'data-test-selector': dataTestSelector, href, title, }: SonicLogoProps): import("react/jsx-runtime").JSX.Element;
@@ -1,13 +1,13 @@
1
+ "use client";
1
2
  import { jsx, jsxs } from 'react/jsx-runtime';
2
3
  import clsx from 'clsx';
4
+ import { Link } from '../../buttons/link/link.js';
3
5
  import { useFormattedMessage } from '../../intl/use-formatted-message.js';
4
- import { RouteLink } from '../../shared/routing/route-link.js';
5
6
  import styles from './sonic-logo.module.css.js';
6
7
 
7
- function SonicLogo({ className, href, title }) {
8
+ function SonicLogo({ className, 'data-test-selector': dataTestSelector, href, title, }) {
8
9
  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" })] }) }) }));
10
+ return (jsx(Link, { className: clsx(styles.wrapper, className), "data-test-selector": dataTestSelector, 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
11
  }
12
12
 
13
13
  export { SonicLogo };
package/dist/index.js CHANGED
@@ -349,13 +349,13 @@ 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 { useRouteLink } from './shared/routing/use-route-link.js';
358
+ export { useRouteLinkElement } from './shared/routing/use-route-link-element.js';
359
359
  export { withRouting } from './shared/routing/with-routing.js';
360
360
  export { ensureArray } from './shared/utils/array.js';
361
361
  export { breakpoints, getCurrentBreakpoints } from './shared/utils/breakpoints.js';
@@ -1,7 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  interface MenuListBackButtonProps {
3
3
  children: ReactNode;
4
+ 'data-test-selector'?: string;
4
5
  onClick: VoidFunction;
5
6
  }
6
- export declare function MenuListBackButton({ children, onClick, }: MenuListBackButtonProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function MenuListBackButton({ children, 'data-test-selector': dataTestSelector, onClick, }: MenuListBackButtonProps): import("react/jsx-runtime").JSX.Element;
7
8
  export {};
@@ -3,8 +3,8 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { GlyphsChevronsSlimLeftIcon } from '../../icons/glyph/glyphs-chevrons-slim-left-icon.js';
4
4
  import styles from './menu-list.module.css.js';
5
5
 
6
- function MenuListBackButton({ children, onClick, }) {
7
- return (jsxs("button", { className: styles['menu-list-back-button'], onClick: onClick, type: "button", children: [jsx(GlyphsChevronsSlimLeftIcon, { className: styles['icon'], role: "presentation" }), children] }));
6
+ function MenuListBackButton({ children, 'data-test-selector': dataTestSelector, onClick, }) {
7
+ return (jsxs("button", { className: styles['menu-list-back-button'], "data-test-selector": dataTestSelector, onClick: onClick, type: "button", children: [jsx(GlyphsChevronsSlimLeftIcon, { className: styles['icon'], role: "presentation" }), children] }));
8
8
  }
9
9
 
10
10
  export { MenuListBackButton };
@@ -1,7 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  interface MenuListHeaderProps {
3
3
  children: ReactNode;
4
+ 'data-test-selector'?: string;
4
5
  href?: string;
5
6
  }
6
- export declare function MenuListHeader({ children, href }: MenuListHeaderProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function MenuListHeader({ children, 'data-test-selector': dataTestSelector, href, }: MenuListHeaderProps): import("react/jsx-runtime").JSX.Element;
7
8
  export {};
@@ -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
- 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] }));
6
+ function MenuListHeader({ children, 'data-test-selector': dataTestSelector, href, }) {
7
+ return (jsxs("h2", { className: styles['menu-list-header'], "data-test-selector": dataTestSelector, 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 };
@@ -4,6 +4,7 @@ export interface MenuListItemProps {
4
4
  'aria-controls'?: string;
5
5
  badge?: ReactNode;
6
6
  children: ReactNode | string;
7
+ 'data-test-selector'?: string;
7
8
  hasChildren?: boolean;
8
9
  href?: string;
9
10
  image?: ImageType;
@@ -11,4 +12,4 @@ export interface MenuListItemProps {
11
12
  onClick?: VoidFunction;
12
13
  openInNewTab?: boolean;
13
14
  }
14
- export declare function MenuListItem({ 'aria-controls': ariaControls, badge, children, hasChildren, href, image, isSelected, onClick, openInNewTab, }: MenuListItemProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function MenuListItem({ 'aria-controls': ariaControls, badge, children, 'data-test-selector': dataTestSelector, hasChildren, href, image, isSelected, onClick, openInNewTab, ...rest }: MenuListItemProps): import("react/jsx-runtime").JSX.Element;
@@ -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
- function MenuListItem({ 'aria-controls': ariaControls, badge, children, hasChildren, href, image, isSelected, onClick, openInNewTab, }) {
10
+ function MenuListItem({ 'aria-controls': ariaControls, badge, children, 'data-test-selector': dataTestSelector, hasChildren, href, image, isSelected, onClick, openInNewTab, ...rest }) {
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']), "data-test-selector": dataTestSelector, ...rest, 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 };
@@ -8,7 +8,7 @@ import styles from './menu-list.module.css.js';
8
8
  function MenuList({ back, children, header, scrollable = true, variant = 'default', }) {
9
9
  const headerTitle = typeof header === 'string' ? header : header?.title;
10
10
  const headerHref = typeof header === 'string' ? undefined : header?.href;
11
- return (jsxs("section", { className: clsx(styles['menu-list'], styles[variant], scrollable && styles['scrollable']), role: "menu", children: [back && (jsx(MenuListBackButton, { onClick: back.onClick, children: back.title })), jsxs("div", { className: styles['scroll-area'], children: [header && (jsx(MenuListHeader, { href: headerHref, children: headerTitle })), jsx("ul", { className: styles['list'], children: children })] })] }));
11
+ return (jsxs("section", { className: clsx(styles['menu-list'], styles[variant], scrollable && styles['scrollable']), role: "menu", children: [back && (jsx(MenuListBackButton, { "data-test-selector": "menuListBackButton", onClick: back.onClick, children: back.title })), jsxs("div", { className: styles['scroll-area'], "data-test-selector": "menuListScrollArea", children: [header && (jsx(MenuListHeader, { "data-test-selector": "menuListHeader", href: headerHref, children: headerTitle })), jsx("ul", { className: styles['list'], children: children })] })] }));
12
12
  }
13
13
 
14
14
  export { MenuList };
@@ -2,9 +2,9 @@
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
  import { useState, useRef } from 'react';
4
4
  import clsx from 'clsx';
5
- import Navigation from '../../node_modules/.pnpm/swiper@11.2.5/node_modules/swiper/modules/navigation.js';
6
- import Thumb from '../../node_modules/.pnpm/swiper@11.2.5/node_modules/swiper/modules/thumbs.js';
7
- import { Swiper, SwiperSlide } from '../../node_modules/.pnpm/swiper@11.2.5/node_modules/swiper/swiper-react.js';
5
+ import Navigation from '../../node_modules/.pnpm/swiper@11.2.8/node_modules/swiper/modules/navigation.js';
6
+ import Thumb from '../../node_modules/.pnpm/swiper@11.2.8/node_modules/swiper/modules/thumbs.js';
7
+ import { Swiper, SwiperSlide } from '../../node_modules/.pnpm/swiper@11.2.8/node_modules/swiper/swiper-react.js';
8
8
  import { CarouselNavigationButton } from '../../carousel/carousel-navigation-button.js';
9
9
  import { CarouselPagination } from '../../carousel/pagination/pagination.js';
10
10
  import { Image } from '../image/image.js';
@@ -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": "cartIcon", 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-foo": "foo", "data-test-selector": "cartIcon", icon: jsx(SolidCartIcon, { role: "presentation" }) }));
11
11
  }
12
12
 
13
13
  export { CartIcon };
@@ -19,7 +19,7 @@ function MobileNavigation({ id, isActive, links, onActiveChange, }) {
19
19
  const t = useFormattedMessage();
20
20
  const { data: { isAuthenticated } = {} } = useFetchSession();
21
21
  const cartCount = useFetchCurrentCartCount();
22
- return (jsxs("section", { "aria-label": t('Main menu'), className: clsx(styles['mobile-navigation'], isActive && styles['active']), id: id, children: [jsxs("header", { className: styles['header'], children: [jsx("div", { className: styles['logo'], role: "presentation", children: jsx(SonicLogo, {}) }), jsx("div", { className: styles['hamburger'], children: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", isActive: isActive, onActiveChange: onActiveChange }) })] }), jsx(PanelNavigation, { allowBack: true, className: styles['panels'], isNarrow: true, links: links, variant: "primary", children: jsxs(MenuList, { header: t('My Sonic'), scrollable: false, children: [jsx(MenuListItem, { badge: jsx(AccountIcon, { isAuthenticated: isAuthenticated }), href: PATHS.ACCOUNT, children: isAuthenticated ? t('My account') : t('Sign in or create account') }), jsx(MenuListItem, { badge: jsx(FavoriteIcon, {}), href: PATHS.FAVORITES, children: t('Favorites') }), jsx(MenuListItem, { badge: jsx(CartIcon, { count: cartCount }), href: PATHS.CART, children: t('Shopping cart') })] }) })] }));
22
+ return (jsxs("section", { "aria-label": t('Main menu'), className: clsx(styles['mobile-navigation'], isActive && styles['active']), "data-test-selector": "mobileNavigationMenu", id: id, children: [jsxs("header", { className: styles['header'], children: [jsx("div", { className: styles['logo'], role: "presentation", children: jsx(SonicLogo, {}) }), jsx("div", { className: styles['hamburger'], children: jsx(HamburgerButton, { "aria-controls": "mobile-navigation", "data-test-selector": "mobileNavigationHamburgerButton", isActive: isActive, onActiveChange: onActiveChange }) })] }), jsx(PanelNavigation, { allowBack: true, className: styles['panels'], "data-test-selector": "mobileNavigationPanel", isNarrow: true, links: links, variant: "primary", children: jsxs(MenuList, { header: t('My Sonic'), scrollable: false, children: [jsx(MenuListItem, { badge: jsx(AccountIcon, { isAuthenticated: isAuthenticated }), "data-authenticated": isAuthenticated ? true : false, "data-test-selector": "mobileNavigationAccountButton", href: PATHS.ACCOUNT, children: isAuthenticated ? t('My account') : t('Sign in or create account') }), jsx(MenuListItem, { badge: jsx(FavoriteIcon, {}), "data-test-selector": "mobileNavigationFavoritesButton", href: PATHS.FAVORITES, children: t('Favorites') }), jsx(MenuListItem, { badge: jsx(CartIcon, { count: cartCount }), "data-count": cartCount, "data-test-selector": "mobileNavigationCartButton", href: PATHS.CART, children: t('Shopping cart') })] }) })] }));
23
23
  }
24
24
 
25
25
  export { MobileNavigation };
@@ -4,6 +4,7 @@ export interface PanelNavigationProps {
4
4
  allowBack?: boolean;
5
5
  children?: ReactNode;
6
6
  className?: string;
7
+ 'data-test-selector'?: string;
7
8
  header?: string | {
8
9
  href: string;
9
10
  title: string;
@@ -13,4 +14,4 @@ export interface PanelNavigationProps {
13
14
  links?: NavigationLink[];
14
15
  variant?: 'primary';
15
16
  }
16
- export declare function PanelNavigation({ allowBack, children, className, header, id, isNarrow, links, variant, }: PanelNavigationProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow, links, variant, }: PanelNavigationProps): import("react/jsx-runtime").JSX.Element;
@@ -37,9 +37,9 @@ const NavigationMenu = forwardRef(({ allowBack, back, children, className, heade
37
37
  setSelectedNavigationVisible(Boolean(selectedNavigationLink));
38
38
  }, [selectedNavigationLink]);
39
39
  const t = useFormattedMessage();
40
- return (jsxs(Fragment, { children: [jsxs("div", { ref: multiRef(ref, menuRef), className: clsx(styles['panel'], isNarrow && styles['narrow'], className), id: id, children: [jsx(MenuList, { back: back, header: header, scrollable: scrollable, variant: variant, children: links?.map(link => link.links && link.links.length > 0 ? (jsx(MenuListItem, { hasChildren: true, "aria-controls": `menu-${link.key}`, image: link.image, isSelected: selectedNavigationLink?.key === link.key, onClick: () => setSelectedNavigationLink(selectedNavigationLink?.key === link.key
40
+ return (jsxs(Fragment, { children: [jsxs("div", { ref: multiRef(ref, menuRef), className: clsx(styles['panel'], isNarrow && styles['narrow'], className), "data-test-selector": "panelNavigation", id: id, children: [jsx(MenuList, { back: back, header: header, scrollable: scrollable, variant: variant, children: links?.map(link => link.links && link.links.length > 0 ? (jsx(MenuListItem, { hasChildren: true, "aria-controls": `menu-${link.key}`, "data-test-selector": "panelNavigationItem", image: link.image, isSelected: selectedNavigationLink?.key === link.key, onClick: () => setSelectedNavigationLink(selectedNavigationLink?.key === link.key
41
41
  ? undefined
42
- : link), children: link.title }, link.key)) : (jsx(MenuListItem, { href: link.url, image: link.image, openInNewTab: link.openInNewTab, children: link.title }, link.key))) }), children] }), jsx(CascadingComponent, { isVisible: selectedNavigationVisible, nodeRef: submenuRef, onEntered: onFocus(submenuRef), onExited: onFocus(menuRef), onUnmounted: onUnmounted, children: jsx(NavigationMenu, { ref: submenuRef, allowBack: allowBack, back: allowBack
42
+ : link), children: link.title }, link.key)) : (jsx(MenuListItem, { "data-test-selector": "panelNavigationItem", href: link.url, image: link.image, openInNewTab: link.openInNewTab, children: link.title }, link.key))) }), children] }), jsx(CascadingComponent, { isVisible: selectedNavigationVisible, nodeRef: submenuRef, onEntered: onFocus(submenuRef), onExited: onFocus(menuRef), onUnmounted: onUnmounted, children: jsx(NavigationMenu, { ref: submenuRef, allowBack: allowBack, back: allowBack
43
43
  ? {
44
44
  onClick: () => {
45
45
  setSelectedNavigationVisible(false);
@@ -62,8 +62,8 @@ const NavigationMenu = forwardRef(({ allowBack, back, children, className, heade
62
62
  : [] }, selectedNavigationLink?.key) })] }));
63
63
  });
64
64
  NavigationMenu.displayName = 'NavigationMenu';
65
- function PanelNavigation({ allowBack, children, className, header, id, isNarrow, links, variant, }) {
66
- return (jsx("section", { className: clsx(styles['panel-navigation'], className), id: id, children: jsx(CascadingComponentContainer, { children: jsx("div", { className: clsx(styles['panels'], isNarrow && styles['narrow']), children: jsx(NavigationMenu, { allowBack: allowBack, className: children ? styles['top-panel'] : undefined, header: header, id: "panel-navigation-first-level", isNarrow: isNarrow, links: links, scrollable: children ? false : undefined, variant: variant, children: children }) }) }) }));
65
+ function PanelNavigation({ allowBack, children, className, 'data-test-selector': dataTestSelector, header, id, isNarrow, links, variant, }) {
66
+ return (jsx("section", { className: clsx(styles['panel-navigation'], className), "data-test-selector": dataTestSelector, id: id, children: jsx(CascadingComponentContainer, { children: jsx("div", { className: clsx(styles['panels'], isNarrow && styles['narrow']), children: jsx(NavigationMenu, { allowBack: allowBack, className: children ? styles['top-panel'] : undefined, header: header, id: "panel-navigation-first-level", isNarrow: isNarrow, links: links, scrollable: children ? false : undefined, variant: variant, children: children }) }) }) }));
67
67
  }
68
68
 
69
69
  export { PanelNavigation };
@@ -1,4 +1,4 @@
1
- import { d as now, k as elementTransitionEnd } from '../shared/utils.js';
1
+ import { f as now, l as elementTransitionEnd } from '../shared/utils.js';
2
2
 
3
3
  function freeMode(_ref) {
4
4
  let {
@@ -1,5 +1,5 @@
1
1
  import { g as getDocument } from '../shared/ssr-window.esm.js';
2
- import { l as isObject, e as elementChildren } from '../shared/utils.js';
2
+ import { o as isObject, e as elementChildren } from '../shared/utils.js';
3
3
 
4
4
  function Thumb(_ref) {
5
5
  let {