@@ -22,7 +22,7 @@ import {DiscreteEvent} from 'shared/ReactTypes';
22
22
*/
23
23
24
24
type FocusEvent = { |
25
- isTargetAttached : boolean ,
25
+ relatedTarget : null | Element | Document ,
26
26
target : Element | Document ,
27
27
type : FocusEventType | FocusWithinEventType ,
28
28
pointerType : PointerType ,
@@ -53,6 +53,7 @@ type FocusEventType = 'focus' | 'blur' | 'focuschange' | 'focusvisiblechange';
53
53
type FocusWithinProps = {
54
54
disabled ?: boolean ,
55
55
onFocusWithin ?: ( e : FocusEvent ) => void ,
56
+ onAfterBlurWithin ?: ( e : FocusEvent ) => void ,
56
57
onBeforeBlurWithin ?: ( e : FocusEvent ) => void ,
57
58
onBlurWithin ?: ( e : FocusEvent ) => void ,
58
59
onFocusWithinChange ?: boolean => void ,
@@ -65,7 +66,8 @@ type FocusWithinEventType =
65
66
| 'focuswithinchange'
66
67
| 'blurwithin'
67
68
| 'focuswithin'
68
- | 'beforeblurwithin' ;
69
+ | 'beforeblurwithin'
70
+ | 'afterblurwithin' ;
69
71
70
72
/**
71
73
* Shared between Focus and FocusWithin
@@ -116,8 +118,7 @@ const focusVisibleEvents = hasPointerEvents
116
118
117
119
const targetEventTypes = [ 'focus' , 'blur' , 'beforeblur' , ...focusVisibleEvents ] ;
118
120
119
- // Used only for the blur "detachedTarget" logic
120
- const rootEventTypes = [ 'blur' ] ;
121
+ const rootEventTypes = [ 'afterblur' ] ;
121
122
122
123
function addWindowEventListener ( types , callback , options ) {
123
124
types . forEach ( type => {
@@ -192,10 +193,10 @@ function createFocusEvent(
192
193
type : FocusEventType | FocusWithinEventType ,
193
194
target : Element | Document ,
194
195
pointerType : PointerType ,
195
- isTargetAttached : boolean ,
196
+ relatedTarget : null | Element | Document ,
196
197
) : FocusEvent {
197
198
return {
198
- isTargetAttached ,
199
+ relatedTarget ,
199
200
target,
200
201
type,
201
202
pointerType,
@@ -297,7 +298,7 @@ function dispatchFocusEvents(
297
298
'focus' ,
298
299
target ,
299
300
pointerType ,
300
- true ,
301
+ null ,
301
302
) ;
302
303
context . dispatchEvent ( syntheticEvent , onFocus , DiscreteEvent ) ;
303
304
}
@@ -321,7 +322,7 @@ function dispatchBlurEvents(
321
322
'blur' ,
322
323
target ,
323
324
pointerType ,
324
- true ,
325
+ null ,
325
326
) ;
326
327
context . dispatchEvent ( syntheticEvent , onBlur , DiscreteEvent ) ;
327
328
}
@@ -346,7 +347,7 @@ function dispatchFocusWithinEvents(
346
347
'focuswithin' ,
347
348
target ,
348
349
pointerType ,
349
- true ,
350
+ null ,
350
351
) ;
351
352
context . dispatchEvent ( syntheticEvent , onFocusWithin , DiscreteEvent ) ;
352
353
}
@@ -361,19 +362,40 @@ function dispatchBlurWithinEvents(
361
362
const pointerType = state . pointerType ;
362
363
const target = ( ( state . focusTarget : any ) : Element | Document ) || event . target ;
363
364
const onBlurWithin = ( props . onBlurWithin : any ) ;
364
- const isTargetAttached = state . detachedTarget === null ;
365
365
if ( isFunction ( onBlurWithin ) ) {
366
366
const syntheticEvent = createFocusEvent (
367
367
context ,
368
368
'blurwithin' ,
369
369
target ,
370
370
pointerType ,
371
- isTargetAttached ,
371
+ null ,
372
372
) ;
373
373
context . dispatchEvent ( syntheticEvent , onBlurWithin , DiscreteEvent ) ;
374
374
}
375
375
}
376
376
377
+ function dispatchAfterBlurWithinEvents (
378
+ context : ReactDOMResponderContext ,
379
+ event : ReactDOMResponderEvent ,
380
+ props : FocusWithinProps ,
381
+ state : FocusState ,
382
+ ) {
383
+ const pointerType = state . pointerType ;
384
+ const target = ( ( state . focusTarget : any ) : Element | Document ) || event . target ;
385
+ const onAfterBlurWithin = ( props . onAfterBlurWithin : any ) ;
386
+ const relatedTarget = state . detachedTarget ;
387
+ if ( isFunction ( onAfterBlurWithin ) ) {
388
+ const syntheticEvent = createFocusEvent (
389
+ context ,
390
+ 'afterblurwithin' ,
391
+ target ,
392
+ pointerType ,
393
+ relatedTarget ,
394
+ ) ;
395
+ context . dispatchEvent ( syntheticEvent , onAfterBlurWithin , DiscreteEvent ) ;
396
+ }
397
+ }
398
+
377
399
function dispatchFocusChange (
378
400
context : ReactDOMResponderContext ,
379
401
props : FocusProps ,
@@ -616,7 +638,7 @@ const focusWithinResponderImpl = {
616
638
'beforeblurwithin' ,
617
639
event . target ,
618
640
state . pointerType ,
619
- true ,
641
+ null ,
620
642
) ;
621
643
state . detachedTarget = event . target ;
622
644
context . dispatchEvent (
@@ -660,10 +682,10 @@ const focusWithinResponderImpl = {
660
682
props : FocusWithinProps ,
661
683
state : FocusState ,
662
684
) : void {
663
- if ( event . type === 'blur ' ) {
685
+ if ( event . type === 'afterblur ' ) {
664
686
const detachedTarget = state . detachedTarget ;
665
687
if ( detachedTarget !== null && detachedTarget === event . target ) {
666
- dispatchBlurWithinEvents ( context , event , props , state ) ;
688
+ dispatchAfterBlurWithinEvents ( context , event , props , state ) ;
667
689
state . detachedTarget = null ;
668
690
if ( state . addedRootEvents ) {
669
691
state . addedRootEvents = false ;
0 commit comments