@@ -207,14 +207,13 @@ export function useModalDismissSignal(
207
207
return ( ) => { } ;
208
208
}
209
209
210
- const handleDocumentKeyDown = ( { key } : any ) => {
211
- if ( key === 'Escape' ) {
210
+ const handleDocumentKeyDown = ( event : any ) => {
211
+ if ( event . key === 'Escape' ) {
212
212
dismissCallback ( ) ;
213
213
}
214
214
} ;
215
215
216
216
const handleDocumentClick = ( event : any ) => {
217
- // $FlowFixMe
218
217
if (
219
218
modalRef . current !== null &&
220
219
! modalRef . current . contains ( event . target )
@@ -226,18 +225,33 @@ export function useModalDismissSignal(
226
225
}
227
226
} ;
228
227
229
- // It's important to listen to the ownerDocument to support the browser extension.
230
- // Here we use portals to render individual tabs (e.g. Profiler),
231
- // and the root document might belong to a different window.
232
- const ownerDocument = modalRef . current . ownerDocument ;
233
- ownerDocument . addEventListener ( 'keydown' , handleDocumentKeyDown ) ;
234
- if ( dismissOnClickOutside ) {
235
- ownerDocument . addEventListener ( 'click' , handleDocumentClick ) ;
236
- }
228
+ let ownerDocument = null ;
229
+
230
+ // Delay until after the current call stack is empty,
231
+ // in case this effect is being run while an event is currently bubbling.
232
+ // In that case, we don't want to listen to the pre-existing event.
233
+ let timeoutID = setTimeout ( ( ) => {
234
+ timeoutID = null ;
235
+
236
+ // It's important to listen to the ownerDocument to support the browser extension.
237
+ // Here we use portals to render individual tabs (e.g. Profiler),
238
+ // and the root document might belong to a different window.
239
+ ownerDocument = ( ( modalRef . current : any ) : HTMLDivElement ) . ownerDocument ;
240
+ ownerDocument . addEventListener ( 'keydown' , handleDocumentKeyDown ) ;
241
+ if ( dismissOnClickOutside ) {
242
+ ownerDocument . addEventListener ( 'click' , handleDocumentClick ) ;
243
+ }
244
+ } , 0 ) ;
237
245
238
246
return ( ) => {
239
- ownerDocument . removeEventListener ( 'keydown' , handleDocumentKeyDown ) ;
240
- ownerDocument . removeEventListener ( 'click' , handleDocumentClick ) ;
247
+ if ( timeoutID !== null ) {
248
+ clearTimeout ( timeoutID ) ;
249
+ }
250
+
251
+ if ( ownerDocument !== null ) {
252
+ ownerDocument . removeEventListener ( 'keydown' , handleDocumentKeyDown ) ;
253
+ ownerDocument . removeEventListener ( 'click' , handleDocumentClick ) ;
254
+ }
241
255
} ;
242
256
} , [ modalRef , dismissCallback , dismissOnClickOutside ] ) ;
243
257
}
0 commit comments