@hortonstudio/main 1.2.34 → 1.4.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.
@@ -1,81 +1,177 @@
1
+ // Global accessibility state
2
+ let supportsInert = null;
3
+ let screenReaderLiveRegion = null;
4
+
1
5
  export const init = () => {
6
+ // Ensure DOM is ready before initializing
7
+ if (document.readyState === "loading") {
8
+ document.addEventListener("DOMContentLoaded", initializeNavbar);
9
+ } else {
10
+ initializeNavbar();
11
+ }
12
+ return { result: "navbar initialized" };
13
+ };
14
+
15
+ function initializeNavbar() {
16
+ setupAccessibilityFeatures();
2
17
  setupDynamicDropdowns();
3
18
  setupMobileMenuButton();
4
19
  setupMobileMenuARIA();
5
20
  setupMobileMenuBreakpointHandler();
6
- return { result: 'navbar initialized' };
7
- };
21
+ }
22
+
23
+ // Accessibility features setup
24
+ function setupAccessibilityFeatures() {
25
+ // Check inert support once
26
+ supportsInert = "inert" in HTMLElement.prototype;
27
+
28
+ // Create screen reader live region only if body exists
29
+ if (document.body) {
30
+ screenReaderLiveRegion = document.createElement("div");
31
+ screenReaderLiveRegion.setAttribute("aria-live", "polite");
32
+ screenReaderLiveRegion.setAttribute("aria-atomic", "true");
33
+ screenReaderLiveRegion.className = "u-sr-only";
34
+ screenReaderLiveRegion.style.cssText =
35
+ "position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;";
36
+ document.body.appendChild(screenReaderLiveRegion);
37
+ }
38
+ }
39
+
40
+ // Inert polyfill for browsers that don't support it
41
+ function setElementInert(element, isInert) {
42
+ if (supportsInert) {
43
+ element.inert = isInert;
44
+ } else {
45
+ // Polyfill: manage tabindex for all focusable elements
46
+ const focusableSelectors =
47
+ 'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])';
48
+ const focusableElements = element.querySelectorAll(focusableSelectors);
49
+
50
+ if (isInert) {
51
+ // Store original tabindex values and disable
52
+ focusableElements.forEach((el) => {
53
+ const currentTabindex = el.getAttribute("tabindex");
54
+ el.setAttribute("data-inert-tabindex", currentTabindex || "0");
55
+ el.setAttribute("tabindex", "-1");
56
+ });
57
+ element.setAttribute("data-inert", "true");
58
+ } else {
59
+ // Restore original tabindex values
60
+ focusableElements.forEach((el) => {
61
+ const originalTabindex = el.getAttribute("data-inert-tabindex");
62
+ if (originalTabindex === "0") {
63
+ el.removeAttribute("tabindex");
64
+ } else if (originalTabindex) {
65
+ el.setAttribute("tabindex", originalTabindex);
66
+ }
67
+ el.removeAttribute("data-inert-tabindex");
68
+ });
69
+ element.removeAttribute("data-inert");
70
+ }
71
+ }
72
+ }
73
+
74
+ // Screen reader announcements
75
+ function announceToScreenReader(message) {
76
+ if (screenReaderLiveRegion) {
77
+ screenReaderLiveRegion.textContent = message;
78
+
79
+ // Clear after a delay to allow for repeat announcements
80
+ setTimeout(() => {
81
+ screenReaderLiveRegion.textContent = "";
82
+ }, 1000);
83
+ }
84
+ }
85
+
86
+ // Extract menu name from element text or aria-label
87
+ function getMenuName(element) {
88
+ const text =
89
+ (element.textContent && element.textContent.trim()) ||
90
+ element.getAttribute("aria-label") ||
91
+ "menu";
92
+ return text
93
+ .replace(/^(Open|Close)\s+/i, "")
94
+ .replace(/\s+(menu|navigation)$/i, "");
95
+ }
8
96
 
9
97
  // Desktop dropdown system
10
98
  function setupDynamicDropdowns() {
11
- const dropdownWrappers = document.querySelectorAll('[data-hs-nav="dropdown"]');
99
+ const dropdownWrappers = document.querySelectorAll(
100
+ '[data-hs-nav="dropdown"]',
101
+ );
12
102
  const allDropdowns = [];
13
-
103
+
14
104
  const closeAllDropdowns = (exceptWrapper = null) => {
15
- allDropdowns.forEach(dropdown => {
105
+ allDropdowns.forEach((dropdown) => {
16
106
  if (dropdown.wrapper !== exceptWrapper && dropdown.isOpen) {
17
107
  dropdown.closeDropdown();
18
108
  }
19
109
  });
20
110
  };
21
-
22
- dropdownWrappers.forEach(wrapper => {
23
- const toggle = wrapper.querySelector('a');
111
+
112
+ dropdownWrappers.forEach((wrapper) => {
113
+ const toggle = wrapper.querySelector("a");
24
114
  if (!toggle) return;
25
-
26
- const allElements = wrapper.querySelectorAll('*');
115
+
116
+ const allElements = wrapper.querySelectorAll("*");
27
117
  let dropdownList = null;
28
-
118
+
29
119
  for (const element of allElements) {
30
- const links = element.querySelectorAll('a');
120
+ const links = element.querySelectorAll("a");
31
121
  if (links.length >= 2 && !element.contains(toggle)) {
32
122
  dropdownList = element;
33
123
  break;
34
124
  }
35
125
  }
36
-
126
+
37
127
  if (!dropdownList) return;
38
-
39
- const toggleText = toggle.textContent?.trim() || 'dropdown';
128
+
129
+ const toggleText =
130
+ (toggle.textContent && toggle.textContent.trim()) || "dropdown";
40
131
  const sanitizedText = sanitizeForID(toggleText);
41
132
  const toggleId = `navbar-dropdown-${sanitizedText}-toggle`;
42
133
  const listId = `navbar-dropdown-${sanitizedText}-list`;
43
-
134
+
44
135
  toggle.id = toggleId;
45
- toggle.setAttribute('aria-haspopup', 'menu');
46
- toggle.setAttribute('aria-expanded', 'false');
47
- toggle.setAttribute('aria-controls', listId);
48
-
136
+ toggle.setAttribute("aria-haspopup", "menu");
137
+ toggle.setAttribute("aria-expanded", "false");
138
+ toggle.setAttribute("aria-controls", listId);
139
+
49
140
  dropdownList.id = listId;
50
- dropdownList.setAttribute('role', 'menu');
51
- dropdownList.setAttribute('aria-hidden', 'true');
52
-
53
- const menuItems = dropdownList.querySelectorAll('a');
54
- menuItems.forEach(item => {
55
- item.setAttribute('role', 'menuitem');
56
- item.setAttribute('tabindex', '-1');
141
+ dropdownList.setAttribute("role", "menu");
142
+ dropdownList.setAttribute("aria-hidden", "true");
143
+
144
+ const menuItems = dropdownList.querySelectorAll("a");
145
+ menuItems.forEach((item) => {
146
+ item.setAttribute("role", "menuitem");
147
+ item.setAttribute("tabindex", "-1");
57
148
  });
58
-
149
+
59
150
  let isOpen = false;
60
151
  let currentMenuItemIndex = -1;
61
-
152
+
62
153
  function openDropdown() {
63
154
  if (isOpen) return;
64
155
  closeAllDropdowns(wrapper);
65
156
  isOpen = true;
66
- toggle.setAttribute('aria-expanded', 'true');
67
- dropdownList.setAttribute('aria-hidden', 'false');
68
- menuItems.forEach(item => {
69
- item.setAttribute('tabindex', '0');
157
+ toggle.setAttribute("aria-expanded", "true");
158
+ dropdownList.setAttribute("aria-hidden", "false");
159
+ menuItems.forEach((item) => {
160
+ item.setAttribute("tabindex", "0");
70
161
  });
71
- const clickEvent = new MouseEvent('click', {
162
+
163
+ // Announce to screen readers
164
+ const menuName = getMenuName(toggle);
165
+ announceToScreenReader(`${menuName} menu opened`);
166
+
167
+ const clickEvent = new MouseEvent("click", {
72
168
  bubbles: true,
73
169
  cancelable: true,
74
- view: window
170
+ view: window,
75
171
  });
76
172
  wrapper.dispatchEvent(clickEvent);
77
173
  }
78
-
174
+
79
175
  function closeDropdown() {
80
176
  if (!isOpen) return;
81
177
  const shouldRestoreFocus = dropdownList.contains(document.activeElement);
@@ -84,71 +180,80 @@ function setupDynamicDropdowns() {
84
180
  if (shouldRestoreFocus) {
85
181
  toggle.focus();
86
182
  }
87
- toggle.setAttribute('aria-expanded', 'false');
88
- dropdownList.setAttribute('aria-hidden', 'true');
89
- menuItems.forEach(item => {
90
- item.setAttribute('tabindex', '-1');
183
+ toggle.setAttribute("aria-expanded", "false");
184
+ dropdownList.setAttribute("aria-hidden", "true");
185
+ menuItems.forEach((item) => {
186
+ item.setAttribute("tabindex", "-1");
91
187
  });
92
- const clickEvent = new MouseEvent('click', {
188
+
189
+ // Announce to screen readers
190
+ const menuName = getMenuName(toggle);
191
+ announceToScreenReader(`${menuName} menu closed`);
192
+
193
+ const clickEvent = new MouseEvent("click", {
93
194
  bubbles: true,
94
195
  cancelable: true,
95
- view: window
196
+ view: window,
96
197
  });
97
198
  wrapper.dispatchEvent(clickEvent);
98
199
  }
99
-
100
- wrapper.addEventListener('mouseenter', () => {
200
+
201
+ wrapper.addEventListener("mouseenter", () => {
101
202
  if (!isOpen) {
102
- const clickEvent = new MouseEvent('click', {
203
+ const clickEvent = new MouseEvent("click", {
103
204
  bubbles: true,
104
205
  cancelable: true,
105
- view: window
206
+ view: window,
106
207
  });
107
208
  wrapper.dispatchEvent(clickEvent);
108
209
  closeAllDropdowns(wrapper);
109
210
  isOpen = true;
110
- toggle.setAttribute('aria-expanded', 'true');
111
- dropdownList.setAttribute('aria-hidden', 'false');
112
- menuItems.forEach(item => {
113
- item.setAttribute('tabindex', '0');
211
+ toggle.setAttribute("aria-expanded", "true");
212
+ dropdownList.setAttribute("aria-hidden", "false");
213
+ menuItems.forEach((item) => {
214
+ item.setAttribute("tabindex", "0");
114
215
  });
115
216
  }
116
217
  });
117
-
118
- wrapper.addEventListener('mouseleave', () => {
218
+
219
+ wrapper.addEventListener("mouseleave", () => {
119
220
  if (isOpen) {
120
221
  if (dropdownList.contains(document.activeElement)) {
121
222
  toggle.focus();
122
223
  }
123
- const clickEvent = new MouseEvent('click', {
224
+ const clickEvent = new MouseEvent("click", {
124
225
  bubbles: true,
125
226
  cancelable: true,
126
- view: window
227
+ view: window,
127
228
  });
128
229
  wrapper.dispatchEvent(clickEvent);
129
230
  isOpen = false;
130
- toggle.setAttribute('aria-expanded', 'false');
131
- dropdownList.setAttribute('aria-hidden', 'true');
132
- menuItems.forEach(item => {
133
- item.setAttribute('tabindex', '-1');
231
+ toggle.setAttribute("aria-expanded", "false");
232
+ dropdownList.setAttribute("aria-hidden", "true");
233
+ menuItems.forEach((item) => {
234
+ item.setAttribute("tabindex", "-1");
134
235
  });
135
236
  currentMenuItemIndex = -1;
136
237
  }
137
238
  });
138
-
139
- document.addEventListener('keydown', function(e) {
239
+
240
+ document.addEventListener("keydown", function (e) {
140
241
  if (!isOpen) return;
141
242
  if (!wrapper.contains(document.activeElement)) return;
142
-
143
- if (e.key === 'ArrowDown') {
243
+
244
+ if (e.key === "ArrowDown") {
144
245
  e.preventDefault();
145
246
  if (document.activeElement === toggle) {
146
247
  currentMenuItemIndex = 0;
147
248
  menuItems[currentMenuItemIndex].focus();
148
249
  } else {
149
250
  if (currentMenuItemIndex === menuItems.length - 1) {
150
- const nextElement = wrapper.nextElementSibling?.querySelector('a, button') ||
151
- document.querySelector('.navbar_cartsearch_wrap a, .navbar_cartsearch_wrap button');
251
+ const nextElement =
252
+ (wrapper.nextElementSibling &&
253
+ wrapper.nextElementSibling.querySelector("a, button")) ||
254
+ document.querySelector(
255
+ ".navbar_cartsearch_wrap a, .navbar_cartsearch_wrap button",
256
+ );
152
257
  if (nextElement) {
153
258
  closeDropdown();
154
259
  nextElement.focus();
@@ -158,14 +263,16 @@ function setupDynamicDropdowns() {
158
263
  currentMenuItemIndex = (currentMenuItemIndex + 1) % menuItems.length;
159
264
  menuItems[currentMenuItemIndex].focus();
160
265
  }
161
- } else if (e.key === 'ArrowUp') {
266
+ } else if (e.key === "ArrowUp") {
162
267
  e.preventDefault();
163
268
  if (document.activeElement === toggle) {
164
269
  currentMenuItemIndex = menuItems.length - 1;
165
270
  menuItems[currentMenuItemIndex].focus();
166
271
  } else {
167
272
  if (currentMenuItemIndex === 0) {
168
- const prevElement = wrapper.previousElementSibling?.querySelector('a, button');
273
+ const prevElement =
274
+ wrapper.previousElementSibling &&
275
+ wrapper.previousElementSibling.querySelector("a, button");
169
276
  if (prevElement) {
170
277
  closeDropdown();
171
278
  prevElement.focus();
@@ -176,10 +283,13 @@ function setupDynamicDropdowns() {
176
283
  return;
177
284
  }
178
285
  }
179
- currentMenuItemIndex = currentMenuItemIndex <= 0 ? menuItems.length - 1 : currentMenuItemIndex - 1;
286
+ currentMenuItemIndex =
287
+ currentMenuItemIndex <= 0
288
+ ? menuItems.length - 1
289
+ : currentMenuItemIndex - 1;
180
290
  menuItems[currentMenuItemIndex].focus();
181
291
  }
182
- } else if (e.key === 'Tab') {
292
+ } else if (e.key === "Tab") {
183
293
  if (e.shiftKey) {
184
294
  if (document.activeElement === menuItems[0]) {
185
295
  e.preventDefault();
@@ -189,8 +299,12 @@ function setupDynamicDropdowns() {
189
299
  } else {
190
300
  if (document.activeElement === menuItems[menuItems.length - 1]) {
191
301
  e.preventDefault();
192
- const nextElement = wrapper.nextElementSibling?.querySelector('a, button') ||
193
- document.querySelector('.navbar_cartsearch_wrap a, .navbar_cartsearch_wrap button');
302
+ const nextElement =
303
+ (wrapper.nextElementSibling &&
304
+ wrapper.nextElementSibling.querySelector("a, button")) ||
305
+ document.querySelector(
306
+ ".navbar_cartsearch_wrap a, .navbar_cartsearch_wrap button",
307
+ );
194
308
  closeDropdown();
195
309
  if (nextElement) {
196
310
  setTimeout(() => {
@@ -199,32 +313,32 @@ function setupDynamicDropdowns() {
199
313
  }
200
314
  }
201
315
  }
202
- } else if (e.key === 'Escape') {
316
+ } else if (e.key === "Escape") {
203
317
  e.preventDefault();
204
318
  closeDropdown();
205
319
  toggle.focus();
206
- } else if (e.key === 'Home') {
320
+ } else if (e.key === "Home") {
207
321
  e.preventDefault();
208
322
  currentMenuItemIndex = 0;
209
323
  menuItems[0].focus();
210
- } else if (e.key === 'End') {
324
+ } else if (e.key === "End") {
211
325
  e.preventDefault();
212
326
  currentMenuItemIndex = menuItems.length - 1;
213
327
  menuItems[menuItems.length - 1].focus();
214
- } else if (e.key === ' ') {
328
+ } else if (e.key === " ") {
215
329
  e.preventDefault();
216
330
  }
217
331
  });
218
-
219
- toggle.addEventListener('keydown', function(e) {
220
- if (e.key === 'ArrowDown') {
332
+
333
+ toggle.addEventListener("keydown", function (e) {
334
+ if (e.key === "ArrowDown") {
221
335
  e.preventDefault();
222
336
  openDropdown();
223
337
  if (menuItems.length > 0) {
224
338
  currentMenuItemIndex = 0;
225
339
  setTimeout(() => menuItems[0].focus(), 100);
226
340
  }
227
- } else if (e.key === ' ') {
341
+ } else if (e.key === " ") {
228
342
  e.preventDefault();
229
343
  if (isOpen) {
230
344
  closeDropdown();
@@ -235,7 +349,7 @@ function setupDynamicDropdowns() {
235
349
  setTimeout(() => menuItems[0].focus(), 100);
236
350
  }
237
351
  }
238
- } else if (e.key === 'ArrowUp') {
352
+ } else if (e.key === "ArrowUp") {
239
353
  e.preventDefault();
240
354
  if (isOpen) {
241
355
  currentMenuItemIndex = menuItems.length - 1;
@@ -243,29 +357,29 @@ function setupDynamicDropdowns() {
243
357
  } else {
244
358
  closeDropdown();
245
359
  }
246
- } else if (e.key === 'Escape') {
360
+ } else if (e.key === "Escape") {
247
361
  e.preventDefault();
248
362
  closeDropdown();
249
363
  }
250
364
  });
251
-
252
- document.addEventListener('click', function(e) {
365
+
366
+ document.addEventListener("click", function (e) {
253
367
  if (!wrapper.contains(e.target) && isOpen) {
254
368
  closeDropdown();
255
369
  }
256
370
  });
257
-
371
+
258
372
  allDropdowns.push({
259
373
  wrapper,
260
374
  isOpen: () => isOpen,
261
375
  closeDropdown,
262
376
  toggle,
263
- dropdownList
377
+ dropdownList,
264
378
  });
265
379
  });
266
-
267
- document.addEventListener('focusin', function(e) {
268
- allDropdowns.forEach(dropdown => {
380
+
381
+ document.addEventListener("focusin", function (e) {
382
+ allDropdowns.forEach((dropdown) => {
269
383
  if (dropdown.isOpen() && !dropdown.wrapper.contains(e.target)) {
270
384
  dropdown.closeDropdown();
271
385
  }
@@ -277,66 +391,73 @@ function setupDynamicDropdowns() {
277
391
 
278
392
  // Desktop left/right arrow navigation
279
393
  function addDesktopArrowNavigation() {
280
- document.addEventListener('keydown', function(e) {
281
- if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;
282
-
394
+ document.addEventListener("keydown", function (e) {
395
+ if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
396
+
283
397
  const mobileMenu = document.querySelector('[data-hs-nav="menu"]');
284
398
  if (mobileMenu && mobileMenu.contains(document.activeElement)) return;
285
-
286
- const navbar = document.querySelector('[data-hs-nav="wrapper"]') ||
287
- document.querySelector('.navbar_component') ||
288
- document.querySelector('nav[role="navigation"]') ||
289
- document.querySelector('nav');
290
-
399
+
400
+ const navbar =
401
+ document.querySelector('[data-hs-nav="wrapper"]') ||
402
+ document.querySelector(".navbar_component") ||
403
+ document.querySelector('nav[role="navigation"]') ||
404
+ document.querySelector("nav");
405
+
291
406
  if (!navbar || !navbar.contains(document.activeElement)) return;
292
-
293
- const openDropdownList = navbar.querySelector('[aria-hidden="false"][role="menu"]');
294
- if (openDropdownList && openDropdownList.contains(document.activeElement)) return;
295
-
407
+
408
+ const openDropdownList = navbar.querySelector(
409
+ '[aria-hidden="false"][role="menu"]',
410
+ );
411
+ if (openDropdownList && openDropdownList.contains(document.activeElement))
412
+ return;
413
+
296
414
  e.preventDefault();
297
-
298
- const allNavbarElements = navbar.querySelectorAll('a, button');
299
- const focusableElements = Array.from(allNavbarElements).filter(el => {
300
- if (el.getAttribute('tabindex') === '-1') return false;
301
-
415
+
416
+ const allNavbarElements = navbar.querySelectorAll("a, button");
417
+ const focusableElements = Array.from(allNavbarElements).filter((el) => {
418
+ if (el.getAttribute("tabindex") === "-1") return false;
419
+
302
420
  const isInDropdownList = el.closest('[role="menu"]');
303
421
  if (isInDropdownList) return false;
304
-
422
+
305
423
  const isInMobileMenu = el.closest('[data-hs-nav="menu"]');
306
424
  if (isInMobileMenu) return false;
307
-
425
+
308
426
  const computedStyle = window.getComputedStyle(el);
309
- const isHidden = computedStyle.display === 'none' ||
310
- computedStyle.visibility === 'hidden' ||
311
- computedStyle.opacity === '0' ||
312
- el.offsetWidth === 0 ||
313
- el.offsetHeight === 0;
427
+ const isHidden =
428
+ computedStyle.display === "none" ||
429
+ computedStyle.visibility === "hidden" ||
430
+ computedStyle.opacity === "0" ||
431
+ el.offsetWidth === 0 ||
432
+ el.offsetHeight === 0;
314
433
  if (isHidden) return false;
315
-
434
+
316
435
  let parent = el.parentElement;
317
436
  while (parent && parent !== navbar) {
318
437
  const parentStyle = window.getComputedStyle(parent);
319
- const parentHidden = parentStyle.display === 'none' ||
320
- parentStyle.visibility === 'hidden' ||
321
- parent.offsetWidth === 0 ||
322
- parent.offsetHeight === 0;
438
+ const parentHidden =
439
+ parentStyle.display === "none" ||
440
+ parentStyle.visibility === "hidden" ||
441
+ parent.offsetWidth === 0 ||
442
+ parent.offsetHeight === 0;
323
443
  if (parentHidden) return false;
324
444
  parent = parent.parentElement;
325
445
  }
326
-
446
+
327
447
  return true;
328
448
  });
329
-
449
+
330
450
  const currentIndex = focusableElements.indexOf(document.activeElement);
331
451
  if (currentIndex === -1) return;
332
-
452
+
333
453
  let nextIndex;
334
- if (e.key === 'ArrowRight') {
454
+ if (e.key === "ArrowRight") {
335
455
  nextIndex = (currentIndex + 1) % focusableElements.length;
336
456
  } else {
337
- nextIndex = currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1;
457
+ nextIndex =
458
+ currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1;
338
459
  }
339
-
460
+
340
461
  focusableElements[nextIndex].focus();
341
462
  });
342
463
  }
@@ -345,233 +466,287 @@ function addDesktopArrowNavigation() {
345
466
  function setupMobileMenuButton() {
346
467
  const menuButton = document.querySelector('[data-hs-nav="menubtn"]');
347
468
  const mobileMenu = document.querySelector('[data-hs-nav="menu"]');
348
-
469
+
349
470
  if (!menuButton || !mobileMenu) return;
350
-
471
+
351
472
  const menuId = `mobile-menu-${Date.now()}`;
352
-
353
- menuButton.setAttribute('aria-expanded', 'false');
354
- menuButton.setAttribute('aria-controls', menuId);
355
- menuButton.setAttribute('aria-label', 'Open navigation menu');
356
-
473
+
474
+ menuButton.setAttribute("aria-expanded", "false");
475
+ menuButton.setAttribute("aria-controls", menuId);
476
+ menuButton.setAttribute("aria-label", "Open navigation menu");
477
+
357
478
  mobileMenu.id = menuId;
358
- mobileMenu.setAttribute('role', 'dialog');
359
- mobileMenu.setAttribute('aria-modal', 'true');
360
- mobileMenu.inert = true;
361
-
479
+ mobileMenu.setAttribute("role", "dialog");
480
+ mobileMenu.setAttribute("aria-modal", "true");
481
+ setElementInert(mobileMenu, true);
482
+
362
483
  let isMenuOpen = false;
363
-
484
+
364
485
  function shouldPreventMobileMenu() {
365
- const menuSizeElement = document.querySelector('.menu-size.is-mobile');
366
- if (!menuSizeElement) return false;
367
-
368
- const computedStyle = window.getComputedStyle(menuSizeElement);
369
- return computedStyle.display === 'none';
486
+ const menuHideElement = document.querySelector(".menu-hide.is-mobile");
487
+ if (!menuHideElement) return false;
488
+
489
+ const computedStyle = window.getComputedStyle(menuHideElement);
490
+ return computedStyle.display === "none";
370
491
  }
371
-
492
+
372
493
  function openMenu() {
373
494
  if (isMenuOpen || shouldPreventMobileMenu()) return;
374
495
  isMenuOpen = true;
375
-
376
- // Add body overflow hidden class
377
- document.body.classList.add('u-overflow-hidden');
378
-
379
- // Add blur effect to modal blur elements
380
- document.querySelectorAll('[data-hs-nav="modal-blur"]').forEach(element => {
381
- element.style.display = 'block';
382
- element.style.opacity = '0.5';
383
- element.style.transition = 'opacity 0.3s ease';
384
- });
385
-
386
- menuButton.setAttribute('aria-expanded', 'true');
387
- menuButton.setAttribute('aria-label', 'Close navigation menu');
388
- mobileMenu.inert = false;
389
-
390
- // Prevent tabbing outside navbar using tabindex management
391
- const navbarWrapper = document.querySelector('[data-hs-nav="wrapper"]') ||
392
- document.querySelector('.navbar_component') ||
393
- document.querySelector('nav[role="navigation"]') ||
394
- document.querySelector('nav');
395
-
396
- const allFocusableElements = document.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
397
- allFocusableElements.forEach(el => {
398
- if (navbarWrapper && !navbarWrapper.contains(el)) {
399
- el.setAttribute('data-mobile-menu-tabindex', el.getAttribute('tabindex') || '0');
400
- el.setAttribute('tabindex', '-1');
401
- }
402
- });
403
-
404
- const clickEvent = new MouseEvent('click', {
405
- bubbles: true,
406
- cancelable: true,
407
- view: window
408
- });
409
- menuButton.dispatchEvent(clickEvent);
496
+
497
+ try {
498
+ // Add body overflow hidden class
499
+ document.body.classList.add("u-overflow-hidden");
500
+
501
+ // Add blur effect to modal blur elements
502
+ document
503
+ .querySelectorAll('[data-hs-nav="modal-blur"]')
504
+ .forEach((element) => {
505
+ element.style.display = "block";
506
+ element.style.opacity = "0.5";
507
+ element.style.transition = "opacity 0.3s ease";
508
+ });
509
+
510
+ menuButton.setAttribute("aria-expanded", "true");
511
+ menuButton.setAttribute("aria-label", "Close navigation menu");
512
+ setElementInert(mobileMenu, false);
513
+
514
+ // Announce to screen readers
515
+ const menuName = getMenuName(menuButton);
516
+ announceToScreenReader(`${menuName} opened`);
517
+
518
+ // Prevent tabbing outside navbar using tabindex management
519
+ const navbarWrapper =
520
+ document.querySelector('[data-hs-nav="wrapper"]') ||
521
+ document.querySelector(".navbar_component") ||
522
+ document.querySelector('nav[role="navigation"]') ||
523
+ document.querySelector("nav");
524
+
525
+ const allFocusableElements = document.querySelectorAll(
526
+ 'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])',
527
+ );
528
+ allFocusableElements.forEach((el) => {
529
+ if (navbarWrapper && !navbarWrapper.contains(el)) {
530
+ el.setAttribute(
531
+ "data-mobile-menu-tabindex",
532
+ el.getAttribute("tabindex") || "0",
533
+ );
534
+ el.setAttribute("tabindex", "-1");
535
+ }
536
+ });
537
+
538
+ const clickEvent = new MouseEvent("click", {
539
+ bubbles: true,
540
+ cancelable: true,
541
+ view: window,
542
+ });
543
+ menuButton.dispatchEvent(clickEvent);
544
+ } catch (e) {
545
+ // DOM operation failed, restore state
546
+ isMenuOpen = false;
547
+ menuButton.setAttribute("aria-expanded", "false");
548
+ menuButton.setAttribute("aria-label", "Open navigation menu");
549
+ }
410
550
  }
411
-
551
+
412
552
  function closeMenu() {
413
553
  if (!isMenuOpen) return;
414
554
  isMenuOpen = false;
415
-
416
- // Remove body overflow hidden class
417
- document.body.classList.remove('u-overflow-hidden');
418
-
419
- // Remove blur effect from modal blur elements
420
- document.querySelectorAll('[data-hs-nav="modal-blur"]').forEach(element => {
421
- element.style.opacity = '0';
422
- element.style.transition = 'opacity 0.3s ease';
423
- setTimeout(() => {
424
- element.style.display = 'none';
425
- }, 300);
426
- });
427
-
428
- if (mobileMenu.contains(document.activeElement)) {
429
- menuButton.focus();
430
- }
431
- menuButton.setAttribute('aria-expanded', 'false');
432
- menuButton.setAttribute('aria-label', 'Open navigation menu');
433
- mobileMenu.inert = true;
434
-
435
- // Restore tabbing to entire page using tabindex management
436
- const elementsToRestore = document.querySelectorAll('[data-mobile-menu-tabindex]');
437
- elementsToRestore.forEach(el => {
438
- const originalTabindex = el.getAttribute('data-mobile-menu-tabindex');
439
- if (originalTabindex === '0') {
440
- el.removeAttribute('tabindex');
441
- } else {
442
- el.setAttribute('tabindex', originalTabindex);
555
+
556
+ try {
557
+ // Remove body overflow hidden class
558
+ document.body.classList.remove("u-overflow-hidden");
559
+
560
+ // Remove blur effect from modal blur elements
561
+ document
562
+ .querySelectorAll('[data-hs-nav="modal-blur"]')
563
+ .forEach((element) => {
564
+ element.style.opacity = "0";
565
+ element.style.transition = "opacity 0.3s ease";
566
+ setTimeout(() => {
567
+ element.style.display = "none";
568
+ }, 300);
569
+ });
570
+
571
+ if (mobileMenu.contains(document.activeElement)) {
572
+ menuButton.focus();
443
573
  }
444
- el.removeAttribute('data-mobile-menu-tabindex');
445
- });
446
-
447
- const clickEvent = new MouseEvent('click', {
448
- bubbles: true,
449
- cancelable: true,
450
- view: window
451
- });
452
- menuButton.dispatchEvent(clickEvent);
574
+ menuButton.setAttribute("aria-expanded", "false");
575
+ menuButton.setAttribute("aria-label", "Open navigation menu");
576
+ setElementInert(mobileMenu, true);
577
+
578
+ // Announce to screen readers
579
+ const menuName = getMenuName(menuButton);
580
+ announceToScreenReader(`${menuName} closed`);
581
+
582
+ // Restore tabbing to entire page using tabindex management
583
+ const elementsToRestore = document.querySelectorAll(
584
+ "[data-mobile-menu-tabindex]",
585
+ );
586
+ elementsToRestore.forEach((el) => {
587
+ const originalTabindex = el.getAttribute("data-mobile-menu-tabindex");
588
+ if (originalTabindex === "0") {
589
+ el.removeAttribute("tabindex");
590
+ } else {
591
+ el.setAttribute("tabindex", originalTabindex);
592
+ }
593
+ el.removeAttribute("data-mobile-menu-tabindex");
594
+ });
595
+
596
+ const clickEvent = new MouseEvent("click", {
597
+ bubbles: true,
598
+ cancelable: true,
599
+ view: window,
600
+ });
601
+ menuButton.dispatchEvent(clickEvent);
602
+ } catch (e) {
603
+ // DOM operation failed, ensure consistent state
604
+ isMenuOpen = false;
605
+ menuButton.setAttribute("aria-expanded", "false");
606
+ menuButton.setAttribute("aria-label", "Open navigation menu");
607
+ }
453
608
  }
454
-
609
+
455
610
  function toggleMenu() {
456
611
  if (shouldPreventMobileMenu()) return;
457
-
612
+
458
613
  if (isMenuOpen) {
459
614
  closeMenu();
460
615
  } else {
461
616
  openMenu();
462
617
  }
463
618
  }
464
-
465
- menuButton.addEventListener('keydown', function(e) {
466
- if (e.key === 'Enter' || e.key === ' ') {
619
+
620
+ menuButton.addEventListener("keydown", function (e) {
621
+ if (e.key === "Enter" || e.key === " ") {
467
622
  e.preventDefault();
468
623
  toggleMenu();
469
- } else if (e.key === 'ArrowDown') {
624
+ } else if (e.key === "ArrowDown") {
470
625
  e.preventDefault();
471
626
  if (!isMenuOpen) {
472
627
  openMenu();
473
628
  }
474
- const firstElement = mobileMenu.querySelector('button, a');
629
+ const firstElement = mobileMenu.querySelector("button, a");
475
630
  if (firstElement) {
476
631
  firstElement.focus();
477
632
  }
478
- } else if (e.key === 'ArrowUp') {
633
+ } else if (e.key === "ArrowUp") {
479
634
  e.preventDefault();
480
635
  if (isMenuOpen) {
481
636
  closeMenu();
482
637
  }
483
638
  }
484
639
  });
485
-
486
- menuButton.addEventListener('click', function(e) {
640
+
641
+ menuButton.addEventListener("click", function (e) {
487
642
  if (!e.isTrusted) return;
488
-
643
+
489
644
  if (shouldPreventMobileMenu()) return;
490
-
645
+
491
646
  if (isMenuOpen && mobileMenu.contains(document.activeElement)) {
492
647
  menuButton.focus();
493
648
  }
494
-
649
+
495
650
  const newMenuState = !isMenuOpen;
496
651
  isMenuOpen = newMenuState;
497
-
652
+
498
653
  // Handle body overflow class
499
654
  if (isMenuOpen) {
500
- document.body.classList.add('u-overflow-hidden');
655
+ document.body.classList.add("u-overflow-hidden");
501
656
  } else {
502
- document.body.classList.remove('u-overflow-hidden');
657
+ document.body.classList.remove("u-overflow-hidden");
503
658
  }
504
-
659
+
505
660
  // Handle blur effect
506
- document.querySelectorAll('[data-hs-nav="modal-blur"]').forEach(element => {
507
- if (isMenuOpen) {
508
- element.style.display = 'block';
509
- element.style.opacity = '0.5';
510
- element.style.transition = 'opacity 0.3s ease';
511
- } else {
512
- element.style.opacity = '0';
513
- element.style.transition = 'opacity 0.3s ease';
514
- setTimeout(() => {
515
- element.style.display = 'none';
516
- }, 300);
517
- }
518
- });
519
-
520
- menuButton.setAttribute('aria-expanded', isMenuOpen);
521
- menuButton.setAttribute('aria-label',
522
- isMenuOpen ? 'Close navigation menu' : 'Open navigation menu'
661
+ document
662
+ .querySelectorAll('[data-hs-nav="modal-blur"]')
663
+ .forEach((element) => {
664
+ if (isMenuOpen) {
665
+ element.style.display = "block";
666
+ element.style.opacity = "0.5";
667
+ element.style.transition = "opacity 0.3s ease";
668
+ } else {
669
+ element.style.opacity = "0";
670
+ element.style.transition = "opacity 0.3s ease";
671
+ setTimeout(() => {
672
+ element.style.display = "none";
673
+ }, 300);
674
+ }
675
+ });
676
+
677
+ menuButton.setAttribute("aria-expanded", isMenuOpen);
678
+ menuButton.setAttribute(
679
+ "aria-label",
680
+ isMenuOpen ? "Close navigation menu" : "Open navigation menu",
523
681
  );
524
- mobileMenu.inert = !isMenuOpen;
525
-
682
+ setElementInert(mobileMenu, !isMenuOpen);
683
+
526
684
  // Handle tabindex management for external clicks
527
685
  if (isMenuOpen) {
528
- const navbarWrapper = document.querySelector('[data-hs-nav="wrapper"]') ||
529
- document.querySelector('.navbar_component') ||
530
- document.querySelector('nav[role="navigation"]') ||
531
- document.querySelector('nav');
532
-
533
- const allFocusableElements = document.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
534
- allFocusableElements.forEach(el => {
686
+ const navbarWrapper =
687
+ document.querySelector('[data-hs-nav="wrapper"]') ||
688
+ document.querySelector(".navbar_component") ||
689
+ document.querySelector('nav[role="navigation"]') ||
690
+ document.querySelector("nav");
691
+
692
+ const allFocusableElements = document.querySelectorAll(
693
+ 'a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])',
694
+ );
695
+ allFocusableElements.forEach((el) => {
535
696
  if (navbarWrapper && !navbarWrapper.contains(el)) {
536
- el.setAttribute('data-mobile-menu-tabindex', el.getAttribute('tabindex') || '0');
537
- el.setAttribute('tabindex', '-1');
697
+ el.setAttribute(
698
+ "data-mobile-menu-tabindex",
699
+ el.getAttribute("tabindex") || "0",
700
+ );
701
+ el.setAttribute("tabindex", "-1");
538
702
  }
539
703
  });
540
704
  } else {
541
- const elementsToRestore = document.querySelectorAll('[data-mobile-menu-tabindex]');
542
- elementsToRestore.forEach(el => {
543
- const originalTabindex = el.getAttribute('data-mobile-menu-tabindex');
544
- if (originalTabindex === '0') {
545
- el.removeAttribute('tabindex');
705
+ const elementsToRestore = document.querySelectorAll(
706
+ "[data-mobile-menu-tabindex]",
707
+ );
708
+ elementsToRestore.forEach((el) => {
709
+ const originalTabindex = el.getAttribute("data-mobile-menu-tabindex");
710
+ if (originalTabindex === "0") {
711
+ el.removeAttribute("tabindex");
546
712
  } else {
547
- el.setAttribute('tabindex', originalTabindex);
713
+ el.setAttribute("tabindex", originalTabindex);
548
714
  }
549
- el.removeAttribute('data-mobile-menu-tabindex');
715
+ el.removeAttribute("data-mobile-menu-tabindex");
550
716
  });
551
717
  }
552
718
  });
553
-
719
+
554
720
  // Store the menu state and functions for breakpoint handler
555
721
  window.mobileMenuState = {
556
722
  isMenuOpen: () => isMenuOpen,
557
723
  closeMenu: closeMenu,
558
- openMenu: openMenu
724
+ openMenu: openMenu,
559
725
  };
726
+
727
+ // Cleanup function for window.mobileMenuState
728
+ if (typeof window !== "undefined") {
729
+ window.addEventListener("unload", () => {
730
+ if (window.mobileMenuState) {
731
+ delete window.mobileMenuState;
732
+ }
733
+ });
734
+ }
560
735
  }
561
736
 
562
737
  // Mobile menu breakpoint handler
563
738
  function setupMobileMenuBreakpointHandler() {
564
739
  let preventedMenuState = false;
565
-
740
+
566
741
  function handleBreakpointChange() {
567
- const menuSizeElement = document.querySelector('.menu-size.is-mobile');
568
- if (!menuSizeElement) return;
569
-
570
- const computedStyle = window.getComputedStyle(menuSizeElement);
571
- const shouldPrevent = computedStyle.display === 'none';
572
-
742
+ const menuHideElement = document.querySelector(".menu-hide.is-mobile");
743
+ if (!menuHideElement) return;
744
+
745
+ const computedStyle = window.getComputedStyle(menuHideElement);
746
+ const shouldPrevent = computedStyle.display === "none";
747
+
573
748
  if (!window.mobileMenuState) return;
574
-
749
+
575
750
  if (shouldPrevent && window.mobileMenuState.isMenuOpen()) {
576
751
  // Store that the menu was open before being prevented
577
752
  preventedMenuState = true;
@@ -582,19 +757,24 @@ function setupMobileMenuBreakpointHandler() {
582
757
  window.mobileMenuState.openMenu();
583
758
  }
584
759
  }
585
-
760
+
586
761
  // Use ResizeObserver for more accurate detection
587
- if (window.ResizeObserver) {
588
- const resizeObserver = new ResizeObserver(handleBreakpointChange);
589
- const menuSizeElement = document.querySelector('.menu-size.is-mobile');
590
- if (menuSizeElement) {
591
- resizeObserver.observe(menuSizeElement);
762
+ if (typeof ResizeObserver !== "undefined") {
763
+ try {
764
+ const resizeObserver = new ResizeObserver(handleBreakpointChange);
765
+ const menuHideElement = document.querySelector(".menu-hide.is-mobile");
766
+ if (menuHideElement) {
767
+ resizeObserver.observe(menuHideElement);
768
+ }
769
+ } catch (e) {
770
+ // ResizeObserver not supported or error occurred
771
+ // Silently fall back to resize event
592
772
  }
593
773
  }
594
-
774
+
595
775
  // Fallback to resize event
596
- window.addEventListener('resize', handleBreakpointChange);
597
-
776
+ window.addEventListener("resize", handleBreakpointChange);
777
+
598
778
  // Initial check
599
779
  handleBreakpointChange();
600
780
  }
@@ -602,9 +782,9 @@ function setupMobileMenuBreakpointHandler() {
602
782
  function sanitizeForID(text) {
603
783
  return text
604
784
  .toLowerCase()
605
- .replace(/[^a-z0-9\s]/g, '')
606
- .replace(/\s+/g, '-')
607
- .replace(/^-+|-+$/g, '')
785
+ .replace(/[^a-z0-9\s]/g, "")
786
+ .replace(/\s+/g, "-")
787
+ .replace(/^-+|-+$/g, "")
608
788
  .substring(0, 50);
609
789
  }
610
790
 
@@ -613,11 +793,11 @@ function setupMobileMenuARIA() {
613
793
  const menuContainer = document.querySelector('[data-hs-nav="menu"]');
614
794
  if (!menuContainer) return;
615
795
 
616
- const buttons = menuContainer.querySelectorAll('button');
617
- const links = menuContainer.querySelectorAll('a');
796
+ const buttons = menuContainer.querySelectorAll("button");
797
+ const links = menuContainer.querySelectorAll("a");
618
798
 
619
- buttons.forEach(button => {
620
- const buttonText = button.textContent?.trim();
799
+ buttons.forEach((button) => {
800
+ const buttonText = button.textContent && button.textContent.trim();
621
801
  if (!buttonText) return;
622
802
 
623
803
  const sanitizedText = sanitizeForID(buttonText);
@@ -625,57 +805,77 @@ function setupMobileMenuARIA() {
625
805
  const listId = `navbar-mobile-${sanitizedText}-list`;
626
806
 
627
807
  button.id = buttonId;
628
- button.setAttribute('aria-expanded', 'false');
629
- button.setAttribute('aria-controls', listId);
808
+ button.setAttribute("aria-expanded", "false");
809
+ button.setAttribute("aria-controls", listId);
630
810
 
631
- let dropdownList = button.nextElementSibling;
632
-
633
- if (!dropdownList || !dropdownList.querySelector('a')) {
634
- dropdownList = button.parentElement?.nextElementSibling;
635
- }
636
-
637
- if (!dropdownList || !dropdownList.querySelector('a')) {
638
- const parent = button.closest('[data-hs-nav="menu"]');
639
- const allListElements = parent?.querySelectorAll('div, ul, nav');
640
- dropdownList = Array.from(allListElements || []).find(el =>
641
- el.querySelectorAll('a').length > 1 &&
642
- !el.contains(button)
811
+ // Look for dropdown list in the same container as the button
812
+ let dropdownList = null;
813
+ const buttonContainer = button.closest(
814
+ '.menu-card_dropdown, .menu_contain, [data-hs-nav="menu"]',
815
+ );
816
+
817
+ if (buttonContainer) {
818
+ // First try to find a list element within the same container
819
+ dropdownList = buttonContainer.querySelector(
820
+ '.menu-card_list, .dropdown-list, [role="menu"]',
643
821
  );
822
+
823
+ // If not found, look for any element with multiple links that's not the button itself
824
+ if (!dropdownList || !dropdownList.querySelector("a")) {
825
+ const allListElements =
826
+ buttonContainer.querySelectorAll("div, ul, nav");
827
+ dropdownList = Array.from(allListElements).find(
828
+ (el) =>
829
+ el.querySelectorAll("a").length > 1 &&
830
+ !el.contains(button) &&
831
+ el !== button,
832
+ );
833
+ }
644
834
  }
645
835
 
646
- if (dropdownList && dropdownList.querySelector('a')) {
836
+ if (dropdownList && dropdownList.querySelector("a")) {
647
837
  dropdownList.id = listId;
648
- dropdownList.inert = true;
838
+ setElementInert(dropdownList, true);
649
839
 
650
- button.addEventListener('click', function() {
651
- const isExpanded = button.getAttribute('aria-expanded') === 'true';
840
+ button.addEventListener("click", function () {
841
+ const isExpanded = button.getAttribute("aria-expanded") === "true";
652
842
  const newState = !isExpanded;
653
- button.setAttribute('aria-expanded', newState);
654
- dropdownList.inert = !newState;
843
+ button.setAttribute("aria-expanded", newState);
844
+ setElementInert(dropdownList, !newState);
845
+
846
+ // Announce to screen readers
847
+ const menuName = getMenuName(button);
848
+ announceToScreenReader(
849
+ `${menuName} submenu ${newState ? "opened" : "closed"}`,
850
+ );
655
851
  });
656
852
  }
657
853
  });
658
854
 
659
- links.forEach(link => {
660
- const linkText = link.textContent?.trim();
855
+ links.forEach((link) => {
856
+ const linkText = link.textContent && link.textContent.trim();
661
857
  if (!linkText) return;
662
858
 
663
859
  const sanitizedText = sanitizeForID(linkText);
664
860
  const linkId = `navbar-mobile-${sanitizedText}-link`;
665
861
  link.id = linkId;
666
862
  });
667
-
863
+
668
864
  setupMobileMenuArrowNavigation(menuContainer);
669
865
  }
670
866
 
671
867
  // Mobile menu arrow navigation
672
868
  function setupMobileMenuArrowNavigation(menuContainer) {
673
869
  function getFocusableElements() {
674
- const allElements = menuContainer.querySelectorAll('button, a');
675
- return Array.from(allElements).filter(el => {
870
+ const allElements = menuContainer.querySelectorAll("button, a");
871
+ return Array.from(allElements).filter((el) => {
676
872
  let current = el;
677
873
  while (current && current !== menuContainer) {
678
- if (current.inert === true) {
874
+ // Check both native inert and polyfill inert
875
+ if (
876
+ current.inert === true ||
877
+ current.getAttribute("data-inert") === "true"
878
+ ) {
679
879
  return false;
680
880
  }
681
881
  current = current.parentElement;
@@ -683,17 +883,17 @@ function setupMobileMenuArrowNavigation(menuContainer) {
683
883
  return true;
684
884
  });
685
885
  }
686
-
886
+
687
887
  let currentFocusIndex = -1;
688
-
689
- menuContainer.addEventListener('keydown', function(e) {
888
+
889
+ menuContainer.addEventListener("keydown", function (e) {
690
890
  const focusableElements = getFocusableElements();
691
891
  if (focusableElements.length === 0) return;
692
-
892
+
693
893
  const activeElement = document.activeElement;
694
894
  currentFocusIndex = focusableElements.indexOf(activeElement);
695
-
696
- if (e.key === 'ArrowDown') {
895
+
896
+ if (e.key === "ArrowDown") {
697
897
  e.preventDefault();
698
898
  if (currentFocusIndex >= focusableElements.length - 1) {
699
899
  currentFocusIndex = 0;
@@ -701,10 +901,12 @@ function setupMobileMenuArrowNavigation(menuContainer) {
701
901
  currentFocusIndex = currentFocusIndex + 1;
702
902
  }
703
903
  focusableElements[currentFocusIndex].focus();
704
- } else if (e.key === 'ArrowUp') {
904
+ } else if (e.key === "ArrowUp") {
705
905
  e.preventDefault();
706
906
  if (currentFocusIndex <= 0) {
707
- const mobileMenuButton = document.querySelector('[data-hs-nav="menubtn"]');
907
+ const mobileMenuButton = document.querySelector(
908
+ '[data-hs-nav="menubtn"]',
909
+ );
708
910
  if (mobileMenuButton) {
709
911
  mobileMenuButton.focus();
710
912
  return;
@@ -712,40 +914,50 @@ function setupMobileMenuArrowNavigation(menuContainer) {
712
914
  }
713
915
  currentFocusIndex = currentFocusIndex - 1;
714
916
  focusableElements[currentFocusIndex].focus();
715
- } else if (e.key === 'ArrowRight') {
917
+ } else if (e.key === "ArrowRight") {
716
918
  e.preventDefault();
717
- if (activeElement.tagName === 'BUTTON' && activeElement.hasAttribute('aria-controls')) {
718
- const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';
919
+ if (
920
+ activeElement.tagName === "BUTTON" &&
921
+ activeElement.hasAttribute("aria-controls")
922
+ ) {
923
+ const isExpanded =
924
+ activeElement.getAttribute("aria-expanded") === "true";
719
925
  if (!isExpanded) {
720
926
  activeElement.click();
721
927
  }
722
928
  return;
723
929
  }
724
- } else if (e.key === 'ArrowLeft') {
930
+ } else if (e.key === "ArrowLeft") {
725
931
  e.preventDefault();
726
- if (activeElement.tagName === 'BUTTON' && activeElement.hasAttribute('aria-controls')) {
727
- const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';
932
+ if (
933
+ activeElement.tagName === "BUTTON" &&
934
+ activeElement.hasAttribute("aria-controls")
935
+ ) {
936
+ const isExpanded =
937
+ activeElement.getAttribute("aria-expanded") === "true";
728
938
  if (isExpanded) {
729
939
  activeElement.click();
730
940
  }
731
941
  return;
732
942
  }
733
- } else if (e.key === 'Home') {
943
+ } else if (e.key === "Home") {
734
944
  e.preventDefault();
735
945
  currentFocusIndex = 0;
736
946
  focusableElements[0].focus();
737
- } else if (e.key === 'End') {
947
+ } else if (e.key === "End") {
738
948
  e.preventDefault();
739
949
  currentFocusIndex = focusableElements.length - 1;
740
950
  focusableElements[focusableElements.length - 1].focus();
741
- } else if (e.key === ' ' && activeElement.tagName === 'A') {
951
+ } else if (e.key === " " && activeElement.tagName === "A") {
742
952
  e.preventDefault();
743
- } else if (e.key === 'Escape') {
744
- const mobileMenuButton = document.querySelector('[data-hs-nav="menubtn"]');
953
+ } else if (e.key === "Escape") {
954
+ const mobileMenuButton = document.querySelector(
955
+ '[data-hs-nav="menubtn"]',
956
+ );
745
957
  if (mobileMenuButton) {
746
958
  mobileMenuButton.click();
747
959
  mobileMenuButton.focus();
748
960
  }
749
961
  }
750
962
  });
751
- }
963
+ }