React events: add a test for focusable descendants (#15457)
Nicolas Gallagher committed
Apr 21, 2019 at 17:47 UTC
59c7aef91d49ce29332ff4ef9711818fbd10f567
2 files changed
+17
-11
packages/react-events/src/Focus.js
+6
-9
@@ -12,6 +12,7 @@ import type {
12
ReactResponderContext,
13
} from 'shared/ReactTypes';
14
import {REACT_EVENT_COMPONENT_TYPE} from 'shared/ReactSymbols';
15
+import {getEventCurrentTarget} from './utils.js';
16
17
const CAPTURE_PHASE = 2;
18
@@ -120,21 +121,17 @@ const FocusResponder = {
121
if (phase === CAPTURE_PHASE) {
122
return false;
123
}
124
+
125
switch (type) {
126
case 'focus': {
127
if (!state.isFocused) {
128
// Limit focus events to the direct child of the event component.
129
// Browser focus is not expected to bubble.
128
- let currentTarget = (target: any);
129
- if (
130
- currentTarget.parentNode &&
131
- context.isTargetWithinEventComponent(currentTarget.parentNode)
132
- ) {
133
- break;
130
+ state.focusTarget = getEventCurrentTarget(event, context);
131
+ if (state.focusTarget === target) {
132
+ dispatchFocusInEvents(context, props, state);
133
+ state.isFocused = true;
134
}
135
- state.focusTarget = currentTarget;
136
- dispatchFocusInEvents(context, props, state);
137
- state.isFocused = true;
135
}
136
break;
137
}
packages/react-events/src/__tests__/Focus-test.internal.js
+11
-2
@@ -62,14 +62,17 @@ describe('Focus event responder', () => {
62
});
63
64
describe('onFocus', () => {
65
- let onFocus, ref;
65
+ let onFocus, ref, innerRef;
66
67
beforeEach(() => {
68
onFocus = jest.fn();
69
ref = React.createRef();
70
+ innerRef = React.createRef();
71
const element = (
72
<Focus onFocus={onFocus}>
72
- <div ref={ref} />
73
+ <div ref={ref}>
74
+ <a ref={innerRef} />
75
+ </div>
76
</Focus>
77
);
78
ReactDOM.render(element, container);
@@ -79,6 +82,12 @@ describe('Focus event responder', () => {
82
ref.current.dispatchEvent(createFocusEvent('focus'));
83
expect(onFocus).toHaveBeenCalledTimes(1);
84
});
85
+
86
+ it('is not called if descendants of target receive focus', () => {
87
+ const target = innerRef.current;
88
+ target.dispatchEvent(createFocusEvent('focus'));
89
+ expect(onFocus).not.toBeCalled();
90
+ });
91
});
92
93
describe('onFocusChange', () => {