@uiw/react-native
Version:
UIW for React Native
147 lines (145 loc) • 3.68 kB
JavaScript
import React, { useEffect, useState } from 'react';
import { TextInput, View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import Icon from '../Icon';
// StyleProp<ViewStyle>
const Input = props => {
const {
wrongfulHandle,
rule,
value,
onChangeText,
onFocus,
clearText,
disabled = false,
clear,
clearStyle,
renderClear,
extraStart,
extraEnd,
style = [],
containerStyle,
border = 'bottom',
borderColor = '#ccc',
error = false,
renderError,
inputRef,
...others
} = props;
const [defaultValue, setDefaultValue] = useState(value);
const [control, setControl] = useState('state');
useEffect(() => {
if (control === 'state' && value === defaultValue) {
setControl('props');
}
if (value !== defaultValue) {
if (control === 'state') {
setControl('props');
} else {
setDefaultValue(value);
setControl('props');
}
}
}, [value, control]);
const fontSize = StyleSheet.flatten(style).fontSize || 14;
const minHeight = StyleSheet.flatten(containerStyle)?.height || 30;
const onInputChange = value => {
let flag = true;
if (rule instanceof RegExp) {
flag = rule.test(value);
}
if (typeof rule === 'function') {
flag = rule(value);
}
if (flag) {
setDefaultValue(value);
setControl('state');
onChangeText?.(value);
return false;
}
setDefaultValue(defaultValue || '');
setControl('state');
onChangeText?.(defaultValue || '');
wrongfulHandle?.();
};
const onInputFocus = e => {
if (clearText) {
setDefaultValue('');
setControl('state');
onChangeText?.('');
}
onFocus && onFocus(e);
};
return <View style={[{
flexDirection: 'row',
backgroundColor: '#fff',
alignItems: 'center',
paddingVertical: 0,
height: minHeight
}, containerStyle]} testID="RNE__Input__wrap">
<View style={[inputStyles.container, {
flex: 1,
borderColor: borderColor
}, border ? inputStyles[border] : {}]} testID="RNE__Input__view">
{typeof extraStart === 'string' ? <Text style={{
color: '#888888',
fontSize
}}>{extraStart}</Text> : extraStart}
<TextInput testID="RNE__Input__input" {...others} ref={inputRef} editable={!disabled} value={defaultValue} onChangeText={onInputChange} onFocus={onInputFocus} 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={() => {
setDefaultValue('');
setControl('state');
onInputChange?.('');
}}>
{renderClear || <Text style={[{
color: '#888888',
fontSize
}, clearStyle]}>清除</Text>}
</TouchableOpacity>}
</View>;
};
export default Input;
const inputStyles = StyleSheet.create({
container: {
height: '100%',
marginTop: 0,
marginBottom: 0,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'transparent',
border: '1px solid',
paddingHorizontal: 5
},
input: {
flex: 1,
color: '#000',
backgroundColor: 'transparent',
paddingVertical: 0,
paddingTop: 0
},
always: {
borderWidth: 1
},
bottom: {
borderBottomWidth: 1
},
top: {
borderTopWidth: 1
},
left: {
borderLeftWidth: 1
},
right: {
borderRightWidth: 1
},
inputErrorColor: {
color: '#f50'
}
});