@@ -50,67 +50,39 @@ function createFocusEvent(
50
50
}
51
51
52
52
function dispatchFocusInEvents (
53
- event : null | ReactResponderEvent ,
54
53
context : ReactResponderContext ,
55
54
props : FocusProps ,
56
55
state : FocusState ,
57
56
) {
58
- if ( event != null ) {
59
- const { nativeEvent} = event ;
60
- if (
61
- context . isTargetWithinEventComponent ( ( nativeEvent : any ) . relatedTarget )
62
- ) {
63
- return ;
64
- }
65
- }
57
+ const target = ( ( state . focusTarget : any ) : Element | Document ) ;
66
58
if ( props . onFocus ) {
67
- const syntheticEvent = createFocusEvent (
68
- 'focus' ,
69
- ( ( state . focusTarget : any ) : Element | Document ) ,
70
- ) ;
59
+ const syntheticEvent = createFocusEvent ( 'focus' , target ) ;
71
60
context . dispatchEvent ( syntheticEvent , props . onFocus , { discrete : true } ) ;
72
61
}
73
62
if ( props . onFocusChange ) {
74
63
const listener = ( ) => {
75
64
props . onFocusChange ( true ) ;
76
65
} ;
77
- const syntheticEvent = createFocusEvent (
78
- 'focuschange' ,
79
- ( ( state . focusTarget : any ) : Element | Document ) ,
80
- ) ;
66
+ const syntheticEvent = createFocusEvent ( 'focuschange' , target ) ;
81
67
context . dispatchEvent ( syntheticEvent , listener , { discrete : true } ) ;
82
68
}
83
69
}
84
70
85
71
function dispatchFocusOutEvents (
86
- event : null | ReactResponderEvent ,
87
72
context : ReactResponderContext ,
88
73
props : FocusProps ,
89
74
state : FocusState ,
90
75
) {
91
- if ( event != null ) {
92
- const { nativeEvent } = event ;
93
- if (
94
- context . isTargetWithinEventComponent ( ( nativeEvent : any ) . relatedTarget )
95
- ) {
96
- return ;
97
- }
98
- }
76
+ const target = ( ( state . focusTarget : any ) : Element | Document ) ;
99
77
if ( props . onBlur ) {
100
- const syntheticEvent = createFocusEvent (
101
- 'blur' ,
102
- ( ( state . focusTarget : any ) : Element | Document ) ,
103
- ) ;
78
+ const syntheticEvent = createFocusEvent ( 'blur' , target ) ;
104
79
context . dispatchEvent ( syntheticEvent , props . onBlur , { discrete : true } ) ;
105
80
}
106
81
if ( props . onFocusChange ) {
107
82
const listener = ( ) = > {
108
83
props . onFocusChange ( false ) ;
109
84
} ;
110
- const syntheticEvent = createFocusEvent (
111
- 'focuschange' ,
112
- ( ( state . focusTarget : any ) : Element | Document ) ,
113
- ) ;
85
+ const syntheticEvent = createFocusEvent ( 'focuschange' , target ) ;
114
86
context . dispatchEvent ( syntheticEvent , listener , { discrete : true } ) ;
115
87
}
116
88
}
@@ -121,7 +93,7 @@ function unmountResponder(
121
93
state : FocusState ,
122
94
) : void {
123
95
if ( state . isFocused ) {
124
- dispatchFocusOutEvents ( null , context , props , state ) ;
96
+ dispatchFocusOutEvents ( context , props , state ) ;
125
97
}
126
98
}
127
99
@@ -140,6 +112,8 @@ const FocusResponder = {
140
112
state : FocusState ,
141
113
) : boolean {
142
114
const { type , phase , target } = event ;
115
+ const shouldStopPropagation =
116
+ props . stopPropagation === undefined ? true : props . stopPropagation ;
143
117
144
118
// Focus doesn't handle capture target events at this point
145
119
if ( phase === CAPTURE_PHASE ) {
@@ -148,22 +122,31 @@ const FocusResponder = {
148
122
switch ( type ) {
149
123
case 'focus ': {
150
124
if ( ! state . isFocused ) {
151
- state . focusTarget = target ;
152
- dispatchFocusInEvents ( event , context , props , state ) ;
125
+ // Limit focus events to the direct child of the event component.
126
+ // Browser focus is not expected to bubble.
127
+ let currentTarget = ( target : any ) ;
128
+ if (
129
+ currentTarget . parentNode &&
130
+ context . isTargetWithinEventComponent ( currentTarget . parentNode )
131
+ ) {
132
+ break ;
133
+ }
134
+ state . focusTarget = currentTarget ;
135
+ dispatchFocusInEvents ( context , props , state ) ;
153
136
state . isFocused = true ;
154
137
}
155
138
break ;
156
139
}
157
140
case 'blur' : {
158
141
if ( state . isFocused ) {
159
- dispatchFocusOutEvents ( event , context , props , state ) ;
142
+ dispatchFocusOutEvents ( context , props , state ) ;
160
143
state . isFocused = false ;
161
144
state . focusTarget = null ;
162
145
}
163
146
break ;
164
147
}
165
148
}
166
- return false ;
149
+ return shouldStopPropagation ;
167
150
} ,
168
151
onUnmount (
169
152
context : ReactResponderContext ,
0 commit comments