11import { LitElement } from 'lit'
2- import { createFocusTrap } from 'focus-trap'
32import type { FocusTrap } from 'focus-trap'
43import { navigate } from 'astro:transitions/client'
54import {
@@ -16,7 +15,7 @@ import {
1615 addButtonEventListeners ,
1716 addLinkEventListeners ,
1817} from '@components/scripts/elementListeners'
19- import { defineCustomElement } from '@components/scripts/utils'
18+ import { defineCustomElement , whenIdle } from '@components/scripts/utils'
2019import { setOverlayPauseState } from '@components/scripts/store'
2120import type { WebComponentModule } from '@components/scripts/@types/webComponentModule'
2221
@@ -62,7 +61,8 @@ export class NavigationElement extends LitElement {
6261 override connectedCallback ( ) : void {
6362 super . connectedCallback ( )
6463 if ( this . initialized ) return
65- this . initialize ( )
64+ this . initialized = true
65+ whenIdle ( ( ) => this . initialize ( ) )
6666 }
6767
6868 private initialize ( ) : void {
@@ -80,10 +80,8 @@ export class NavigationElement extends LitElement {
8080 )
8181 }
8282
83- this . setupFocusTrap ( )
8483 this . bindEvents ( )
8584 this . toggleBtn . setAttribute ( 'aria-label' , MENU_TOGGLE_LABELS . open )
86- this . initialized = true
8785 this . setAttribute ( 'data-nav-ready' , 'true' )
8886 }
8987
@@ -139,8 +137,10 @@ export class NavigationElement extends LitElement {
139137 this . splashFallbackTimeoutId = window . setTimeout ( reveal , 700 )
140138 }
141139
142- private setupFocusTrap ( ) : void {
140+ private async setupFocusTrap ( ) : Promise < void > {
141+ if ( this . focusTrap ) return
143142 try {
143+ const { createFocusTrap } = await import ( 'focus-trap' )
144144 this . focusTrap = createFocusTrap ( this . focusContainer , {
145145 initialFocus : ( ) => this . toggleBtn ,
146146 // Allow backdrop taps without collapsing the menu
@@ -215,7 +215,7 @@ export class NavigationElement extends LitElement {
215215 }
216216 }
217217
218- toggleMenu ( force ?: boolean ) : void {
218+ async toggleMenu ( force ?: boolean ) : Promise < void > {
219219 if ( this . isMenuOpen === force ) return
220220 this . isMenuOpen = force !== undefined ? force : ! this . isMenuOpen
221221
@@ -235,6 +235,9 @@ export class NavigationElement extends LitElement {
235235 this . toggleAttribute ( ATTRIBUTES . navOpen , this . isMenuOpen )
236236
237237 if ( this . isMenuOpen ) {
238+ await this . setupFocusTrap ( )
239+ // Menu may have been closed while the dynamic import was loading
240+ if ( ! this . isMenuOpen ) return
238241 this . focusTrap ?. activate ( )
239242 this . menu . classList . remove ( 'menu-visible' )
240243 this . revealMenuWhenSplashCompletes ( )
0 commit comments