@@ -5,6 +5,9 @@ const NAV_DONATE_CLASS = '.nav-donate';
55const NAV_SUBMENU_CLASS = '.nav-submenu' ;
66const SITE_LOGO_CLASS = '.site-logo' ;
77const NAV_MENU_CLOSE_CLASS = '.nav-menu-close' ;
8+ const MOBILE_NAV_ID = '#nav-main' ;
9+ const PAGE_WRAPPER_ID = '#content' ;
10+ const NAV_MENU_TOGGLE_CLASS = '.nav-menu-toggle' ;
811
912/**
1013 * Function to handle keyboard accessibility in the navigation menu.
@@ -121,6 +124,9 @@ export const setupAccessibleNavMenu = () => {
121124 }
122125
123126 if ( mobileNav ) {
127+ const doc = mobileNav . ownerDocument ;
128+ let lastFocusedElement = null ;
129+ const isMobileMenuOpen = ( ) => mobileNav . classList . contains ( 'open' ) ;
124130 /**
125131 * Adds event listeners to create a keyboard trap between the buttons.
126132 */
@@ -156,10 +162,16 @@ export const setupAccessibleNavMenu = () => {
156162 return ;
157163 }
158164
159- hamburgerBtn . addEventListener ( 'keydown' , event => {
160- if ( event . key === 'Enter' ) {
161- setTimeout ( ( ) => logo . focus ( ) , 0 ) ;
162- }
165+ hamburgerBtn . addEventListener ( 'click' , ( ) => {
166+ lastFocusedElement = doc . activeElement ;
167+
168+ // Wait for CSS class to apply
169+ requestAnimationFrame ( ( ) => {
170+ if ( isMobileMenuOpen ( ) ) {
171+ syncMobileNavAria ( true ) ;
172+ logo . focus ( ) ;
173+ }
174+ } ) ;
163175 } ) ;
164176 } ;
165177
@@ -168,21 +180,18 @@ export const setupAccessibleNavMenu = () => {
168180 */
169181 const focusLogoOnMenuClose = ( ) => {
170182 const closeBtn = mobileNav . querySelector ( NAV_MENU_CLOSE_CLASS ) ;
171- const hamburgerLogo = mobileNav . querySelector ( SITE_LOGO_CLASS ) ;
172- const mainLogo = document . querySelector ( `#header ${ SITE_LOGO_CLASS } ` ) ;
173183
174- if ( ! mainLogo || ! hamburgerLogo || ! closeBtn ) {
184+ if ( ! closeBtn ) {
175185 return ;
176186 }
177187
178- closeBtn . addEventListener ( 'keydown' , event => {
179- if ( event . key === 'Enter' ) {
180- setTimeout ( ( ) => mainLogo . focus ( ) , 0 ) ;
181- }
182- if ( event . key === 'Tab' && event . shiftKey ) {
183- setTimeout ( ( ) => hamburgerLogo . focus ( ) , 0 ) ;
184- }
188+ closeBtn . addEventListener ( 'click' , ( ) => {
189+ requestAnimationFrame ( ( ) => {
190+ syncMobileNavAria ( false ) ;
191+ lastFocusedElement ?. focus ( ) ;
192+ } ) ;
185193 } ) ;
194+
186195 } ;
187196
188197 addKeyboardTrap ( ) ;
@@ -209,3 +218,36 @@ export const updateNavMenuTabIndex = () => {
209218 ] ;
210219 tabbingItems . forEach ( item => item . setAttribute ( 'tabindex' , menu . classList . contains ( 'open' ) ? 0 : - 1 ) ) ;
211220} ;
221+
222+ /**
223+ * Function to update aria attributes for mobile navigation.
224+ * @param {boolean } isOpen - Whether the mobile navigation is open.
225+ */
226+ const syncMobileNavAria = isOpen => {
227+ const mobileNav = document . querySelector ( MOBILE_NAV_ID ) ;
228+ const page = document . querySelector ( PAGE_WRAPPER_ID ) ;
229+ const toggleBtn = document . querySelector ( NAV_MENU_TOGGLE_CLASS ) ;
230+
231+ if ( ! mobileNav || ! page || ! toggleBtn ) {
232+ return ;
233+ }
234+
235+ // Mobile menu
236+ if ( isOpen ) {
237+ mobileNav . removeAttribute ( 'aria-hidden' ) ;
238+ } else {
239+ mobileNav . setAttribute ( 'aria-hidden' , 'true' ) ;
240+ }
241+
242+ // Page behind
243+ if ( isOpen ) {
244+ page . setAttribute ( 'aria-hidden' , 'true' ) ;
245+ page . inert = true ;
246+ } else {
247+ page . removeAttribute ( 'aria-hidden' ) ;
248+ page . inert = false ;
249+ }
250+
251+ // Toggle button state
252+ toggleBtn . setAttribute ( 'aria-expanded' , String ( isOpen ) ) ;
253+ } ;
0 commit comments