@@ -99,12 +99,48 @@ function decorateMega(li) {
9999}
100100
101101function setupDropdown ( li ) {
102+ const submenu = li . querySelector ( ':scope > ul' ) ;
103+ const heading = li . querySelector ( ':scope > p' ) ;
104+ const parentLink = li . querySelector ( ':scope > p > a' ) ;
105+ let toggleBtn = null ;
106+
107+ const syncToggle = ( ) => {
108+ if ( ! toggleBtn ) return ;
109+ const expanded = li . getAttribute ( 'aria-expanded' ) === 'true' ;
110+ toggleBtn . setAttribute ( 'aria-expanded' , String ( expanded ) ) ;
111+ toggleBtn . setAttribute ( 'aria-label' , expanded ? 'Collapse submenu' : 'Expand submenu' ) ;
112+ } ;
113+
114+ if ( submenu && heading ) {
115+ toggleBtn = heading . querySelector ( '.nav-submenu-toggle' ) ;
116+ if ( ! toggleBtn ) {
117+ toggleBtn = document . createElement ( 'button' ) ;
118+ toggleBtn . type = 'button' ;
119+ toggleBtn . className = 'nav-submenu-toggle' ;
120+ heading . append ( toggleBtn ) ;
121+ }
122+ syncToggle ( ) ;
123+ toggleBtn . addEventListener ( 'click' , ( e ) => {
124+ e . preventDefault ( ) ;
125+ e . stopPropagation ( ) ;
126+ if ( DESKTOP . matches ) return ;
127+ const wasOpen = li . getAttribute ( 'aria-expanded' ) === 'true' ;
128+ collapseAll ( li . closest ( 'nav' ) ) ;
129+ li . setAttribute ( 'aria-expanded' , wasOpen ? 'false' : 'true' ) ;
130+ syncToggle ( ) ;
131+ } ) ;
132+ }
133+
102134 const open = ( ) => {
103135 li . megaSync ?. ( ) ;
104136 collapseAll ( li . closest ( 'nav' ) ) ;
105137 li . setAttribute ( 'aria-expanded' , 'true' ) ;
138+ syncToggle ( ) ;
139+ } ;
140+ const close = ( ) => {
141+ li . setAttribute ( 'aria-expanded' , 'false' ) ;
142+ syncToggle ( ) ;
106143 } ;
107- const close = ( ) => li . setAttribute ( 'aria-expanded' , 'false' ) ;
108144
109145 li . addEventListener ( 'mouseenter' , ( ) => { if ( DESKTOP . matches ) open ( ) ; } ) ;
110146 li . addEventListener ( 'mouseleave' , ( e ) => {
@@ -117,16 +153,22 @@ function setupDropdown(li) {
117153
118154 li . addEventListener ( 'click' , ( e ) => {
119155 if ( ! DESKTOP . matches ) {
120- const submenu = li . querySelector ( ':scope > ul' ) ;
121156 const clickedSubmenuLink = submenu ?. contains ( e . target ) && e . target . closest ( 'a' ) ;
157+ const clickedToggle = e . target . closest ( '.nav-submenu-toggle' ) ;
158+ const clickedParentLink = parentLink && ( e . target === parentLink || parentLink . contains ( e . target ) ) ;
159+ if ( clickedToggle ) return ;
122160 if ( clickedSubmenuLink ) {
123161 collapseAll ( li . closest ( 'nav' ) ) ;
124162 close ( ) ;
163+ } else if ( clickedParentLink ) {
164+ collapseAll ( li . closest ( 'nav' ) ) ;
165+ close ( ) ;
125166 } else if ( submenu ) {
126167 e . preventDefault ( ) ;
127168 const wasOpen = li . getAttribute ( 'aria-expanded' ) === 'true' ;
128169 collapseAll ( li . closest ( 'nav' ) ) ;
129170 li . setAttribute ( 'aria-expanded' , wasOpen ? 'false' : 'true' ) ;
171+ syncToggle ( ) ;
130172 }
131173 } else if ( li . querySelector ( 'ul' ) ?. contains ( e . target ) && e . target . closest ( 'a' ) ) {
132174 collapseAll ( li . closest ( 'nav' ) ) ;
0 commit comments