@sonic-equipment/ui 187.0.0 → 189.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cards/data-card/data-card.js +1 -1
- package/dist/country-selector/connected-country-selector.js +0 -11
- package/dist/country-selector/use-countries-languages.js +0 -11
- package/dist/delivery-time/delivery-time.js +3 -4
- package/dist/exports.d.ts +13 -3
- package/dist/footer/connected-footer.js +8 -1
- package/dist/footer/footer.d.ts +5 -10
- package/dist/footer/footer.js +23 -18
- package/dist/forms/fields/select-field/select-field.js +1 -1
- package/dist/forms/layout/form/form.js +1 -1
- package/dist/header/connected-header.js +9 -1
- package/dist/header/drawers/desktop-navigation-drawer.d.ts +3 -3
- package/dist/header/drawers/desktop-navigation-drawer.js +2 -4
- package/dist/header/drawers/mobile-navigation-drawer.d.ts +3 -3
- package/dist/header/drawers/mobile-navigation-drawer.js +2 -2
- package/dist/header/header.d.ts +3 -3
- package/dist/header/header.js +15 -9
- package/dist/header/link-list/navigation-link-list.d.ts +5 -5
- package/dist/header/link-list/navigation-link-list.js +20 -5
- package/dist/index.js +14 -4
- package/dist/intl/formatted-date.d.ts +4 -0
- package/dist/intl/formatted-date.js +8 -0
- package/dist/intl/translation-id.d.ts +1 -1
- package/dist/intl/use-formatted-date.d.ts +6 -0
- package/dist/intl/use-formatted-date.js +19 -0
- package/dist/lists/menu-list/menu-list-header.d.ts +1 -1
- package/dist/lists/menu-list/menu-list-item.d.ts +2 -2
- package/dist/lists/menu-list/menu-list-item.js +3 -1
- package/dist/lists/menu-list/menu-list-provider.d.ts +11 -0
- package/dist/lists/menu-list/menu-list-provider.js +30 -0
- package/dist/lists/menu-list/menu-list.d.ts +8 -5
- package/dist/lists/menu-list/menu-list.js +6 -5
- package/dist/lists/menu-list/menu-list.module.css.js +1 -1
- package/dist/lists/menu-list/use-menu-list-item.d.ts +5 -0
- package/dist/lists/menu-list/use-menu-list-item.js +12 -0
- package/dist/lists/menu-list/use-menu-list.d.ts +1 -0
- package/dist/lists/menu-list/use-menu-list.js +11 -0
- package/dist/loading/dynamic-loading-overlay.d.ts +5 -0
- package/dist/loading/dynamic-loading-overlay.js +26 -0
- package/dist/loading/dynamic-loading-overlay.module.css.js +3 -0
- package/dist/media/image-lightbox/image-lightbox.js +12 -2
- package/dist/media/zoom-image/zoom-image.js +6 -1
- package/dist/navigation/mobile-navigation/mobile-navigation.d.ts +3 -3
- package/dist/navigation/mobile-navigation/mobile-navigation.js +2 -2
- package/dist/navigation/panel-navigation/panel-navigation.d.ts +5 -7
- package/dist/navigation/panel-navigation/panel-navigation.js +11 -14
- package/dist/pages/checkout/cart-page/cart-page.js +1 -1
- package/dist/pages/checkout/order-confirmation-page/order-confirmation-page-content.js +2 -4
- package/dist/pages/error-page/error-page.js +2 -7
- package/dist/pages/my-sonic/actions/change-password/connected-change-password-dialog.js +0 -2
- package/dist/pages/my-sonic/navigation/my-sonic-desktop-navigation.js +1 -1
- package/dist/pages/my-sonic/pages/order-history/order-history.d.ts +1 -0
- package/dist/pages/my-sonic/pages/order-history/order-history.js +166 -0
- package/dist/pages/my-sonic/pages/order-history/order-history.module.css.js +3 -0
- package/dist/pages/product/product-listing-page/product-listing.js +1 -1
- package/dist/pages/product/search-result-page/search-results-page.js +1 -1
- package/dist/shared/api/bff/hooks/use-fetch-navigation-links.d.ts +1 -1
- package/dist/shared/api/bff/model/bff.model.d.ts +22 -14
- package/dist/shared/api/bff/model/bff.model.js +11 -0
- package/dist/shared/api/bff/services/bff-service.d.ts +2 -2
- package/dist/shared/api/bff/services/bff-service.js +1 -1
- package/dist/shared/api/storefront/hooks/orders/use-fetch-orders.d.ts +10 -0
- package/dist/shared/api/storefront/hooks/orders/use-fetch-orders.js +13 -0
- package/dist/shared/api/storefront/model/storefront.model.d.ts +13 -1
- package/dist/shared/api/storefront/model/storefront.model.js +28 -1
- package/dist/shared/api/storefront/services/order-service.d.ts +12 -0
- package/dist/shared/api/storefront/services/order-service.js +29 -0
- package/dist/shared/data/navigation.d.ts +2 -0
- package/dist/shared/data/navigation.js +2605 -0
- package/dist/shared/hooks/use-intersection-observer.d.ts +3 -1
- package/dist/shared/hooks/use-intersection-observer.js +3 -2
- package/dist/shared/utils/date.d.ts +4 -1
- package/dist/shared/utils/date.js +6 -5
- package/dist/shared/utils/price.d.ts +1 -1
- package/dist/shared/{hooks/use-scroll-to.d.ts → utils/scrolling.d.ts} +1 -1
- package/dist/shared/utils/scrolling.js +16 -0
- package/dist/shared/utils/uuid.d.ts +2 -1
- package/dist/styles.css +896 -634
- package/dist/table/data-table.d.ts +37 -10
- package/dist/table/data-table.js +72 -17
- package/dist/table/data-table.module.css.js +1 -1
- package/dist/table/elements/switch-sort-direction.d.ts +2 -0
- package/dist/table/elements/switch-sort-direction.js +11 -0
- package/dist/table/elements/table-context.d.ts +6 -5
- package/dist/table/elements/table-context.js +1 -16
- package/dist/table/elements/table-provider.d.ts +6 -5
- package/dist/table/elements/table-provider.js +23 -17
- package/dist/table/elements/table-row-context.d.ts +2 -2
- package/dist/table/elements/table-row-provider.js +4 -4
- package/dist/table/elements/table-sort-button.d.ts +8 -7
- package/dist/table/elements/table-sort-button.js +5 -4
- package/dist/table/elements/table.d.ts +1 -1
- package/dist/table/elements/table.js +2 -2
- package/dist/table/elements/table.module.css.js +1 -1
- package/dist/table/elements/td.d.ts +1 -1
- package/dist/table/elements/th.d.ts +1 -7
- package/dist/table/elements/th.js +2 -3
- package/dist/table/elements/tr.d.ts +2 -8
- package/dist/table/elements/tr.js +1 -3
- package/dist/table/elements/types.d.ts +36 -0
- package/dist/table/elements/use-table.js +1 -3
- package/dist/table/elements/use-td.d.ts +1 -1
- package/dist/table/elements/use-th.d.ts +2 -2
- package/package.json +1 -1
- package/dist/shared/hooks/use-scroll-to.js +0 -19
- package/dist/table/elements/table-column-properties.d.ts +0 -10
- package/dist/table/elements/use-tr.d.ts +0 -2
- package/dist/table/elements/use-tr.js +0 -16
|
@@ -18,7 +18,7 @@ function renderValue(rendering, key, value) {
|
|
|
18
18
|
const renderedValue = rendering?.value
|
|
19
19
|
? rendering.value({ key, value })
|
|
20
20
|
: value !== undefined && value !== null
|
|
21
|
-
?
|
|
21
|
+
? value
|
|
22
22
|
: null;
|
|
23
23
|
if (renderedValue === null ||
|
|
24
24
|
renderedValue === undefined ||
|
|
@@ -16,17 +16,6 @@ function ConnectedCountrySelector({ defaultCountryCode, defaultLanguageCode, onC
|
|
|
16
16
|
const isCountryLanguageSelected = useMemo(() => selectedCountry !== undefined && selectedLanguage !== undefined, [selectedCountry, selectedLanguage]);
|
|
17
17
|
const isDismissable = isCountryLanguageSelected;
|
|
18
18
|
useEffect(() => {
|
|
19
|
-
if (!isFetching) {
|
|
20
|
-
if (selectedCountry === undefined && selectedLanguage === undefined) {
|
|
21
|
-
logger.info('Opening country selector dialog because no country or language is selected');
|
|
22
|
-
}
|
|
23
|
-
else if (selectedCountry === undefined) {
|
|
24
|
-
logger.info('Opening country selector dialog because no country is selected');
|
|
25
|
-
}
|
|
26
|
-
else if (selectedLanguage === undefined) {
|
|
27
|
-
logger.info('Opening country selector dialog because no language is selected');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
19
|
if (isOpen)
|
|
31
20
|
return;
|
|
32
21
|
setIsOpen(!isFetching && !isCountryLanguageSelected);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
3
|
import { config } from '../config.js';
|
|
4
|
-
import { logger } from '../logging/logger.js';
|
|
5
4
|
import { useFetchCountriesWithLanguages } from '../shared/api/storefront/hooks/website/use-fetch-countries-with-languages.js';
|
|
6
5
|
import { updateLocale } from '../shared/api/storefront/services/website-service.js';
|
|
7
6
|
import { useCookie } from '../shared/hooks/use-cookie.js';
|
|
@@ -38,16 +37,6 @@ function useCountriesLanguages({ defaultCountryCode, defaultLanguageCode, }) {
|
|
|
38
37
|
languageId: language.id,
|
|
39
38
|
});
|
|
40
39
|
}
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
logger.info('CountryID from cookie', currentCountryId, countries?.find(country => country.id === currentCountryId)?.name ||
|
|
43
|
-
'Unknown');
|
|
44
|
-
}, [countries, currentCountryId]);
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
logger.info('LanguageID from cookie', currentLanguageId, countries
|
|
47
|
-
?.find(country => country.id === currentCountryId)
|
|
48
|
-
?.languages.find(language => language.id === currentLanguageId)
|
|
49
|
-
?.description || 'Unknown');
|
|
50
|
-
}, [countries, currentCountryId, currentLanguageId]);
|
|
51
40
|
try {
|
|
52
41
|
if (error)
|
|
53
42
|
throw error;
|
|
@@ -3,14 +3,13 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { FormattedMessage } from '../intl/formatted-message.js';
|
|
5
5
|
import { InfoIconTooltip } from '../info-icon-tooltip/info-icon-tooltip.js';
|
|
6
|
+
import { useFormattedDate } from '../intl/use-formatted-date.js';
|
|
6
7
|
import { useFormattedMessage } from '../intl/use-formatted-message.js';
|
|
7
|
-
import { useIntl } from '../intl/use-intl.js';
|
|
8
|
-
import { formatDateToLocaleString } from '../shared/utils/date.js';
|
|
9
8
|
import styles from './delivery-time.module.css.js';
|
|
10
9
|
|
|
11
10
|
function DeliveryTime({ className, deliveryDate }) {
|
|
12
|
-
const { cultureCode } = useIntl();
|
|
13
11
|
const t = useFormattedMessage();
|
|
12
|
+
const formatDate = useFormattedDate();
|
|
14
13
|
if (deliveryDate === undefined)
|
|
15
14
|
return null;
|
|
16
15
|
if (deliveryDate === null) {
|
|
@@ -20,7 +19,7 @@ function DeliveryTime({ className, deliveryDate }) {
|
|
|
20
19
|
__html: t('Availability unknown, please contact customer support for lead time or alternatives.'),
|
|
21
20
|
}, "data-test-selector": "deliveryTime_unknown" }) }));
|
|
22
21
|
}
|
|
23
|
-
const localeDate =
|
|
22
|
+
const localeDate = formatDate(deliveryDate, {
|
|
24
23
|
day: 'numeric',
|
|
25
24
|
month: 'short',
|
|
26
25
|
year: 'numeric',
|
package/dist/exports.d.ts
CHANGED
|
@@ -149,6 +149,7 @@ export * from './header/header-layout/header-layout';
|
|
|
149
149
|
export * from './header/link-list/navigation-link-list';
|
|
150
150
|
export * from './header/sonic-logo/sonic-logo';
|
|
151
151
|
export * from './info-icon-tooltip/info-icon-tooltip';
|
|
152
|
+
export * from './intl/formatted-date';
|
|
152
153
|
export * from './intl/formatted-message';
|
|
153
154
|
export * from './intl/intl-context';
|
|
154
155
|
export * from './intl/intl-provider';
|
|
@@ -158,6 +159,7 @@ export * from './intl/types';
|
|
|
158
159
|
export * from './intl/use-country-code';
|
|
159
160
|
export * from './intl/use-culture-code';
|
|
160
161
|
export * from './intl/use-currency-code';
|
|
162
|
+
export * from './intl/use-formatted-date';
|
|
161
163
|
export * from './intl/use-formatted-message';
|
|
162
164
|
export * from './intl/use-intl';
|
|
163
165
|
export * from './intl/use-language-code';
|
|
@@ -170,11 +172,15 @@ export * from './lists/menu-list/menu-list';
|
|
|
170
172
|
export * from './lists/menu-list/menu-list-back-button';
|
|
171
173
|
export * from './lists/menu-list/menu-list-header';
|
|
172
174
|
export * from './lists/menu-list/menu-list-item';
|
|
175
|
+
export * from './lists/menu-list/menu-list-provider';
|
|
176
|
+
export * from './lists/menu-list/use-menu-list';
|
|
177
|
+
export * from './lists/menu-list/use-menu-list-item';
|
|
173
178
|
export * from './lists/orderline-list/orderline-list';
|
|
174
179
|
export * from './lists/product-overview-grid/product-overview-grid';
|
|
175
180
|
export * from './lists/widget-grid/widget';
|
|
176
181
|
export * from './lists/widget-grid/widget-grid';
|
|
177
182
|
export * from './loading/blank-page-spacer';
|
|
183
|
+
export * from './loading/dynamic-loading-overlay';
|
|
178
184
|
export * from './loading/loading-overlay';
|
|
179
185
|
export * from './loading/progress-circle';
|
|
180
186
|
export * from './logging/logger';
|
|
@@ -255,6 +261,7 @@ export * from './pages/my-sonic/navigation/connected-my-sonic-navigation';
|
|
|
255
261
|
export * from './pages/my-sonic/navigation/my-sonic-desktop-navigation';
|
|
256
262
|
export * from './pages/my-sonic/navigation/my-sonic-mobile-navigation';
|
|
257
263
|
export * from './pages/my-sonic/navigation/my-sonic-navigation-items';
|
|
264
|
+
export * from './pages/my-sonic/pages/order-history/order-history';
|
|
258
265
|
export * from './pages/my-sonic/widgets/components/address-data-card';
|
|
259
266
|
export * from './pages/my-sonic/widgets/connected-bill-to-address-widget';
|
|
260
267
|
export * from './pages/my-sonic/widgets/connected-customer-information-widget';
|
|
@@ -324,6 +331,7 @@ export * from './shared/api/storefront/hooks/customer/use-fetch-fulfillment-meth
|
|
|
324
331
|
export * from './shared/api/storefront/hooks/customer/use-fetch-fulfillment-methods-for-current-cart';
|
|
325
332
|
export * from './shared/api/storefront/hooks/customer/use-fetch-ship-to-addresses';
|
|
326
333
|
export * from './shared/api/storefront/hooks/customer/use-patch-bill-to-address';
|
|
334
|
+
export * from './shared/api/storefront/hooks/orders/use-fetch-orders';
|
|
327
335
|
export * from './shared/api/storefront/hooks/payment/use-create-adyen-session';
|
|
328
336
|
export * from './shared/api/storefront/hooks/payment/use-fetch-adyen-config';
|
|
329
337
|
export * from './shared/api/storefront/hooks/payment/use-invalidate-adyen';
|
|
@@ -345,6 +353,7 @@ export * from './shared/api/storefront/services/authentication-service';
|
|
|
345
353
|
export * from './shared/api/storefront/services/cart-service';
|
|
346
354
|
export * from './shared/api/storefront/services/customer-service';
|
|
347
355
|
export * from './shared/api/storefront/services/finance-service';
|
|
356
|
+
export * from './shared/api/storefront/services/order-service';
|
|
348
357
|
export * from './shared/api/storefront/services/payment-service';
|
|
349
358
|
export * from './shared/api/storefront/services/product-service';
|
|
350
359
|
export * from './shared/api/storefront/services/translation-service';
|
|
@@ -352,6 +361,7 @@ export * from './shared/api/storefront/services/website-service';
|
|
|
352
361
|
export * from './shared/api/storefront/services/wishlist-service';
|
|
353
362
|
export * from './shared/data/cart.data';
|
|
354
363
|
export * from './shared/data/countries-languages.data';
|
|
364
|
+
export * from './shared/data/navigation';
|
|
355
365
|
export * from './shared/feature-flags/use-feature-flags';
|
|
356
366
|
export * from './shared/fetch/request';
|
|
357
367
|
export * from './shared/ga/data-layer';
|
|
@@ -372,7 +382,6 @@ export * from './shared/hooks/use-mutation-observer';
|
|
|
372
382
|
export * from './shared/hooks/use-resize-observer';
|
|
373
383
|
export * from './shared/hooks/use-script';
|
|
374
384
|
export * from './shared/hooks/use-scroll-lock';
|
|
375
|
-
export * from './shared/hooks/use-scroll-to';
|
|
376
385
|
export * from './shared/hooks/use-session-storage';
|
|
377
386
|
export * from './shared/hooks/use-watch-css-property';
|
|
378
387
|
export * from './shared/model/account';
|
|
@@ -411,6 +420,7 @@ export * from './shared/utils/price';
|
|
|
411
420
|
export * from './shared/utils/promise';
|
|
412
421
|
export * from './shared/utils/random';
|
|
413
422
|
export * from './shared/utils/refs';
|
|
423
|
+
export * from './shared/utils/scrolling';
|
|
414
424
|
export * from './shared/utils/string';
|
|
415
425
|
export * from './shared/utils/time';
|
|
416
426
|
export * from './shared/utils/types';
|
|
@@ -422,8 +432,8 @@ export * from './sidebar/types';
|
|
|
422
432
|
export * from './sidebar/use-sidebar';
|
|
423
433
|
export * from './table/data-table';
|
|
424
434
|
export * from './table/elements/col';
|
|
435
|
+
export * from './table/elements/switch-sort-direction';
|
|
425
436
|
export * from './table/elements/table';
|
|
426
|
-
export * from './table/elements/table-column-properties';
|
|
427
437
|
export * from './table/elements/table-context';
|
|
428
438
|
export * from './table/elements/table-provider';
|
|
429
439
|
export * from './table/elements/table-row-context';
|
|
@@ -432,11 +442,11 @@ export * from './table/elements/table-sort-button';
|
|
|
432
442
|
export * from './table/elements/td';
|
|
433
443
|
export * from './table/elements/th';
|
|
434
444
|
export * from './table/elements/tr';
|
|
445
|
+
export * from './table/elements/types';
|
|
435
446
|
export * from './table/elements/use-table';
|
|
436
447
|
export * from './table/elements/use-table-row';
|
|
437
448
|
export * from './table/elements/use-td';
|
|
438
449
|
export * from './table/elements/use-th';
|
|
439
|
-
export * from './table/elements/use-tr';
|
|
440
450
|
export * from './text/highlight-text/highlight-text';
|
|
441
451
|
export * from './text/truncated/truncated';
|
|
442
452
|
export * from './toast/toast';
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { ConnectedCountrySelector } from '../country-selector/connected-country-selector.js';
|
|
4
|
+
import { FormattedMessage } from '../intl/formatted-message.js';
|
|
4
5
|
import { useCultureCode } from '../intl/use-culture-code.js';
|
|
5
6
|
import { useFetchNavigationLinks } from '../shared/api/bff/hooks/use-fetch-navigation-links.js';
|
|
7
|
+
import { isNavigationSection } from '../shared/api/bff/model/bff.model.js';
|
|
6
8
|
import { Footer } from './footer.js';
|
|
7
9
|
|
|
8
10
|
function ConnectedFooter({ className, onCountryLanguageChange, source, }) {
|
|
9
11
|
const cultureCode = useCultureCode();
|
|
10
12
|
const { data } = useFetchNavigationLinks({ cultureCode, source });
|
|
11
|
-
|
|
13
|
+
if (data && data.key !== 'navigation')
|
|
14
|
+
throw new Error('Invalid navigation data');
|
|
15
|
+
const footerNavigationSection = data?.items
|
|
16
|
+
.filter(isNavigationSection)
|
|
17
|
+
.find(item => item.key === 'footer');
|
|
18
|
+
return (jsx(Footer, { className: className, copyright: jsx(FormattedMessage, { id: "Copyright \u00A9 Sonic Equipment B.V." }), countrySelector: jsx(ConnectedCountrySelector, { defaultCountryCode: "NL", defaultLanguageCode: "EN", onChange: onCountryLanguageChange }), footerNavigationSection: footerNavigationSection }));
|
|
12
19
|
}
|
|
13
20
|
|
|
14
21
|
export { ConnectedFooter };
|
package/dist/footer/footer.d.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export interface
|
|
4
|
-
bottomLinks: NavigationLink[];
|
|
2
|
+
import { NavigationSection } from '../shared/api/bff/model/bff.model';
|
|
3
|
+
export interface FooterProps {
|
|
5
4
|
className?: string;
|
|
6
|
-
copyright:
|
|
5
|
+
copyright: ReactNode;
|
|
7
6
|
countrySelector: ReactNode;
|
|
7
|
+
footerNavigationSection: NavigationSection | undefined;
|
|
8
8
|
}
|
|
9
|
-
export
|
|
10
|
-
linkBlocks: NavigationLink[];
|
|
11
|
-
}
|
|
12
|
-
export interface FooterProps extends FooterBottomSectionProps, FooterLinkBlockProps {
|
|
13
|
-
}
|
|
14
|
-
export declare function Footer({ bottomLinks, className, copyright, countrySelector, linkBlocks, }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function Footer({ className, copyright, countrySelector, footerNavigationSection, }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/footer/footer.js
CHANGED
|
@@ -4,33 +4,38 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { Link } from '../buttons/link/link.js';
|
|
5
5
|
import { Accordion } from '../collapsables/accordion/accordion.js';
|
|
6
6
|
import { AccordionItem } from '../collapsables/accordion/accordion-item.js';
|
|
7
|
-
import {
|
|
7
|
+
import { isNavigationSection, isNavigationLinkItem, isNavigationLink } from '../shared/api/bff/model/bff.model.js';
|
|
8
8
|
import { useIsBreakpoint } from '../shared/hooks/use-is-breakpoint.js';
|
|
9
9
|
import styles from './footer.module.css.js';
|
|
10
10
|
|
|
11
|
-
function BottomSection({
|
|
12
|
-
|
|
11
|
+
function BottomSection({ copyright, countrySelector, footerBottomSection, }) {
|
|
12
|
+
if (!footerBottomSection)
|
|
13
|
+
return null;
|
|
14
|
+
const links = footerBottomSection.items.filter(isNavigationLink);
|
|
15
|
+
return (jsxs("section", { className: styles['bottom-section'], children: [copyright && jsx("p", { className: styles.copyright, children: copyright }), footerBottomSection.items.length > 0 && (jsx("ul", { className: styles['bottom-links'], children: links.map(link => (jsx(Link, { className: styles['bottom-link'], href: link.href || undefined, target: link.openInNewTab ? '_blank' : undefined, children: link.label }, link.key))) })), countrySelector && (jsx("div", { className: styles['country-selector'], children: countrySelector }))] }));
|
|
13
16
|
}
|
|
14
|
-
function LinkSection({
|
|
17
|
+
function LinkSection({ linkGroup }) {
|
|
15
18
|
const isXl = useIsBreakpoint('xl');
|
|
16
|
-
return (jsx("section", { className: styles['link-block'], children: jsx(Accordion, { color: "white", hasLineSeparator: false, size: "lg", children: jsx(AccordionItem, { allowCollapse: !isXl, id: `link-block-${
|
|
19
|
+
return (jsx("section", { className: styles['link-block'], children: jsx(Accordion, { color: "white", hasLineSeparator: false, size: "lg", children: jsx(AccordionItem, { allowCollapse: !isXl, id: `link-block-${linkGroup.key}`, initialIsOpen: isXl, title: linkGroup.header || linkGroup.label, children: jsx("ul", { className: styles['list'], children: linkGroup.items.filter(isNavigationLink).map(link => (jsx("li", { children: jsx(FooterLink, { link: link }) }, link.key))) }) }) }) }, linkGroup.key));
|
|
17
20
|
}
|
|
18
21
|
function FooterLink({ link }) {
|
|
19
|
-
|
|
20
|
-
if (type === 'link' || type === 'category') {
|
|
21
|
-
return (jsx(Link, { href: link.url, target: link.openInNewTab ? '_blank' : undefined, children: link.title }));
|
|
22
|
-
}
|
|
23
|
-
if (type === 'section') {
|
|
24
|
-
return jsx(LinkSection, { link: link });
|
|
25
|
-
}
|
|
26
|
-
logger.warn(`Unknown link type '${type}' in footer with key '${link.key}'`);
|
|
27
|
-
return null;
|
|
22
|
+
return (jsx(Link, { href: link.href || undefined, target: link.openInNewTab ? '_blank' : undefined, children: link.label }));
|
|
28
23
|
}
|
|
29
|
-
function FooterLinkBlock({
|
|
30
|
-
|
|
24
|
+
function FooterLinkBlock({ footerLinkBlockSection }) {
|
|
25
|
+
if (!footerLinkBlockSection)
|
|
26
|
+
return null;
|
|
27
|
+
return (jsx("nav", { className: styles['main-links'], children: footerLinkBlockSection.items
|
|
28
|
+
.filter(isNavigationLinkItem)
|
|
29
|
+
.map(linkItem => isNavigationLink(linkItem) ? (jsx(FooterLink, { link: linkItem }, linkItem.key)) : (jsx(LinkSection, { linkGroup: linkItem }, linkItem.key))) }));
|
|
31
30
|
}
|
|
32
|
-
function Footer({
|
|
33
|
-
|
|
31
|
+
function Footer({ className, copyright, countrySelector, footerNavigationSection, }) {
|
|
32
|
+
const footerLinkBlockSection = footerNavigationSection?.items
|
|
33
|
+
.filter(isNavigationSection)
|
|
34
|
+
.find(section => section.key === 'footer-link-block');
|
|
35
|
+
const footerBottomSection = footerNavigationSection?.items
|
|
36
|
+
.filter(isNavigationSection)
|
|
37
|
+
.find(section => section.key === 'footer-bottom');
|
|
38
|
+
return (jsxs("footer", { className: clsx(styles.footer, className), children: [jsx(FooterLinkBlock, { footerLinkBlockSection: footerLinkBlockSection }), jsx(BottomSection, { copyright: copyright, countrySelector: countrySelector, footerBottomSection: footerBottomSection })] }));
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
export { Footer };
|
|
@@ -26,7 +26,7 @@ function SelectField({ className, 'data-test-selector': dataTestSelector, defaul
|
|
|
26
26
|
[styles['loading']]: isLoading,
|
|
27
27
|
}, className), "data-test-selector": dataTestSelector, defaultSelectedKey: defaultSelectedOption === undefined
|
|
28
28
|
? undefined
|
|
29
|
-
: String(defaultSelectedOption), isDisabled: isDisabled, isInvalid: isInvalid, isRequired: isRequired, name: name, onSelectionChange: key => handleChange(key), placeholder: placeholder || label, selectedKey: selectedOption === undefined ? undefined : String(selectedOption), children: jsx(FormFieldLayout, { errorSlot: jsx(FieldError, {}), infoSlot: info && jsx(InfoIconTooltip, { children: info }), labelSlot: showLabel && jsx(Label, { isRequired: isRequired, children: label }), children: jsxs(Fragment, { children: [jsxs(Button, { className: styles.button, children: [jsx(SelectValue, { className: styles.value, "data-test-selector": "value" }), isLoading ? (jsx(ProgressCircle, { "aria-hidden": "true", className: styles.
|
|
29
|
+
: String(defaultSelectedOption), isDisabled: isDisabled, isInvalid: isInvalid, isRequired: isRequired, name: name, onSelectionChange: key => handleChange(key), placeholder: placeholder || label, selectedKey: selectedOption === undefined ? undefined : String(selectedOption), children: jsx(FormFieldLayout, { errorSlot: jsx(FieldError, {}), infoSlot: info && jsx(InfoIconTooltip, { children: info }), labelSlot: showLabel && jsx(Label, { isRequired: isRequired, children: label }), children: jsxs(Fragment, { children: [jsxs(Button, { className: styles.button, children: [jsx(SelectValue, { className: styles.value, "data-test-selector": "value" }), isLoading ? (jsx(ProgressCircle, { "aria-hidden": "true", className: styles.loading, variant: "gray" })) : (jsx(GlyphsChevronsSlimDownIcon, { "aria-hidden": "true", className: styles.icon }))] }), jsx(Popover, { className: clsx(styles.popover, styles[variant]), placement: "bottom left", children: jsx(ListBox, { className: styles.listbox, "data-test-selector": dataTestSelector ? `${dataTestSelector}_options` : undefined, children: jsxs(ListBoxSection, { children: [showPlaceholder && (jsx(Header, { className: styles.header, children: placeholder || label })), Object.entries(options).map(([key, value]) => (jsxs(ListBoxItem, { "aria-label": value, className: styles.item, id: key, textValue: value, children: [selectedKey === key && (jsx("span", { slot: "description", children: jsx(StrokeCheckmarkIcon, { className: styles.check }) })), jsx("span", { slot: "label", children: value })] }, key)))] }) }) })] }) }) }));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export { SelectField };
|
|
@@ -4,7 +4,7 @@ import { useEffect } from 'react';
|
|
|
4
4
|
import { Form as Form$1 } from 'react-aria-components';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { Message } from '../../../message/message.js';
|
|
7
|
-
import { scrollToTop } from '../../../shared/
|
|
7
|
+
import { scrollToTop } from '../../../shared/utils/scrolling.js';
|
|
8
8
|
import styles from './form.module.css.js';
|
|
9
9
|
|
|
10
10
|
function Form({ autoComplete = false, children, className, errorMessage, footer, header, onSubmit, title, validationErrors, }) {
|
|
@@ -2,12 +2,20 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useCultureCode } from '../intl/use-culture-code.js';
|
|
4
4
|
import { useFetchNavigationLinks } from '../shared/api/bff/hooks/use-fetch-navigation-links.js';
|
|
5
|
+
import { isNavigationSection } from '../shared/api/bff/model/bff.model.js';
|
|
5
6
|
import { Header } from './header.js';
|
|
6
7
|
|
|
7
8
|
function ConnectedHeader({ className, source, }) {
|
|
8
9
|
const cultureCode = useCultureCode();
|
|
9
10
|
const { data } = useFetchNavigationLinks({ cultureCode, source });
|
|
10
|
-
|
|
11
|
+
if (data && data.key !== 'navigation')
|
|
12
|
+
throw new Error('Invalid navigation data');
|
|
13
|
+
const headerNavigationSection = data?.items
|
|
14
|
+
.filter(isNavigationSection)
|
|
15
|
+
.find(item => item.key === 'header');
|
|
16
|
+
if (data && !headerNavigationSection)
|
|
17
|
+
throw new Error('Header section not found in navigation data');
|
|
18
|
+
return (jsx(Header, { className: className, headerNavigationSection: headerNavigationSection, sticky: true }));
|
|
11
19
|
}
|
|
12
20
|
|
|
13
21
|
export { ConnectedHeader };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NavigationLinkGroup } from '../../shared/api/bff/model/bff.model';
|
|
2
2
|
export interface DesktopNavigationDrawerProps {
|
|
3
3
|
groupId?: string;
|
|
4
4
|
instanceId?: string;
|
|
5
|
+
linkGroup?: NavigationLinkGroup;
|
|
5
6
|
onClosed?: () => void;
|
|
6
|
-
submenu?: NavigationLink;
|
|
7
7
|
}
|
|
8
|
-
export declare function DesktopNavigationDrawer({ groupId, instanceId,
|
|
8
|
+
export declare function DesktopNavigationDrawer({ groupId, instanceId, linkGroup, onClosed, }: DesktopNavigationDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,10 +4,8 @@ import { Drawer } from '../../drawer/drawer.js';
|
|
|
4
4
|
import { PanelNavigation } from '../../navigation/panel-navigation/panel-navigation.js';
|
|
5
5
|
import styles from './desktop-navigation-drawer.module.css.js';
|
|
6
6
|
|
|
7
|
-
function DesktopNavigationDrawer({ groupId, instanceId,
|
|
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:
|
|
9
|
-
? { href: submenu.url, title: submenu.title }
|
|
10
|
-
: submenu.title, id: `panels-${submenu.key}`, links: submenu.links }, submenu.key)) }));
|
|
7
|
+
function DesktopNavigationDrawer({ groupId, instanceId, linkGroup, onClosed, }) {
|
|
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: linkGroup && (jsx(PanelNavigation, { "data-test-selector": "desktopNavigationPanel", header: linkGroup, id: `panels-${linkGroup.key}`, linkItems: linkGroup.items }, linkGroup.key)) }));
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
export { DesktopNavigationDrawer };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NavigationLinkItem } from '../../shared/api/bff/model/bff.model';
|
|
2
2
|
export interface MobileNavigationDrawerProps {
|
|
3
3
|
groupId?: string;
|
|
4
4
|
instanceId?: string;
|
|
5
|
-
|
|
5
|
+
linkItems: NavigationLinkItem[] | undefined;
|
|
6
6
|
}
|
|
7
|
-
export declare function MobileNavigationDrawer({ groupId, instanceId,
|
|
7
|
+
export declare function MobileNavigationDrawer({ groupId, instanceId, linkItems, }: MobileNavigationDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,8 +4,8 @@ import { Drawer } from '../../drawer/drawer.js';
|
|
|
4
4
|
import { MobileNavigation } from '../../navigation/mobile-navigation/mobile-navigation.js';
|
|
5
5
|
import styles from './mobile-navigation-drawer.module.css.js';
|
|
6
6
|
|
|
7
|
-
function MobileNavigationDrawer({ groupId, instanceId,
|
|
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,
|
|
7
|
+
function MobileNavigationDrawer({ groupId, instanceId, linkItems, }) {
|
|
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, linkItems: linkItems, onActiveChange: close })) }));
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export { MobileNavigationDrawer };
|
package/dist/header/header.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NavigationSection } from '../shared/api/bff/model/bff.model';
|
|
2
2
|
export interface HeaderProps {
|
|
3
3
|
className?: string;
|
|
4
|
-
|
|
4
|
+
headerNavigationSection?: NavigationSection;
|
|
5
5
|
sticky?: boolean;
|
|
6
6
|
}
|
|
7
|
-
export declare function Header({ className,
|
|
7
|
+
export declare function Header({ className, headerNavigationSection, sticky, }: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/header/header.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import { config } from '../config.js';
|
|
6
5
|
import { useDrawer } from '../drawer/use-drawer.js';
|
|
7
6
|
import { useGlobalSearchDisclosure } from '../global-search/global-search-provider/use-search-disclosure.js';
|
|
8
7
|
import { useFormattedMessage } from '../intl/use-formatted-message.js';
|
|
9
8
|
import { PATHS } from '../pages/paths.js';
|
|
9
|
+
import { isNavigationLink, isNavigationSection, isNavigationLinkItem } from '../shared/api/bff/model/bff.model.js';
|
|
10
10
|
import { useIsBreakpoint } from '../shared/hooks/use-is-breakpoint.js';
|
|
11
11
|
import { useResizeObserver } from '../shared/hooks/use-resize-observer.js';
|
|
12
12
|
import { useOnNavigate } from '../shared/routing/use-on-navigate.js';
|
|
@@ -23,8 +23,8 @@ import { NavigationLinkList } from './link-list/navigation-link-list.js';
|
|
|
23
23
|
import { SonicLogo } from './sonic-logo/sonic-logo.js';
|
|
24
24
|
import styles from './header.module.css.js';
|
|
25
25
|
|
|
26
|
-
function Header({ className,
|
|
27
|
-
const [
|
|
26
|
+
function Header({ className, headerNavigationSection, sticky, }) {
|
|
27
|
+
const [activeLinkGroup, setActiveLinkGroup] = useState();
|
|
28
28
|
const t = useFormattedMessage();
|
|
29
29
|
const isXl = useIsBreakpoint('xl');
|
|
30
30
|
const { ref: headerRef } = useResizeObserver((_, size) => {
|
|
@@ -50,11 +50,11 @@ function Header({ className, links, sticky }) {
|
|
|
50
50
|
const toggleMobileNavigation = (isActive) => {
|
|
51
51
|
setMobileNavigationOpen(isActive);
|
|
52
52
|
};
|
|
53
|
-
const toggleActiveSubmenu = (
|
|
54
|
-
if (
|
|
53
|
+
const toggleActiveSubmenu = (linkGroup) => {
|
|
54
|
+
if (linkGroup === activeLinkGroup)
|
|
55
55
|
setDesktopNavigationOpen(false);
|
|
56
56
|
else
|
|
57
|
-
|
|
57
|
+
setActiveLinkGroup(linkGroup);
|
|
58
58
|
};
|
|
59
59
|
const hasDrawersOpen = searchOpen || mobileNavigationOpen || desktopNavigationOpen;
|
|
60
60
|
useOnNavigate(() => {
|
|
@@ -63,10 +63,16 @@ function Header({ className, links, sticky }) {
|
|
|
63
63
|
desktopNavigationDrawer.close();
|
|
64
64
|
});
|
|
65
65
|
useEffect(() => {
|
|
66
|
-
if (
|
|
66
|
+
if (activeLinkGroup)
|
|
67
67
|
setDesktopNavigationOpen(true);
|
|
68
|
-
}, [
|
|
69
|
-
|
|
68
|
+
}, [activeLinkGroup, setDesktopNavigationOpen]);
|
|
69
|
+
const homeLink = headerNavigationSection?.items
|
|
70
|
+
.filter(isNavigationLink)
|
|
71
|
+
.find(item => item.key === 'home');
|
|
72
|
+
const mainNavigationSection = headerNavigationSection?.items
|
|
73
|
+
.filter(isNavigationSection)
|
|
74
|
+
.find(item => item.key === 'main-navigation');
|
|
75
|
+
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: homeLink?.href || undefined, title: t('Home') }), mainNavigation: jsx(NavigationLinkList, { activeLink: activeLinkGroup, "data-test-selector": "pageHeaderMainNavigation", navigationSection: mainNavigationSection, onSubmenuToggle: toggleActiveSubmenu }), 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, linkItems: mainNavigationSection?.items.filter(isNavigationLinkItem) })), isXl && (jsx(DesktopNavigationDrawer, { groupId: desktopNavigationDrawer.groupId, instanceId: desktopNavigationDrawer.instanceId, linkGroup: activeLinkGroup, onClosed: () => setActiveLinkGroup(undefined) }))] }));
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
export { Header };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NavigationLinkGroup, NavigationLinkItem, NavigationSection } from '../../shared/api/bff/model/bff.model';
|
|
2
2
|
export interface LinkListProps {
|
|
3
|
-
activeLink?:
|
|
3
|
+
activeLink?: NavigationLinkItem;
|
|
4
4
|
'data-test-selector'?: string;
|
|
5
|
-
|
|
6
|
-
onSubmenuToggle: (
|
|
5
|
+
navigationSection: NavigationSection | undefined;
|
|
6
|
+
onSubmenuToggle: (linkGroup: NavigationLinkGroup) => void;
|
|
7
7
|
}
|
|
8
|
-
export declare function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector,
|
|
8
|
+
export declare function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector, navigationSection, onSubmenuToggle, }: LinkListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,14 +2,29 @@
|
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { Link } from '../../buttons/link/link.js';
|
|
4
4
|
import { GlyphsChevronsBoldDownIcon } from '../../icons/glyph/glyphs-chevrons-bold-down-icon.js';
|
|
5
|
+
import { logger } from '../../logging/logger.js';
|
|
6
|
+
import { isNavigationLinkGroup, isNavigationLink } from '../../shared/api/bff/model/bff.model.js';
|
|
5
7
|
import styles from './navigation-link-list.module.css.js';
|
|
6
8
|
|
|
7
|
-
function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
function NavigationLinkList({ activeLink, 'data-test-selector': dataTestSelector, navigationSection, onSubmenuToggle, }) {
|
|
10
|
+
const items = navigationSection?.items ?? [];
|
|
11
|
+
return (jsx("ul", { className: styles['navigation-link-list'], "data-test-selector": dataTestSelector, children: items.map(item => {
|
|
12
|
+
if (isNavigationLinkGroup(item)) {
|
|
13
|
+
if (item.items.length > 0) {
|
|
14
|
+
return (jsx("li", { className: activeLink === item ? styles['active'] : undefined, children: jsxs(Link, { "aria-controls": `panels-${item.key}`, "aria-expanded": activeLink === item, className: styles.link, "data-test-selector": `navigationLink-${item.key}`, onClick: () => onSubmenuToggle(item), target: item.openInNewTab ? '_blank' : undefined, children: [item.label, jsx(GlyphsChevronsBoldDownIcon, { className: styles.chevron, role: "presentation" })] }) }, item.key));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
logger.warn(`Link-group has no items: ${JSON.stringify(item, null, 2)}`);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (isNavigationLink(item)) {
|
|
22
|
+
return (jsx("li", { children: jsx(Link, { className: styles.link, href: item.href, children: item.label }) }, item.key));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
logger.warn(`Unsupported link type: ${JSON.stringify(item, null, 2)}`);
|
|
26
|
+
return null;
|
|
11
27
|
}
|
|
12
|
-
return (jsx("li", { children: jsx(Link, { className: styles.link, href: link.url, children: link.title }) }, link.key));
|
|
13
28
|
}) }));
|
|
14
29
|
}
|
|
15
30
|
|