todo import * as React from 'react' ; import { TextInput , Platform , NativeSyntheticEvent , TextInputKeyPressEventData , TextInputContentSizeChangeEventData , KeyboardTypeOptions } from 'react-native' ; import { noop , omit } from '../../utils' ; import { InputProps , InputState } from './PropsType' ; const keyboardTypeMap = { text : 'default' , number : 'numeric' , idcard : 'default' , digit : Platform . select ( { ios : 'decimal-pad' , android : 'numeric' } ) || '' } ; class _Input extends React . Component < InputProps , InputState > { static defaultProps = { type : 'text' , maxlength : 140 , confirmType : 'done' , selectionStart : - 1 , selectionEnd : - 1 } ; static getDerivedStateFromProps ( props , state ) { return props . value !== state . value ? { ... state , returnValue : props . value } : null ; } state : InputState = { returnValue : undefined , height : 0 , value : undefined } ; tmpValue ? : string ; lineCount = 0 ; onChangeText = ( text ) : void => { const { onInput , onChange } = this . props ; const { returnValue } = this . state ; const onEvent = onInput || onChange ; this . tmpValue = text || '' ; if ( onEvent ) { const result = onEvent ( { target : { value : text } , detail : { value : text } } ) ; if ( typeof result === 'string' ) { this . tmpValue = result ; this . setState ( { returnValue : result } ) ; } else if ( returnValue ) { this . setState ( { returnValue : undefined } ) ; } } } ; onFocus = ( ) : void => { const { onFocus = noop } = this . props ; const { returnValue } = this . state ; this . tmpValue = returnValue || '' ; onFocus ( { target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; } ; onBlur = ( ) : void => { const { onBlur = noop } = this . props ; onBlur ( { target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; } ; /**
     * 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.
     */ onKeyPress = ( event ) : void => { const { onKeyDown = noop , onConfirm = noop } = this . props ; const keyValue = event . nativeEvent . key ; let which ; keyValue === 'Enter' && ( which = 13 ) ; keyValue === 'Backspace' && ( which = 8 ) ; onKeyDown ( { which , target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; if ( keyValue !== 'Enter' ) return ; onConfirm ( { target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; } ; onSubmitEditing = ( ) : void => { const { onKeyDown = noop , onConfirm = noop , _multiline } = this . props ; if ( _multiline ) return ; onKeyDown ( { which : 13 , target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; onConfirm ( { target : { value : this . tmpValue || '' } , detail : { value : this . tmpValue || '' } } ) ; } ; onContentSizeChange = ( event ) : void => { const { width , height } = event . nativeEvent . contentSize ; if ( width && height ) { const { _multiline , _autoHeight , _onLineChange = noop } = this . props ; if ( ! _multiline || ! _autoHeight || height === this . state . height ) return ; this . lineCount += height > this . state . height ? 1 : - 1 ; _onLineChange ( { detail : { height , lineCount : this . lineCount } } ) ; this . setState ( { height } ) ; } } ; render ( ) { let { style , value , type , password , placeholder , disabled , maxlength , confirmType , confirmHold , cursor , selectionStart , selectionEnd , _multiline , _autoHeight , autoFocus , focus , } = this . props ; const keyboardType = keyboardTypeMap [ type ] as KeyboardTypeOptions ; const selection = ( ( ) => { if ( selectionStart >= 0 && selectionEnd >= 0 ) { return { start : selectionStart , end : selectionEnd } ; } else if ( typeof cursor === 'number' ) { return { start : cursor , end : cursor } ; } } ) ( ) ; value = type === 'number' && value ? value + '' : value ; const textAlignVertical = _multiline ? 'top' : 'auto' ; return ( < TextInput { ... omit ( this . props , [ 'style' , 'value' , 'type' , 'password' , 'placeholder' , 'disabled' , 'maxlength' , 'confirmType' , 'confirmHold' , 'cursor' , 'selectionStart' , 'selectionEnd' , 'onInput' , 'onFocus' , 'onBlur' , 'onKeyDown' , 'onConfirm' , '_multiline' , '_autoHeight' , '_onLineChange' ] ) } defaultValue = { value } keyboardType = { keyboardType } secureTextEntry = { ! ! password } placeholder = { placeholder } editable = { ! disabled } maxLength = { maxlength === - 1 ? undefined : maxlength } returnKeyType = { confirmType } blurOnSubmit = { ! _multiline && ! confirmHold } autoFocus = { ! ! autoFocus || ! ! focus } selection = { selection } onChangeText = { this . onChangeText } value = { this . state . returnValue } onFocus = { this . onFocus } onBlur = { this . onBlur } onKeyPress = { this . onKeyPress } onSubmitEditing = { this . onSubmitEditing } multiline = { ! ! _multiline } textAlignVertical = { textAlignVertical } onContentSizeChange = { this . onContentSizeChange } underlineColorAndroid = "rgba(0,0,0,0)" style = { [ { padding : 0 , } , style , _multiline && _autoHeight && { height : Math . max ( 35 , this . state . height ) } ] } / > ) ; } } export default _Input ;