@sonic-equipment/ui 163.0.0 → 165.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/algolia/algolia-categories-filters.js +9 -7
  2. package/dist/background-overlay/background-overlay-manager.d.ts +178 -0
  3. package/dist/background-overlay/background-overlay-manager.js +291 -0
  4. package/dist/background-overlay/background-overlay.d.ts +12 -2
  5. package/dist/background-overlay/background-overlay.js +28 -27
  6. package/dist/badges/badge/badge.d.ts +2 -1
  7. package/dist/badges/badge/badge.js +2 -2
  8. package/dist/badges/badge/icon-with-badge/icon-with-badge.d.ts +2 -1
  9. package/dist/badges/badge/icon-with-badge/icon-with-badge.js +2 -2
  10. package/dist/cards/orderline-card/orderline-card.js +5 -1
  11. package/dist/cards/product-card/product-card.js +5 -1
  12. package/dist/collapsables/cascading-component/cascading-component.d.ts +6 -2
  13. package/dist/collapsables/cascading-component/cascading-component.js +5 -5
  14. package/dist/collapsables/unmounter/unmounter.js +2 -2
  15. package/dist/country-select/country-select.js +1 -1
  16. package/dist/country-selector/connected-country-selector.js +20 -2
  17. package/dist/country-selector/country-selector-dialog/country-selector-dialog.js +1 -1
  18. package/dist/country-selector/use-countries-languages.d.ts +17 -1
  19. package/dist/country-selector/use-countries-languages.js +58 -29
  20. package/dist/delivery-time/delivery-time.d.ts +1 -1
  21. package/dist/delivery-time/delivery-time.js +20 -8
  22. package/dist/delivery-time/delivery-time.module.css.js +1 -1
  23. package/dist/drawer/drawer.d.ts +26 -0
  24. package/dist/drawer/drawer.js +37 -0
  25. package/dist/drawer/drawer.module.css.js +3 -0
  26. package/dist/drawer/use-drawer.d.ts +17 -0
  27. package/dist/drawer/use-drawer.js +71 -0
  28. package/dist/exports.d.ts +12 -0
  29. package/dist/global-search/global-search-provider/global-search-provider.js +1 -2
  30. package/dist/global-search/global-search.module.css.js +1 -1
  31. package/dist/header/cart-icon/connected-cart-icon.js +4 -4
  32. package/dist/icons/solid/solid-login-icon.js +7 -0
  33. package/dist/index.js +13 -1
  34. package/dist/intl/translation-id.d.ts +1 -1
  35. package/dist/layout/center.d.ts +5 -0
  36. package/dist/layout/center.js +9 -0
  37. package/dist/layout/center.module.css.js +3 -0
  38. package/dist/lists/menu-list/menu-list.d.ts +4 -2
  39. package/dist/lists/menu-list/menu-list.js +2 -2
  40. package/dist/lists/menu-list/menu-list.module.css.js +1 -1
  41. package/dist/lists/orderline-list/orderline-list.js +1 -2
  42. package/dist/navigation/account-icon/account-icon.d.ts +5 -0
  43. package/dist/navigation/account-icon/account-icon.js +12 -0
  44. package/dist/navigation/cart-icon/cart-icon.d.ts +5 -0
  45. package/dist/navigation/cart-icon/cart-icon.js +12 -0
  46. package/dist/navigation/favorite-icon/favorite-icon.d.ts +5 -0
  47. package/dist/navigation/favorite-icon/favorite-icon.js +12 -0
  48. package/dist/navigation/mobile-navigation/mobile-navigation.d.ts +5 -0
  49. package/dist/navigation/mobile-navigation/mobile-navigation.js +20 -0
  50. package/dist/navigation/panel-navigation/panel-navigation.d.ts +28 -0
  51. package/dist/navigation/panel-navigation/panel-navigation.js +69 -0
  52. package/dist/navigation/panel-navigation/panel-navigation.module.css.js +3 -0
  53. package/dist/pages/checkout/payment-page/components/payment.js +9 -9
  54. package/dist/pages/paths.d.ts +1 -0
  55. package/dist/pages/paths.js +1 -0
  56. package/dist/shared/hooks/use-global-disclosure.d.ts +10 -0
  57. package/dist/shared/hooks/use-global-disclosure.js +25 -0
  58. package/dist/shared/hooks/use-watch-css-property.d.ts +1 -1
  59. package/dist/shared/hooks/use-watch-css-property.js +2 -3
  60. package/dist/shared/model/category.d.ts +5 -0
  61. package/dist/shared/model/category.js +7 -1
  62. package/dist/shared/model/price.d.ts +2 -2
  63. package/dist/shared/utils/css.d.ts +1 -0
  64. package/dist/shared/utils/css.js +13 -0
  65. package/dist/shared/utils/date.d.ts +1 -12
  66. package/dist/shared/utils/date.js +8 -64
  67. package/dist/shared/utils/refs.d.ts +2 -0
  68. package/dist/shared/utils/refs.js +14 -0
  69. package/dist/sidebar/sidebar-provider.js +1 -1
  70. package/dist/styles.css +278 -66
  71. package/package.json +1 -1
  72. package/dist/background-overlay/background-overlay.module.css.js +0 -3
  73. package/dist/shared/utils/date.test.d.ts +0 -1
@@ -6,24 +6,26 @@ import clsx from 'clsx';
6
6
  import { Link } from '../buttons/link/link.js';
7
7
  import { StrokeCategoriesIcon } from '../icons/stroke/stroke-categories-icon.js';
8
8
  import { useFormattedMessage } from '../intl/use-formatted-message.js';
9
+ import { transformAlgoliaCategoryData } from '../shared/model/category.js';
9
10
  import { FilterSection } from './filter-section.js';
10
11
  import styles from './algolia-filter-panel.module.css.js';
11
12
  import filterSectionStyles from './filter-section.module.css.js';
12
13
 
13
14
  function AlgoliaCategoriesFilters() {
14
- const { items: categories, refine } = useHierarchicalMenu({
15
+ const { items, refine } = useHierarchicalMenu({
15
16
  attributes: [
16
- 'hierarchicalCategories.lvl0',
17
- 'hierarchicalCategories.lvl1',
18
- 'hierarchicalCategories.lvl2',
17
+ 'hierarchicalStorefrontCategories.lvl0',
18
+ 'hierarchicalStorefrontCategories.lvl1',
19
+ 'hierarchicalStorefrontCategories.lvl2',
19
20
  ],
20
21
  });
21
22
  const t = useFormattedMessage();
22
- if (categories.length <= 0)
23
+ if (items.length <= 0)
23
24
  return null;
24
- return (jsx(FilterSection, { title: t('facet.categories'), variant: "default", children: categories.map(category => (jsx(Fragment, { children: jsx("div", { className: filterSectionStyles['filter-section-item'], children: jsxs(Link, { hasUnderline: true, className: clsx(styles.category, {
25
+ const categories = transformAlgoliaCategoryData(items);
26
+ return (jsx(FilterSection, { title: t('facet.categories'), variant: "default", children: categories.map((category, index) => (jsx(Fragment, { children: jsx("div", { className: filterSectionStyles['filter-section-item'], children: jsxs(Link, { hasUnderline: true, className: clsx(styles.category, {
25
27
  [styles['is-active']]: category.isRefined,
26
- }), color: "primary", onClick: () => refine(category.value), children: [jsx(StrokeCategoriesIcon, { height: 24, width: 24 }), jsx("span", { children: category.label }), jsxs("span", { className: styles.count, children: ["(", category.count, ")"] })] }) }) }, category.value))) }));
28
+ }), color: "primary", onClick: () => refine(category.value), children: [jsx(StrokeCategoriesIcon, { height: 24, width: 24 }), jsx("span", { children: category.name }), jsxs("span", { className: styles.count, children: ["(", category.count, ")"] })] }) }) }, category.href || index))) }));
27
29
  }
28
30
 
29
31
  export { AlgoliaCategoriesFilters };
@@ -0,0 +1,178 @@
1
+ /**
2
+ * BackgroundOverlayManager is a singleton class that manages the background overlay elements.
3
+ * It creates, updates, and removes the background overlay elements as needed.
4
+ */
5
+ export declare class BackgroundOverlayManager {
6
+ private static _element;
7
+ private static _overlayZIndexes;
8
+ private static _overlayQueue;
9
+ /**
10
+ * Gets the z-index from a css variable using a given overlay name.
11
+ * @private
12
+ * @param overlayName - The name of the overlay.
13
+ * @returns The z-index of the overlay.
14
+ */
15
+ private static _getZIndexByOverlayName;
16
+ /**
17
+ * Gets, or creates, the background DOM element to use as the dim layer.
18
+ * When the element is created, it is appended to the document body.
19
+ * The element is also given an ID and a class name.
20
+ * @private
21
+ * @returns The background DOM element.
22
+ */
23
+ private static _getElement;
24
+ /**
25
+ * Removes the background DOM element visually by removing the 'visible' class.
26
+ * @private
27
+ */
28
+ private static _removeElement;
29
+ /**
30
+ * Gets the current, visual, most in front, overlay entry from the overlay queue.
31
+ * @private
32
+ * @returns The current overlay entry.
33
+ */
34
+ private static get _currentOverlayEntry();
35
+ /**
36
+ * Get the overlay entry by instance ID.
37
+ * @private
38
+ * @param instanceId - The instance ID of the overlay entry.
39
+ * @returns The overlay entry.
40
+ */
41
+ private static _getOverlayEntryByInstanceId;
42
+ /**
43
+ * Removes the overlay entry by instance ID from the overlay queue.
44
+ * This method also calls the onClose function of the entry if it exists.
45
+ * @private
46
+ * @param instanceId - The instance ID of the overlay entry.
47
+ * @returns Void
48
+ */
49
+ private static _removeOverlayEntry;
50
+ /**
51
+ * Rerenders the background overlay element.
52
+ * This method updates the z-index of the element and adds the 'visible' class.
53
+ * If there is no current overlay entry, it removes the element.
54
+ * @private
55
+ * @returns Void
56
+ */
57
+ private static _rerender;
58
+ /**
59
+ * Handles the click event on the background overlay element.
60
+ * This method stops the event from propagating and prevents the default action.
61
+ * It also calls the onClick function of the current overlay entry if it exists.
62
+ * @private
63
+ * @param e - The mouse event.
64
+ * @returns Void
65
+ */
66
+ private static _onClick;
67
+ /**
68
+ * Mounts an overlay instance.
69
+ * This method creates a new overlay entry in the overlay queue.
70
+ * It also sets the z-index and timestamp of the entry.
71
+ * @public
72
+ * @param instanceId - The instance ID of the overlay entry.
73
+ * @param isVisible - A boolean indicating whether the overlay is visible or not.
74
+ * @param onClick - A function to call when the overlay is clicked.
75
+ * @param onClose - A function to call when the overlay is closed.
76
+ * @param overlayName - The name of the overlay.
77
+ * @returns Void
78
+ */
79
+ static mountInstance({ instanceId, isVisible, onClick, onClose, overlayName, }: {
80
+ instanceId: string;
81
+ isVisible: boolean;
82
+ onClick: VoidFunction | undefined;
83
+ onClose: VoidFunction | undefined;
84
+ overlayName: string;
85
+ }): void;
86
+ /**
87
+ * Unmounts an overlay instance.
88
+ * This method removes the overlay entry from the overlay queue.
89
+ * @public
90
+ * @param instanceId - The instance ID of the overlay entry.
91
+ * @returns Void
92
+ */
93
+ static unmountInstance(instanceId: string): void;
94
+ /**
95
+ * Updates an overlay instance.
96
+ * This method updates the properties of the overlay entry in the overlay queue.
97
+ * It also sets the z-index of the entry.
98
+ * @public
99
+ * @param instanceId - The instance ID of the overlay entry.
100
+ * @param isVisible - A boolean indicating whether the overlay is visible or not.
101
+ * @param onClick - A function to call when the overlay is clicked.
102
+ * @param onClose - A function to call when the overlay is closed.
103
+ * @param overlayName - The name of the overlay.
104
+ * @returns Void
105
+ */
106
+ static updateInstance({ instanceId, isVisible, onClick, onClose, overlayName, }: {
107
+ instanceId: string;
108
+ isVisible: boolean;
109
+ onClick: VoidFunction | undefined;
110
+ onClose: VoidFunction | undefined;
111
+ overlayName: string;
112
+ }): void;
113
+ /**
114
+ * Shows or hides the overlay.
115
+ * This method updates the visibility of the overlay entry in the overlay queue.
116
+ * @public
117
+ * @param instanceId - The instance ID of the overlay entry.
118
+ * @param isOpen - A boolean indicating whether to show or hide the overlay.
119
+ * @returns Void
120
+ */
121
+ static showOverlay({ instanceId, isOpen, }: {
122
+ instanceId: string;
123
+ isOpen: boolean;
124
+ }): void;
125
+ /**
126
+ * Creates a new background overlay instance.
127
+ * This method returns a new instance of the BackgroundOverlay class.
128
+ * @public
129
+ * @returns A new instance of the BackgroundOverlay class.
130
+ */
131
+ static createBackgroundOverlay(): BackgroundOverlay;
132
+ }
133
+ /**
134
+ * BackgroundOverlay is a class that represents a single background overlay.
135
+ * It is used to create and manage the background overlay elements.
136
+ * It is a wrapper around the BackgroundOverlayManager class.
137
+ */
138
+ declare class BackgroundOverlay {
139
+ /**
140
+ * The ID of the overlay instance.
141
+ * This is a unique identifier for the overlay instance.
142
+ * @private
143
+ * @default A unique UUID string.
144
+ */
145
+ private _instanceId;
146
+ /**
147
+ * A boolean indicating whether the overlay instance is mounted.
148
+ * This is used to determine whether to create or update the overlay instance.
149
+ * @private
150
+ * @default false
151
+ */
152
+ private _isMounted;
153
+ /**
154
+ * Mounts or updates the overlay instance.
155
+ * This method creates or updates the overlay instance with the given properties.
156
+ * @returns Void
157
+ */
158
+ mountOrUpdate({ isVisible, onClick, onClose, overlayName, }: {
159
+ isVisible?: boolean;
160
+ onClick?: VoidFunction;
161
+ onClose?: VoidFunction;
162
+ overlayName: string;
163
+ }): void;
164
+ /**
165
+ * Unmounts the overlay instance.
166
+ * This method removes the overlay instance visually and from the overlay queue
167
+ * @returns Void
168
+ */
169
+ unmount(): void;
170
+ /**
171
+ * Shows or hides the overlay.
172
+ * This method updates the visibility of the overlay instance.
173
+ * @param isOpen - A boolean indicating whether to show or hide the overlay.
174
+ * @returns Void
175
+ */
176
+ show(isOpen: boolean): void;
177
+ }
178
+ export {};
@@ -0,0 +1,291 @@
1
+ import { getCssPropertyValue } from '../shared/utils/css.js';
2
+ import { createUUID } from '../shared/utils/uuid.js';
3
+
4
+ /**
5
+ * BackgroundOverlayManager is a singleton class that manages the background overlay elements.
6
+ * It creates, updates, and removes the background overlay elements as needed.
7
+ */
8
+ class BackgroundOverlayManager {
9
+ /**
10
+ * Gets the z-index from a css variable using a given overlay name.
11
+ * @private
12
+ * @param overlayName - The name of the overlay.
13
+ * @returns The z-index of the overlay.
14
+ */
15
+ static _getZIndexByOverlayName(overlayName) {
16
+ if (BackgroundOverlayManager._overlayZIndexes[overlayName])
17
+ return BackgroundOverlayManager._overlayZIndexes[overlayName];
18
+ const zIndex = Number.parseFloat(String(getCssPropertyValue(`--background-overlay-${overlayName}`)));
19
+ if (Number.isNaN(zIndex))
20
+ throw new Error(`Unable to determine z-index for CSS property: --background-overlay-${overlayName}`);
21
+ return (BackgroundOverlayManager._overlayZIndexes[overlayName] = zIndex);
22
+ }
23
+ /**
24
+ * Gets, or creates, the background DOM element to use as the dim layer.
25
+ * When the element is created, it is appended to the document body.
26
+ * The element is also given an ID and a class name.
27
+ * @private
28
+ * @returns The background DOM element.
29
+ */
30
+ static _getElement() {
31
+ if (BackgroundOverlayManager._element)
32
+ return BackgroundOverlayManager._element;
33
+ if (!document)
34
+ throw new Error('Not running in browser? document is not defined.');
35
+ const element = (BackgroundOverlayManager._element =
36
+ document.createElement('div'));
37
+ element.id = 'background-overlay';
38
+ element.classList.add('background-overlay');
39
+ element.addEventListener('click', BackgroundOverlayManager._onClick);
40
+ document.body.append(element);
41
+ return element;
42
+ }
43
+ /**
44
+ * Removes the background DOM element visually by removing the 'visible' class.
45
+ * @private
46
+ */
47
+ static _removeElement() {
48
+ BackgroundOverlayManager._element?.classList.remove('visible');
49
+ }
50
+ /**
51
+ * Gets the current, visual, most in front, overlay entry from the overlay queue.
52
+ * @private
53
+ * @returns The current overlay entry.
54
+ */
55
+ static get _currentOverlayEntry() {
56
+ return BackgroundOverlayManager._overlayQueue
57
+ .sort((a, b) => b.zIndex - a.zIndex || b.timestamp - a.timestamp)
58
+ .find(entry => entry.isVisible);
59
+ }
60
+ /**
61
+ * Get the overlay entry by instance ID.
62
+ * @private
63
+ * @param instanceId - The instance ID of the overlay entry.
64
+ * @returns The overlay entry.
65
+ */
66
+ static _getOverlayEntryByInstanceId(instanceId) {
67
+ return BackgroundOverlayManager._overlayQueue.find(entry => entry.instanceId === instanceId);
68
+ }
69
+ /**
70
+ * Removes the overlay entry by instance ID from the overlay queue.
71
+ * This method also calls the onClose function of the entry if it exists.
72
+ * @private
73
+ * @param instanceId - The instance ID of the overlay entry.
74
+ * @returns Void
75
+ */
76
+ static _removeOverlayEntry(instanceId) {
77
+ const entry = BackgroundOverlayManager._getOverlayEntryByInstanceId(instanceId);
78
+ entry?.onClose?.();
79
+ BackgroundOverlayManager._overlayQueue =
80
+ BackgroundOverlayManager._overlayQueue.filter(entry => entry.instanceId !== instanceId);
81
+ BackgroundOverlayManager._rerender();
82
+ }
83
+ /**
84
+ * Rerenders the background overlay element.
85
+ * This method updates the z-index of the element and adds the 'visible' class.
86
+ * If there is no current overlay entry, it removes the element.
87
+ * @private
88
+ * @returns Void
89
+ */
90
+ static _rerender() {
91
+ const currentOverlayZindex = BackgroundOverlayManager._currentOverlayEntry?.zIndex;
92
+ if (currentOverlayZindex === undefined)
93
+ return this._removeElement();
94
+ BackgroundOverlayManager._getElement().style.zIndex =
95
+ String(currentOverlayZindex);
96
+ BackgroundOverlayManager._getElement().classList.add('visible');
97
+ }
98
+ /**
99
+ * Mounts an overlay instance.
100
+ * This method creates a new overlay entry in the overlay queue.
101
+ * It also sets the z-index and timestamp of the entry.
102
+ * @public
103
+ * @param instanceId - The instance ID of the overlay entry.
104
+ * @param isVisible - A boolean indicating whether the overlay is visible or not.
105
+ * @param onClick - A function to call when the overlay is clicked.
106
+ * @param onClose - A function to call when the overlay is closed.
107
+ * @param overlayName - The name of the overlay.
108
+ * @returns Void
109
+ */
110
+ static mountInstance({ instanceId, isVisible, onClick, onClose, overlayName, }) {
111
+ const zIndex = BackgroundOverlayManager._getZIndexByOverlayName(overlayName);
112
+ const timestamp = Date.now();
113
+ BackgroundOverlayManager._overlayQueue.push({
114
+ instanceId,
115
+ isVisible,
116
+ onClick,
117
+ onClose,
118
+ timestamp,
119
+ zIndex,
120
+ });
121
+ BackgroundOverlayManager._rerender();
122
+ }
123
+ /**
124
+ * Unmounts an overlay instance.
125
+ * This method removes the overlay entry from the overlay queue.
126
+ * @public
127
+ * @param instanceId - The instance ID of the overlay entry.
128
+ * @returns Void
129
+ */
130
+ static unmountInstance(instanceId) {
131
+ BackgroundOverlayManager._removeOverlayEntry(instanceId);
132
+ }
133
+ /**
134
+ * Updates an overlay instance.
135
+ * This method updates the properties of the overlay entry in the overlay queue.
136
+ * It also sets the z-index of the entry.
137
+ * @public
138
+ * @param instanceId - The instance ID of the overlay entry.
139
+ * @param isVisible - A boolean indicating whether the overlay is visible or not.
140
+ * @param onClick - A function to call when the overlay is clicked.
141
+ * @param onClose - A function to call when the overlay is closed.
142
+ * @param overlayName - The name of the overlay.
143
+ * @returns Void
144
+ */
145
+ static updateInstance({ instanceId, isVisible, onClick, onClose, overlayName, }) {
146
+ const zIndex = BackgroundOverlayManager._getZIndexByOverlayName(overlayName);
147
+ const instance = BackgroundOverlayManager._getOverlayEntryByInstanceId(instanceId);
148
+ if (!instance)
149
+ return;
150
+ instance.isVisible = isVisible;
151
+ instance.onClick = onClick;
152
+ instance.onClose = onClose;
153
+ instance.zIndex = zIndex;
154
+ BackgroundOverlayManager._rerender();
155
+ }
156
+ /**
157
+ * Shows or hides the overlay.
158
+ * This method updates the visibility of the overlay entry in the overlay queue.
159
+ * @public
160
+ * @param instanceId - The instance ID of the overlay entry.
161
+ * @param isOpen - A boolean indicating whether to show or hide the overlay.
162
+ * @returns Void
163
+ */
164
+ static showOverlay({ instanceId, isOpen, }) {
165
+ const entry = BackgroundOverlayManager._getOverlayEntryByInstanceId(instanceId);
166
+ if (!entry)
167
+ return;
168
+ entry.isVisible = isOpen;
169
+ BackgroundOverlayManager._rerender();
170
+ }
171
+ /**
172
+ * Creates a new background overlay instance.
173
+ * This method returns a new instance of the BackgroundOverlay class.
174
+ * @public
175
+ * @returns A new instance of the BackgroundOverlay class.
176
+ */
177
+ static createBackgroundOverlay() {
178
+ return new BackgroundOverlay();
179
+ }
180
+ }
181
+ Object.defineProperty(BackgroundOverlayManager, "_element", {
182
+ enumerable: true,
183
+ configurable: true,
184
+ writable: true,
185
+ value: null
186
+ });
187
+ Object.defineProperty(BackgroundOverlayManager, "_overlayZIndexes", {
188
+ enumerable: true,
189
+ configurable: true,
190
+ writable: true,
191
+ value: {}
192
+ });
193
+ Object.defineProperty(BackgroundOverlayManager, "_overlayQueue", {
194
+ enumerable: true,
195
+ configurable: true,
196
+ writable: true,
197
+ value: []
198
+ });
199
+ /**
200
+ * Handles the click event on the background overlay element.
201
+ * This method stops the event from propagating and prevents the default action.
202
+ * It also calls the onClick function of the current overlay entry if it exists.
203
+ * @private
204
+ * @param e - The mouse event.
205
+ * @returns Void
206
+ */
207
+ Object.defineProperty(BackgroundOverlayManager, "_onClick", {
208
+ enumerable: true,
209
+ configurable: true,
210
+ writable: true,
211
+ value: (e) => {
212
+ e.stopPropagation();
213
+ e.preventDefault();
214
+ const currentOverlayEntry = BackgroundOverlayManager._currentOverlayEntry;
215
+ if (!currentOverlayEntry)
216
+ return;
217
+ return currentOverlayEntry.onClick?.();
218
+ }
219
+ });
220
+ /**
221
+ * BackgroundOverlay is a class that represents a single background overlay.
222
+ * It is used to create and manage the background overlay elements.
223
+ * It is a wrapper around the BackgroundOverlayManager class.
224
+ */
225
+ class BackgroundOverlay {
226
+ constructor() {
227
+ /**
228
+ * The ID of the overlay instance.
229
+ * This is a unique identifier for the overlay instance.
230
+ * @private
231
+ * @default A unique UUID string.
232
+ */
233
+ Object.defineProperty(this, "_instanceId", {
234
+ enumerable: true,
235
+ configurable: true,
236
+ writable: true,
237
+ value: createUUID()
238
+ });
239
+ /**
240
+ * A boolean indicating whether the overlay instance is mounted.
241
+ * This is used to determine whether to create or update the overlay instance.
242
+ * @private
243
+ * @default false
244
+ */
245
+ Object.defineProperty(this, "_isMounted", {
246
+ enumerable: true,
247
+ configurable: true,
248
+ writable: true,
249
+ value: false
250
+ });
251
+ }
252
+ /**
253
+ * Mounts or updates the overlay instance.
254
+ * This method creates or updates the overlay instance with the given properties.
255
+ * @returns Void
256
+ */
257
+ mountOrUpdate({ isVisible = false, onClick, onClose, overlayName, }) {
258
+ (this._isMounted
259
+ ? BackgroundOverlayManager.updateInstance
260
+ : BackgroundOverlayManager.mountInstance)({
261
+ instanceId: this._instanceId,
262
+ isVisible,
263
+ onClick,
264
+ onClose,
265
+ overlayName,
266
+ });
267
+ this._isMounted = true;
268
+ }
269
+ /**
270
+ * Unmounts the overlay instance.
271
+ * This method removes the overlay instance visually and from the overlay queue
272
+ * @returns Void
273
+ */
274
+ unmount() {
275
+ BackgroundOverlayManager.unmountInstance(this._instanceId);
276
+ }
277
+ /**
278
+ * Shows or hides the overlay.
279
+ * This method updates the visibility of the overlay instance.
280
+ * @param isOpen - A boolean indicating whether to show or hide the overlay.
281
+ * @returns Void
282
+ */
283
+ show(isOpen) {
284
+ BackgroundOverlayManager.showOverlay({
285
+ instanceId: this._instanceId,
286
+ isOpen,
287
+ });
288
+ }
289
+ }
290
+
291
+ export { BackgroundOverlayManager };
@@ -1,7 +1,17 @@
1
+ import './background-overlay.module.css';
2
+ type Position = 'in-front' | 'behind-header';
1
3
  interface BackgroundOverlayProps {
2
- className?: string;
4
+ /** Whether the overlay is open or not. */
3
5
  isOpen: boolean;
6
+ /** Function to call when the overlay is clicked. */
7
+ onClick?: VoidFunction;
8
+ /** Function to call when the overlay is closed. */
4
9
  onClose?: VoidFunction;
10
+ /** Position of the overlay. Can be 'in-front' or 'behind-header' */
11
+ position?: Position;
5
12
  }
6
- export declare function BackgroundOverlay({ className, isOpen, onClose, }: BackgroundOverlayProps): React.ReactPortal | null;
13
+ /**
14
+ * BackgroundOverlay is a component that renders a "virtual" background overlay.
15
+ */
16
+ export declare function BackgroundOverlay({ isOpen, onClick, onClose, position, }: BackgroundOverlayProps): null;
7
17
  export {};
@@ -1,33 +1,34 @@
1
1
  "use client";
2
- import { jsx } from 'react/jsx-runtime';
3
- import { useRef, useEffect } from 'react';
4
- import ReactDOM from 'react-dom';
5
- import clsx from 'clsx';
6
- import styles from './background-overlay.module.css.js';
2
+ import { useMemo, useEffect } from 'react';
3
+ import { BackgroundOverlayManager } from './background-overlay-manager.js';
7
4
 
8
- function BackgroundOverlay({ className, isOpen, onClose, }) {
9
- const nodeRef = useRef(null);
5
+ /**
6
+ * BackgroundOverlay is a component that renders a "virtual" background overlay.
7
+ */
8
+ function BackgroundOverlay({ isOpen, onClick, onClose, position = 'in-front', }) {
9
+ /**
10
+ * An instance of the BackgroundOverlay class is
11
+ * created using the BackgroundOverlayManager.
12
+ */
13
+ const backgroundOverlay = useMemo(() => BackgroundOverlayManager.createBackgroundOverlay(), []);
10
14
  useEffect(() => {
11
- const node = nodeRef.current;
12
- if (!node || isOpen)
13
- return;
14
- const handleAnimationEnd = () => {
15
- node.removeEventListener('animationend', handleAnimationEnd);
16
- };
17
- node.addEventListener('animationend', handleAnimationEnd);
18
- return () => {
19
- node.removeEventListener('animationend', handleAnimationEnd);
20
- };
21
- }, [isOpen]);
22
- if (typeof document === 'undefined')
23
- return null;
24
- return ReactDOM.createPortal(jsx("div", { ref: nodeRef, className: clsx(styles['background-overlay'], {
25
- [styles['open']]: isOpen,
26
- [styles['close']]: !isOpen,
27
- }, className), onClick: onClose, onKeyUp: event => {
28
- if (event.key === 'Escape')
29
- onClose?.();
30
- }, role: "none" }), document.body);
15
+ /* Mount or update the background overlay instance */
16
+ backgroundOverlay.mountOrUpdate({
17
+ isVisible: isOpen,
18
+ onClick,
19
+ onClose,
20
+ overlayName: position,
21
+ });
22
+ }, [backgroundOverlay, isOpen, onClick, onClose, position]);
23
+ useEffect(() => {
24
+ /* Show or hide the background overlay */
25
+ backgroundOverlay.show(isOpen);
26
+ }, [backgroundOverlay, isOpen]);
27
+ useEffect(() => {
28
+ /* Unmount the background overlay instance */
29
+ return () => backgroundOverlay.unmount();
30
+ }, [backgroundOverlay]);
31
+ return null;
31
32
  }
32
33
 
33
34
  export { BackgroundOverlay };
@@ -1,5 +1,6 @@
1
1
  export interface BadgeProps {
2
+ 'aria-label'?: string;
2
3
  count?: number;
3
4
  variant?: 'red' | 'orange' | 'green';
4
5
  }
5
- export declare function Badge({ count, variant }: BadgeProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function Badge({ 'aria-label': ariaLabel, count, variant, }: BadgeProps): import("react/jsx-runtime").JSX.Element;
@@ -5,12 +5,12 @@ import clsx from 'clsx';
5
5
  import styles from './badge.module.css.js';
6
6
 
7
7
  const ANIMATION_DURATION = 600;
8
- function Badge({ count, variant = 'red' }) {
8
+ function Badge({ 'aria-label': ariaLabel, count, variant = 'red', }) {
9
9
  const lastCount = useRef(null);
10
10
  useEffect(() => {
11
11
  lastCount.current = count;
12
12
  }, [count]);
13
- return (jsx("span", { className: clsx(styles.badge, styles[variant], {
13
+ return (jsx("span", { "aria-label": ariaLabel, className: clsx(styles.badge, styles[variant], {
14
14
  [styles['is-animating']]: count !== undefined && count !== lastCount.current,
15
15
  }), style: { '--animation-duration': `${ANIMATION_DURATION}ms` }, children: count !== undefined && jsx("span", { className: styles.count, children: count }) }, count));
16
16
  }
@@ -1,7 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  export interface IconWithBadgeProps {
3
+ 'aria-label'?: string;
3
4
  badge: ReactNode;
4
5
  'data-test-selector'?: string;
5
6
  icon: ReactNode;
6
7
  }
7
- export declare function IconWithBadge({ badge, 'data-test-selector': dataTestSelector, icon, }: IconWithBadgeProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function IconWithBadge({ 'aria-label': ariaLabel, badge, 'data-test-selector': dataTestSelector, icon, }: IconWithBadgeProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import styles from './icon-with-badge.module.css.js';
3
3
 
4
- function IconWithBadge({ badge, 'data-test-selector': dataTestSelector, icon, }) {
5
- return (jsxs("div", { className: styles['icon-with-badge'], children: [icon, jsx("div", { className: styles['badge-wrapper'], "data-test-selector": dataTestSelector, children: badge })] }));
4
+ function IconWithBadge({ 'aria-label': ariaLabel, badge, 'data-test-selector': dataTestSelector, icon, }) {
5
+ return (jsxs("div", { "aria-label": ariaLabel, className: styles['icon-with-badge'], children: [icon, jsx("div", { className: styles['badge-wrapper'], "data-test-selector": dataTestSelector, children: badge })] }));
6
6
  }
7
7
 
8
8
  export { IconWithBadge };
@@ -5,13 +5,17 @@ import { DeliveryTime } from '../../delivery-time/delivery-time.js';
5
5
  import { Price } from '../../display/price/price.js';
6
6
  import { ProductSku } from '../../display/product-sku/product-sku.js';
7
7
  import { FormattedMessage } from '../../intl/formatted-message.js';
8
+ import { logger } from '../../logging/logger.js';
8
9
  import { Image } from '../../media/image/image.js';
9
10
  import { RouteLink } from '../../shared/routing/route-link.js';
10
11
  import styles from './orderline-card.module.css.js';
11
12
 
12
13
  function OrderLineCard(props) {
13
14
  const { deliveryDate, href, image, isReadonly, price, productId, sku, tags, title, } = props;
14
- return (jsxs("article", { "aria-labelledby": `title-${productId}`, className: clsx(styles['orderline-card'], isReadonly && styles.readonly), "data-disabled": isReadonly ? true : undefined, "data-product-id": sku, "data-test-selector": "orderLineListItem", id: productId, children: [isReadonly ? (jsx("div", { className: styles.title, "data-test-selector": "orderLineCardTitle", id: `title-${productId}`, children: title })) : (jsx(RouteLink, { className: styles.title, "data-test-selector": "orderLineCardTitle", href: href, id: `title-${productId}`, children: title })), tags && tags.length > 0 && (jsx("div", { className: styles.tags, children: tags.map(tag => (jsx(Tag, { children: jsx(FormattedMessage, { fallbackValue: tag, id: `tag.${tag.toLowerCase()}` }) }, tag))) })), jsx(ProductSku, { className: styles.sku, sku: sku }), jsx(Price, { className: styles.price, currencyCode: price.currencyCode, "data-test-selector": "orderLineCardPrice", originalPrice: price.originalTotalPrice, price: price.totalPrice, pricePerUnit: price.pricePerUnit, variant: "sonic" }), jsx("div", { className: styles['image-container'], role: "presentation", children: jsx(Image, { "data-test-selector": "orderLineCardImage", ...image, fit: "contain" }) }), isReadonly ? (jsx("p", { className: styles.amount, children: jsx(FormattedMessage, { id: "Amount: {0}", replacementValues: { '0': props.quantity.toString() } }) })) : (jsx("div", { className: styles['add-to-cart-button'], children: props.addToCartButton })), deliveryDate && (jsx(DeliveryTime, { className: styles.delivery, deliveryDate: deliveryDate })), !isReadonly && (jsx("div", { className: styles.remove, "data-test-selector": "orderLineCardRemove", children: props.removeButton }))] }));
15
+ if (!price.currencyCode) {
16
+ logger.error(`Product '${sku}' does not have a currency code`);
17
+ }
18
+ return (jsxs("article", { "aria-labelledby": `title-${productId}`, className: clsx(styles['orderline-card'], isReadonly && styles.readonly), "data-disabled": isReadonly ? true : undefined, "data-product-id": sku, "data-test-selector": "orderLineListItem", id: productId, children: [isReadonly ? (jsx("div", { className: styles.title, "data-test-selector": "orderLineCardTitle", id: `title-${productId}`, children: title })) : (jsx(RouteLink, { className: styles.title, "data-test-selector": "orderLineCardTitle", href: href, id: `title-${productId}`, children: title })), tags && tags.length > 0 && (jsx("div", { className: styles.tags, children: tags.map(tag => (jsx(Tag, { children: jsx(FormattedMessage, { fallbackValue: tag, id: `tag.${tag.toLowerCase()}` }) }, tag))) })), jsx(ProductSku, { className: styles.sku, sku: sku }), price.currencyCode && (jsx(Price, { className: styles.price, currencyCode: price.currencyCode, "data-test-selector": "orderLineCardPrice", originalPrice: price.originalTotalPrice, price: price.totalPrice, pricePerUnit: price.pricePerUnit, variant: "sonic" })), jsx("div", { className: styles['image-container'], role: "presentation", children: jsx(Image, { "data-test-selector": "orderLineCardImage", ...image, fit: "contain" }) }), isReadonly ? (jsx("p", { className: styles.amount, children: jsx(FormattedMessage, { id: "Amount: {0}", replacementValues: { '0': props.quantity.toString() } }) })) : (jsx("div", { className: styles['add-to-cart-button'], children: props.addToCartButton })), jsx(DeliveryTime, { className: styles.delivery, deliveryDate: deliveryDate }), !isReadonly && (jsx("div", { className: styles.remove, "data-test-selector": "orderLineCardRemove", children: props.removeButton }))] }));
15
19
  }
16
20
 
17
21
  export { OrderLineCard };