diff --git a/docs/components/TextInput.md b/docs/components/TextInput.md
index 769d9658..a8a7db9c 100644
--- a/docs/components/TextInput.md
+++ b/docs/components/TextInput.md
@@ -6,12 +6,10 @@ such as auto-complete, auto-focus, placeholder text, and event callbacks.
Note: some props are exclusive to or excluded from `multiline`.
Unsupported React Native props:
-`autoCapitalize`,
-`autoCorrect`,
`onEndEditing`,
-`onSubmitEditing`,
`clearButtonMode` (ios),
`enablesReturnKeyAutomatically` (ios),
+`placeholderTextColor`,
`returnKeyType` (ios),
`selectionState` (ios),
`underlineColorAndroid` (android)
@@ -128,10 +126,6 @@ Callback that is called when the keyboard's submit button is pressed.
The string that will be rendered in an empty `TextInput` before text has been
entered.
-**placeholderTextColor**: string
-
-The text color of the placeholder string.
-
**secureTextEntry**: bool = false
If true, the text input obscures the text entered so that sensitive text like
diff --git a/examples/components/TextInput/TextInputExample.js b/examples/components/TextInput/TextInputExample.js
index df7f813f..8727cf6a 100644
--- a/examples/components/TextInput/TextInputExample.js
+++ b/examples/components/TextInput/TextInputExample.js
@@ -210,25 +210,16 @@ class TokenizedTextExample extends React.Component {
}
parts.push(_text);
- //highlight hashtags
- parts = parts.map((text) => {
- if (/^#/.test(text)) {
- return {text};
- } else {
- return text;
- }
- });
-
return (
{
this.setState({text});
- }}>
- {parts}
-
+ }}
+ />
);
}
@@ -279,7 +270,7 @@ class BlurOnSubmitExample extends React.Component {
@@ -519,15 +510,15 @@ const examples = [
render: function() {
var keyboardTypes = [
'default',
- 'ascii-capable',
- 'numbers-and-punctuation',
+ //'ascii-capable',
+ //'numbers-and-punctuation',
'url',
'number-pad',
'phone-pad',
- 'name-phone-pad',
+ //'name-phone-pad',
'email-address',
- 'decimal-pad',
- 'twitter',
+ //'decimal-pad',
+ //'twitter',
'web-search',
'numeric',
];
@@ -776,14 +767,6 @@ const examples = [
style={styles.multiline}
dataDetectorTypes="phoneNumber"
/>
-
-
-
);
}
diff --git a/src/components/TextInput/__tests__/index-test.js b/src/components/TextInput/__tests__/index-test.js
index 3f7e7c6b..eae052cc 100644
--- a/src/components/TextInput/__tests__/index-test.js
+++ b/src/components/TextInput/__tests__/index-test.js
@@ -1,15 +1,12 @@
/* eslint-env jasmine, jest */
import React from 'react';
-import StyleSheet from '../../../apis/StyleSheet';
import TextareaAutosize from 'react-textarea-autosize';
import TextInput from '..';
import { mount, shallow } from 'enzyme';
-const placeholderText = 'placeholderText';
const findNativeInput = (wrapper) => wrapper.find('input');
const findNativeTextarea = (wrapper) => wrapper.find(TextareaAutosize);
-const findPlaceholder = (wrapper) => wrapper.find({ children: placeholderText });
const testIfDocumentIsFocused = (message, fn) => {
if (document.hasFocus && document.hasFocus()) {
@@ -184,24 +181,6 @@ describe('components/TextInput', () => {
}
});
- test('prop "placeholder"', () => {
- let textInput = shallow();
- expect(findPlaceholder(textInput).length).toEqual(0);
-
- textInput = shallow();
- expect(findPlaceholder(textInput).length).toEqual(1);
- });
-
- test('prop "placeholderTextColor"', () => {
- let placeholderElement = findPlaceholder(shallow());
- expect(StyleSheet.flatten(placeholderElement.prop('style')).color).toEqual('darkgray');
-
- placeholderElement = findPlaceholder(
- shallow()
- );
- expect(StyleSheet.flatten(placeholderElement.prop('style')).color).toEqual('red');
- });
-
test('prop "secureTextEntry"', () => {
let input = findNativeInput(shallow());
expect(input.prop('type')).toEqual('password');
@@ -224,20 +203,6 @@ describe('components/TextInput', () => {
// assert.equal(input.node.selectionStart, 0)
});
- test('prop "style"', () => {
- const styles = StyleSheet.create({
- root: {
- borderWidth: 1,
- textAlign: 'center'
- }
- });
- const textInput = shallow();
- const input = findNativeInput(textInput);
- const borderWidth = StyleSheet.flatten(textInput.prop('style')).borderWidth;
- expect(borderWidth).toEqual(1);
- expect(input.prop('style').textAlign).toEqual('center');
- });
-
test('prop "value"', () => {
const value = 'value';
const input = findNativeInput(shallow());
diff --git a/src/components/TextInput/index.js b/src/components/TextInput/index.js
index 9dc98b7f..f60a1277 100644
--- a/src/components/TextInput/index.js
+++ b/src/components/TextInput/index.js
@@ -1,18 +1,14 @@
+import applyLayout from '../../modules/applyLayout';
import applyNativeMethods from '../../modules/applyNativeMethods';
import createDOMElement from '../../modules/createDOMElement';
import findNodeHandle from '../../modules/findNodeHandle';
-import omit from 'lodash/omit';
-import pick from 'lodash/pick';
import StyleSheet from '../../apis/StyleSheet';
import Text from '../Text';
import TextareaAutosize from 'react-textarea-autosize';
import TextInputState from './TextInputState';
import UIManager from '../../apis/UIManager';
import View from '../View';
-import ViewStylePropTypes from '../View/ViewStylePropTypes';
-import React, { Component, PropTypes } from 'react';
-
-const viewStyleProps = Object.keys(ViewStylePropTypes);
+import { Component, PropTypes } from 'react';
/**
* React Native events differ from W3C events.
@@ -25,7 +21,7 @@ const normalizeEventHandler = (handler) => (e) => {
};
/**
- * Determins whether a 'selection' prop differs from a node's existing
+ * Determines whether a 'selection' prop differs from a node's existing
* selection state.
*/
const isSelectionStale = (node, selection) => {
@@ -64,7 +60,7 @@ class TextInput extends Component {
defaultValue: PropTypes.string,
editable: PropTypes.bool,
keyboardType: PropTypes.oneOf([
- 'default', 'email-address', 'numeric', 'phone-pad', 'search', 'url', 'web-search'
+ 'default', 'email-address', 'number-pad', 'numeric', 'phone-pad', 'search', 'url', 'web-search'
]),
maxLength: PropTypes.number,
maxNumberOfLines: PropTypes.number,
@@ -85,7 +81,6 @@ class TextInput extends Component {
end: PropTypes.number
}),
style: Text.propTypes.style,
- testID: Text.propTypes.testID,
value: PropTypes.string
};
@@ -101,60 +96,63 @@ class TextInput extends Component {
style: {}
};
- constructor(props, context) {
- super(props, context);
- this.state = { showPlaceholder: !props.value && !props.defaultValue };
- }
-
blur() {
- TextInputState.blurTextInput(findNodeHandle(this._inputRef));
+ TextInputState.blurTextInput(this._node);
}
clear() {
- this.setNativeProps({ text: '' });
+ this._node.value = '';
}
focus() {
- TextInputState.focusTextInput(findNodeHandle(this._inputRef));
+ TextInputState.focusTextInput(this._node);
}
isFocused() {
- return TextInputState.currentlyFocusedField() === findNodeHandle(this._inputRef);
+ return TextInputState.currentlyFocusedField() === this._node;
}
setNativeProps(props) {
- UIManager.updateView(this._inputRef, props, this);
+ UIManager.updateView(this._node, props, this);
}
componentDidMount() {
- setSelection(findNodeHandle(this._inputRef), this.props.selection);
+ setSelection(this._node, this.props.selection);
}
componentDidUpdate() {
- setSelection(findNodeHandle(this._inputRef), this.props.selection);
+ setSelection(this._node, this.props.selection);
}
render() {
const {
- accessibilityLabel, // eslint-disable-line
- autoCapitalize,
- autoComplete,
autoCorrect,
- autoFocus,
- defaultValue,
editable,
keyboardType,
- maxLength,
maxNumberOfLines,
multiline,
numberOfLines,
- onLayout,
- placeholder,
- placeholderTextColor,
secureTextEntry,
style,
- testID,
- value
+ /* eslint-disable */
+ blurOnSubmit,
+ clearTextOnFocus,
+ dataDetectorTypes,
+ enablesReturnKeyAutomatically,
+ keyboardAppearance,
+ onChangeText,
+ onContentSizeChange,
+ onEndEditing,
+ onLayout,
+ onSelectionChange,
+ onSubmitEditing,
+ placeholderTextColor,
+ returnKeyType,
+ selection,
+ selectionColor,
+ selectTextOnFocus,
+ /* eslint-enable */
+ ...other
} = this.props;
let type;
@@ -163,6 +161,7 @@ class TextInput extends Component {
case 'email-address':
type = 'email';
break;
+ case 'number-pad':
case 'numeric':
type = 'number';
break;
@@ -184,29 +183,22 @@ class TextInput extends Component {
type = 'password';
}
- // In order to support 'Text' styles on 'TextInput', we split the 'Text'
- // and 'View' styles and apply them to the 'Text' and 'View' components
- // used in the implementation
- const flattenedStyle = StyleSheet.flatten(style);
- const rootStyles = pick(flattenedStyle, viewStyleProps);
- const textStyles = omit(flattenedStyle, viewStyleProps);
+ const component = multiline ? TextareaAutosize : 'input';
const props = {
- autoCapitalize,
- autoComplete,
+ ...other,
autoCorrect: autoCorrect ? 'on' : 'off',
- autoFocus,
- defaultValue,
- maxLength,
onBlur: normalizeEventHandler(this._handleBlur),
onChange: normalizeEventHandler(this._handleChange),
onFocus: normalizeEventHandler(this._handleFocus),
onKeyPress: normalizeEventHandler(this._handleKeyPress),
onSelect: normalizeEventHandler(this._handleSelectionChange),
readOnly: !editable,
- ref: this._setInputRef,
- style: [ styles.input, textStyles, { outline: style.outline } ],
- value
+ ref: this._setNode,
+ style: [
+ styles.initial,
+ style
+ ]
};
if (multiline) {
@@ -216,66 +208,27 @@ class TextInput extends Component {
props.type = type;
}
- const component = multiline ? TextareaAutosize : 'input';
-
- const optionalPlaceholder = placeholder && this.state.showPlaceholder && (
-
-
-
- );
-
- return (
-
-
- {createDOMElement(component, props)}
- {optionalPlaceholder}
-
-
- );
+ return createDOMElement(component, props);
}
_handleBlur = (e) => {
const { onBlur } = this.props;
- const { text } = e.nativeEvent;
- this.setState({ showPlaceholder: text === '' });
if (onBlur) { onBlur(e); }
}
_handleChange = (e) => {
const { onChange, onChangeText } = this.props;
const { text } = e.nativeEvent;
- this.setState({ showPlaceholder: text === '' });
if (onChange) { onChange(e); }
if (onChangeText) { onChangeText(text); }
}
- _handleClick = (e) => {
- if (this.props.editable) {
- this.focus();
- }
- }
-
_handleFocus = (e) => {
const { clearTextOnFocus, onFocus, selectTextOnFocus } = this.props;
- const { text } = e.nativeEvent;
- const node = findNodeHandle(this._inputRef);
+ const node = this._node;
if (onFocus) { onFocus(e); }
if (clearTextOnFocus) { this.clear(); }
if (selectTextOnFocus) { node && node.select(); }
- this.setState({ showPlaceholder: text === '' });
}
_handleKeyPress = (e) => {
@@ -303,43 +256,24 @@ class TextInput extends Component {
}
}
- _setInputRef = (component) => {
- this._inputRef = component;
+ _setNode = (component) => {
+ this._node = findNodeHandle(component);
}
}
const styles = StyleSheet.create({
initial: {
- borderColor: 'black'
- },
- wrapper: {
- flex: 1
- },
- input: {
appearance: 'none',
backgroundColor: 'transparent',
+ borderColor: 'black',
borderRadius: 0,
borderWidth: 0,
boxSizing: 'border-box',
color: 'inherit',
flex: 1,
font: 'inherit',
- minHeight: '100%', // center small inputs (fix #139)
- padding: 0,
- zIndex: 1
- },
- placeholder: {
- bottom: 0,
- left: 0,
- position: 'absolute',
- right: 0,
- top: 0
- },
- placeholderText: {
- color: 'darkgray',
- overflow: 'hidden',
- whiteSpace: 'pre'
+ padding: 0
}
});
-module.exports = applyNativeMethods(TextInput);
+module.exports = applyLayout(applyNativeMethods(TextInput));
diff --git a/src/modules/applyLayout/index.js b/src/modules/applyLayout/index.js
index 8cb3de08..7213773a 100644
--- a/src/modules/applyLayout/index.js
+++ b/src/modules/applyLayout/index.js
@@ -12,13 +12,13 @@ const applyLayout = (Component) => {
const componentDidUpdate = Component.prototype.componentDidUpdate || emptyFunction;
Component.prototype.componentDidMount = function () {
- componentDidMount();
+ componentDidMount.call(this);
this._layoutState = {};
this._handleLayout();
};
Component.prototype.componentDidUpdate = function () {
- componentDidUpdate();
+ componentDidUpdate.call(this);
this._handleLayout();
};