From 4f6cab547bab2001f74998bd3979134e18ae1257 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 3 Jun 2019 14:34:08 -0700 Subject: [PATCH] [Flare] Ignore keyboard interactions on text input children (#15810) --- packages/react-events/src/Press.js | 17 ++++++++++----- .../src/__tests__/Press-test.internal.js | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/react-events/src/Press.js b/packages/react-events/src/Press.js index 860fe51382..ffa589ab59 100644 --- a/packages/react-events/src/Press.js +++ b/packages/react-events/src/Press.js @@ -414,10 +414,17 @@ function dispatchCancel( } } -function isValidKeyPress(key: string): boolean { +function isValidKeyboardEvent(nativeEvent: Object): boolean { + const {key, target} = nativeEvent; + const {tagName, isContentEditable} = target; // Accessibility for keyboards. Space and Enter only. // "Spacebar" is for IE 11 - return key === 'Enter' || key === ' ' || key === 'Spacebar'; + return ( + (key === 'Enter' || key === ' ' || key === 'Spacebar') && + (tagName !== 'INPUT' && + tagName !== 'TEXTAREA' && + isContentEditable !== true) + ); } function calculateDelayMS(delay: ?number, min = 0, fallback = 0) { @@ -671,7 +678,7 @@ const PressResponder = { // Ignore unrelated key events if (pointerType === 'keyboard') { - if (!isValidKeyPress(nativeEvent.key)) { + if (!isValidKeyboardEvent(nativeEvent)) { return; } } @@ -717,7 +724,7 @@ const PressResponder = { addRootEventTypes(context, state); } else { // Prevent spacebar press from scrolling the window - if (isValidKeyPress(nativeEvent.key) && nativeEvent.key === ' ') { + if (isValidKeyboardEvent(nativeEvent) && nativeEvent.key === ' ') { nativeEvent.preventDefault(); } } @@ -859,7 +866,7 @@ const PressResponder = { // Ignore unrelated keyboard events and verify press is within // responder region for non-keyboard events. if (pointerType === 'keyboard') { - if (!isValidKeyPress(nativeEvent.key)) { + if (!isValidKeyboardEvent(nativeEvent)) { return; } // If the event target isn't within the press target, check if we're still diff --git a/packages/react-events/src/__tests__/Press-test.internal.js b/packages/react-events/src/__tests__/Press-test.internal.js index 97ba7d8cc7..e4e6f3c4c5 100644 --- a/packages/react-events/src/__tests__/Press-test.internal.js +++ b/packages/react-events/src/__tests__/Press-test.internal.js @@ -561,6 +561,27 @@ describe('Event responder: Press', () => { ); }); + it('is not called after invalid "keyup" event', () => { + const inputRef = React.createRef(); + const element = ( + + + + ); + ReactDOM.render(element, container); + inputRef.current.dispatchEvent( + createKeyboardEvent('keydown', {key: 'Enter'}), + ); + inputRef.current.dispatchEvent( + createKeyboardEvent('keyup', {key: 'Enter'}), + ); + inputRef.current.dispatchEvent( + createKeyboardEvent('keydown', {key: ' '}), + ); + inputRef.current.dispatchEvent(createKeyboardEvent('keyup', {key: ' '})); + expect(onPress).not.toBeCalled(); + }); + it('is always called immediately after press is released', () => { const element = (