Skip to content

Commit d72e661

Browse files
committed
PLANET-8026 Review update
- Refactor mobile nav focus trap logic
1 parent 2d2025d commit d72e661

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

assets/src/js/header/setupAccessibleNavMenu.js

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const NAV_MENU_TOGGLE_CLASS = '.nav-menu-toggle';
1414
*/
1515
export const setupAccessibleNavMenu = () => {
1616
const mainNav = document.querySelector('#nav-main-desktop');
17-
const mobileNav = document.querySelector('#nav-main');
17+
const mobileNav = document.querySelector(MOBILE_NAV_ID);
1818

1919
if (!mainNav && !mobileNav) {
2020
return;
@@ -131,22 +131,33 @@ export const setupAccessibleNavMenu = () => {
131131
* Adds event listeners to create a keyboard trap between the buttons.
132132
*/
133133
const addKeyboardTrap = () => {
134-
const donateBtn = mobileNav.querySelector('.btn-donate');
135-
const closeBtn = mobileNav.querySelector(NAV_MENU_CLOSE_CLASS);
136-
const logo = mobileNav.querySelector(SITE_LOGO_CLASS);
134+
const focusableSelectors =
135+
'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])';
137136

138-
closeBtn.addEventListener('keydown', event => {
139-
if (event.key === 'Tab' && event.shiftKey) {
140-
event.preventDefault();
141-
setTimeout(() => donateBtn.focus(), 5);
137+
const focusableElements = Array.from(
138+
mobileNav.querySelectorAll(focusableSelectors)
139+
);
140+
141+
if (!focusableElements.length) {
142+
return;
143+
}
144+
145+
const firstEl = focusableElements[0];
146+
const lastEl = focusableElements[focusableElements.length - 1];
147+
148+
mobileNav.addEventListener('keydown', event => {
149+
if (event.key !== 'Tab') {
150+
return;
142151
}
143-
if (event.key === 'Tab') {
144-
setTimeout(() => logo.focus(), 0);
152+
153+
if (event.shiftKey && doc.activeElement === firstEl) {
154+
event.preventDefault();
155+
lastEl.focus({preventScroll: true});
145156
}
146-
});
147-
logo.addEventListener('keydown', event => {
148-
if (event.key === 'Tab' && event.shiftKey) {
149-
setTimeout(() => closeBtn.focus(), 0);
157+
158+
if (!event.shiftKey && doc.activeElement === lastEl) {
159+
event.preventDefault();
160+
firstEl.focus({preventScroll: true});
150161
}
151162
});
152163
};
@@ -167,10 +178,12 @@ export const setupAccessibleNavMenu = () => {
167178

168179
// Wait for CSS class to apply
169180
requestAnimationFrame(() => {
170-
if (isMobileMenuOpen()) {
171-
syncMobileNavAria(true);
172-
logo.focus();
181+
if (!isMobileMenuOpen()) {
182+
return;
173183
}
184+
185+
syncMobileNavAria(true);
186+
logo.focus();
174187
});
175188
});
176189
};

0 commit comments

Comments
 (0)