@sonic-equipment/ui 0.0.33 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, useCallback, createContext, useContext, forwardRef, useLayoutEffect, Children, cloneElement, createElement as createElement$1, useMemo, Fragment as Fragment$1 } from 'react';
1
+ import React, { useState, useCallback, useEffect, useRef, createContext, useContext, forwardRef, useLayoutEffect, Children, cloneElement, createElement as createElement$1, useMemo, Fragment as Fragment$1 } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import { Breadcrumbs, Breadcrumb as Breadcrumb$1, Link, Button as Button$1, FieldError as FieldError$1, useContextProps, InputContext, Input as Input$1, Label as Label$1, NumberField as NumberField$1, Checkbox as Checkbox$1, Select as Select$1, SelectValue, Popover, ListBox, Section, Header, ListBoxItem, TextAreaContext, TextArea as TextArea$1, TextField as TextField$1 } from 'react-aria-components';
4
4
  import clsx from 'clsx';
@@ -46,28 +46,36 @@ const useBreakpoint = () => {
46
46
  }, defaultBreakpointReturnType);
47
47
  };
48
48
  const [device, setDevice] = useState(getBreakpoints());
49
+ const handleResize = useCallback(() => {
50
+ const breakpoints = getBreakpoints();
51
+ setDevice(previousBreakpoints => {
52
+ if (previousBreakpoints.current === breakpoints.current)
53
+ return previousBreakpoints;
54
+ return breakpoints;
55
+ });
56
+ }, []);
49
57
  useEffect(() => {
50
58
  if (typeof window === 'undefined')
51
59
  return;
52
- const handleResize = () => setDevice(getBreakpoints());
53
60
  handleResize();
54
61
  window.addEventListener('resize', handleResize);
55
62
  return () => window.removeEventListener('resize', handleResize);
56
- }, []);
63
+ }, [handleResize]);
57
64
  return device;
58
65
  };
59
66
 
60
67
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
68
  function useDebouncedCallback(func, delay) {
62
69
  const timeoutId = useRef();
63
- if (typeof window === 'undefined')
64
- return func;
65
- return function debounced(...args) {
70
+ const debouncedCallback = useCallback(function debounced(...args) {
71
+ if (typeof window === 'undefined')
72
+ return func(...args);
66
73
  clearTimeout(timeoutId.current);
67
74
  timeoutId.current = setTimeout(() => {
68
75
  func(...args);
69
76
  }, delay);
70
- };
77
+ }, [delay, func]);
78
+ return debouncedCallback;
71
79
  }
72
80
 
73
81
  const useDisclosure = (initialState = false) => {
@@ -541,9 +549,11 @@ function Tag({ children }) {
541
549
 
542
550
  const IntlContext = createContext({
543
551
  formatMessage: text => text,
552
+ languageCode: 'en-GB',
553
+ updateLanguageCode: () => { },
544
554
  });
545
555
 
546
- const useFormattedMessage = () => {
556
+ function useFormattedMessage() {
547
557
  const { formatMessage } = useContext(IntlContext);
548
558
  return (id, { fallbackValue, optional, replacementValues } = {}) => {
549
559
  const message = formatMessage(id,
@@ -566,7 +576,7 @@ const useFormattedMessage = () => {
566
576
  console.warn(`Missing translation with id: ${id}`);
567
577
  return message || fallbackValue || id;
568
578
  };
569
- };
579
+ }
570
580
 
571
581
  const FormattedMessage = ({ fallbackValue, id, optional, replacementValues, }) => useFormattedMessage()(id, { fallbackValue, optional, replacementValues });
572
582
 
@@ -627,7 +637,7 @@ function ProductCard({ addToCartButton: AddToCartButton, favoriteButton: Favorit
627
637
  return (jsxs(Link, { className: styles$o['product-card'], href: href,
628
638
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
629
639
  // @ts-expect-error
630
- onClick: onClick, onPress: onPress, children: [jsx("div", { className: styles$o.image, children: jsx(Image, { alt: alt, fit: fit, src: src, title: imageTitle }) }), jsx("div", { className: styles$o['favorite-button'], children: FavoriteButton && FavoriteButton }), jsxs("div", { className: styles$o.content, children: [jsxs("div", { className: styles$o.top, children: [jsx("div", { className: styles$o.tag, children: tags?.map(tag => (jsx(Tag, { children: jsx(FormattedMessage, { optional: true, id: tag }) }, tag))) }), jsx("h2", { className: styles$o.title, children: title }), jsx(ProductSku, { sku: sku })] }), jsxs("div", { className: styles$o.bottom, children: [jsx("div", { className: styles$o.price, children: jsx(ProductPrice, { isVatIncluded: price.isVatIncluded, originalPrice: price.originalPrice, price: price.price }) }), jsx("div", { className: styles$o['add-to-cart-button'], children: AddToCartButton })] })] })] }));
640
+ onClick: onClick, onPress: onPress, children: [jsx("div", { className: styles$o.image, children: jsx(Image, { alt: alt, fit: fit, src: src, title: imageTitle }) }), jsx("div", { className: styles$o['favorite-button'], children: FavoriteButton && FavoriteButton }), jsxs("div", { className: styles$o.content, children: [jsxs("div", { className: styles$o.top, children: [jsx("div", { className: styles$o.tag, children: tags?.map(tag => (jsx(Tag, { children: jsx(FormattedMessage, { optional: true, fallbackValue: tag, id: `tag.${tag.toLowerCase()}` }) }, tag))) }), jsx("h2", { className: styles$o.title, children: title }), jsx(ProductSku, { sku: sku })] }), jsxs("div", { className: styles$o.bottom, children: [jsx("div", { className: styles$o.price, children: jsx(ProductPrice, { isVatIncluded: price.isVatIncluded, originalPrice: price.originalPrice, price: price.price }) }), jsx("div", { className: styles$o['add-to-cart-button'], children: AddToCartButton })] })] })] }));
631
641
  }
632
642
 
633
643
  var styles$n = {"category-card":"category-card-module-4NUjH","title":"category-card-module-LEhh3","is-selected":"category-card-module-vJ7vB","image-container":"category-card-module-oNTrK"};
@@ -635,7 +645,7 @@ var styles$n = {"category-card":"category-card-module-4NUjH","title":"category-c
635
645
  function CategoryCard({ href, image, isSelected = false, title, }) {
636
646
  return (jsxs(Link, { className: clsx({
637
647
  [styles$n['is-selected']]: isSelected,
638
- }, styles$n['category-card']), href: href, children: [jsx("div", { className: styles$n['image-container'], children: jsx(Image, { ...image }) }), jsx("p", { className: styles$n.title, children: title })] }));
648
+ }, styles$n['category-card']), href: href, children: [jsx("div", { className: styles$n['image-container'], children: jsx(Image, { ...image, fit: "contain" }) }), jsx("p", { className: styles$n.title, children: title })] }));
639
649
  }
640
650
 
641
651
  /**
@@ -5791,9 +5801,9 @@ function CheckmarkFilledIcon(props) {
5791
5801
  return (jsx("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M10.864 17c-.2 0-.378-.045-.534-.135a1.588 1.588 0 0 1-.446-.407L6.278 12.22c-.185-.233-.278-.474-.278-.722 0-.264.087-.488.262-.672a.86.86 0 0 1 .651-.276c.156 0 .299.033.429.101s.258.188.384.361l3.094 3.71 5.42-8.19c.216-.354.483-.531.802-.531.245 0 .466.08.663.243A.785.785 0 0 1 18 6.88c0 .12-.028.243-.084.367a2.53 2.53 0 0 1-.194.356l-5.934 8.844c-.23.369-.538.553-.924.553z", fill: "currentColor", fillRule: "evenodd" }) }));
5792
5802
  }
5793
5803
 
5794
- var styles$h = {"select":"select-module-ui-Wc","button":"select-module-aMQIQ","chevron":"select-module-00uRU","focus":"select-module-XMc0P","popover":"select-module-z8cWq","listbox":"select-module-S21ba","header":"select-module-4Bm2j","item":"select-module-LgEJO","check":"select-module-lQFw3"};
5804
+ var styles$h = {"select":"select-module-ui-Wc","sm":"select-module-44a1l","md":"select-module-QUm-8","button":"select-module-aMQIQ","chevron":"select-module-00uRU","focus":"select-module-XMc0P","popover":"select-module-z8cWq","listbox":"select-module-S21ba","header":"select-module-4Bm2j","item":"select-module-LgEJO","check":"select-module-lQFw3"};
5795
5805
 
5796
- function Select({ isDisabled = false, label, onChange, options, selectedOption, showLabel = true, }) {
5806
+ function Select({ isDisabled = false, label, onChange, options, selectedOption, showLabel = true, size = 'md', }) {
5797
5807
  const selectRef = useRef(null);
5798
5808
  useEffect(() => {
5799
5809
  const updateWidth = () => {
@@ -5808,7 +5818,7 @@ function Select({ isDisabled = false, label, onChange, options, selectedOption,
5808
5818
  window.addEventListener('resize', updateWidth);
5809
5819
  return () => window.removeEventListener('resize', updateWidth);
5810
5820
  }, []);
5811
- return (jsxs(Select$1, { ref: selectRef, "aria-label": label, className: styles$h.select, isDisabled: isDisabled, onSelectionChange: selected => onChange(selected), placeholder: label, selectedKey: String(selectedOption), children: [showLabel && jsx(Label, { children: label }), jsxs(Button$1, { className: styles$h.button, children: [jsx(SelectValue, {}), jsx(ChevronDownSlim, { "aria-hidden": "true", className: styles$h.chevron })] }), jsx(Popover, { className: styles$h.popover, placement: "bottom left", triggerRef: selectRef, children: jsx(ListBox, { className: styles$h.listbox, children: jsxs(Section, { children: [jsx(Header, { className: styles$h.header, children: label }), Object.entries(options).map(([key, value]) => (jsxs(ListBoxItem, { "aria-label": value, className: styles$h.item, id: key, textValue: value, children: [selectedOption === key && (jsx("span", { slot: "description", children: jsx(CheckmarkFilledIcon, { className: styles$h.check }) })), jsx("span", { slot: "label", children: value })] }, key)))] }) }) })] }));
5821
+ return (jsxs(Select$1, { ref: selectRef, "aria-label": label, className: clsx(styles$h.select, styles$h[size]), isDisabled: isDisabled, onSelectionChange: selected => onChange(selected), placeholder: label, selectedKey: String(selectedOption), children: [showLabel && jsx(Label, { children: label }), jsxs(Button$1, { className: styles$h.button, children: [jsx(SelectValue, {}), jsx(ChevronDownSlim, { "aria-hidden": "true", className: styles$h.chevron })] }), jsx(Popover, { className: styles$h.popover, placement: "bottom left", triggerRef: selectRef, children: jsx(ListBox, { className: styles$h.listbox, children: jsxs(Section, { children: [jsx(Header, { className: styles$h.header, children: label }), Object.entries(options).map(([key, value]) => (jsxs(ListBoxItem, { "aria-label": value, className: styles$h.item, id: key, textValue: value, children: [selectedOption === key && (jsx("span", { slot: "description", children: jsx(CheckmarkFilledIcon, { className: styles$h.check }) })), jsx("span", { slot: "label", children: value })] }, key)))] }) }) })] }));
5812
5822
  }
5813
5823
 
5814
5824
  var styles$g = {"input-container":"textarea-module-C6Xr1","lg":"textarea-module-vksG-","md":"textarea-module-6JrQJ"};
@@ -5882,8 +5892,9 @@ function HashedOutlinedIcon(props) {
5882
5892
  return (jsx("svg", { height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M12 7.666C9.54 7.666 7.538 9.61 7.538 12c0 2.39 2.001 4.334 4.462 4.334 2.46 0 4.462-1.944 4.462-4.334 0-2.39-2.001-4.334-4.462-4.334M12 5c5.514 0 10 3.14 10 7s-4.486 7-10 7-10-3.14-10-7 4.486-7 10-7zm0 1.292c-2.39 0-4.624.642-6.29 1.809C4.175 9.175 3.33 10.56 3.33 12s.845 2.825 2.38 3.9c1.666 1.166 3.9 1.808 6.29 1.808s4.624-.642 6.29-1.809c1.535-1.074 2.38-2.459 2.38-3.9 0-1.44-.845-2.824-2.38-3.898-1.666-1.167-3.9-1.81-6.29-1.81zm0 3.958c.994 0 1.802.785 1.802 1.75s-.808 1.75-1.802 1.75-1.802-.785-1.802-1.75.808-1.75 1.802-1.75z", fill: "currentColor", fillRule: "evenodd" }) }));
5883
5893
  }
5884
5894
 
5885
- function IntlProvider({ children, formatMessage }) {
5886
- return (jsx(IntlContext.Provider, { value: { formatMessage }, children: children }));
5895
+ function IntlProvider({ children, formatMessage, languageCode: _languageCode, }) {
5896
+ const [languageCode, updateLanguageCode] = useState(_languageCode);
5897
+ return (jsx(IntlContext.Provider, { value: { formatMessage, languageCode, updateLanguageCode }, children: children }));
5887
5898
  }
5888
5899
 
5889
5900
  var styles$e = {"product-grid":"product-overview-grid-module-bzys-","grid-item":"product-overview-grid-module-MlUVA"};
@@ -5892,10 +5903,10 @@ function ProductOverviewGrid({ children }) {
5892
5903
  return (jsx("div", { className: styles$e['product-grid'], children: Children.map(children, (child, index) => (jsx("div", { className: styles$e['grid-item'], children: child }, index))) }));
5893
5904
  }
5894
5905
 
5895
- var styles$d = {"page-container":"page-layout-module-sSsgZ","page-layout":"page-layout-module-osQ2n"};
5906
+ var styles$d = {"page-container":"page-container-module-PYmbC","inner-page-container":"page-container-module-uD8GF"};
5896
5907
 
5897
- function PageLayout({ children, className, }) {
5898
- return (jsx("div", { className: styles$d['page-container'], children: jsx("div", { className: clsx(styles$d['page-layout'], className), children: children }) }));
5908
+ function PageContainer({ children, className, }) {
5909
+ return (jsx("div", { className: styles$d['page-container'], children: jsx("div", { className: clsx(styles$d['inner-page-container'], className), children: children }) }));
5899
5910
  }
5900
5911
 
5901
5912
  var styles$c = {"heading":"heading-module-pMC65","uppercase":"heading-module-6spgX","italic":"heading-module-XXMDM","xxl":"heading-module-Kn3ZN","xl":"heading-module--hZs-","l":"heading-module-WrJRY","m":"heading-module-hTexc","s":"heading-module-7W29m","xs":"heading-module-SgaLB","xxs":"heading-module-33en7"};
@@ -5922,7 +5933,7 @@ var styles$b = {"page":"page-module-XtZ9Y","breadcrumb":"page-module-ohh9z","tit
5922
5933
 
5923
5934
  function Page({ children, className, title }) {
5924
5935
  const { lg, xxl } = useBreakpoint();
5925
- return (jsxs(PageLayout, { className: clsx(styles$b.page, className), children: [jsx("div", { className: styles$b.breadcrumb, children: jsx(ConnectedBreadcrumb, {}) }), title && (jsx(Heading, { italic: true, uppercase: true, className: styles$b.title, size: xxl ? 'xl' : lg ? 'm' : 's', tag: "h1", children: title })), children] }));
5936
+ return (jsxs(PageContainer, { className: clsx(styles$b.page, className), children: [jsx("div", { className: styles$b.breadcrumb, children: jsx(ConnectedBreadcrumb, {}) }), title && (jsx(Heading, { italic: true, uppercase: true, className: styles$b.title, size: xxl ? 'xl' : lg ? 'm' : 's', tag: "h1", children: title })), children] }));
5926
5937
  }
5927
5938
 
5928
5939
  function CloseFilledIcon(props) {
@@ -5970,7 +5981,7 @@ function AccordionItem({ _pseudo = 'none', children, className, id, initialIsOpe
5970
5981
  }), children: [jsx("h3", { children: jsxs("button", { "aria-controls": panelId, "aria-expanded": isOpen, className: clsx(styles$l.button, styles$l[_pseudo]), disabled: isDisabled, id: id, onClick: toggle, type: "button", children: [title, jsx("span", { className: styles$l.icon, children: size === 'lg' ? jsx(ChevronDownBold, {}) : jsx(ChevronDownSlim, {}) })] }) }), jsx("div", { "aria-labelledby": id, className: styles$l.panel, id: panelId, role: "region", children: jsx("div", { className: styles$l.content, children: children }) })] }));
5971
5982
  }
5972
5983
 
5973
- var styles$9 = {"filter-panel":"filter-panel-module-8oxI1","scroll-container":"filter-panel-module-w0hhZ","accordion-title":"filter-panel-module-bRChA","categories-section":"filter-panel-module-AHlq3","category":"filter-panel-module-TMp3J","count":"filter-panel-module-ykW1a","categories":"filter-panel-module-xvhRz","categories-header":"filter-panel-module-hJVR0","button":"filter-panel-module-hMmIb"};
5984
+ var styles$9 = {"filter-panel":"filter-panel-module-8oxI1","scroll-container":"filter-panel-module-w0hhZ","categories-section":"filter-panel-module-AHlq3","category":"filter-panel-module-TMp3J","count":"filter-panel-module-ykW1a","categories":"filter-panel-module-xvhRz","categories-header":"filter-panel-module-hJVR0","button":"filter-panel-module-hMmIb"};
5974
5985
 
5975
5986
  function AlgoliaFilterSection({ attribute, children, initialIsOpen = true, }) {
5976
5987
  const { items, refine } = useRefinementList({
@@ -5982,7 +5993,7 @@ function AlgoliaFilterSection({ attribute, children, initialIsOpen = true, }) {
5982
5993
  if (items.length < 2 && items.filter(item => item.isRefined).length === 0) {
5983
5994
  return null;
5984
5995
  }
5985
- return (jsx(Accordion, { children: jsx(AccordionItem, { id: attribute, initialIsOpen: initialIsOpen, title: jsx("span", { className: styles$9['accordion-title'], children: jsx(FormattedMessage, { optional: true, fallbackValue: attribute, id: `facets.${attribute}` }) }), children: children({ items, refine }) }) }));
5996
+ return (jsx(Accordion, { children: jsx(AccordionItem, { id: attribute, initialIsOpen: initialIsOpen, title: jsx("span", { className: styles$9['accordion-title'], children: jsx(FormattedMessage, { optional: true, fallbackValue: attribute, id: `facet.${attribute.toLowerCase()}` }) }), children: children({ items, refine }) }) }));
5986
5997
  }
5987
5998
 
5988
5999
  function AlgoliaMultiSelectFilterSection({ attribute, }) {
@@ -6029,126 +6040,149 @@ function AlgoliaPagination({ onChange }) {
6029
6040
  return (jsx(Pagination, { currentPage: currentRefinement + 1, onChange: pageNumber => handlePageChange(pageNumber), totalPages: nbPages }));
6030
6041
  }
6031
6042
 
6032
- const environmentUrl = typeof process !== 'undefined'
6033
- ? process.env.ISC_API_URL
6034
- : typeof window !== 'undefined'
6035
- ? window.location.hostname
6036
- : undefined;
6037
- const environment = environmentUrl?.match(/local|insitesandbox.com|azurestaticapps|ui.sonic-equipment.com/i)
6038
- ? 'sandbox'
6039
- : environmentUrl?.match(/sonic-equipment.com/i)
6040
- ? 'production'
6041
- : undefined;
6043
+ const sandboxUrls = /local|insitesandbox.com|azurestaticapps|ui.sonic-equipment.com/i;
6044
+ const productionUrls = /sonic-equipment.com/i;
6045
+ let environmentUrl;
6046
+ if (typeof process !== 'undefined' && process.env.ISC_API_URL) {
6047
+ environmentUrl = process.env.ISC_API_URL;
6048
+ }
6049
+ else if (typeof window !== 'undefined') {
6050
+ environmentUrl = window.location.hostname;
6051
+ }
6052
+ else {
6053
+ throw new Error('Unable to detect environment url');
6054
+ }
6055
+ let environment;
6056
+ if (environmentUrl.match(sandboxUrls)) {
6057
+ environment = 'sandbox';
6058
+ }
6059
+ else if (environmentUrl.match(productionUrls)) {
6060
+ environment = 'production';
6061
+ }
6062
+ else {
6063
+ throw new Error('Environment not detected for url ${environmentUrl}');
6064
+ }
6042
6065
 
6043
6066
  const algoliaIndexesPerEnvironment = {
6044
6067
  production: {
6045
- default: 'prod_sonic_products_en',
6068
+ default: 'prod_sonic_products_<languageCode>',
6046
6069
  sort: [
6047
6070
  {
6048
- index: 'prod_sonic_products_en',
6071
+ index: 'prod_sonic_products_<languageCode>',
6049
6072
  name: 'relevance',
6050
6073
  },
6051
6074
  {
6052
- index: 'prod_sonic_products_en_is-new_desc',
6075
+ index: 'prod_sonic_products_<languageCode>_is-new_desc',
6053
6076
  name: 'newest',
6054
6077
  },
6055
6078
  {
6056
- index: 'prod_sonic_products_en_price_asc',
6079
+ index: 'prod_sonic_products_<languageCode>_price_asc',
6057
6080
  name: 'price_asc',
6058
6081
  },
6059
6082
  {
6060
- index: 'prod_sonic_products_en_price_desc',
6083
+ index: 'prod_sonic_products_<languageCode>_price_desc',
6061
6084
  name: 'price_desc',
6062
6085
  },
6063
6086
  ],
6064
6087
  },
6065
6088
  sandbox: {
6066
- default: 'dev_sonic_products_en',
6089
+ default: 'dev_sonic_products_<languageCode>',
6067
6090
  sort: [
6068
6091
  {
6069
- index: 'dev_sonic_products_en',
6092
+ index: 'dev_sonic_products_<languageCode>',
6070
6093
  name: 'relevance',
6071
6094
  },
6072
6095
  {
6073
- index: 'dev_sonic_products_en_is-new_desc',
6096
+ index: 'dev_sonic_products_<languageCode>_is-new_desc',
6074
6097
  name: 'newest',
6075
6098
  },
6076
6099
  {
6077
- index: 'dev_sonic_products_en_price_asc',
6100
+ index: 'dev_sonic_products_<languageCode>_price_asc',
6078
6101
  name: 'price_asc',
6079
6102
  },
6080
6103
  {
6081
- index: 'dev_sonic_products_en_price_desc',
6104
+ index: 'dev_sonic_products_<languageCode>_price_desc',
6082
6105
  name: 'price_desc',
6083
6106
  },
6084
6107
  ],
6085
6108
  },
6086
6109
  };
6087
- const currentIndexes = environment
6088
- ? algoliaIndexesPerEnvironment[environment]
6089
- : undefined;
6090
-
6091
- const queryStringRouting = {
6092
- router: history({
6093
- cleanUrlOnDispose: true,
6094
- createURL({ location, qsModule: qs, routeState }) {
6095
- const indexNames = Object.keys(routeState);
6096
- const indexName = indexNames[0];
6097
- if (!indexName)
6098
- return location.href;
6099
- if (indexNames.length !== 1)
6100
- throw new Error('Only one index is supported');
6101
- const state = routeState[indexName];
6102
- if (!state)
6103
- throw new Error(`Index ${indexName} not found in routeState`);
6104
- const queryString = qs.parse(location.search.slice(1), {
6105
- allowDots: true,
6106
- duplicates: 'combine',
6107
- });
6108
- queryString.filters = state.refinementList;
6109
- queryString.sortBy = state.sortBy;
6110
- const newQueryString = qs.stringify(queryString, {
6111
- addQueryPrefix: true,
6112
- allowDots: true,
6113
- arrayFormat: 'repeat',
6114
- });
6115
- return `${location.href.split('?')[0]}${newQueryString}`;
6116
- },
6117
- parseURL({ location, qsModule: qs }) {
6118
- if (!currentIndexes)
6119
- throw new Error('Environment not detected');
6120
- const queryString = qs.parse(location.search.slice(1), {
6121
- allowDots: true,
6122
- duplicates: 'combine',
6123
- });
6124
- const refinementList = Object.keys(queryString.filters || {}).reduce((refinementList, filter) => {
6125
- refinementList[filter] = [].concat(queryString.filters?.[filter]);
6126
- return refinementList;
6127
- }, {});
6128
- const uiState = {
6129
- [currentIndexes.default]: {
6130
- refinementList,
6131
- sortBy: queryString.sortBy?.toString(),
6132
- },
6133
- };
6134
- return uiState;
6135
- },
6136
- }),
6137
- stateMapping: simple(),
6110
+ const getAlgoliaIndex = (environment, languageCode) => {
6111
+ const environmentIndex = algoliaIndexesPerEnvironment[environment];
6112
+ const shortLanguageCode = languageCode.split('-')[0];
6113
+ if (!shortLanguageCode)
6114
+ throw new Error('Language code not detected');
6115
+ if (!environmentIndex)
6116
+ throw new Error('Environment not detected');
6117
+ return {
6118
+ default: environmentIndex.default.replace(/<languageCode>/, shortLanguageCode),
6119
+ sort: environmentIndex.sort.map(({ index, name }) => ({
6120
+ index: index.replace(/<languageCode>/, shortLanguageCode),
6121
+ name,
6122
+ })),
6123
+ };
6138
6124
  };
6139
6125
 
6126
+ function createQueryStringRouting(algoliaIndex) {
6127
+ return {
6128
+ router: history({
6129
+ cleanUrlOnDispose: true,
6130
+ createURL({ location, qsModule: qs, routeState }) {
6131
+ const indexNames = Object.keys(routeState);
6132
+ const indexName = indexNames[0];
6133
+ if (!indexName)
6134
+ return location.href;
6135
+ if (indexNames.length !== 1)
6136
+ throw new Error('Only one index is supported');
6137
+ const state = routeState[indexName];
6138
+ if (!state)
6139
+ throw new Error(`Index ${indexName} not found in routeState`);
6140
+ const queryString = qs.parse(location.search.slice(1), {
6141
+ allowDots: true,
6142
+ duplicates: 'combine',
6143
+ });
6144
+ queryString.filters = state.refinementList;
6145
+ queryString.sortBy = state.sortBy;
6146
+ const newQueryString = qs.stringify(queryString, {
6147
+ addQueryPrefix: true,
6148
+ allowDots: true,
6149
+ arrayFormat: 'repeat',
6150
+ });
6151
+ return `${location.href.split('?')[0]}${newQueryString}`;
6152
+ },
6153
+ parseURL({ location, qsModule: qs }) {
6154
+ const queryString = qs.parse(location.search.slice(1), {
6155
+ allowDots: true,
6156
+ duplicates: 'combine',
6157
+ });
6158
+ const refinementList = Object.keys(queryString.filters || {}).reduce((refinementList, filter) => {
6159
+ refinementList[filter] = [].concat(queryString.filters?.[filter]);
6160
+ return refinementList;
6161
+ }, {});
6162
+ const uiState = {
6163
+ [algoliaIndex.default]: {
6164
+ refinementList,
6165
+ sortBy: queryString.sortBy?.toString(),
6166
+ },
6167
+ };
6168
+ return uiState;
6169
+ },
6170
+ }),
6171
+ stateMapping: simple(),
6172
+ };
6173
+ }
6174
+
6140
6175
  const AlgoliaContext = createContext({
6141
6176
  online: false,
6142
6177
  setOnline: () => { },
6143
6178
  toggleOnline: () => { },
6144
6179
  });
6145
- function AlgoliaProvider({ category, children, offlineSearchClient, online: _online = true, routing = queryStringRouting, searchClient, }) {
6180
+ function AlgoliaProvider({ category, children, languageCode, offlineSearchClient, online: _online = true, routing, searchClient, }) {
6146
6181
  const [online, setOnline] = useState(_online);
6147
- if (!currentIndexes)
6148
- throw new Error('Environment not detected');
6182
+ const algoliaIndex = getAlgoliaIndex(environment, languageCode);
6149
6183
  if (!category) {
6150
6184
  // TODO: Implement loading page
6151
- return jsx("h1", { children: "Loading..." });
6185
+ return null;
6152
6186
  }
6153
6187
  return (jsx(AlgoliaContext.Provider, { value: {
6154
6188
  online,
@@ -6157,9 +6191,9 @@ function AlgoliaProvider({ category, children, offlineSearchClient, online: _onl
6157
6191
  }, children: jsxs(InstantSearch, { future: {
6158
6192
  persistHierarchicalRootCount: true,
6159
6193
  preserveSharedStateOnUnmount: true,
6160
- }, indexName: currentIndexes.default, routing: routing, searchClient: online ? searchClient : offlineSearchClient || searchClient, children: [jsx(Configure, { analytics: false, filters: category.length
6194
+ }, indexName: algoliaIndex.default, routing: routing || createQueryStringRouting(algoliaIndex), searchClient: online ? searchClient : offlineSearchClient || searchClient, children: [jsx(Configure, { analytics: false, filters: category.length
6161
6195
  ? `categoryPages: '${category.join(' > ')}'`
6162
- : undefined, hitsPerPage: 9, maxValuesPerFacet: 100, ruleContexts: ['storefront'] }), children] }) }));
6196
+ : undefined, maxValuesPerFacet: 100, ruleContexts: ['storefront'] }), children] }) }));
6163
6197
  }
6164
6198
  function useAlgolia() {
6165
6199
  return useContext(AlgoliaContext);
@@ -6184,12 +6218,17 @@ const createSonicSearchClient = (url) => ({
6184
6218
  },
6185
6219
  });
6186
6220
 
6221
+ function useLanguageCode() {
6222
+ const { languageCode } = useContext(IntlContext);
6223
+ return languageCode;
6224
+ }
6225
+
6187
6226
  function AlgoliaSortBy() {
6188
- if (!currentIndexes)
6189
- throw new Error('Environment not detected');
6227
+ const languageCode = useLanguageCode();
6228
+ const algoliaIndex = getAlgoliaIndex(environment, languageCode);
6190
6229
  const t = useFormattedMessage();
6191
6230
  const { currentRefinement, options: algoliaOptions, refine, } = useSortBy({
6192
- items: currentIndexes.sort.map(({ index, name }) => ({
6231
+ items: algoliaIndex.sort.map(({ index, name }) => ({
6193
6232
  label: t(`sort.${name}`),
6194
6233
  value: index,
6195
6234
  })),
@@ -6200,16 +6239,11 @@ function AlgoliaSortBy() {
6200
6239
  acc[option.value] = option.label;
6201
6240
  return acc;
6202
6241
  }, {});
6203
- return (jsx(Select, { label: t('Sort by'), onChange: value => refine(String(value)), options: options, selectedOption: currentRefinement, showLabel: false }));
6204
- }
6205
-
6206
- function ConnectedFavoriteButton({ productId }) {
6207
- const { isFavorite, toggle } = useFavorite(productId);
6208
- return jsx(FavoriteButton, { isFavorite: isFavorite, onPress: toggle });
6242
+ return (jsx(Select, { label: t('Sort by'), onChange: value => refine(String(value)), options: options, selectedOption: currentRefinement, showLabel: false, size: "sm" }));
6209
6243
  }
6210
6244
 
6211
6245
  function ConnectedProductCart({ productId, ...props }) {
6212
- return (jsx(ProductCard, { ...props, addToCartButton: jsx(ConnectedAddToCartButton, { productId: productId }), favoriteButton: jsx(ConnectedFavoriteButton, { productId: productId }) }));
6246
+ return (jsx(ProductCard, { ...props, addToCartButton: jsx(ConnectedAddToCartButton, { productId: productId }) }));
6213
6247
  }
6214
6248
 
6215
6249
  function useSubcatagories() {
@@ -6278,7 +6312,9 @@ const scrollToTop = (scrollOptions) => {
6278
6312
  };
6279
6313
 
6280
6314
  const SidebarContext = createContext({
6315
+ close: () => { },
6281
6316
  isOpen: false,
6317
+ open: () => { },
6282
6318
  toggle: () => { },
6283
6319
  transition: false,
6284
6320
  });
@@ -6311,15 +6347,17 @@ const ToggleSidebarButton = () => {
6311
6347
  return (jsx(Button, { color: "secondary", icon: jsx(FilterOutlinedIcon, {}), onPress: toggle, size: "sm", variant: "outline", children: isOpen ? (jsx(FormattedMessage, { id: "Hide filters" })) : (jsx(FormattedMessage, { id: "Show filters" })) }));
6312
6348
  };
6313
6349
 
6314
- function useFetchProductListingPageData(bffUrl, pageUrl) {
6350
+ function useFetchProductListingPageData(bffUrl, { languageCode, pageUrl }) {
6315
6351
  return useQuery({
6316
6352
  queryFn: async () => {
6317
- const response = await fetch(`${bffUrl}/api/v1/plp/?pageUrl=${pageUrl}`);
6353
+ const response = await fetch(`${bffUrl}/api/v1/plp/?pageUrl=${pageUrl}`, {
6354
+ headers: { 'Current-Language-Id': languageCode },
6355
+ });
6318
6356
  if (!response.ok)
6319
6357
  throw new ResponseError(response);
6320
6358
  return (await response.json());
6321
6359
  },
6322
- queryKey: [bffUrl, 'product-listing-page-data', pageUrl],
6360
+ queryKey: [bffUrl, 'product-listing-page-data', pageUrl, languageCode],
6323
6361
  retry: false,
6324
6362
  select: (data) => {
6325
6363
  return {
@@ -6351,11 +6389,11 @@ function useFetchProductListingPageData(bffUrl, pageUrl) {
6351
6389
  });
6352
6390
  }
6353
6391
 
6354
- var styles$6 = {"product-listing":"product-listing-page-module-dmIHF","header":"product-listing-page-module-Oz76Z","action-bar":"product-listing-page-module-XxGrr","sort":"product-listing-page-module-aQzHr","count":"product-listing-page-module-zx79v","categories":"product-listing-page-module-R4aOl","product-grid-container":"product-listing-page-module-ICkKg","product-grid":"product-listing-page-module-LHE7z","pagination":"product-listing-page-module-xsRaj"};
6392
+ var styles$6 = {"product-listing":"product-listing-page-module-dmIHF","header":"product-listing-page-module-Oz76Z","action-bar":"product-listing-page-module-XxGrr","sidebar-toggle":"product-listing-page-module-F7bxy","sort":"product-listing-page-module-aQzHr","count":"product-listing-page-module-zx79v","categories":"product-listing-page-module-R4aOl","product-grid-container":"product-listing-page-module-ICkKg","product-grid":"product-listing-page-module-LHE7z","pagination":"product-listing-page-module-xsRaj"};
6355
6393
 
6356
6394
  function ProductListingPage({ bffUrl, pageUrl, searchClient, }) {
6357
- const { toggle } = useSidebar();
6358
- const { data, error, isError, isFetching } = useFetchProductListingPageData(bffUrl, pageUrl);
6395
+ const languageCode = useLanguageCode();
6396
+ const { data, error, isError, isFetching } = useFetchProductListingPageData(bffUrl, { languageCode, pageUrl });
6359
6397
  if (isError) {
6360
6398
  if (!isResponseError(error))
6361
6399
  throw error;
@@ -6364,11 +6402,15 @@ function ProductListingPage({ bffUrl, pageUrl, searchClient, }) {
6364
6402
  }
6365
6403
  if (!data || isFetching) {
6366
6404
  // TODO: Implement loading page
6367
- return jsx("h1", { children: "Loading..." });
6405
+ return null;
6368
6406
  }
6369
6407
  const category = data.breadCrumb.slice(1).map(breadCrumb => breadCrumb.label);
6370
- return (jsx(ProductListingPageProvider, { data: data, error: error, isError: isError, isLoading: isFetching, children: jsx(AlgoliaProvider, { category: category, offlineSearchClient: offlineSearchClient, searchClient: searchClient ||
6371
- createSonicSearchClient(`${bffUrl}${bffUrl.endsWith('/') ? '' : '/'}search`), children: jsxs(Page, { className: styles$6['product-listing'], title: category.slice().pop(), children: [jsx("section", { className: styles$6.categories, children: jsx(ConnectedCategoryCarousel, {}) }), jsxs("section", { className: styles$6['action-bar'], children: [jsx("div", { children: jsx(ToggleSidebarButton, {}) }), jsx("span", { className: styles$6.count, children: jsx(AlgoliaResultsCount, {}) }), jsx("div", { className: styles$6.sort, children: jsx(AlgoliaSortBy, {}) })] }), jsx("section", { children: jsxs("div", { className: styles$6['product-grid-container'], children: [jsx(Sidebar, { children: jsx(AlgoliaFilterPanel, { onShowProducts: toggle }) }), jsxs("div", { className: styles$6['product-grid'], children: [jsx(ProductOverview, {}), jsx("div", { className: styles$6.pagination, children: jsx(AlgoliaPagination, { onChange: () => scrollToTop() }) })] })] }) })] }) }) }));
6408
+ return (jsx(ProductListingPageProvider, { data: data, error: error, isError: isError, isLoading: isFetching, children: jsx(AlgoliaProvider, { category: category, languageCode: languageCode, offlineSearchClient: offlineSearchClient, searchClient: searchClient ||
6409
+ createSonicSearchClient(`${bffUrl}${bffUrl.endsWith('/') ? '' : '/'}search`), children: jsx(Page, { className: styles$6['product-listing'], title: category.slice().pop(), children: jsx(ProductListingPageContent, {}) }) }) }));
6410
+ }
6411
+ function ProductListingPageContent() {
6412
+ const { toggle } = useSidebar();
6413
+ return (jsxs(Fragment, { children: [jsx("section", { className: styles$6.categories, children: jsx(ConnectedCategoryCarousel, {}) }), jsxs("section", { className: styles$6['action-bar'], children: [jsx("div", { className: styles$6['sidebar-toggle'], children: jsx(ToggleSidebarButton, {}) }), jsx("span", { className: styles$6.count, children: jsx(AlgoliaResultsCount, {}) }), jsx("div", { className: styles$6.sort, children: jsx(AlgoliaSortBy, {}) })] }), jsx("section", { children: jsxs("div", { className: styles$6['product-grid-container'], children: [jsx(Sidebar, { children: jsx(AlgoliaFilterPanel, { onShowProducts: toggle }) }), jsxs("div", { className: styles$6['product-grid'], children: [jsx(ProductOverview, {}), jsx("div", { className: styles$6.pagination, children: jsx(AlgoliaPagination, { onChange: () => scrollToTop() }) })] })] }) })] }));
6372
6414
  }
6373
6415
  function ProductOverview() {
6374
6416
  const { hits: productHits } = useHits();
@@ -6431,14 +6473,37 @@ function OverlayBackground({ isOpen, onClick }) {
6431
6473
  }), onClick: onClick }), document.body);
6432
6474
  }
6433
6475
 
6476
+ function useIsBreakpoint(breakpoint) {
6477
+ const getWindowWidth = () => typeof window !== 'undefined' ? window.innerWidth : 0;
6478
+ const checkIsMatch = useCallback(() => getWindowWidth() >= breakpoints$1[breakpoint], [breakpoint]);
6479
+ const [isMatch, setIsMatch] = useState(checkIsMatch());
6480
+ const handleResize = useCallback(() => setIsMatch(checkIsMatch()), [checkIsMatch]);
6481
+ useEffect(() => {
6482
+ window.addEventListener('resize', handleResize);
6483
+ return () => {
6484
+ window.removeEventListener('resize', handleResize);
6485
+ };
6486
+ }, [handleResize]);
6487
+ return isMatch;
6488
+ }
6489
+
6434
6490
  var styles$4 = {"sidebar-container":"sidebar-provider-module-rjeCL","transition":"sidebar-provider-module-C0cKR","sidebar-background":"sidebar-provider-module-VRgS9","is-open":"sidebar-provider-module-lxq2-"};
6435
6491
 
6436
- function SidebarProvider({ children }) {
6437
- const { xxl } = useBreakpoint();
6492
+ function SidebarDetectBreakpoint() {
6493
+ const xxl = useIsBreakpoint('xxl');
6438
6494
  const lastBreakpoint = useRef(xxl);
6439
- const { close, isOpen, open, toggle } = useDisclosure(xxl);
6495
+ const { close, isOpen, open } = useSidebar();
6440
6496
  const [transition, setTransition] = useState(false);
6441
6497
  useScrollLock(isOpen && !xxl);
6498
+ useEffect(() => {
6499
+ if (!transition)
6500
+ return;
6501
+ setTimeout(() => setTransition(false), 300);
6502
+ }, [transition]);
6503
+ const closeTransitions = () => {
6504
+ setTransition(true);
6505
+ close();
6506
+ };
6442
6507
  useEffect(() => {
6443
6508
  if (lastBreakpoint.current === xxl)
6444
6509
  return;
@@ -6450,22 +6515,20 @@ function SidebarProvider({ children }) {
6450
6515
  }
6451
6516
  lastBreakpoint.current = xxl;
6452
6517
  }, [xxl, close, open]);
6453
- useEffect(() => {
6454
- if (!transition)
6455
- return;
6456
- setTimeout(() => setTransition(false), 300);
6457
- }, [transition]);
6518
+ if (xxl)
6519
+ return null;
6520
+ return jsx(OverlayBackground, { isOpen: isOpen, onClick: closeTransitions });
6521
+ }
6522
+ function SidebarProvider({ children }) {
6523
+ const { close, isOpen, open, toggle } = useDisclosure(false);
6524
+ const [transition, setTransition] = useState(isOpen);
6458
6525
  const toggleTransition = () => {
6459
6526
  setTransition(true);
6460
6527
  toggle();
6461
6528
  };
6462
- const closeTransitions = () => {
6463
- setTransition(true);
6464
- close();
6465
- };
6466
- return (jsx(SidebarContext.Provider, { value: { isOpen, toggle: toggleTransition, transition }, children: jsxs("div", { className: clsx(styles$4['sidebar-container'], {
6529
+ return (jsx(SidebarContext.Provider, { value: { close, isOpen, open, toggle: toggleTransition, transition }, children: jsxs("div", { className: clsx(styles$4['sidebar-container'], {
6467
6530
  [styles$4['transition']]: transition,
6468
- }), children: [!xxl && (jsx(OverlayBackground, { isOpen: isOpen, onClick: closeTransitions })), children] }) }));
6531
+ }), children: [jsx(SidebarDetectBreakpoint, {}), children] }) }));
6469
6532
  }
6470
6533
 
6471
6534
  function AlgoliaCategories() {
@@ -6983,4 +7046,4 @@ function GlobalSearch({ children, searchClient }) {
6983
7046
  return (jsx(GlobalSearchContainer, { children: jsx(AlgoliaSearchProvider, { searchClient: searchClient, children: jsxs("div", { className: styles['search-wrapper'], children: [children, jsx("div", { className: styles['search-root'], children: jsx(SearchRoot, {}) })] }) }) }));
6984
7047
  }
6985
7048
 
6986
- export { Accordion, AddToCartButton, AlgoliaCategories, AlgoliaFilterPanel, AlgoliaFilterSection, AlgoliaMultiSelectFilterSection, AlgoliaPagination, AlgoliaProvider, AlgoliaResultsCount, AlgoliaSortBy, Breadcrumb, Button, CartFilledIcon, CartOutlinedIcon, CartProvider, CategoryCarousel, Checkbox, ColorCheckbox, ConnectedAddToCartButton, ConnectedBreadcrumb, DehashedOutlinedIcon, FavoriteButton, FavoriteFilledIcon, FavoriteOutlinedIcon, FavoriteProvider, FormattedMessage, GlobalSearch, GlobalSearchContainer, GlobalSearchDisclosureContext, GlobalStateProvider, GlobalStateProviderContext, HashedOutlinedIcon, IconButton, Image, IntlProvider, LeftArrowFilledIcon, LinkButton, MultiSelect, NumberField, Page, PageLayout, ProductCard, ProductListingPage, ProductOverviewGrid, ProductPrice, ProductSku, RightArrowFilledIcon, Select, ShowAll, Sidebar, SidebarProvider, TextAlignedArrowIcon, TextField, createSonicSearchClient, useAlgolia, useAlgoliaSearch, useBreakpoint, useCart, useDebouncedCallback, useDisclosure, useFavorite, useFormattedMessage, useGlobalSearchDisclosure, useGlobalState, useProductCartLine, useScrollLock };
7049
+ export { Accordion, AddToCartButton, AlgoliaCategories, AlgoliaFilterPanel, AlgoliaFilterSection, AlgoliaMultiSelectFilterSection, AlgoliaPagination, AlgoliaProvider, AlgoliaResultsCount, AlgoliaSortBy, Breadcrumb, Button, CartFilledIcon, CartOutlinedIcon, CartProvider, CategoryCarousel, Checkbox, ColorCheckbox, ConnectedAddToCartButton, ConnectedBreadcrumb, DehashedOutlinedIcon, FavoriteButton, FavoriteFilledIcon, FavoriteOutlinedIcon, FavoriteProvider, FormattedMessage, GlobalSearch, GlobalSearchContainer, GlobalSearchDisclosureContext, GlobalStateProvider, GlobalStateProviderContext, HashedOutlinedIcon, IconButton, Image, IntlProvider, LeftArrowFilledIcon, LinkButton, MultiSelect, NumberField, Page, PageContainer, ProductCard, ProductListingPage, ProductOverviewGrid, ProductPrice, ProductSku, RightArrowFilledIcon, Select, ShowAll, Sidebar, SidebarDetectBreakpoint, SidebarProvider, TextAlignedArrowIcon, TextField, breakpoints$1 as breakpoints, createSonicSearchClient, useAlgolia, useAlgoliaSearch, useBreakpoint, useCart, useDebouncedCallback, useDisclosure, useFavorite, useFormattedMessage, useGlobalSearchDisclosure, useGlobalState, useProductCartLine, useScrollLock };
@@ -1,6 +1,8 @@
1
1
  import { FormatMessageFunction } from './types';
2
2
  interface IntlContextType {
3
3
  formatMessage: FormatMessageFunction;
4
+ languageCode: string;
5
+ updateLanguageCode: (languageCode: string) => void;
4
6
  }
5
7
  export declare const IntlContext: React.Context<IntlContextType>;
6
8
  export {};
@@ -2,6 +2,7 @@ import { FormatMessageFunction } from './types';
2
2
  interface IntlProviderProps {
3
3
  children: React.ReactNode;
4
4
  formatMessage: FormatMessageFunction;
5
+ languageCode: string;
5
6
  }
6
- export declare function IntlProvider({ children, formatMessage }: IntlProviderProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function IntlProvider({ children, formatMessage, languageCode: _languageCode, }: IntlProviderProps): import("react/jsx-runtime").JSX.Element;
7
8
  export {};
@@ -1 +1 @@
1
- export type TranslationId = 'Chosen filters' | 'Clear' | 'Clear filters' | 'Excl. VAT' | 'Hide filters' | 'Incl. VAT' | 'Show' | 'Show all' | 'Show filters' | 'Show less' | 'Sort by' | 'Submit' | 'articles' | 'article' | 'of' | 'sort.relevance' | 'sort.newest' | 'sort.price_asc' | 'sort.price_desc';
1
+ export type TranslationId = 'Chosen filters' | 'Clear' | 'Clear filters' | 'Excl. VAT' | 'Hide filters' | 'Incl. VAT' | 'Show' | 'Show all' | 'Show filters' | 'Show less' | 'Sort by' | 'Submit' | 'articles' | 'article' | 'of' | 'sort.relevance' | 'sort.newest' | 'sort.price_asc' | 'sort.price_desc' | 'tag.new' | 'facet.weight' | 'facet.height';
@@ -4,4 +4,4 @@ export type FormattedMessageFunction = (id: TranslationId, options?: {
4
4
  optional?: boolean;
5
5
  replacementValues?: Record<string, string>;
6
6
  }) => string;
7
- export declare const useFormattedMessage: () => FormattedMessageFunction;
7
+ export declare function useFormattedMessage(): FormattedMessageFunction;
@@ -0,0 +1,2 @@
1
+ export declare function useLanguageCode(): string;
2
+ export declare function useUpdateLanguageCode(): (languageCode: string) => void;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- export declare function PageLayout({ children, className, }: {
2
+ export declare function PageContainer({ children, className, }: {
3
3
  children: ReactNode;
4
4
  className?: string;
5
5
  }): import("react/jsx-runtime").JSX.Element;