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.
}
/>