UNPKG

@uiw/react-native

Version:
171 lines (158 loc) 3.91 kB
import React from 'react'; import { TextInput, View, StyleSheet, Text, TouchableOpacity } from 'react-native'; import Icon from '../Icon'; // StyleProp<ViewStyle> export default class Input extends React.Component { ref = React.createRef(); state = { value: this.props.value, control: 'state' }; static getDerivedStateFromProps(props, state) { if (state.control === 'state' && props.value === state.value) { return { control: 'props' }; } if (props.value !== state.value) { if (state.control === 'state') { return { control: 'props' }; } return { value: props.value, control: 'props' }; } return null; } onChangeText = value => { let flag = true; if (this.props.rule instanceof RegExp) { flag = this.props.rule.test(value); } if (typeof this.props.rule === 'function') { flag = this.props.rule(value); } if (flag) { this.setState({ value, control: 'state' }); this.props.onChangeText?.(value); return false; } this.setState({ value: this.state.value || '', control: 'state' }); this.props.onChangeText?.(this.state.value || ''); this.props.wrongfulHandle?.(); }; onFocus = e => { if (this.props.clearText) { this.setState({ value: '', control: 'state' }); this.props.onChangeText?.(''); } this.props.onFocus?.(e); }; render() { const { wrongfulHandle, rule, value, onChangeText, clearText, disabled = false, clear, clearStyle, renderClear, extraStart, extraEnd, style, containerStyle, border = 'bottom', borderColor = '#ccc', error = false, renderError, inputRef, ...others } = this.props; const fontSize = StyleSheet.flatten(style).fontSize || 14; const minHeight = StyleSheet.flatten(containerStyle)?.height || 30; return <View style={[{ flexDirection: 'row', backgroundColor: '#fff', alignItems: 'center', paddingVertical: 0, height: minHeight }, containerStyle]}> <View style={[inputStyles.container, { flex: 1, borderColor: borderColor }, border ? inputStyles[border] : {}]}> {typeof extraEnd === 'string' ? <Text style={{ color: '#888888', fontSize }}>{extraStart}</Text> : extraStart} <TextInput {...others} ref={inputRef} editable={!disabled} value={this.state.value} onChangeText={this.onChangeText} onFocus={this.onFocus} style={[{ fontSize }, inputStyles.input, style]} /> {typeof extraEnd === 'string' ? <Text style={{ color: '#888888', fontSize }}>{extraEnd}</Text> : extraEnd} {error && (renderError || <Icon name="circle-close" color="#dc3545" />)} </View> {clear && <TouchableOpacity onPress={() => { this.setState({ value: '', control: 'state' }); this.props.onChangeText?.(''); }}> {renderClear || <Text style={[{ color: '#888888', fontSize }, clearStyle]}>清除</Text>} </TouchableOpacity>} </View>; } } const inputStyles = StyleSheet.create({ container: { height: '100%', marginTop: 0, marginBottom: 0, flexDirection: 'row', alignItems: 'center', backgroundColor: 'transparent' }, input: { flex: 1, color: '#000', backgroundColor: 'transparent', paddingVertical: 0 }, always: { borderWidth: 1 }, bottom: { borderBottomWidth: 1 }, top: { borderTopWidth: 1 }, left: { borderLeftWidth: 1 }, right: { borderRightWidth: 1 }, inputErrorColor: { color: '#f50' } });