@@ -104,6 +104,7 @@ class TopNavBarSmallViewportLayout extends Component<
104104 private readonly _inPlaceDialogId : string
105105 private readonly _inPlaceDialogCloseButtonId : string
106106 private readonly _separatorId : string
107+ private _drilldownRef : Drilldown | null = null
107108
108109 private _raf : RequestAnimationFrameType [ ] = [ ]
109110
@@ -286,7 +287,44 @@ class TopNavBarSmallViewportLayout extends Component<
286287 onDropdownMenuToggle ( ! isDropdownMenuOpen )
287288 }
288289
289- this . setState ( { isDropdownMenuOpen : ! isDropdownMenuOpen } )
290+ this . setState (
291+ { isDropdownMenuOpen : ! this . state . isDropdownMenuOpen } ,
292+ ( ) => {
293+ if ( this . state . isDropdownMenuOpen ) {
294+ this . focusFirstAvailableItem ( )
295+ }
296+ }
297+ )
298+ }
299+
300+ focusFirstAvailableItem ( ) {
301+ const userChildren = Children . toArray (
302+ this . props . renderUser ?. props . children
303+ ) as ItemChild [ ]
304+
305+ // If option is a User, it preceeds other item, so focus that first
306+ const targetId = userChildren [ 0 ]
307+ ? userChildren [ 0 ] . props . id
308+ : this . mappedMenuItemsOptions [ 0 ] . optionData . id
309+
310+ setTimeout ( ( ) => {
311+ const container = document . getElementById ( this . _trayContainerId )
312+ const firstOption = container ?. querySelector (
313+ `[id="${ targetId } "]`
314+ ) as HTMLSpanElement
315+ firstOption ?. focus ( )
316+ if ( this . _drilldownRef ) {
317+ const drilldownRef = this . _drilldownRef
318+ setTimeout ( ( ) => {
319+ if ( drilldownRef ) {
320+ // highlight the option using Drilldown's handleOptionHighlight function
321+ drilldownRef . handleOptionHighlight ( { } as React . SyntheticEvent , {
322+ id : targetId
323+ } )
324+ }
325+ } , 10 )
326+ }
327+ } , 10 )
290328 }
291329
292330 renderOptionContent : RenderOptionContent = ( children , itemProps ) => {
@@ -402,6 +440,9 @@ class TopNavBarSmallViewportLayout extends Component<
402440 return (
403441 < div css = { styles ?. menuTriggerContainer } >
404442 { menuTrigger }
443+ { ! this . hasBreadcrumbBlock && ! this . props . trayMountNode && (
444+ < div css = { styles ?. trayContainer } id = { this . _trayContainerId } />
445+ ) }
405446
406447 { this . hasBrandBlock ( renderBrand ) && ! alternativeTitle && (
407448 < div css = { styles ?. brandContainer } > { renderBrand } </ div >
@@ -442,6 +483,9 @@ class TopNavBarSmallViewportLayout extends Component<
442483
443484 return (
444485 < Drilldown
486+ ref = { ( el ) => {
487+ this . _drilldownRef = el
488+ } }
445489 id = { this . _drilldownId }
446490 rootPageId = { this . _menuId }
447491 label = { dropdownMenuLabel }
@@ -576,13 +620,7 @@ class TopNavBarSmallViewportLayout extends Component<
576620 }
577621
578622 render ( ) {
579- const {
580- trayMountNode,
581- navLabel,
582- renderActionItems,
583- renderBreadcrumb,
584- styles
585- } = this . props
623+ const { navLabel, renderActionItems, renderBreadcrumb, styles } = this . props
586624
587625 return (
588626 < nav
@@ -607,10 +645,6 @@ class TopNavBarSmallViewportLayout extends Component<
607645
608646 { ! this . hasBreadcrumbBlock && this . renderInPlaceDialog ( ) }
609647
610- { ! this . hasBreadcrumbBlock && ! trayMountNode && (
611- < div css = { styles ?. trayContainer } id = { this . _trayContainerId } />
612- ) }
613-
614648 { ! this . hasBreadcrumbBlock && this . renderDropdownMenuTray ( ) }
615649 </ nav >
616650 )
0 commit comments