mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-23 14:57:13 +00:00
[change] TextInput: implement placeholder and placeholderTextColor
Without access to the Shadow DOM pseudo-elements, the placeholder behaviour needs to be reimplemented. Update to match React Native's modification to `TextInput` to include all `View` props and use the `Text` style props. Fix #12 Fix #48
This commit is contained in:
@@ -48,9 +48,10 @@ updating the `value` prop to keep the controlled state in sync.
|
||||
|
||||
If `false`, text is not editable (i.e., read-only).
|
||||
|
||||
**keyboardType**: oneOf('default', 'email-address', 'numeric', 'phone-pad', 'url') = 'default'
|
||||
**keyboardType**: oneOf('default', 'email-address', 'numeric', 'phone-pad', 'search', 'url', 'web-search') = 'default'
|
||||
|
||||
Determines which keyboard to open.
|
||||
Determines which keyboard to open. (NOTE: Safari iOS requires an ancestral
|
||||
`<form action>` element to display the `search` keyboard).
|
||||
|
||||
(Not available when `multiline` is `true`.)
|
||||
|
||||
@@ -111,11 +112,12 @@ object is passed as an argument to the callback handler.
|
||||
|
||||
**placeholder**: string
|
||||
|
||||
The string that will be rendered before text input has been entered.
|
||||
The string that will be rendered in an empty `TextInput` before text has been
|
||||
entered.
|
||||
|
||||
**placeholderTextColor**: string
|
||||
|
||||
TODO. The text color of the placeholder string.
|
||||
The text color of the placeholder string.
|
||||
|
||||
**secureTextEntry**: bool = false
|
||||
|
||||
@@ -130,18 +132,8 @@ If `true`, all text will automatically be selected on focus.
|
||||
|
||||
**style**: style
|
||||
|
||||
+ ...[View#style](View.md)
|
||||
+ `color`
|
||||
+ `direction`
|
||||
+ `fontFamily`
|
||||
+ `fontSize`
|
||||
+ `fontStyle`
|
||||
+ `fontWeight`
|
||||
+ `letterSpacing`
|
||||
+ `lineHeight`
|
||||
+ `textAlign`
|
||||
+ `textDecoration`
|
||||
+ `textTransform`
|
||||
+ ...[Text#style](Text.md)
|
||||
+ `outline`
|
||||
|
||||
**testID**: string
|
||||
|
||||
@@ -166,6 +158,10 @@ export default class TextInputExample extends Component {
|
||||
this.state = { isFocused: false }
|
||||
}
|
||||
|
||||
_onBlur(e) {
|
||||
this.setState({ isFocused: false })
|
||||
}
|
||||
|
||||
_onFocus(e) {
|
||||
this.setState({ isFocused: true })
|
||||
}
|
||||
@@ -177,6 +173,7 @@ export default class TextInputExample extends Component {
|
||||
maxNumberOfLines={5}
|
||||
multiline
|
||||
numberOfLines={2}
|
||||
onBlur={this._onBlur.bind(this)}
|
||||
onFocus={this._onFocus.bind(this)}
|
||||
placeholder={`What's happening?`}
|
||||
style={{
|
||||
|
||||
@@ -95,10 +95,10 @@ export default class App extends React.Component {
|
||||
/>
|
||||
<TextInput secureTextEntry />
|
||||
<TextInput defaultValue='read only' editable={false} />
|
||||
<TextInput keyboardType='email-address' />
|
||||
<TextInput keyboardType='email-address' placeholder='you@domain.com' placeholderTextColor='red' />
|
||||
<TextInput keyboardType='numeric' />
|
||||
<TextInput keyboardType='phone-pad' />
|
||||
<TextInput keyboardType='url' selectTextOnFocus />
|
||||
<TextInput defaultValue='https://delete-me' keyboardType='url' placeholder='https://www.some-website.com' selectTextOnFocus />
|
||||
<TextInput
|
||||
defaultValue='default value'
|
||||
maxNumberOfLines={10}
|
||||
|
||||
@@ -28,7 +28,7 @@ const MediaQueryWidget = ({ mediaQuery = {} }) => {
|
||||
return (
|
||||
<View style={styles.root}>
|
||||
<Text style={styles.heading}>Active Media Query</Text>
|
||||
<Text>{`"${active.alias}"`} {active.mql.media}</Text>
|
||||
<Text>{`"${active.alias}"`} {active.mql && active.mql.media}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
import { pickProps } from '../../modules/filterObjectProps'
|
||||
import View from '../View'
|
||||
import CoreComponent from '../CoreComponent'
|
||||
import React from 'react'
|
||||
import Text from '../Text'
|
||||
|
||||
export default {
|
||||
...(View.stylePropTypes),
|
||||
...pickProps(CoreComponent.stylePropTypes, [
|
||||
'color',
|
||||
'direction',
|
||||
'fontFamily',
|
||||
'fontSize',
|
||||
'fontStyle',
|
||||
'fontWeight',
|
||||
'letterSpacing',
|
||||
'lineHeight',
|
||||
'textAlign',
|
||||
'textDecoration',
|
||||
'textTransform'
|
||||
])
|
||||
...Text.stylePropTypes,
|
||||
outline: React.PropTypes.string
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import ReactTestUtils from 'react-addons-test-utils'
|
||||
|
||||
import TextInput from '../'
|
||||
|
||||
const findInput = (dom) => dom.querySelector('input, textarea')
|
||||
const findShallowInput = (vdom) => vdom.props.children.props.children[0]
|
||||
const findShallowPlaceholder = (vdom) => vdom.props.children.props.children[1]
|
||||
|
||||
suite('components/TextInput', () => {
|
||||
test('prop "accessibilityLabel"', () => {
|
||||
const accessibilityLabel = 'accessibilityLabel'
|
||||
@@ -16,123 +20,120 @@ suite('components/TextInput', () => {
|
||||
|
||||
test('prop "autoComplete"', () => {
|
||||
// off
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
assert.equal(dom.getAttribute('autocomplete'), undefined)
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.equal(input.getAttribute('autocomplete'), undefined)
|
||||
// on
|
||||
dom = utils.renderToDOM(<TextInput autoComplete />)
|
||||
assert.equal(dom.getAttribute('autocomplete'), 'on')
|
||||
input = findInput(utils.renderToDOM(<TextInput autoComplete />))
|
||||
assert.equal(input.getAttribute('autocomplete'), 'on')
|
||||
})
|
||||
|
||||
test('prop "autoFocus"', () => {
|
||||
// false
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.deepEqual(document.activeElement, document.body)
|
||||
// true
|
||||
dom = utils.renderToDOM(<TextInput autoFocus />)
|
||||
assert.deepEqual(document.activeElement, dom)
|
||||
input = findInput(utils.renderToDOM(<TextInput autoFocus />))
|
||||
assert.deepEqual(document.activeElement, input)
|
||||
})
|
||||
|
||||
utils.testIfDocumentFocused('prop "clearTextOnFocus"', () => {
|
||||
const defaultValue = 'defaultValue'
|
||||
// false
|
||||
let dom = utils.renderAndInject(<TextInput defaultValue={defaultValue} />)
|
||||
dom.focus()
|
||||
assert.equal(dom.value, defaultValue)
|
||||
let input = findInput(utils.renderAndInject(<TextInput defaultValue={defaultValue} />))
|
||||
input.focus()
|
||||
assert.equal(input.value, defaultValue)
|
||||
// true
|
||||
dom = utils.renderAndInject(<TextInput clearTextOnFocus defaultValue={defaultValue} />)
|
||||
dom.focus()
|
||||
assert.equal(dom.value, '')
|
||||
input = findInput(utils.renderAndInject(<TextInput clearTextOnFocus defaultValue={defaultValue} />))
|
||||
input.focus()
|
||||
assert.equal(input.value, '')
|
||||
})
|
||||
|
||||
test('prop "defaultValue"', () => {
|
||||
const defaultValue = 'defaultValue'
|
||||
const result = utils.shallowRender(<TextInput defaultValue={defaultValue} />)
|
||||
assert.equal(result.props.defaultValue, defaultValue)
|
||||
const input = findShallowInput(utils.shallowRender(<TextInput defaultValue={defaultValue} />))
|
||||
assert.equal(input.props.defaultValue, defaultValue)
|
||||
})
|
||||
|
||||
test('prop "editable"', () => {
|
||||
// true
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
assert.equal(dom.getAttribute('readonly'), undefined)
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.equal(input.getAttribute('readonly'), undefined)
|
||||
// false
|
||||
dom = utils.renderToDOM(<TextInput editable={false} />)
|
||||
assert.equal(dom.getAttribute('readonly'), '')
|
||||
input = findInput(utils.renderToDOM(<TextInput editable={false} />))
|
||||
assert.equal(input.getAttribute('readonly'), '')
|
||||
})
|
||||
|
||||
test('prop "keyboardType"', () => {
|
||||
// default
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
assert.equal(dom.getAttribute('type'), undefined)
|
||||
dom = utils.renderToDOM(<TextInput keyboardType='default' />)
|
||||
assert.equal(dom.getAttribute('type'), undefined)
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.equal(input.getAttribute('type'), undefined)
|
||||
input = findInput(utils.renderToDOM(<TextInput keyboardType='default' />))
|
||||
assert.equal(input.getAttribute('type'), undefined)
|
||||
// email-address
|
||||
dom = utils.renderToDOM(<TextInput keyboardType='email-address' />)
|
||||
assert.equal(dom.getAttribute('type'), 'email')
|
||||
input = findInput(utils.renderToDOM(<TextInput keyboardType='email-address' />))
|
||||
assert.equal(input.getAttribute('type'), 'email')
|
||||
// numeric
|
||||
dom = utils.renderToDOM(<TextInput keyboardType='numeric' />)
|
||||
assert.equal(dom.getAttribute('type'), 'number')
|
||||
input = findInput(utils.renderToDOM(<TextInput keyboardType='numeric' />))
|
||||
assert.equal(input.getAttribute('type'), 'number')
|
||||
// phone-pad
|
||||
dom = utils.renderToDOM(<TextInput keyboardType='phone-pad' />)
|
||||
assert.equal(dom.getAttribute('type'), 'tel')
|
||||
input = findInput(utils.renderToDOM(<TextInput keyboardType='phone-pad' />))
|
||||
assert.equal(input.getAttribute('type'), 'tel')
|
||||
// url
|
||||
dom = utils.renderToDOM(<TextInput keyboardType='url' />)
|
||||
assert.equal(dom.getAttribute('type'), 'url')
|
||||
input = findInput(utils.renderToDOM(<TextInput keyboardType='url' />))
|
||||
assert.equal(input.getAttribute('type'), 'url')
|
||||
})
|
||||
|
||||
test('prop "maxLength"', () => {
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
assert.equal(dom.getAttribute('maxlength'), undefined)
|
||||
dom = utils.renderToDOM(<TextInput maxLength={10} />)
|
||||
assert.equal(dom.getAttribute('maxlength'), '10')
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.equal(input.getAttribute('maxlength'), undefined)
|
||||
input = findInput(utils.renderToDOM(<TextInput maxLength={10} />))
|
||||
assert.equal(input.getAttribute('maxlength'), '10')
|
||||
})
|
||||
|
||||
test('prop "maxNumberOfLines"', () => {
|
||||
const style = { borderWidth: 0, fontSize: 20, lineHeight: 1 }
|
||||
const generateValue = () => {
|
||||
let str = ''
|
||||
while (str.length < 100) str += 'x'
|
||||
return str
|
||||
}
|
||||
|
||||
let dom = utils.renderAndInject(
|
||||
let input = findInput(utils.renderAndInject(
|
||||
<TextInput
|
||||
maxNumberOfLines={3}
|
||||
multiline
|
||||
style={style}
|
||||
value={generateValue()}
|
||||
/>
|
||||
)
|
||||
const height = dom.getBoundingClientRect().height
|
||||
))
|
||||
const height = input.getBoundingClientRect().height
|
||||
// need a range because of cross-browser differences
|
||||
assert.ok(height >= 60, height)
|
||||
assert.ok(height <= 66, height)
|
||||
assert.ok(height >= 42, height)
|
||||
assert.ok(height <= 48, height)
|
||||
})
|
||||
|
||||
test('prop "multiline"', () => {
|
||||
// false
|
||||
let dom = utils.renderToDOM(<TextInput />)
|
||||
assert.equal(dom.tagName, 'INPUT')
|
||||
let input = findInput(utils.renderToDOM(<TextInput />))
|
||||
assert.equal(input.tagName, 'INPUT')
|
||||
// true
|
||||
dom = utils.renderToDOM(<TextInput multiline />)
|
||||
assert.equal(dom.tagName, 'TEXTAREA')
|
||||
input = findInput(utils.renderToDOM(<TextInput multiline />))
|
||||
assert.equal(input.tagName, 'TEXTAREA')
|
||||
})
|
||||
|
||||
test('prop "numberOfLines"', () => {
|
||||
const style = { borderWidth: 0, fontSize: 20, lineHeight: 1 }
|
||||
// missing multiline
|
||||
let dom = utils.renderToDOM(<TextInput numberOfLines={2} />)
|
||||
assert.equal(dom.tagName, 'INPUT')
|
||||
let input = findInput(utils.renderToDOM(<TextInput numberOfLines={2} />))
|
||||
assert.equal(input.tagName, 'INPUT')
|
||||
// with multiline
|
||||
dom = utils.renderAndInject(<TextInput multiline numberOfLines={2} style={style} />)
|
||||
assert.equal(dom.tagName, 'TEXTAREA')
|
||||
const height = dom.getBoundingClientRect().height
|
||||
input = findInput(utils.renderAndInject(<TextInput multiline numberOfLines={2} />))
|
||||
assert.equal(input.tagName, 'TEXTAREA')
|
||||
const height = input.getBoundingClientRect().height
|
||||
// need a range because of cross-browser differences
|
||||
assert.ok(height >= 40)
|
||||
assert.ok(height <= 46)
|
||||
assert.ok(height >= 30, height)
|
||||
assert.ok(height <= 36, height)
|
||||
})
|
||||
|
||||
test('prop "onBlur"', (done) => {
|
||||
const input = utils.renderToDOM(<TextInput onBlur={onBlur} />)
|
||||
const input = findInput(utils.renderToDOM(<TextInput onBlur={onBlur} />))
|
||||
ReactTestUtils.Simulate.blur(input)
|
||||
function onBlur(e) {
|
||||
assert.ok(e)
|
||||
@@ -141,7 +142,7 @@ suite('components/TextInput', () => {
|
||||
})
|
||||
|
||||
test('prop "onChange"', (done) => {
|
||||
const input = utils.renderToDOM(<TextInput onChange={onChange} />)
|
||||
const input = findInput(utils.renderToDOM(<TextInput onChange={onChange} />))
|
||||
ReactTestUtils.Simulate.change(input)
|
||||
function onChange(e) {
|
||||
assert.ok(e)
|
||||
@@ -151,7 +152,7 @@ suite('components/TextInput', () => {
|
||||
|
||||
test('prop "onChangeText"', (done) => {
|
||||
const newText = 'newText'
|
||||
const input = utils.renderToDOM(<TextInput onChangeText={onChangeText} />)
|
||||
const input = findInput(utils.renderToDOM(<TextInput onChangeText={onChangeText} />))
|
||||
ReactTestUtils.Simulate.change(input, { target: { value: newText } })
|
||||
function onChangeText(text) {
|
||||
assert.equal(text, newText)
|
||||
@@ -160,7 +161,7 @@ suite('components/TextInput', () => {
|
||||
})
|
||||
|
||||
test('prop "onFocus"', (done) => {
|
||||
const input = utils.renderToDOM(<TextInput onFocus={onFocus} />)
|
||||
const input = findInput(utils.renderToDOM(<TextInput onFocus={onFocus} />))
|
||||
ReactTestUtils.Simulate.focus(input)
|
||||
function onFocus(e) {
|
||||
assert.ok(e)
|
||||
@@ -171,7 +172,7 @@ suite('components/TextInput', () => {
|
||||
test('prop "onLayout"')
|
||||
|
||||
test('prop "onSelectionChange"', (done) => {
|
||||
const input = utils.renderAndInject(<TextInput defaultValue='12345' onSelectionChange={onSelectionChange} />)
|
||||
const input = findInput(utils.renderAndInject(<TextInput defaultValue='12345' onSelectionChange={onSelectionChange} />))
|
||||
ReactTestUtils.Simulate.select(input, { target: { selectionStart: 0, selectionEnd: 3 } })
|
||||
function onSelectionChange(e) {
|
||||
assert.equal(e.selectionEnd, 3)
|
||||
@@ -180,30 +181,42 @@ suite('components/TextInput', () => {
|
||||
}
|
||||
})
|
||||
|
||||
test('prop "placeholder"')
|
||||
test('prop "placeholder"', () => {
|
||||
const placeholder = 'placeholder'
|
||||
const result = findShallowPlaceholder(utils.shallowRender(<TextInput placeholder={placeholder} />))
|
||||
assert.equal(result.props.children, placeholder)
|
||||
})
|
||||
|
||||
test('prop "placeholderTextColor"')
|
||||
test('prop "placeholderTextColor"', () => {
|
||||
const placeholder = 'placeholder'
|
||||
|
||||
let result = findShallowPlaceholder(utils.shallowRender(<TextInput placeholder={placeholder} />))
|
||||
assert.equal(result.props.style.color, 'darkgray')
|
||||
|
||||
result = findShallowPlaceholder(utils.shallowRender(<TextInput placeholder={placeholder} placeholderTextColor='red' />))
|
||||
assert.equal(result.props.style.color, 'red')
|
||||
})
|
||||
|
||||
test('prop "secureTextEntry"', () => {
|
||||
let dom = utils.renderToDOM(<TextInput secureTextEntry />)
|
||||
assert.equal(dom.getAttribute('type'), 'password')
|
||||
let input = findInput(utils.renderToDOM(<TextInput secureTextEntry />))
|
||||
assert.equal(input.getAttribute('type'), 'password')
|
||||
// ignored for multiline
|
||||
dom = utils.renderToDOM(<TextInput multiline secureTextEntry />)
|
||||
assert.equal(dom.getAttribute('type'), undefined)
|
||||
input = findInput(utils.renderToDOM(<TextInput multiline secureTextEntry />))
|
||||
assert.equal(input.getAttribute('type'), undefined)
|
||||
})
|
||||
|
||||
utils.testIfDocumentFocused('prop "selectTextOnFocus"', () => {
|
||||
const text = 'Text'
|
||||
// false
|
||||
let dom = utils.renderAndInject(<TextInput defaultValue={text} />)
|
||||
dom.focus()
|
||||
assert.equal(dom.selectionEnd, 0)
|
||||
assert.equal(dom.selectionStart, 0)
|
||||
let input = findInput(utils.renderAndInject(<TextInput defaultValue={text} />))
|
||||
input.focus()
|
||||
assert.equal(input.selectionEnd, 0)
|
||||
assert.equal(input.selectionStart, 0)
|
||||
// true
|
||||
dom = utils.renderAndInject(<TextInput defaultValue={text} selectTextOnFocus />)
|
||||
dom.focus()
|
||||
assert.equal(dom.selectionEnd, 4)
|
||||
assert.equal(dom.selectionStart, 0)
|
||||
input = findInput(utils.renderAndInject(<TextInput defaultValue={text} selectTextOnFocus />))
|
||||
input.focus()
|
||||
assert.equal(input.selectionEnd, 4)
|
||||
assert.equal(input.selectionStart, 0)
|
||||
})
|
||||
|
||||
test('prop "style"', () => {
|
||||
@@ -218,7 +231,7 @@ suite('components/TextInput', () => {
|
||||
|
||||
test('prop "value"', () => {
|
||||
const value = 'value'
|
||||
const result = utils.shallowRender(<TextInput value={value} />)
|
||||
assert.equal(result.props.value, value)
|
||||
const input = findShallowInput(utils.shallowRender(<TextInput value={value} />))
|
||||
assert.equal(input.props.value, value)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,27 +3,50 @@ import CoreComponent from '../CoreComponent'
|
||||
import React, { PropTypes } from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import StyleSheet from '../../modules/StyleSheet'
|
||||
import Text from '../Text'
|
||||
import TextareaAutosize from 'react-textarea-autosize'
|
||||
import TextInputStylePropTypes from './TextInputStylePropTypes'
|
||||
import View from '../View'
|
||||
|
||||
const textInputStyleKeys = Object.keys(TextInputStylePropTypes)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
initial: {
|
||||
...View.defaultProps.style,
|
||||
borderColor: 'black',
|
||||
borderWidth: 1
|
||||
},
|
||||
input: {
|
||||
appearance: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: 'black',
|
||||
borderWidth: '1px',
|
||||
borderWidth: 0,
|
||||
boxSizing: 'border-box',
|
||||
color: 'inherit',
|
||||
flexGrow: 1,
|
||||
font: 'inherit',
|
||||
padding: 0
|
||||
padding: 0,
|
||||
zIndex: 1
|
||||
},
|
||||
placeholder: {
|
||||
bottom: 0,
|
||||
color: 'darkgray',
|
||||
left: 0,
|
||||
overflow: 'hidden',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
whiteSpace: 'pre'
|
||||
}
|
||||
})
|
||||
|
||||
class TextInput extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props, context)
|
||||
this.state = { showPlaceholder: !props.value && !props.defaultValue }
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
accessibilityLabel: CoreComponent.propTypes.accessibilityLabel,
|
||||
...View.propTypes,
|
||||
autoComplete: PropTypes.bool,
|
||||
autoFocus: PropTypes.bool,
|
||||
clearTextOnFocus: PropTypes.bool,
|
||||
@@ -61,20 +84,26 @@ class TextInput extends React.Component {
|
||||
|
||||
_onBlur(e) {
|
||||
const { onBlur } = this.props
|
||||
const value = e.target.value
|
||||
this.setState({ showPlaceholder: value === '' })
|
||||
if (onBlur) onBlur(e)
|
||||
}
|
||||
|
||||
_onChange(e) {
|
||||
const { onChange, onChangeText } = this.props
|
||||
if (onChangeText) onChangeText(e.target.value)
|
||||
const value = e.target.value
|
||||
this.setState({ showPlaceholder: value === '' })
|
||||
if (onChangeText) onChangeText(value)
|
||||
if (onChange) onChange(e)
|
||||
}
|
||||
|
||||
_onFocus(e) {
|
||||
const { clearTextOnFocus, onFocus, selectTextOnFocus } = this.props
|
||||
const node = ReactDOM.findDOMNode(this)
|
||||
const node = ReactDOM.findDOMNode(this.refs.input)
|
||||
const value = e.target.value
|
||||
if (clearTextOnFocus) node.value = ''
|
||||
if (selectTextOnFocus) node.select()
|
||||
this.setState({ showPlaceholder: value === '' })
|
||||
if (onFocus) onFocus(e)
|
||||
}
|
||||
|
||||
@@ -92,7 +121,9 @@ class TextInput extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
/* eslint-disable react/prop-types */
|
||||
accessibilityLabel,
|
||||
/* eslint-enable react/prop-types */
|
||||
autoComplete,
|
||||
autoFocus,
|
||||
defaultValue,
|
||||
@@ -102,11 +133,9 @@ class TextInput extends React.Component {
|
||||
maxNumberOfLines,
|
||||
multiline,
|
||||
numberOfLines,
|
||||
onBlur,
|
||||
onChange,
|
||||
onChangeText,
|
||||
onSelectionChange,
|
||||
placeholder,
|
||||
placeholderTextColor,
|
||||
secureTextEntry,
|
||||
style,
|
||||
testID,
|
||||
@@ -126,6 +155,10 @@ class TextInput extends React.Component {
|
||||
case 'phone-pad':
|
||||
type = 'tel'
|
||||
break
|
||||
case 'search':
|
||||
case 'web-search':
|
||||
type = 'search'
|
||||
break
|
||||
case 'url':
|
||||
type = 'url'
|
||||
break
|
||||
@@ -136,23 +169,16 @@ class TextInput extends React.Component {
|
||||
}
|
||||
|
||||
const propsCommon = {
|
||||
accessibilityLabel,
|
||||
autoComplete: autoComplete && 'on',
|
||||
autoFocus,
|
||||
className: 'TextInput',
|
||||
defaultValue,
|
||||
maxLength,
|
||||
onBlur: onBlur && this._onBlur.bind(this),
|
||||
onChange: (onChange || onChangeText) && this._onChange.bind(this),
|
||||
onBlur: this._onBlur.bind(this),
|
||||
onChange: this._onChange.bind(this),
|
||||
onFocus: this._onFocus.bind(this),
|
||||
onSelect: onSelectionChange && this._onSelectionChange.bind(this),
|
||||
placeholder,
|
||||
readOnly: !editable,
|
||||
style: {
|
||||
...styles.initial,
|
||||
...resolvedStyle
|
||||
},
|
||||
testID,
|
||||
style: { ...styles.input, outline: style.outline },
|
||||
value
|
||||
}
|
||||
|
||||
@@ -172,7 +198,26 @@ class TextInput extends React.Component {
|
||||
const props = multiline ? propsMultiline : propsSingleline
|
||||
|
||||
return (
|
||||
<CoreComponent {...props} />
|
||||
<CoreComponent
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
className='TextInput'
|
||||
style={{
|
||||
...styles.initial,
|
||||
...resolvedStyle
|
||||
}}
|
||||
testID={testID}
|
||||
>
|
||||
<View style={{ flexGrow: 1 }}>
|
||||
<CoreComponent {...props} ref='input' />
|
||||
{placeholder && this.state.showPlaceholder && <Text
|
||||
pointerEvents='none'
|
||||
style={{
|
||||
...styles.placeholder,
|
||||
...(placeholderTextColor && { color: placeholderTextColor })
|
||||
}}
|
||||
>{placeholder}</Text>}
|
||||
</View>
|
||||
</CoreComponent>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ export default {
|
||||
minWidth: numberOrString,
|
||||
opacity: numberOrString,
|
||||
order: numberOrString,
|
||||
outline: string,
|
||||
overflow: string,
|
||||
overflowX: string,
|
||||
overflowY: string,
|
||||
|
||||
Reference in New Issue
Block a user