@dnanpm/ui-components 0.7.0 → 0.9.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 (159) hide show
  1. package/dist/components/Accordion/Accordion.css +6 -3
  2. package/dist/components/AccordionItem/AccordionItem.css +6 -3
  3. package/dist/components/Breadcrumb/Breadcrumb.css +15 -12
  4. package/dist/components/Breadcrumb/Breadcrumb.module.css.cjs +6 -6
  5. package/dist/components/Breadcrumb/Breadcrumb.module.css.js +6 -6
  6. package/dist/components/Button/Button.css +33 -32
  7. package/dist/components/Button/Button.module.css.cjs +11 -11
  8. package/dist/components/Button/Button.module.css.js +11 -11
  9. package/dist/components/ButtonCard/ButtonCard.cjs +105 -0
  10. package/dist/components/ButtonCard/ButtonCard.cjs.map +1 -0
  11. package/dist/components/ButtonCard/ButtonCard.css +166 -0
  12. package/dist/components/ButtonCard/ButtonCard.d.ts +3 -0
  13. package/dist/components/ButtonCard/ButtonCard.d.ts.map +1 -0
  14. package/dist/components/ButtonCard/ButtonCard.js +105 -0
  15. package/dist/components/ButtonCard/ButtonCard.js.map +1 -0
  16. package/dist/components/ButtonCard/ButtonCard.module.css.cjs +18 -0
  17. package/dist/components/ButtonCard/ButtonCard.module.css.cjs.map +1 -0
  18. package/dist/components/ButtonCard/ButtonCard.module.css.js +19 -0
  19. package/dist/components/ButtonCard/ButtonCard.module.css.js.map +1 -0
  20. package/dist/components/ButtonCard/ButtonCard.types.d.ts +103 -0
  21. package/dist/components/ButtonCard/ButtonCard.types.d.ts.map +1 -0
  22. package/dist/components/ButtonCard/index.d.ts +3 -0
  23. package/dist/components/ButtonCard/index.d.ts.map +1 -0
  24. package/dist/components/ContentCard/ContentCard.cjs +96 -0
  25. package/dist/components/ContentCard/ContentCard.cjs.map +1 -0
  26. package/dist/components/ContentCard/ContentCard.css +249 -0
  27. package/dist/components/ContentCard/ContentCard.d.ts +3 -0
  28. package/dist/components/ContentCard/ContentCard.d.ts.map +1 -0
  29. package/dist/components/ContentCard/ContentCard.js +96 -0
  30. package/dist/components/ContentCard/ContentCard.js.map +1 -0
  31. package/dist/components/ContentCard/ContentCard.module.css.cjs +24 -0
  32. package/dist/components/ContentCard/ContentCard.module.css.cjs.map +1 -0
  33. package/dist/components/ContentCard/ContentCard.module.css.js +25 -0
  34. package/dist/components/ContentCard/ContentCard.module.css.js.map +1 -0
  35. package/dist/components/ContentCard/ContentCard.types.d.ts +99 -0
  36. package/dist/components/ContentCard/ContentCard.types.d.ts.map +1 -0
  37. package/dist/components/ContentCard/index.d.ts +3 -0
  38. package/dist/components/ContentCard/index.d.ts.map +1 -0
  39. package/dist/components/Drawer/Drawer.cjs +101 -0
  40. package/dist/components/Drawer/Drawer.cjs.map +1 -0
  41. package/dist/components/Drawer/Drawer.css +218 -0
  42. package/dist/components/Drawer/Drawer.d.ts +3 -0
  43. package/dist/components/Drawer/Drawer.d.ts.map +1 -0
  44. package/dist/components/Drawer/Drawer.js +101 -0
  45. package/dist/components/Drawer/Drawer.js.map +1 -0
  46. package/dist/components/Drawer/Drawer.module.css.cjs +37 -0
  47. package/dist/components/Drawer/Drawer.module.css.cjs.map +1 -0
  48. package/dist/components/Drawer/Drawer.module.css.js +37 -0
  49. package/dist/components/Drawer/Drawer.module.css.js.map +1 -0
  50. package/dist/components/Drawer/Drawer.types.d.ts +63 -0
  51. package/dist/components/Drawer/Drawer.types.d.ts.map +1 -0
  52. package/dist/components/Drawer/index.d.ts +3 -0
  53. package/dist/components/Drawer/index.d.ts.map +1 -0
  54. package/dist/components/Footer/Footer.css +87 -77
  55. package/dist/components/Footer/Footer.module.css.cjs +39 -39
  56. package/dist/components/Footer/Footer.module.css.js +39 -39
  57. package/dist/components/FunctionButton/FunctionButton.cjs +34 -0
  58. package/dist/components/FunctionButton/FunctionButton.cjs.map +1 -0
  59. package/dist/components/FunctionButton/FunctionButton.css +124 -0
  60. package/dist/components/FunctionButton/FunctionButton.d.ts +3 -0
  61. package/dist/components/FunctionButton/FunctionButton.d.ts.map +1 -0
  62. package/dist/components/FunctionButton/FunctionButton.js +34 -0
  63. package/dist/components/FunctionButton/FunctionButton.js.map +1 -0
  64. package/dist/components/FunctionButton/FunctionButton.module.css.cjs +11 -0
  65. package/dist/components/FunctionButton/FunctionButton.module.css.cjs.map +1 -0
  66. package/dist/components/FunctionButton/FunctionButton.module.css.js +12 -0
  67. package/dist/components/FunctionButton/FunctionButton.module.css.js.map +1 -0
  68. package/dist/components/FunctionButton/FunctionButton.types.d.ts +21 -0
  69. package/dist/components/FunctionButton/FunctionButton.types.d.ts.map +1 -0
  70. package/dist/components/FunctionButton/index.d.ts +3 -0
  71. package/dist/components/FunctionButton/index.d.ts.map +1 -0
  72. package/dist/components/Hero/Hero.cjs +24 -26
  73. package/dist/components/Hero/Hero.cjs.map +1 -1
  74. package/dist/components/Hero/Hero.css +81 -74
  75. package/dist/components/Hero/Hero.js +24 -26
  76. package/dist/components/Hero/Hero.js.map +1 -1
  77. package/dist/components/Hero/Hero.module.css.cjs +20 -17
  78. package/dist/components/Hero/Hero.module.css.cjs.map +1 -1
  79. package/dist/components/Hero/Hero.module.css.js +20 -17
  80. package/dist/components/Hero/Hero.module.css.js.map +1 -1
  81. package/dist/components/IconButton/IconButton.css +32 -34
  82. package/dist/components/IconButton/IconButton.module.css.cjs +9 -9
  83. package/dist/components/IconButton/IconButton.module.css.js +9 -9
  84. package/dist/components/Label/Label.css +2 -3
  85. package/dist/components/MainNavigation/MainNavigation.cjs +415 -120
  86. package/dist/components/MainNavigation/MainNavigation.cjs.map +1 -1
  87. package/dist/components/MainNavigation/MainNavigation.css +265 -159
  88. package/dist/components/MainNavigation/MainNavigation.d.ts +1 -1
  89. package/dist/components/MainNavigation/MainNavigation.d.ts.map +1 -1
  90. package/dist/components/MainNavigation/MainNavigation.js +417 -122
  91. package/dist/components/MainNavigation/MainNavigation.js.map +1 -1
  92. package/dist/components/MainNavigation/MainNavigation.module.css.cjs +78 -68
  93. package/dist/components/MainNavigation/MainNavigation.module.css.cjs.map +1 -1
  94. package/dist/components/MainNavigation/MainNavigation.module.css.js +78 -68
  95. package/dist/components/MainNavigation/MainNavigation.module.css.js.map +1 -1
  96. package/dist/components/MainNavigation/MainNavigation.types.d.ts +64 -17
  97. package/dist/components/MainNavigation/MainNavigation.types.d.ts.map +1 -1
  98. package/dist/components/MainNavigation/MainNavigation.utils.cjs +20 -0
  99. package/dist/components/MainNavigation/MainNavigation.utils.cjs.map +1 -1
  100. package/dist/components/MainNavigation/MainNavigation.utils.d.ts +10 -1
  101. package/dist/components/MainNavigation/MainNavigation.utils.d.ts.map +1 -1
  102. package/dist/components/MainNavigation/MainNavigation.utils.js +20 -0
  103. package/dist/components/MainNavigation/MainNavigation.utils.js.map +1 -1
  104. package/dist/components/MainNavigation/index.d.ts +1 -1
  105. package/dist/components/MainNavigation/index.d.ts.map +1 -1
  106. package/dist/components/Modal/Modal.cjs +101 -0
  107. package/dist/components/Modal/Modal.cjs.map +1 -0
  108. package/dist/components/Modal/Modal.css +204 -0
  109. package/dist/components/Modal/Modal.d.ts +3 -0
  110. package/dist/components/Modal/Modal.d.ts.map +1 -0
  111. package/dist/components/Modal/Modal.js +101 -0
  112. package/dist/components/Modal/Modal.js.map +1 -0
  113. package/dist/components/Modal/Modal.module.css.cjs +39 -0
  114. package/dist/components/Modal/Modal.module.css.cjs.map +1 -0
  115. package/dist/components/Modal/Modal.module.css.js +39 -0
  116. package/dist/components/Modal/Modal.module.css.js.map +1 -0
  117. package/dist/components/Modal/Modal.types.d.ts +62 -0
  118. package/dist/components/Modal/Modal.types.d.ts.map +1 -0
  119. package/dist/components/Modal/index.d.ts +3 -0
  120. package/dist/components/Modal/index.d.ts.map +1 -0
  121. package/dist/components/Modal/useDialogDismissal.cjs +41 -0
  122. package/dist/components/Modal/useDialogDismissal.cjs.map +1 -0
  123. package/dist/components/Modal/useDialogDismissal.d.ts +17 -0
  124. package/dist/components/Modal/useDialogDismissal.d.ts.map +1 -0
  125. package/dist/components/Modal/useDialogDismissal.js +41 -0
  126. package/dist/components/Modal/useDialogDismissal.js.map +1 -0
  127. package/dist/components/Modal/useNativeDialog.cjs +126 -0
  128. package/dist/components/Modal/useNativeDialog.cjs.map +1 -0
  129. package/dist/components/Modal/useNativeDialog.d.ts +14 -0
  130. package/dist/components/Modal/useNativeDialog.d.ts.map +1 -0
  131. package/dist/components/Modal/useNativeDialog.js +126 -0
  132. package/dist/components/Modal/useNativeDialog.js.map +1 -0
  133. package/dist/components/Notification/Notification.css +6 -3
  134. package/dist/components/Pictograph/Pictograph.css +6 -3
  135. package/dist/components/Pictograph/PictographItem.css +6 -3
  136. package/dist/components/Quote/Quote.css +2 -3
  137. package/dist/components/Spinner/Spinner.css +6 -3
  138. package/dist/index.cjs +10 -0
  139. package/dist/index.cjs.map +1 -1
  140. package/dist/index.d.ts +11 -1
  141. package/dist/index.d.ts.map +1 -1
  142. package/dist/index.js +10 -0
  143. package/dist/index.js.map +1 -1
  144. package/dist/styles/utils/elevation.css +2 -3
  145. package/dist/styles/utils/elevation.module.css.cjs +3 -0
  146. package/dist/styles/utils/elevation.module.css.cjs.map +1 -1
  147. package/dist/styles/utils/elevation.module.css.js +4 -1
  148. package/dist/styles/utils/elevation.module.css.js.map +1 -1
  149. package/dist/styles/utils/focus.css +26 -24
  150. package/dist/styles/utils/focus.module.css.cjs +3 -6
  151. package/dist/styles/utils/focus.module.css.cjs.map +1 -1
  152. package/dist/styles/utils/focus.module.css.js +4 -7
  153. package/dist/styles/utils/focus.module.css.js.map +1 -1
  154. package/dist/styles/utils/overlay.css +2 -3
  155. package/dist/styles/utils/text-decoration.css +4 -4
  156. package/dist/styles/utils/text-decoration.module.css.cjs +2 -2
  157. package/dist/styles/utils/text-decoration.module.css.js +2 -2
  158. package/dist/styles.css +17 -7
  159. package/package.json +3 -3
@@ -11,6 +11,7 @@ const MainNavigation_module = require("./MainNavigation.module.css.cjs");
11
11
  const MainNavigation_utils = require("./MainNavigation.utils.cjs");
12
12
  const cn = require("../../utils/cn/cn.cjs");
13
13
  const Button = require("../Button/Button.cjs");
14
+ const Drawer = require("../Drawer/Drawer.cjs");
14
15
  const IconButton = require("../IconButton/IconButton.cjs");
15
16
  const defaultOrganizations = [];
16
17
  const defaultItems = [];
@@ -21,25 +22,30 @@ const mobileBodyScrollLockClass = "dds-un-scrollable";
21
22
  const defaultOverflowCategoryLabel = "Muut kategoriat";
22
23
  const desktopMinWidthMediaQuery = "(min-width: 1024px)";
23
24
  const defaultRenderLink = (props) => /* @__PURE__ */ jsxRuntime.jsx("a", { ...props });
25
+ const defaultRenderLanguageLink = (props) => /* @__PURE__ */ jsxRuntime.jsx("a", { ...props });
24
26
  const MainNavigation = ({
25
27
  organizations = defaultOrganizations,
26
28
  items = defaultItems,
27
- loginHref = "#",
28
29
  loginLabel = "Kirjaudu",
29
30
  logoHref = "/",
30
- languageSelectorLabel = "FI",
31
+ languages,
32
+ renderLanguageLink = defaultRenderLanguageLink,
31
33
  searchLabel = "Haku",
32
34
  cartLabel = "Ostoskori",
33
- showLanguageSelector = false,
34
- showSearch = false,
35
- showCart = false,
36
35
  cartCounter,
37
36
  cartCounterLabel = "tuotetta ostoskorissa",
38
- onLanguageSelectorClick,
39
- onSearchClick,
40
- onCartClick,
41
- mobileMenuOpenAriaLabel = "Avaa valikko",
42
- mobileMenuCloseAriaLabel = "Sulje valikko",
37
+ defaultCartOpen = false,
38
+ cartOpen,
39
+ onCartOpenChange,
40
+ defaultOpenDropdown,
41
+ onSearchOpenChange,
42
+ onLanguageOpenChange,
43
+ onLoginOpenChange,
44
+ searchDropdownContent,
45
+ loginDropdownContent,
46
+ cartContent,
47
+ mobileMenuOpenAriaLabel = "Avaa päävalikko",
48
+ mobileMenuCloseAriaLabel = "Sulje päävalikko",
43
49
  organizationStripAriaLabel = "Sivustot",
44
50
  logoAriaLabel = "Siirry etusivulle",
45
51
  mobilePrimaryNavigationAriaLabel = "Päävalikko",
@@ -61,8 +67,17 @@ const MainNavigation = ({
61
67
  const [openTopLevelItemIndex, setOpenTopLevelItemIndex] = react.useState(
62
68
  defaultOpenItemIndex
63
69
  );
64
- const [isDesktopHeaderOpen, setIsDesktopHeaderOpen] = react.useState(true);
70
+ const [isHeaderOpen, setIsHeaderOpen] = react.useState(true);
65
71
  const [mobileActiveCategoryIndex, setMobileActiveCategoryIndex] = react.useState(null);
72
+ const [internalCartOpen, setInternalCartOpen] = react.useState(defaultCartOpen);
73
+ const isCartControlled = cartOpen !== void 0;
74
+ const isCartOpen = cartOpen ?? internalCartOpen;
75
+ const hasInitialNavigationSurface = (cartOpen ?? defaultCartOpen) || defaultMobileMenuOpen || defaultOpenItemIndex != null && items[defaultOpenItemIndex]?.panel != null;
76
+ const [openUtilityDropdown, setOpenUtilityDropdown] = react.useState(hasInitialNavigationSurface ? null : defaultOpenDropdown ?? null);
77
+ const openUtilityDropdownRef = react.useRef(openUtilityDropdown);
78
+ const searchDropdownId = react.useId();
79
+ const languageDropdownId = react.useId();
80
+ const loginDropdownId = react.useId();
66
81
  const [isMobileSecondPanelClosing, setIsMobileSecondPanelClosing] = react.useState(false);
67
82
  const [isMobileThirdPanelClosing, setIsMobileThirdPanelClosing] = react.useState(false);
68
83
  const mobileSecondPanelCloseTimeoutRef = react.useRef(null);
@@ -78,6 +93,9 @@ const MainNavigation = ({
78
93
  );
79
94
  const headerElementRef = react.useRef(null);
80
95
  const desktopPanelTriggerButtonRefs = react.useRef([]);
96
+ const searchTriggerRef = react.useRef(null);
97
+ const languageTriggerRef = react.useRef(null);
98
+ const loginTriggerRef = react.useRef(null);
81
99
  const mobilePrimaryNavRef = react.useRef(null);
82
100
  const mobileMenuToggleButtonRef = react.useRef(null);
83
101
  const mobileModalPanelRef = react.useRef(null);
@@ -87,9 +105,14 @@ const MainNavigation = ({
87
105
  const mobileLevelTwoCategoryButtonRefs = react.useRef([]);
88
106
  const focusMobilePanelBackOnOpenRef = react.useRef(false);
89
107
  const focusMobileThirdPanelBackOnOpenRef = react.useRef(false);
108
+ const lastInteractionWasKeyboardRef = react.useRef(false);
90
109
  const focusReturnToMobileCategoryTimeoutRef = react.useRef(
91
110
  null
92
111
  );
112
+ const mobileMenuOpenRef = react.useRef(mobileMenuOpen);
113
+ const openTopLevelItemIndexRef = react.useRef(openTopLevelItemIndex);
114
+ const lastAppliedViewportModeRef = react.useRef(null);
115
+ const internalCartOpenRef = react.useRef(internalCartOpen);
93
116
  const setHeaderRef = react.useCallback(
94
117
  (node) => {
95
118
  headerElementRef.current = node;
@@ -132,19 +155,18 @@ const MainNavigation = ({
132
155
  let previousScrollY = window.pageYOffset;
133
156
  let headerHeight = parseFloat(window.getComputedStyle(headerElement).height.replace("px", "")) || headerElement.offsetHeight;
134
157
  const openHeader = () => {
135
- setIsDesktopHeaderOpen(true);
158
+ setIsHeaderOpen(true);
136
159
  };
137
160
  const closeHeader = () => {
138
- setIsDesktopHeaderOpen(false);
161
+ setIsHeaderOpen(false);
162
+ };
163
+ const headerHasVisibleFocus = () => {
164
+ const active = document.activeElement;
165
+ return lastInteractionWasKeyboardRef.current && active instanceof HTMLElement && headerElement.contains(active);
139
166
  };
140
167
  const handleScroll = () => {
141
168
  const currentScrollY = window.pageYOffset;
142
- if (!desktopQuery.matches) {
143
- openHeader();
144
- previousScrollY = currentScrollY;
145
- return;
146
- }
147
- if (mobileMenuOpen || openTopLevelItemIndex != null) {
169
+ if (mobileMenuOpen || openTopLevelItemIndex != null || openUtilityDropdown != null || headerHasVisibleFocus()) {
148
170
  openHeader();
149
171
  previousScrollY = currentScrollY;
150
172
  return;
@@ -158,6 +180,11 @@ const MainNavigation = ({
158
180
  }
159
181
  previousScrollY = currentScrollY;
160
182
  };
183
+ const handleFocusIn = () => {
184
+ if (headerHasVisibleFocus()) {
185
+ openHeader();
186
+ }
187
+ };
161
188
  const handleViewportChange = () => {
162
189
  openHeader();
163
190
  previousScrollY = window.pageYOffset;
@@ -165,14 +192,33 @@ const MainNavigation = ({
165
192
  };
166
193
  window.addEventListener("scroll", handleScroll, { passive: true });
167
194
  window.addEventListener("resize", handleViewportChange);
195
+ document.addEventListener("focusin", handleFocusIn);
168
196
  desktopQuery.addEventListener("change", handleViewportChange);
169
197
  handleScroll();
170
198
  return () => {
171
199
  window.removeEventListener("scroll", handleScroll);
172
200
  window.removeEventListener("resize", handleViewportChange);
201
+ document.removeEventListener("focusin", handleFocusIn);
173
202
  desktopQuery.removeEventListener("change", handleViewportChange);
174
203
  };
175
- }, [mobileMenuOpen, openTopLevelItemIndex]);
204
+ }, [mobileMenuOpen, openTopLevelItemIndex, openUtilityDropdown]);
205
+ react.useEffect(() => {
206
+ if (typeof document === "undefined") {
207
+ return;
208
+ }
209
+ const handleKeyDown = () => {
210
+ lastInteractionWasKeyboardRef.current = true;
211
+ };
212
+ const handlePointerDown = () => {
213
+ lastInteractionWasKeyboardRef.current = false;
214
+ };
215
+ document.addEventListener("keydown", handleKeyDown, true);
216
+ document.addEventListener("pointerdown", handlePointerDown, true);
217
+ return () => {
218
+ document.removeEventListener("keydown", handleKeyDown, true);
219
+ document.removeEventListener("pointerdown", handlePointerDown, true);
220
+ };
221
+ }, []);
176
222
  react.useEffect(() => {
177
223
  const browserWindow = globalThis.window;
178
224
  const browserDocument = globalThis.document;
@@ -210,6 +256,11 @@ const MainNavigation = ({
210
256
  }
211
257
  const desktopQuery = window.matchMedia(desktopMinWidthMediaQuery);
212
258
  const applyViewportModeChange = ({ matches: isDesktopViewport2 }) => {
259
+ const viewportMode = isDesktopViewport2 ? "desktop" : "mobile";
260
+ if (lastAppliedViewportModeRef.current === viewportMode) {
261
+ return;
262
+ }
263
+ lastAppliedViewportModeRef.current = viewportMode;
213
264
  if (isDesktopViewport2) {
214
265
  clearTimeout(mobileSecondPanelCloseTimeoutRef.current ?? void 0);
215
266
  mobileSecondPanelCloseTimeoutRef.current = null;
@@ -217,23 +268,23 @@ const MainNavigation = ({
217
268
  mobileThirdPanelCloseTimeoutRef.current = null;
218
269
  clearTimeout(resetMobileThirdPanelScrollTimeoutRef.current ?? void 0);
219
270
  resetMobileThirdPanelScrollTimeoutRef.current = null;
220
- setMobileMenuOpen((previous) => {
221
- if (previous) {
222
- onMobileMenuToggle?.(false);
223
- }
224
- return false;
225
- });
271
+ const wasMobileMenuOpen = mobileMenuOpenRef.current;
272
+ mobileMenuOpenRef.current = false;
273
+ if (wasMobileMenuOpen) {
274
+ onMobileMenuToggle?.(false);
275
+ }
276
+ setMobileMenuOpen(false);
226
277
  setMobileActiveCategoryIndex(null);
227
278
  setIsMobileSecondPanelClosing(false);
228
279
  setIsMobileThirdPanelClosing(false);
229
280
  return;
230
281
  }
231
- setOpenTopLevelItemIndex((previous) => {
232
- if (previous !== null) {
233
- onDesktopItemToggle?.(null);
234
- }
235
- return null;
236
- });
282
+ const hadOpenDesktopItem = openTopLevelItemIndexRef.current !== null;
283
+ openTopLevelItemIndexRef.current = null;
284
+ if (hadOpenDesktopItem) {
285
+ onDesktopItemToggle?.(null);
286
+ }
287
+ setOpenTopLevelItemIndex(null);
237
288
  };
238
289
  applyViewportModeChange(desktopQuery);
239
290
  desktopQuery.addEventListener("change", applyViewportModeChange);
@@ -242,6 +293,7 @@ const MainNavigation = ({
242
293
  };
243
294
  }, [onDesktopItemToggle, onMobileMenuToggle]);
244
295
  const resetMobilePanelState = react.useCallback(() => {
296
+ openTopLevelItemIndexRef.current = null;
245
297
  setOpenTopLevelItemIndex(null);
246
298
  setMobileActiveCategoryIndex(null);
247
299
  setIsMobileSecondPanelClosing(false);
@@ -258,20 +310,20 @@ const MainNavigation = ({
258
310
  return;
259
311
  }
260
312
  const shouldAnimateMobileClose = mobileMenuOpen;
313
+ const wasMobileMenuOpen = mobileMenuOpenRef.current;
314
+ const openDesktopItemIndex = openTopLevelItemIndexRef.current;
315
+ mobileMenuOpenRef.current = false;
316
+ openTopLevelItemIndexRef.current = null;
317
+ if (wasMobileMenuOpen) {
318
+ onMobileMenuToggle?.(false);
319
+ }
320
+ if (openDesktopItemIndex !== null) {
321
+ onDesktopItemToggle?.(null);
322
+ }
261
323
  clearTimeout(mobileMenuCloseResetTimeoutRef.current ?? void 0);
262
324
  setIsMobileMenuClosing(shouldAnimateMobileClose);
263
- setMobileMenuOpen((previous) => {
264
- if (previous) {
265
- onMobileMenuToggle?.(false);
266
- }
267
- return false;
268
- });
269
- setOpenTopLevelItemIndex((previous) => {
270
- if (previous !== null) {
271
- onDesktopItemToggle?.(null);
272
- }
273
- return null;
274
- });
325
+ setMobileMenuOpen(false);
326
+ setOpenTopLevelItemIndex(null);
275
327
  if (shouldAnimateMobileClose) {
276
328
  mobileMenuCloseResetTimeoutRef.current = setTimeout(() => {
277
329
  resetMobilePanelState();
@@ -294,19 +346,21 @@ const MainNavigation = ({
294
346
  closeMobileMenu();
295
347
  return;
296
348
  }
349
+ closeUtilityDropdown();
350
+ mobileMenuOpenRef.current = true;
297
351
  setMobileMenuOpen(true);
298
352
  setIsMobileMenuClosing(false);
299
353
  onMobileMenuToggle?.(true);
300
354
  };
301
355
  const toggleTopLevelItem = (index) => {
302
- setOpenTopLevelItemIndex((previous) => {
303
- const next = previous === index ? null : index;
304
- setMobileActiveCategoryIndex(null);
305
- setIsMobileSecondPanelClosing(false);
306
- setIsMobileThirdPanelClosing(false);
307
- onDesktopItemToggle?.(next);
308
- return next;
309
- });
356
+ closeUtilityDropdown();
357
+ const next = openTopLevelItemIndex === index ? null : index;
358
+ openTopLevelItemIndexRef.current = next;
359
+ setOpenTopLevelItemIndex(next);
360
+ setMobileActiveCategoryIndex(null);
361
+ setIsMobileSecondPanelClosing(false);
362
+ setIsMobileThirdPanelClosing(false);
363
+ onDesktopItemToggle?.(next);
310
364
  };
311
365
  const isDesktopViewport = react.useCallback(() => {
312
366
  return MainNavigation_utils.isDesktopViewportByEnvironment(globalThis.window);
@@ -358,6 +412,23 @@ const MainNavigation = ({
358
412
  },
359
413
  [getDesktopPanelInteractiveElements, isFocusable]
360
414
  );
415
+ const getUtilityDropdownFocusLoopElements = react.useCallback(
416
+ (kind) => {
417
+ const focusLoopElements = /* @__PURE__ */ new Set();
418
+ const triggerButton = kind === "search" ? searchTriggerRef.current : kind === "language" ? languageTriggerRef.current : loginTriggerRef.current;
419
+ if (triggerButton != null && isFocusable(triggerButton)) {
420
+ focusLoopElements.add(triggerButton);
421
+ }
422
+ getFocusableElements(
423
+ headerElementRef.current,
424
+ `.${MainNavigation_module["main-navigation__dropdown"]} a[href], .${MainNavigation_module["main-navigation__dropdown"]} button:not([disabled]), .${MainNavigation_module["main-navigation__dropdown"]} input:not([disabled]), .${MainNavigation_module["main-navigation__dropdown"]} select:not([disabled]), .${MainNavigation_module["main-navigation__dropdown"]} textarea:not([disabled]), .${MainNavigation_module["main-navigation__dropdown"]} [tabindex]:not([tabindex="-1"])`
425
+ ).forEach((element) => {
426
+ focusLoopElements.add(element);
427
+ });
428
+ return Array.from(focusLoopElements);
429
+ },
430
+ [getFocusableElements, isFocusable]
431
+ );
361
432
  const getMobileFocusableElements = react.useCallback(() => {
362
433
  const focusableElements = [];
363
434
  const addFocusableElements = (elements) => {
@@ -401,6 +472,26 @@ const MainNavigation = ({
401
472
  resetMobileThirdPanelScrollTimeoutRef.current = null;
402
473
  }, 0);
403
474
  }, []);
475
+ const notifyUtilityOpenChange = react.useCallback(
476
+ (kind, open) => {
477
+ if (kind === "search") {
478
+ onSearchOpenChange?.(open);
479
+ } else if (kind === "language") {
480
+ onLanguageOpenChange?.(open);
481
+ } else {
482
+ onLoginOpenChange?.(open);
483
+ }
484
+ },
485
+ [onLanguageOpenChange, onLoginOpenChange, onSearchOpenChange]
486
+ );
487
+ const closeUtilityDropdown = react.useCallback(() => {
488
+ const openDropdown = openUtilityDropdownRef.current;
489
+ if (openDropdown != null) {
490
+ openUtilityDropdownRef.current = null;
491
+ notifyUtilityOpenChange(openDropdown, false);
492
+ }
493
+ setOpenUtilityDropdown(null);
494
+ }, [notifyUtilityOpenChange]);
404
495
  const closeMenus = react.useCallback(() => {
405
496
  clearTimeout(mobileSecondPanelCloseTimeoutRef.current ?? void 0);
406
497
  mobileSecondPanelCloseTimeoutRef.current = null;
@@ -416,8 +507,14 @@ const MainNavigation = ({
416
507
  focusReturnToMobileTopLevelItemTimeoutRef.current = null;
417
508
  clearTimeout(focusReturnToMobileCategoryTimeoutRef.current ?? void 0);
418
509
  focusReturnToMobileCategoryTimeoutRef.current = null;
510
+ const openDropdown = openUtilityDropdownRef.current;
511
+ if (openDropdown != null) {
512
+ openUtilityDropdownRef.current = null;
513
+ notifyUtilityOpenChange(openDropdown, false);
514
+ }
515
+ setOpenUtilityDropdown(null);
419
516
  closeMobileMenu();
420
- }, [closeMobileMenu]);
517
+ }, [closeMobileMenu, notifyUtilityOpenChange]);
421
518
  const closeMobilePanel = react.useCallback(
422
519
  ({
423
520
  isClosing,
@@ -466,9 +563,87 @@ const MainNavigation = ({
466
563
  const openItem = openTopLevelItemIndex != null ? items[openTopLevelItemIndex] : void 0;
467
564
  const openPanel = openItem?.panel;
468
565
  const isMobilePanelClosingOut = isMobileMenuClosing && !mobileMenuOpen;
469
- const showPageOverlay = mobileMenuOpen || openPanel != null || isMobilePanelClosingOut;
470
566
  const isOverlayClosingOut = isMobilePanelClosingOut && openPanel == null;
567
+ const showSearch = searchDropdownContent != null && typeof searchDropdownContent !== "boolean";
568
+ const showLogin = loginDropdownContent != null && typeof loginDropdownContent !== "boolean";
569
+ const showCart = cartContent != null && typeof cartContent !== "boolean";
471
570
  const cartAccessibleLabel = cartCounter != null ? `${cartLabel} ${cartCounter} ${cartCounterLabel}` : cartLabel;
571
+ const currentLanguage = languages?.find((language) => language.current) ?? languages?.[0];
572
+ const alternativeLanguages = currentLanguage != null ? (languages ?? []).filter((language) => language.code !== currentLanguage.code) : [];
573
+ const showLanguage = currentLanguage != null && alternativeLanguages.length > 0;
574
+ const languageAnnouncements = currentLanguage != null ? MainNavigation_utils.getLanguageToggleAnnouncements(
575
+ (languages ?? []).map((language) => language.code),
576
+ currentLanguage.code
577
+ ) : [];
578
+ const activeUtilityDropdown = openUtilityDropdown === "search" && showSearch ? "search" : openUtilityDropdown === "language" && showLanguage ? "language" : openUtilityDropdown === "login" && showLogin ? "login" : null;
579
+ const isSearchOpen = activeUtilityDropdown === "search";
580
+ const isLanguageOpen = activeUtilityDropdown === "language";
581
+ const isLoginOpen = activeUtilityDropdown === "login";
582
+ const showPageOverlay = mobileMenuOpen || openPanel != null || isMobilePanelClosingOut || activeUtilityDropdown != null;
583
+ const toggleUtilityDropdown = (kind) => {
584
+ const previous = openUtilityDropdown;
585
+ const next = previous === kind ? null : kind;
586
+ if (previous != null && previous !== next) {
587
+ notifyUtilityOpenChange(previous, false);
588
+ }
589
+ if (next != null) {
590
+ notifyUtilityOpenChange(next, true);
591
+ closeMobileMenu();
592
+ if (isCartOpen) {
593
+ if (!isCartControlled) {
594
+ internalCartOpenRef.current = false;
595
+ setInternalCartOpen(false);
596
+ }
597
+ onCartOpenChange?.(false);
598
+ }
599
+ }
600
+ openUtilityDropdownRef.current = next;
601
+ setOpenUtilityDropdown(next);
602
+ };
603
+ const handleLanguageClick = () => {
604
+ toggleUtilityDropdown("language");
605
+ };
606
+ const handleSearchClick = () => {
607
+ toggleUtilityDropdown("search");
608
+ };
609
+ const handleLoginClick = () => {
610
+ toggleUtilityDropdown("login");
611
+ };
612
+ const handleCartClick = () => {
613
+ const next = !isCartOpen;
614
+ if (next) {
615
+ closeMenus();
616
+ }
617
+ if (!isCartControlled) {
618
+ internalCartOpenRef.current = next;
619
+ setInternalCartOpen(next);
620
+ }
621
+ onCartOpenChange?.(next);
622
+ };
623
+ const handleCartOpenChange = (open) => {
624
+ if (!isCartControlled) {
625
+ internalCartOpenRef.current = open;
626
+ setInternalCartOpen(open);
627
+ }
628
+ onCartOpenChange?.(open);
629
+ };
630
+ react.useEffect(() => {
631
+ if (isCartOpen) {
632
+ closeMenus();
633
+ }
634
+ }, [closeMenus, isCartOpen]);
635
+ react.useEffect(() => {
636
+ if (openUtilityDropdown != null && activeUtilityDropdown == null) {
637
+ closeUtilityDropdown();
638
+ }
639
+ }, [activeUtilityDropdown, closeUtilityDropdown, openUtilityDropdown]);
640
+ react.useEffect(() => {
641
+ if (!showCart && !isCartControlled && internalCartOpen && internalCartOpenRef.current) {
642
+ internalCartOpenRef.current = false;
643
+ setInternalCartOpen(false);
644
+ onCartOpenChange?.(false);
645
+ }
646
+ }, [internalCartOpen, isCartControlled, onCartOpenChange, showCart]);
472
647
  react.useEffect(() => {
473
648
  if (!showPageOverlay) {
474
649
  return;
@@ -568,8 +743,7 @@ const MainNavigation = ({
568
743
  type: "button",
569
744
  className: cn.cn(
570
745
  MainNavigation_module["main-navigation__mobile-back-item"],
571
- focus_module.default.focusableInset,
572
- focus_module.default.focusableRadiusSm
746
+ focus_module.default.focusableInset
573
747
  ),
574
748
  onClick: () => closeMobilePanel({
575
749
  isClosing: isMobileSecondPanelClosing,
@@ -577,6 +751,7 @@ const MainNavigation = ({
577
751
  closeTimeoutRef: mobileSecondPanelCloseTimeoutRef,
578
752
  onClosed: () => {
579
753
  const closedTopLevelItemIndex = openTopLevelItemIndex;
754
+ openTopLevelItemIndexRef.current = null;
580
755
  setOpenTopLevelItemIndex(null);
581
756
  setMobileActiveCategoryIndex(null);
582
757
  onDesktopItemToggle?.(null);
@@ -663,8 +838,7 @@ const MainNavigation = ({
663
838
  type: "button",
664
839
  className: cn.cn(
665
840
  MainNavigation_module["main-navigation__mobile-level-2-category-button"],
666
- focus_module.default.focusableInset,
667
- focus_module.default.focusableRadiusSm
841
+ focus_module.default.focusableInset
668
842
  ),
669
843
  onClick: () => openMobileCategoryPanel(index),
670
844
  onKeyDown: (event) => {
@@ -703,8 +877,7 @@ const MainNavigation = ({
703
877
  type: "button",
704
878
  className: cn.cn(
705
879
  MainNavigation_module["main-navigation__mobile-back-item"],
706
- focus_module.default.focusableInset,
707
- focus_module.default.focusableRadiusSm
880
+ focus_module.default.focusableInset
708
881
  ),
709
882
  onClick: () => closeMobilePanel({
710
883
  isClosing: isMobileThirdPanelClosing,
@@ -747,8 +920,7 @@ const MainNavigation = ({
747
920
  link,
748
921
  className: cn.cn(
749
922
  MainNavigation_module["main-navigation__mobile-level-3-link"],
750
- focus_module.default.focusableInset,
751
- focus_module.default.focusableRadiusSm
923
+ focus_module.default.focusableInset
752
924
  ),
753
925
  children: link.label
754
926
  })
@@ -789,7 +961,6 @@ const MainNavigation = ({
789
961
  className: cn.cn(
790
962
  MainNavigation_module["main-navigation__panel-link"],
791
963
  focus_module.default.focusableInset,
792
- focus_module.default.focusableRadiusSm,
793
964
  textDecoration_module.default.underlineLinkOnHover,
794
965
  isInCurrentPage && MainNavigation_module["main-navigation__panel-link--current"]
795
966
  ),
@@ -827,8 +998,7 @@ const MainNavigation = ({
827
998
  className: cn.cn(
828
999
  MainNavigation_module["main-navigation__feature-link"],
829
1000
  textDecoration_module.default.underlineLinkOnHover,
830
- focus_module.default.focusableInset,
831
- focus_module.default.focusableRadiusSm
1001
+ focus_module.default.focusableInset
832
1002
  ),
833
1003
  children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
834
1004
  isExternalFeatureLink ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -880,7 +1050,6 @@ const MainNavigation = ({
880
1050
  className: cn.cn(
881
1051
  MainNavigation_module["main-navigation__item-toggle"],
882
1052
  focus_module.default.focusableInset,
883
- focus_module.default.focusableRadiusSm,
884
1053
  isCurrentPathItem && MainNavigation_module["main-navigation__item-toggle--current"],
885
1054
  isOpen && MainNavigation_module["main-navigation__item-toggle--open"]
886
1055
  ),
@@ -906,7 +1075,6 @@ const MainNavigation = ({
906
1075
  className: cn.cn(
907
1076
  MainNavigation_module["main-navigation__item-link"],
908
1077
  focus_module.default.focusableInset,
909
- focus_module.default.focusableRadiusSm,
910
1078
  isCurrentPathItem && MainNavigation_module["main-navigation__item-link--current"]
911
1079
  ),
912
1080
  ariaCurrent: isCurrentPathItem ? "page" : void 0,
@@ -919,7 +1087,7 @@ const MainNavigation = ({
919
1087
  ref: setHeaderRef,
920
1088
  className: cn.cn(
921
1089
  MainNavigation_module["main-navigation"],
922
- isDesktopHeaderOpen && MainNavigation_module["main-navigation--open"],
1090
+ isHeaderOpen && MainNavigation_module["main-navigation--open"],
923
1091
  mobileMenuOpen && MainNavigation_module["main-navigation--menu-open"],
924
1092
  isMobileMenuClosing && MainNavigation_module["main-navigation--menu-closing"],
925
1093
  showPageOverlay && MainNavigation_module["main-navigation--overlay"],
@@ -929,6 +1097,21 @@ const MainNavigation = ({
929
1097
  ),
930
1098
  ...props,
931
1099
  onKeyDown: (event) => {
1100
+ if (event.key === "Tab" && activeUtilityDropdown != null) {
1101
+ const focusLoopElements = getUtilityDropdownFocusLoopElements(activeUtilityDropdown);
1102
+ if (focusLoopElements.length > 1) {
1103
+ event.preventDefault();
1104
+ const currentIndex = focusLoopElements.indexOf(
1105
+ document.activeElement
1106
+ );
1107
+ const direction = event.shiftKey ? -1 : 1;
1108
+ const nextIndex = currentIndex === -1 ? event.shiftKey ? focusLoopElements.length - 1 : 0 : (currentIndex + direction + focusLoopElements.length) % focusLoopElements.length;
1109
+ focusLoopElements[nextIndex]?.focus();
1110
+ } else {
1111
+ closeUtilityDropdown();
1112
+ }
1113
+ return;
1114
+ }
932
1115
  if (event.key === "Tab" && mobileMenuOpen && !isDesktopViewport()) {
933
1116
  const focusableElements = getMobileFocusableElements();
934
1117
  if (focusableElements.length > 0) {
@@ -956,7 +1139,12 @@ const MainNavigation = ({
956
1139
  }
957
1140
  }
958
1141
  if (event.key === "Escape") {
1142
+ const utilityDropdownToRestore = activeUtilityDropdown;
959
1143
  closeMenus();
1144
+ if (utilityDropdownToRestore != null) {
1145
+ const triggerButton = utilityDropdownToRestore === "search" ? searchTriggerRef.current : utilityDropdownToRestore === "language" ? languageTriggerRef.current : loginTriggerRef.current;
1146
+ triggerButton?.focus();
1147
+ }
960
1148
  }
961
1149
  props.onKeyDown?.(event);
962
1150
  },
@@ -981,11 +1169,7 @@ const MainNavigation = ({
981
1169
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: MainNavigation_module["main-navigation__navbar"], children: [
982
1170
  renderUtilityLink({
983
1171
  href: MainNavigation_utils.toNavigableHref(logoHref),
984
- className: cn.cn(
985
- MainNavigation_module["main-navigation__logo"],
986
- focus_module.default.focusable,
987
- focus_module.default.focusableRadiusSm
988
- ),
1172
+ className: cn.cn(MainNavigation_module["main-navigation__logo"], focus_module.default.focusable),
989
1173
  "aria-label": logoAriaLabel,
990
1174
  children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: defaultLogoSrc, alt: "", "aria-hidden": "true" })
991
1175
  }),
@@ -1012,51 +1196,116 @@ const MainNavigation = ({
1012
1196
  }
1013
1197
  ),
1014
1198
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: MainNavigation_module["main-navigation__icon-nav"], children: [
1015
- showLanguageSelector && /* @__PURE__ */ jsxRuntime.jsxs(
1016
- "button",
1017
- {
1018
- type: "button",
1019
- className: cn.cn(
1020
- MainNavigation_module["main-navigation__icon-nav-item"],
1021
- focus_module.default.focusableInset,
1022
- focus_module.default.focusableRadiusSm
1023
- ),
1024
- "aria-label": languageSelectorLabel,
1025
- onClick: onLanguageSelectorClick,
1026
- children: [
1027
- /* @__PURE__ */ jsxRuntime.jsx(icons.Globe, {}),
1028
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: MainNavigation_module["main-navigation__icon-nav-label"], children: languageSelectorLabel })
1029
- ]
1030
- }
1031
- ),
1032
- showSearch && /* @__PURE__ */ jsxRuntime.jsxs(
1033
- "button",
1034
- {
1035
- type: "button",
1036
- className: cn.cn(
1037
- MainNavigation_module["main-navigation__icon-nav-item"],
1038
- focus_module.default.focusableInset,
1039
- focus_module.default.focusableRadiusSm
1199
+ showLanguage && currentLanguage != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: MainNavigation_module["main-navigation__utility"], children: [
1200
+ /* @__PURE__ */ jsxRuntime.jsxs(
1201
+ "button",
1202
+ {
1203
+ ref: languageTriggerRef,
1204
+ type: "button",
1205
+ className: cn.cn(
1206
+ MainNavigation_module["main-navigation__icon-nav-item"],
1207
+ isLanguageOpen && MainNavigation_module["main-navigation__icon-nav-item--active"],
1208
+ focus_module.default.focusableInset
1209
+ ),
1210
+ "aria-expanded": isLanguageOpen,
1211
+ "aria-controls": isLanguageOpen ? languageDropdownId : void 0,
1212
+ onClick: handleLanguageClick,
1213
+ children: [
1214
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Globe, { "aria-hidden": "true" }),
1215
+ /* @__PURE__ */ jsxRuntime.jsx(
1216
+ "span",
1217
+ {
1218
+ "aria-hidden": "true",
1219
+ className: MainNavigation_module["main-navigation__icon-nav-label"],
1220
+ children: currentLanguage.code.toUpperCase()
1221
+ }
1222
+ ),
1223
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: MainNavigation_module["main-navigation__sr-only"], children: languageAnnouncements.map((announcement, index) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
1224
+ index > 0 ? " " : null,
1225
+ /* @__PURE__ */ jsxRuntime.jsx("span", { lang: announcement.lang, children: announcement.text })
1226
+ ] }, announcement.lang)) })
1227
+ ]
1228
+ }
1229
+ ),
1230
+ isLanguageOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1231
+ /* @__PURE__ */ jsxRuntime.jsx(
1232
+ "span",
1233
+ {
1234
+ "aria-hidden": "true",
1235
+ className: MainNavigation_module["main-navigation__dropdown-caret"]
1236
+ }
1040
1237
  ),
1041
- "aria-label": searchLabel,
1042
- onClick: onSearchClick,
1043
- children: [
1044
- /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {}),
1045
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: MainNavigation_module["main-navigation__icon-nav-label"], children: searchLabel })
1046
- ]
1047
- }
1048
- ),
1238
+ /* @__PURE__ */ jsxRuntime.jsx(
1239
+ "div",
1240
+ {
1241
+ id: languageDropdownId,
1242
+ className: cn.cn(
1243
+ MainNavigation_module["main-navigation__dropdown"],
1244
+ MainNavigation_module["main-navigation__dropdown--language"],
1245
+ elevation_module.default.elevationMedium
1246
+ ),
1247
+ children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: MainNavigation_module["main-navigation__language-list"], children: alternativeLanguages.map((language) => /* @__PURE__ */ jsxRuntime.jsx(
1248
+ "li",
1249
+ {
1250
+ className: MainNavigation_module["main-navigation__language-list-item"],
1251
+ children: renderLanguageLink({
1252
+ href: MainNavigation_utils.toNavigableHref(language.href),
1253
+ lang: language.code,
1254
+ "aria-label": language.ariaLabel ?? MainNavigation_utils.languageLinkAriaLabels[language.code],
1255
+ className: cn.cn(
1256
+ MainNavigation_module["main-navigation__language-link"],
1257
+ focus_module.default.focusable
1258
+ ),
1259
+ children: language.code.toUpperCase()
1260
+ })
1261
+ },
1262
+ language.code
1263
+ )) })
1264
+ }
1265
+ )
1266
+ ] })
1267
+ ] }),
1268
+ showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: MainNavigation_module["main-navigation__utility"], children: [
1269
+ /* @__PURE__ */ jsxRuntime.jsxs(
1270
+ "button",
1271
+ {
1272
+ ref: searchTriggerRef,
1273
+ type: "button",
1274
+ className: cn.cn(
1275
+ MainNavigation_module["main-navigation__icon-nav-item"],
1276
+ isSearchOpen && MainNavigation_module["main-navigation__icon-nav-item--active"],
1277
+ focus_module.default.focusableInset
1278
+ ),
1279
+ "aria-label": searchLabel,
1280
+ "aria-expanded": isSearchOpen,
1281
+ "aria-controls": isSearchOpen ? searchDropdownId : void 0,
1282
+ onClick: handleSearchClick,
1283
+ children: [
1284
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {}),
1285
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: MainNavigation_module["main-navigation__icon-nav-label"], children: searchLabel })
1286
+ ]
1287
+ }
1288
+ ),
1289
+ isSearchOpen && /* @__PURE__ */ jsxRuntime.jsx(
1290
+ "span",
1291
+ {
1292
+ "aria-hidden": "true",
1293
+ className: MainNavigation_module["main-navigation__dropdown-caret"]
1294
+ }
1295
+ )
1296
+ ] }),
1049
1297
  showCart && /* @__PURE__ */ jsxRuntime.jsxs(
1050
1298
  "button",
1051
1299
  {
1052
1300
  type: "button",
1053
1301
  className: cn.cn(
1054
1302
  MainNavigation_module["main-navigation__icon-nav-item"],
1055
- focus_module.default.focusableInset,
1056
- focus_module.default.focusableRadiusSm
1303
+ isCartOpen && MainNavigation_module["main-navigation__icon-nav-item--active"],
1304
+ focus_module.default.focusableInset
1057
1305
  ),
1058
1306
  "aria-label": cartAccessibleLabel,
1059
- onClick: onCartClick,
1307
+ "aria-expanded": isCartOpen,
1308
+ onClick: handleCartClick,
1060
1309
  children: [
1061
1310
  /* @__PURE__ */ jsxRuntime.jsx(icons.Cart, {}),
1062
1311
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: MainNavigation_module["main-navigation__icon-nav-label"], children: cartLabel }),
@@ -1071,16 +1320,53 @@ const MainNavigation = ({
1071
1320
  ]
1072
1321
  }
1073
1322
  ),
1074
- /* @__PURE__ */ jsxRuntime.jsx(
1075
- Button.Button,
1076
- {
1077
- href: MainNavigation_utils.toNavigableHref(loginHref),
1078
- size: "small",
1079
- renderLink: renderUtilityLink,
1080
- children: loginLabel
1081
- }
1082
- )
1323
+ showLogin && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: MainNavigation_module["main-navigation__utility"], children: [
1324
+ /* @__PURE__ */ jsxRuntime.jsx(
1325
+ Button.Button,
1326
+ {
1327
+ ref: loginTriggerRef,
1328
+ size: "small",
1329
+ "aria-expanded": isLoginOpen,
1330
+ "aria-controls": isLoginOpen ? loginDropdownId : void 0,
1331
+ onClick: handleLoginClick,
1332
+ children: loginLabel
1333
+ }
1334
+ ),
1335
+ isLoginOpen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1336
+ /* @__PURE__ */ jsxRuntime.jsx(
1337
+ "span",
1338
+ {
1339
+ "aria-hidden": "true",
1340
+ className: MainNavigation_module["main-navigation__dropdown-caret"]
1341
+ }
1342
+ ),
1343
+ /* @__PURE__ */ jsxRuntime.jsx(
1344
+ "div",
1345
+ {
1346
+ id: loginDropdownId,
1347
+ className: cn.cn(
1348
+ MainNavigation_module["main-navigation__dropdown"],
1349
+ MainNavigation_module["main-navigation__dropdown--login"],
1350
+ elevation_module.default.elevationMedium
1351
+ ),
1352
+ children: loginDropdownContent
1353
+ }
1354
+ )
1355
+ ] })
1356
+ ] })
1083
1357
  ] }),
1358
+ showSearch && isSearchOpen && /* @__PURE__ */ jsxRuntime.jsx(
1359
+ "div",
1360
+ {
1361
+ id: searchDropdownId,
1362
+ className: cn.cn(
1363
+ MainNavigation_module["main-navigation__dropdown"],
1364
+ MainNavigation_module["main-navigation__dropdown--search"],
1365
+ elevation_module.default.elevationMedium
1366
+ ),
1367
+ children: searchDropdownContent
1368
+ }
1369
+ ),
1084
1370
  /* @__PURE__ */ jsxRuntime.jsx(
1085
1371
  "button",
1086
1372
  {
@@ -1089,8 +1375,7 @@ const MainNavigation = ({
1089
1375
  className: cn.cn(
1090
1376
  MainNavigation_module["main-navigation__menu-toggle"],
1091
1377
  mobileMenuOpen && MainNavigation_module["main-navigation__menu-toggle--open"],
1092
- focus_module.default.focusableInset,
1093
- focus_module.default.focusableRadiusSm
1378
+ focus_module.default.focusableInset
1094
1379
  ),
1095
1380
  "aria-label": mobileMenuOpen ? mobileMenuCloseAriaLabel : mobileMenuOpenAriaLabel,
1096
1381
  "aria-expanded": mobileMenuOpen,
@@ -1101,6 +1386,16 @@ const MainNavigation = ({
1101
1386
  ] }),
1102
1387
  !mobileMenuOpen && renderPanel(
1103
1388
  cn.cn(MainNavigation_module["main-navigation__panel"], MainNavigation_module["main-navigation__panel--desktop"])
1389
+ ),
1390
+ showCart && /* @__PURE__ */ jsxRuntime.jsx(
1391
+ Drawer.Drawer,
1392
+ {
1393
+ open: isCartOpen,
1394
+ onOpenChange: handleCartOpenChange,
1395
+ title: cartLabel,
1396
+ size: "small",
1397
+ children: cartContent
1398
+ }
1104
1399
  )
1105
1400
  ]
1106
1401
  }