diff --git a/docs/components/TextInput.md b/docs/components/TextInput.md index 4cf96db8..4d0dbd1a 100644 --- a/docs/components/TextInput.md +++ b/docs/components/TextInput.md @@ -103,8 +103,10 @@ Callback that is called when the text input is focused. **onKeyPress**: ?function -Callback that is called when a key is pressed. Pressed key value is passed as -an argument to the callback handler. Fires before `onChange` callbacks. +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. +Fires before onChange callbacks. **onSelectionChange**: ?function diff --git a/src/components/TextInput/__tests__/index-test.js b/src/components/TextInput/__tests__/index-test.js index bdddda16..0be0e031 100644 --- a/src/components/TextInput/__tests__/index-test.js +++ b/src/components/TextInput/__tests__/index-test.js @@ -146,6 +146,44 @@ describe('components/TextInput', () => { } }); + describe('prop "onKeyPress"', () => { + test('enter', done => { + const input = findNativeInput(mount()); + input.simulate('keyPress', { which: 13 }); + function onKeyPress(e) { + expect(e.nativeEvent.key).toEqual('Enter'); + done(); + } + }); + + test('space', done => { + const input = findNativeInput(mount()); + input.simulate('keyPress', { which: 32 }); + function onKeyPress(e) { + expect(e.nativeEvent.key).toEqual(' '); + done(); + } + }); + + test('backspace', done => { + const input = findNativeInput(mount()); + input.simulate('keyDown', { which: 8 }); + function onKeyPress(e) { + expect(e.nativeEvent.key).toEqual('Backspace'); + done(); + } + }); + + test('text', done => { + const input = findNativeInput(mount()); + input.simulate('keyPress', { which: 97 }); + function onKeyPress(e) { + expect(e.nativeEvent.key).toEqual('a'); + done(); + } + }); + }); + test('prop "onSelectionChange"', done => { const input = findNativeInput( mount() diff --git a/src/components/TextInput/index.js b/src/components/TextInput/index.js index dcd4c469..3467d5bd 100644 --- a/src/components/TextInput/index.js +++ b/src/components/TextInput/index.js @@ -227,7 +227,8 @@ class TextInput extends Component { onBlur: normalizeEventHandler(this._handleBlur), onChange: normalizeEventHandler(this._handleChange), onFocus: normalizeEventHandler(this._handleFocus), - onKeyPress: normalizeEventHandler(this._handleKeyPress), + onKeyDown: this._handleKeyDown, + onKeyPress: this._handleKeyPress, onSelect: normalizeEventHandler(this._handleSelectionChange), readOnly: !editable, ref: this._setNode, @@ -275,13 +276,40 @@ class TextInput extends Component { } }; + _handleKeyDown = e => { + const { onKeyPress } = this.props; + if (onKeyPress && e.which === 8) { + onKeyPress({ nativeEvent: { key: 'Backspace' } }); + } + }; + _handleKeyPress = e => { const { blurOnSubmit, multiline, onKeyPress, onSubmitEditing } = this.props; const blurOnSubmitDefault = !multiline; const shouldBlurOnSubmit = blurOnSubmit == null ? blurOnSubmitDefault : blurOnSubmit; + if (onKeyPress) { - onKeyPress(e); + let keyValue; + // enter + if (e.which === 13) { + keyValue = 'Enter'; + } else if (e.which === 32) { + // space + keyValue = ' '; + } else { + // we trim to only care about the keys that has a textual representation + if (e.shiftKey) { + keyValue = String.fromCharCode(e.which).trim(); + } else { + keyValue = String.fromCharCode(e.which).toLowerCase().trim(); + } + } + + if (keyValue) { + onKeyPress({ nativeEvent: { key: keyValue } }); + } } + if (!e.isDefaultPrevented() && e.which === 13) { if (onSubmitEditing) { onSubmitEditing(e);