[add] TextInput onKeyPress support for arrow keys

Close #791
Close #792
This commit is contained in:
Nicolas Gallagher
2018-02-08 10:56:48 -08:00
parent a41af0f65f
commit 73b459e770
3 changed files with 48 additions and 12 deletions

View File

@@ -216,6 +216,25 @@ describe('components/TextInput', () => {
);
});
test('arrow key', () => {
const onKeyPress = jest.fn();
const input = findNativeInput(mount(<TextInput onKeyPress={onKeyPress} />));
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(<TextInput onKeyPress={onKeyPress} />));

View File

@@ -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 {

View File

@@ -220,10 +220,11 @@ const TextInputScreen = () => (
Callback that is called when a key is pressed. This will be called with{' '}
<Code>{`{
nativeEvent: { key: keyValue } }`}</Code>{' '}
where keyValue is <Code>Enter</Code> or <Code>Backspace</Code> for respective keys and
the typed-in character otherwise including <Code>' '</Code>
for space. Modifier keys (e.g., <Code>shiftKey</Code>) are also included in the{' '}
<Code>nativeEvent</Code>. Fires before <Code>onChange</Code> callbacks.
where keyValue is <Code>Enter</Code>, <Code>Backspace</Code>, <Code>Tab</Code>,{' '}
<Code>{'Arrow{Up,Right,Down,Left}'}</Code> for respective keys and the typed-in
character otherwise including <Code>' '</Code> for space. Modifier keys (e.g.,{' '}
<Code>shiftKey</Code>) are also included in the <Code>nativeEvent</Code>. Fires before{' '}
<Code>onChange</Code> callbacks.
</AppText>
}
/>