@sonic-equipment/ui 260.0.7 → 260.0.9

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.
@@ -95,7 +95,6 @@ function ConnectedCountryLanguageSelectionList() {
95
95
  'ba',
96
96
  'bg',
97
97
  'by',
98
- 'bg',
99
98
  'cz',
100
99
  'ge',
101
100
  'hr',
@@ -8,7 +8,7 @@ function CountryLanguageSelectionSublist({ handleClick, items, }) {
8
8
  const t = useFormattedMessage();
9
9
  return (jsx("ul", { className: styles.list, children: items.map(({ country, key, language, path }) => {
10
10
  const label = t(`clselector.country.${country}.${language}`);
11
- return (jsx("li", { children: jsx(Link, { color: "secondary", "data-country": country, "data-language": language, "data-test-selector": "clselector-option", href: path, hrefLang: language, onClick: () => handleClick(key), children: jsx("span", { lang: language, children: label }) }) }, key));
11
+ return (jsx("li", { children: jsx(Link, { ignoreLocalePrefix: true, color: "secondary", "data-country": country, "data-language": language, "data-test-selector": "clselector-option", href: path, hrefLang: language, onClick: () => handleClick(key), children: jsx("span", { lang: language, children: label }) }) }, key));
12
12
  }) }));
13
13
  }
14
14
  function CountryLanguageSelectionList({ itemGroups, items, onSelect, }) {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useState, useEffect } from 'react';
3
+ import { useState, useMemo, useCallback, useEffect } from 'react';
4
4
  import { useCookie } from '../cookies/use-cookie.js';
5
5
  import { useCountriesLanguages } from '../country-selector/use-countries-languages.js';
6
6
  import { isCountryLanguageCode } from '../intl/types.js';
@@ -32,100 +32,99 @@ function ConnectedCountryLanguageSelector({ className, countries: _countries, is
32
32
  const [isOpen, setIsOpen] = useState(_isOpen ?? !CLSelectorCookie?.includes('closed=true'));
33
33
  const { countries } = useCountriesLanguages({});
34
34
  const router = useRouter();
35
- // options for the selector menu
36
- const menuOptions = {
37
- other: t('Choose your country or region…'),
38
- };
39
- // option groups for the selector menu to sort the menu options under
40
- const menuOptionGroups = [];
41
- // array to hold option data for easy lookup on submit
42
- const optionData = [];
43
- // construct menu options, groups and option data
44
- countries?.forEach(country => {
45
- const options = [];
46
- const countryCode = country.abbreviation.toLowerCase();
47
- // stop if countryCode is not included in _countries prop
48
- if (_countries && !_countries.includes(country.abbreviation)) {
49
- return;
50
- }
51
- const languageCodes = country.languages
52
- .map(({ languageCode }) => languageCode.toLowerCase())
53
- .sort();
54
- // group label to sort on
55
- const groupLabel = t(`clselector.country.${countryCode}.${languageCodes[0]}`);
56
- // group reactNode to display
57
- const groupReactNode = languageCodes.flatMap((languageCode, index) => {
58
- const translation = t(`clselector.country.${countryCode}.${languageCode}`);
59
- return index === 0
60
- ? [
61
- jsx("span", { lang: languageCode, children: translation }, languageCode),
62
- ]
63
- : [
64
- '/',
65
- jsx("span", { lang: languageCode, children: translation }, languageCode),
66
- ];
67
- });
68
- languageCodes.forEach(languageCode => {
69
- const optionKey = `${languageCode}-${countryCode}`;
70
- const optionCountryLabel = `clselector.country.${countryCode}.${languageCode}`;
71
- const optionLanguageLabel = `clselector.language.${languageCode}.${languageCode}`;
72
- // add option key to group's options
73
- options.push(optionKey);
74
- const { alternativeHrefs, pathname } = router.url;
75
- let path;
76
- if (alternativeHrefs && alternativeHrefs[optionKey]) {
77
- path = `/${optionKey}${alternativeHrefs[optionKey]}`;
78
- }
79
- else if (!alternativeHrefs ||
80
- Object.keys(alternativeHrefs).length === 0) {
81
- const currentCountryLanguage = pathname.split('/')[1]?.toLowerCase();
82
- path = isCountryLanguageCode(currentCountryLanguage)
83
- ? pathname
84
- .toLowerCase()
85
- .replace(`${currentCountryLanguage}`, `${optionKey}`)
86
- : `/${optionKey}${pathname}`;
87
- }
88
- else {
89
- path = `/${optionKey}`;
35
+ const { alternativeHrefs, pathname } = router.url;
36
+ const { defaultSelectedOption, menuOptionGroups, menuOptions, optionData } = useMemo(() => {
37
+ const menuOptions = {
38
+ other: t('Choose your country or region…'),
39
+ };
40
+ const menuOptionGroups = [];
41
+ const optionData = [];
42
+ countries?.forEach(country => {
43
+ const options = [];
44
+ const countryCode = country.abbreviation.toLowerCase();
45
+ if (_countries && !_countries.includes(country.abbreviation)) {
46
+ return;
90
47
  }
91
- // add option key/value to menu options
92
- menuOptions[optionKey] =
93
- environment === 'next-production' ? (jsx("span", { lang: languageCode, children: `${t(optionCountryLabel)} - ${t(optionLanguageLabel)}` })) : (
94
- // in development, show the path to help identify the correct option
95
- jsxs("span", { lang: languageCode, children: [`${t(optionCountryLabel)} - ${t(optionLanguageLabel)}`, jsx("code", { style: { fontSize: '12px' }, children: path })] }));
96
- // add to option data
97
- optionData.push({
98
- country: countryCode,
99
- key: optionKey,
100
- language: languageCode,
101
- path,
48
+ const languageCodes = country.languages
49
+ .map(({ languageCode }) => languageCode.toLowerCase())
50
+ .sort();
51
+ const groupLabel = t(`clselector.country.${countryCode}.${languageCodes[0]}`);
52
+ const groupReactNode = languageCodes.flatMap((languageCode, index) => {
53
+ const translation = t(`clselector.country.${countryCode}.${languageCode}`);
54
+ return index === 0
55
+ ? [
56
+ jsx("span", { lang: languageCode, children: translation }, languageCode),
57
+ ]
58
+ : [
59
+ '/',
60
+ jsx("span", { lang: languageCode, children: translation }, languageCode),
61
+ ];
62
+ });
63
+ languageCodes.forEach(languageCode => {
64
+ const optionKey = `${languageCode}-${countryCode}`;
65
+ const optionCountryLabel = `clselector.country.${countryCode}.${languageCode}`;
66
+ const optionLanguageLabel = `clselector.language.${languageCode}.${languageCode}`;
67
+ options.push(optionKey);
68
+ let path;
69
+ if (alternativeHrefs && alternativeHrefs[optionKey]) {
70
+ path = `/${optionKey}${alternativeHrefs[optionKey]}`;
71
+ }
72
+ else if (!alternativeHrefs ||
73
+ Object.keys(alternativeHrefs).length === 0) {
74
+ const currentCountryLanguage = pathname.split('/')[1]?.toLowerCase();
75
+ path = isCountryLanguageCode(currentCountryLanguage)
76
+ ? pathname
77
+ .toLowerCase()
78
+ .replace(`${currentCountryLanguage}`, `${optionKey}`)
79
+ : `/${optionKey}${pathname}`;
80
+ }
81
+ else {
82
+ path = `/${optionKey}`;
83
+ }
84
+ menuOptions[optionKey] =
85
+ environment === 'next-production' ? (jsx("span", { lang: languageCode, children: `${t(optionCountryLabel)} - ${t(optionLanguageLabel)}` })) : (jsxs("span", { lang: languageCode, children: [`${t(optionCountryLabel)} - ${t(optionLanguageLabel)}`, jsx("code", { style: { fontSize: '12px' }, children: path })] }));
86
+ optionData.push({
87
+ country: countryCode,
88
+ key: optionKey,
89
+ language: languageCode,
90
+ path,
91
+ });
92
+ });
93
+ menuOptionGroups.push({
94
+ key: countryCode,
95
+ label: groupLabel,
96
+ options,
97
+ reactNode: groupReactNode,
102
98
  });
103
99
  });
104
- // push new group to groups
105
- menuOptionGroups.push({
106
- key: countryCode,
107
- label: groupLabel,
108
- options,
109
- reactNode: groupReactNode,
110
- });
111
- });
112
- // sort groups alphabetically by label
113
- menuOptionGroups.sort((a, b) => a.label.localeCompare(b.label));
114
- // determine default selected option
115
- const defaultSelectedLanguageCountry = selectedLanguage && selectedCountry
116
- ? `${selectedLanguage.toLowerCase()}-${selectedCountry.toLowerCase()}`
117
- : undefined;
118
- const defaultSelectedOption = defaultSelectedLanguageCountry &&
119
- Object.keys(menuOptions).includes(defaultSelectedLanguageCountry)
120
- ? defaultSelectedLanguageCountry
121
- : undefined;
122
- // handle close action
123
- const handleClose = () => {
100
+ menuOptionGroups.sort((a, b) => a.label.localeCompare(b.label));
101
+ const defaultSelectedLanguageCountry = selectedLanguage && selectedCountry
102
+ ? `${selectedLanguage.toLowerCase()}-${selectedCountry.toLowerCase()}`
103
+ : undefined;
104
+ const defaultSelectedOption = defaultSelectedLanguageCountry &&
105
+ Object.keys(menuOptions).includes(defaultSelectedLanguageCountry)
106
+ ? defaultSelectedLanguageCountry
107
+ : undefined;
108
+ return {
109
+ defaultSelectedOption,
110
+ menuOptionGroups,
111
+ menuOptions,
112
+ optionData,
113
+ };
114
+ }, [
115
+ _countries,
116
+ alternativeHrefs,
117
+ countries,
118
+ pathname,
119
+ selectedCountry,
120
+ selectedLanguage,
121
+ t,
122
+ ]);
123
+ const handleClose = useCallback(() => {
124
124
  setIsOpen(false);
125
125
  setCLSelectorCookie('closed=true');
126
- };
127
- // handle submit action
128
- const handleSubmit = (selectedOption) => {
126
+ }, [setCLSelectorCookie]);
127
+ const handleSubmit = useCallback((selectedOption) => {
129
128
  setIsOpen(false);
130
129
  if (selectedOption === 'other') {
131
130
  setCLSelectorCookie('closed=true');
@@ -141,7 +140,7 @@ function ConnectedCountryLanguageSelector({ className, countries: _countries, is
141
140
  setCLSelectorCookie(`closed=true;language=${language};country=${country}`);
142
141
  navigate(path, { ignoreLocalePrefix: true, reload: true });
143
142
  }
144
- };
143
+ }, [navigate, optionData, setCLSelectorCookie]);
145
144
  // react to CountryLanguageSelectorButton clicked
146
145
  useEffect(() => {
147
146
  if (showSelector) {
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { useMemo } from 'react';
2
+ import { useMemo, useEffect } from 'react';
3
3
  import { useCookie } from '../../cookies/use-cookie.js';
4
4
  import { isCountryCode, isCultureCode, isLanguageCode } from '../../intl/types.js';
5
5
  import { useFetchCountriesWithLanguages } from '../../shared/api/storefront/hooks/website/use-fetch-countries-with-languages.js';
@@ -39,8 +39,10 @@ function useCountries({ enabled = true, } = {}) {
39
39
  });
40
40
  return countries;
41
41
  }, [apiCountries, sessionCountries]);
42
- if (countries !== sessionCountries)
43
- setSessionCountries(countries);
42
+ useEffect(() => {
43
+ if (countries !== sessionCountries)
44
+ setSessionCountries(countries);
45
+ }, [countries, sessionCountries, setSessionCountries]);
44
46
  const currentCountry = countries?.find(country => country.id === currentCountryId);
45
47
  return {
46
48
  countries,
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { useMemo } from 'react';
3
4
  import { Button } from '../../../buttons/button/button.js';
4
5
  import { CartTotals } from '../../../cart-totals/cart-totals.js';
5
6
  import { CartTotalsSummary } from '../../../cart-totals/cart-totals-summary.js';
@@ -18,10 +19,10 @@ import styles from './shipping-page.module.css.js';
18
19
  function ShippingPageContent({ cart, editAddress, errorPatchBillingAddress, fulfillmentMethods, isGuest, isLoadingFulfillmentMethods, isPatching, isPatchingSession, onChangeFulfillmentMethod, readOnlyAddress, }) {
19
20
  const t = useFormattedMessage();
20
21
  const paths = usePaths();
21
- const fulfillmentMethodOptions = fulfillmentMethods?.reduce((acc, method) => ({
22
+ const fulfillmentMethodOptions = useMemo(() => fulfillmentMethods?.reduce((acc, method) => ({
22
23
  ...acc,
23
24
  [method]: t(`fulfillmentmethod.${method}`),
24
- }), {});
25
+ }), {}), [fulfillmentMethods, t]);
25
26
  const hasBillToAddress = Boolean(cart.billTo?.address1);
26
27
  const currencyCode = getCurrencyCodeBySymbol(cart.currencySymbol);
27
28
  if (!currencyCode)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sonic-equipment/ui",
3
- "version": "260.0.7",
3
+ "version": "260.0.9",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "engines": {