@@ -56,7 +56,6 @@ class Menu {
5656 return ;
5757 }
5858 const menu = this . #menu;
59- menu . classList . toggle ( "hidden" , true ) ;
6059 this . #triggeringButton. ariaExpanded = "false" ;
6160 this . #openMenuAC. abort ( ) ;
6261 this . #openMenuAC = null ;
@@ -82,7 +81,6 @@ class Menu {
8281 }
8382
8483 const menu = this . #menu;
85- menu . classList . toggle ( "hidden" , false ) ;
8684 this . #triggeringButton. ariaExpanded = "true" ;
8785 this . #openMenuAC = new AbortController ( ) ;
8886 const signal = AbortSignal . any ( [
@@ -137,6 +135,13 @@ class Menu {
137135 . focus ( ) ;
138136 stopEvent ( e ) ;
139137 break ;
138+ default :
139+ const char = e . key . toLocaleLowerCase ( ) ;
140+ this . #goToNextItem( e . target , true , item =>
141+ item . textContent . trim ( ) . toLowerCase ( ) . startsWith ( char )
142+ ) ;
143+ stopEvent ( e ) ;
144+ break ;
140145 }
141146 } ,
142147 { signal, capture : true }
@@ -148,32 +153,38 @@ class Menu {
148153 } ) ;
149154 this . #triggeringButton. addEventListener (
150155 "keydown" ,
151- ev => {
152- if ( ! this . #openMenuAC) {
153- return ;
154- }
155- switch ( ev . key ) {
156+ e => {
157+ switch ( e . key ) {
158+ case " " :
159+ case "Enter" :
156160 case "ArrowDown" :
157161 case "Home" :
162+ if ( ! this . #openMenuAC) {
163+ this . #triggeringButton. click ( ) ;
164+ }
158165 this . #menuItems
159166 . find (
160167 item => ! item . disabled && ! item . classList . contains ( "hidden" )
161168 )
162169 . focus ( ) ;
163- stopEvent ( ev ) ;
170+ stopEvent ( e ) ;
164171 break ;
165172 case "ArrowUp" :
166173 case "End" :
174+ if ( ! this . #openMenuAC) {
175+ this . #triggeringButton. click ( ) ;
176+ }
167177 this . #menuItems
168178 . findLast (
169179 item => ! item . disabled && ! item . classList . contains ( "hidden" )
170180 )
171181 . focus ( ) ;
172- stopEvent ( ev ) ;
182+ stopEvent ( e ) ;
173183 break ;
174184 case "Escape" :
175185 this . #closeMenu( ) ;
176- stopEvent ( ev ) ;
186+ stopEvent ( e ) ;
187+ break ;
177188 }
178189 } ,
179190 { signal }
@@ -185,7 +196,7 @@ class Menu {
185196 * @param {HTMLElement } element
186197 * @param {boolean } forward
187198 */
188- #goToNextItem( element , forward ) {
199+ #goToNextItem( element , forward , check = ( ) => true ) {
189200 const index =
190201 this . #lastIndex === - 1
191202 ? this . #menuItems. indexOf ( element )
@@ -198,7 +209,11 @@ class Menu {
198209 i = ( i + increment ) % len
199210 ) {
200211 const menuItem = this . #menuItems[ i ] ;
201- if ( ! menuItem . disabled && ! menuItem . classList . contains ( "hidden" ) ) {
212+ if (
213+ ! menuItem . disabled &&
214+ ! menuItem . classList . contains ( "hidden" ) &&
215+ check ( menuItem )
216+ ) {
202217 menuItem . focus ( ) ;
203218 this . #lastIndex = i ;
204219 break ;
0 commit comments