@@ -28,10 +28,12 @@ const FocusTrap = ({
2828 const onFocusRef = useRefFrom ( onFocus ) ;
2929 const onLeaveRef = useRefFrom ( onLeave ) ;
3030
31- const getTabbableElementsInBody = useCallback (
32- ( ) => tabbableElements ( bodyRef . current ) . filter ( element => element . getAttribute ( 'aria-disabled' ) !== 'true' ) ,
33- [ bodyRef ]
34- ) ;
31+ const getTabbableElementsInBody = useCallback ( ( ) => {
32+ const nestedTraps = Array . from ( bodyRef . current ?. querySelectorAll ( '.webchat__focus-trap' ) ) ;
33+ return tabbableElements ( bodyRef . current )
34+ . filter ( element => element . getAttribute ( 'aria-disabled' ) !== 'true' )
35+ . filter ( element => ! nestedTraps . some ( trap => trap . contains ( element ) ) ) ;
36+ } , [ bodyRef ] ) ;
3537
3638 const focusOrTriggerLeave = useCallback (
3739 ( element : HTMLElement | undefined ) => ( element ? element . focus ( ) : onLeaveRef . current ?.( ) ) ,
@@ -85,6 +87,8 @@ const FocusTrap = ({
8587 event . stopPropagation ( ) ;
8688
8789 focusOrTriggerLeave ( focusables . at ( 0 ) ) ;
90+ } else if ( bodyRef . current . contains ( target ) ) {
91+ event . stopPropagation ( ) ;
8892 }
8993 } ,
9094 [ focusOrTriggerLeave , getTabbableElementsInBody ]
@@ -109,7 +113,13 @@ const FocusTrap = ({
109113
110114 return (
111115 < Fragment >
112- < div onBlur = { handleBlur } onFocus = { handleFocus } onKeyDown = { handleBodyKeyDown } ref = { bodyRef } >
116+ < div
117+ className = "webchat__focus-trap"
118+ onBlur = { handleBlur }
119+ onFocus = { handleFocus }
120+ onKeyDown = { handleBodyKeyDown }
121+ ref = { bodyRef }
122+ >
113123 { children }
114124 </ div >
115125 < div aria-hidden = "true" className = { targetClassName } onFocus = { handleTrapFocus } tabIndex = { - 1 } />
0 commit comments