@@ -16,6 +16,7 @@ let ReactFeatureFlags;
16
16
let ReactDOM ;
17
17
let FocusWithinResponder ;
18
18
let useFocusWithin ;
19
+ let Scheduler ;
19
20
20
21
const initializeModules = hasPointerEvents => {
21
22
setPointerEvent ( hasPointerEvents ) ;
@@ -27,6 +28,7 @@ const initializeModules = hasPointerEvents => {
27
28
FocusWithinResponder = require ( 'react-interactions/events/focus' )
28
29
. FocusWithinResponder ;
29
30
useFocusWithin = require ( 'react-interactions/events/focus' ) . useFocusWithin ;
31
+ Scheduler = require ( 'scheduler' ) ;
30
32
} ;
31
33
32
34
const forcePointerEvents = true ;
@@ -336,6 +338,68 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
336
338
expect . objectContaining ( { isTargetAttached : false } ) ,
337
339
) ;
338
340
} ) ;
341
+
342
+ it . experimental (
343
+ 'is called after a focused suspended element is hidden' ,
344
+ ( ) => {
345
+ const Suspense = React . Suspense ;
346
+ let suspend = false ;
347
+ let resolve ;
348
+ let promise = new Promise ( resolvePromise => ( resolve = resolvePromise ) ) ;
349
+
350
+ function Child ( ) {
351
+ if ( suspend ) {
352
+ throw promise ;
353
+ } else {
354
+ return < input ref = { innerRef } /> ;
355
+ }
356
+ }
357
+
358
+ const Component = ( { show} ) => {
359
+ const listener = useFocusWithin ( {
360
+ onBeforeBlurWithin,
361
+ onBlurWithin,
362
+ } ) ;
363
+
364
+ return (
365
+ < div DEPRECATED_flareListeners = { listener } >
366
+ < Suspense fallback = "Loading..." >
367
+ < Child />
368
+ </ Suspense >
369
+ </ div >
370
+ ) ;
371
+ } ;
372
+
373
+ const container2 = document . createElement ( 'div' ) ;
374
+ document . body . appendChild ( container2 ) ;
375
+
376
+ let root = ReactDOM . createRoot ( container2 ) ;
377
+ root . render ( < Component /> ) ;
378
+ Scheduler . unstable_flushAll ( ) ;
379
+ jest . runAllTimers ( ) ;
380
+ expect ( container2 . innerHTML ) . toBe ( '<div><input></div>' ) ;
381
+
382
+ const inner = innerRef . current ;
383
+ const target = createEventTarget ( inner ) ;
384
+ target . keydown ( { key : 'Tab' } ) ;
385
+ target . focus ( ) ;
386
+ expect ( onBeforeBlurWithin ) . toHaveBeenCalledTimes ( 0 ) ;
387
+ expect ( onBlurWithin ) . toHaveBeenCalledTimes ( 0 ) ;
388
+
389
+ suspend = true ;
390
+ root . render ( < Component /> ) ;
391
+ Scheduler . unstable_flushAll ( ) ;
392
+ jest . runAllTimers ( ) ;
393
+ expect ( container2 . innerHTML ) . toBe (
394
+ '<div><input style="display: none;">Loading...</div>' ,
395
+ ) ;
396
+ expect ( onBeforeBlurWithin ) . toHaveBeenCalledTimes ( 1 ) ;
397
+ expect ( onBlurWithin ) . toHaveBeenCalledTimes ( 1 ) ;
398
+ resolve ( ) ;
399
+
400
+ document . body . removeChild ( container2 ) ;
401
+ } ,
402
+ ) ;
339
403
} ) ;
340
404
341
405
it ( 'expect displayName to show up for event component' , ( ) => {
0 commit comments