@uiw/react-native
Version:
UIW for React Native
99 lines (98 loc) • 2.93 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { StyleSheet, View, Text, TextInput, PanResponder } from 'react-native';
import { useTheme } from '@shopify/restyle';
function TextArea(props) {
const theme = useTheme();
const {
draggable = false,
textAlignVertical = 'top',
placeholder = '',
placeholderTextColor = theme.colors.gray200 || '#989FB2',
numberOfLines = 30,
onChange,
maxLength = 50,
value = '',
editable = true,
showWords = false,
autoSize = false,
style,
fontStyle,
height: defaultHeight = 0,
...other
} = props;
const styles = createStyles({
backgroundColor: theme.colors.mask,
borderColor: theme.colors.border,
color: theme.colors.text
});
const [defaultText, setDefaultText] = useState('');
const [height, setHeight] = useState(defaultHeight);
const [panResponder, setPanResponder] = useState();
// Create PanResponder for resizing text box
useEffect(() => {
if (draggable) {
const panResponder = PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderMove: (_, gestureState) => {
const {
dy
} = gestureState;
setHeight(Math.max(height + dy, 35));
}
});
setPanResponder(panResponder);
} else {
setPanResponder(undefined);
}
}, [draggable]);
const onChangeValue = event => {
if (autoSize) {
setDefaultText(event?.nativeEvent?.text);
}
};
const onContentSizeChange = event => {
if (autoSize) {
setHeight(event?.nativeEvent?.contentSize?.height + 20);
}
};
return <View style={[styles.viewBody, style]} {...panResponder?.panHandlers}>
<View style={styles.bodyLayout}>
<TextInput style={[styles.TextInput, fontStyle, {
height: Math.max(35, height)
}]} multiline={true} textAlignVertical={textAlignVertical} placeholder={placeholder} placeholderTextColor={placeholderTextColor} numberOfLines={numberOfLines} maxLength={maxLength} onChangeText={value => {
onChange?.(value);
}} onChange={onChangeValue} onContentSizeChange={onContentSizeChange} editable={editable} value={value} {...other} />
{showWords && <Text style={[styles.textWords, fontStyle]}>{value.length + '/' + maxLength}</Text>}
</View>
</View>;
}
function createStyles({
backgroundColor = '#fff',
borderColor = 'gray',
color = '#000'
}) {
return StyleSheet.create({
viewBody: {
// marginHorizontal: 10,
borderColor: borderColor,
borderWidth: 0.2,
borderRadius: 2,
backgroundColor: backgroundColor
},
bodyLayout: {
padding: 10
},
TextInput: {
backgroundColor: 'transparent',
borderWidth: 0,
fontSize: 16,
color: color
},
textWords: {
padding: 0,
color: color,
textAlign: 'right'
}
});
}
export default TextArea;