From 73b459e770d40831d044cebb34f15cd4e22e66f3 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Thu, 8 Feb 2018 10:56:48 -0800 Subject: [PATCH] [add] TextInput onKeyPress support for arrow keys Close #791 Close #792 --- .../exports/TextInput/__tests__/index-test.js | 19 +++++++++++ .../src/exports/TextInput/index.js | 32 ++++++++++++++----- .../1-components/TextInput/TextInputScreen.js | 9 +++--- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/packages/react-native-web/src/exports/TextInput/__tests__/index-test.js b/packages/react-native-web/src/exports/TextInput/__tests__/index-test.js index f815b5e7..66cb9733 100644 --- a/packages/react-native-web/src/exports/TextInput/__tests__/index-test.js +++ b/packages/react-native-web/src/exports/TextInput/__tests__/index-test.js @@ -216,6 +216,25 @@ describe('components/TextInput', () => { ); }); + test('arrow key', () => { + const onKeyPress = jest.fn(); + const input = findNativeInput(mount()); + input.simulate('keyPress', { which: 37 }); + expect(onKeyPress).toHaveBeenCalledTimes(1); + expect(onKeyPress).toBeCalledWith( + expect.objectContaining({ + nativeEvent: { + altKey: undefined, + ctrlKey: undefined, + key: 'ArrowLeft', + metaKey: undefined, + shiftKey: undefined, + target: expect.anything() + } + }) + ); + }); + test('text key', () => { const onKeyPress = jest.fn(); const input = findNativeInput(mount()); diff --git a/packages/react-native-web/src/exports/TextInput/index.js b/packages/react-native-web/src/exports/TextInput/index.js index e919c4f4..995e4d88 100644 --- a/packages/react-native-web/src/exports/TextInput/index.js +++ b/packages/react-native-web/src/exports/TextInput/index.js @@ -297,11 +297,19 @@ class TextInput extends Component<*> { }; _handleKeyDown = e => { - // prevent key events bubbling (see #612) + // Prevent key events bubbling (see #612) e.stopPropagation(); - // Backspace, Tab, and Cmd+Enter only fire 'keydown' DOM events - if (e.which === 8 || e.which === 9 || (e.which === 13 && e.metaKey)) { + // Backspace, Tab, Cmd+Enter, and Arrow keys only fire 'keydown' DOM events + if ( + e.which === 8 || + e.which === 9 || + (e.which === 13 && e.metaKey) || + e.which === 37 || + e.which === 38 || + e.which === 39 || + e.which === 40 + ) { this._handleKeyPress(e); } }; @@ -314,24 +322,32 @@ class TextInput extends Component<*> { if (onKeyPress) { let keyValue; switch (e.which) { - // backspace case 8: keyValue = 'Backspace'; break; - // tab case 9: keyValue = 'Tab'; break; - // enter case 13: keyValue = 'Enter'; break; - // spacebar case 32: keyValue = ' '; break; + case 37: + keyValue = 'ArrowLeft'; + break; + case 38: + keyValue = 'ArrowUp'; + break; + case 39: + keyValue = 'ArrowRight'; + break; + case 40: + keyValue = 'ArrowDown'; + break; default: { - // we trim to only care about the keys that has a textual representation + // Trim to only care about the keys that have a textual representation if (e.shiftKey) { keyValue = String.fromCharCode(e.which).trim(); } else { diff --git a/website/storybook/1-components/TextInput/TextInputScreen.js b/website/storybook/1-components/TextInput/TextInputScreen.js index 9910b3cf..c431186c 100644 --- a/website/storybook/1-components/TextInput/TextInputScreen.js +++ b/website/storybook/1-components/TextInput/TextInputScreen.js @@ -220,10 +220,11 @@ const TextInputScreen = () => ( Callback that is called when a key is pressed. This will be called with{' '} {`{ nativeEvent: { key: keyValue } }`}{' '} - where keyValue is Enter or Backspace for respective keys and - the typed-in character otherwise including ' ' - for space. Modifier keys (e.g., shiftKey) are also included in the{' '} - nativeEvent. Fires before onChange callbacks. + where keyValue is Enter, Backspace, Tab,{' '} + {'Arrow{Up,Right,Down,Left}'} for respective keys and the typed-in + character otherwise including ' ' for space. Modifier keys (e.g.,{' '} + shiftKey) are also included in the nativeEvent. Fires before{' '} + onChange callbacks. } />