From 59c7aef91d49ce29332ff4ef9711818fbd10f567 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 21 Apr 2019 17:47:52 -0700 Subject: [PATCH] React events: add a test for focusable descendants (#15457) --- packages/react-events/src/Focus.js | 15 ++++++--------- .../src/__tests__/Focus-test.internal.js | 13 +++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/react-events/src/Focus.js b/packages/react-events/src/Focus.js index a5532a0667165..83c121b5635ac 100644 --- a/packages/react-events/src/Focus.js +++ b/packages/react-events/src/Focus.js @@ -12,6 +12,7 @@ import type { ReactResponderContext, } from 'shared/ReactTypes'; import {REACT_EVENT_COMPONENT_TYPE} from 'shared/ReactSymbols'; +import {getEventCurrentTarget} from './utils.js'; const CAPTURE_PHASE = 2; @@ -120,21 +121,17 @@ const FocusResponder = { if (phase === CAPTURE_PHASE) { return false; } + switch (type) { case 'focus': { if (!state.isFocused) { // Limit focus events to the direct child of the event component. // Browser focus is not expected to bubble. - let currentTarget = (target: any); - if ( - currentTarget.parentNode && - context.isTargetWithinEventComponent(currentTarget.parentNode) - ) { - break; + state.focusTarget = getEventCurrentTarget(event, context); + if (state.focusTarget === target) { + dispatchFocusInEvents(context, props, state); + state.isFocused = true; } - state.focusTarget = currentTarget; - dispatchFocusInEvents(context, props, state); - state.isFocused = true; } break; } diff --git a/packages/react-events/src/__tests__/Focus-test.internal.js b/packages/react-events/src/__tests__/Focus-test.internal.js index 9e7131f7b6b2b..2364389c49792 100644 --- a/packages/react-events/src/__tests__/Focus-test.internal.js +++ b/packages/react-events/src/__tests__/Focus-test.internal.js @@ -62,14 +62,17 @@ describe('Focus event responder', () => { }); describe('onFocus', () => { - let onFocus, ref; + let onFocus, ref, innerRef; beforeEach(() => { onFocus = jest.fn(); ref = React.createRef(); + innerRef = React.createRef(); const element = ( -
+
+ +
); ReactDOM.render(element, container); @@ -79,6 +82,12 @@ describe('Focus event responder', () => { ref.current.dispatchEvent(createFocusEvent('focus')); expect(onFocus).toHaveBeenCalledTimes(1); }); + + it('is not called if descendants of target receive focus', () => { + const target = innerRef.current; + target.dispatchEvent(createFocusEvent('focus')); + expect(onFocus).not.toBeCalled(); + }); }); describe('onFocusChange', () => {