@@ -77,6 +77,12 @@ export class AppMenu extends React.Component<IAppMenuProps, {}> {
7777 */
7878 private expandCollapseTimer : number | null = null
7979
80+ /**
81+ * Refs to the menu pane elements, indexed by depth. Used to restore
82+ * focus when navigating back from a submenu with the left arrow key.
83+ */
84+ private menuPaneRefs : Map < number , HTMLDivElement | null > = new Map ( )
85+
8086 private onItemClicked = (
8187 depth : number ,
8288 item : MenuItem ,
@@ -127,6 +133,13 @@ export class AppMenu extends React.Component<IAppMenuProps, {}> {
127133 menu . withClosedMenu ( this . props . state [ depth ] )
128134 )
129135
136+ // Restore focus to the parent menu pane to prevent the menu bar
137+ // from detecting focus loss and closing the entire menu
138+ const parentPane = this . menuPaneRefs . get ( depth - 1 )
139+ if ( parentPane ) {
140+ parentPane . focus ( )
141+ }
142+
130143 event . preventDefault ( )
131144 }
132145 } else if ( event . key === 'ArrowRight' ) {
@@ -211,6 +224,10 @@ export class AppMenu extends React.Component<IAppMenuProps, {}> {
211224 }
212225 }
213226
227+ private onMenuPaneRef = ( depth : number , element : HTMLDivElement | null ) => {
228+ this . menuPaneRefs . set ( depth , element )
229+ }
230+
214231 private renderMenuPane ( depth : number , menu : IMenu ) : JSX . Element {
215232 // If the menu doesn't have an id it's the root menu
216233 const key = menu . id || '@'
@@ -230,6 +247,7 @@ export class AppMenu extends React.Component<IAppMenuProps, {}> {
230247 enableAccessKeyNavigation = { this . props . enableAccessKeyNavigation }
231248 onClearSelection = { this . onClearSelection }
232249 ariaLabelledby = { this . props . ariaLabelledby }
250+ onRef = { this . onMenuPaneRef }
233251 />
234252 )
235253 }
0 commit comments