@ramses-superapp/ramses-ui
Version:
UI kit for Ramses Built Apps
129 lines (128 loc) • 4.12 kB
JavaScript
"use strict";
import { StyleSheet, TextInput, Animated, TouchableWithoutFeedback, View, Platform } from 'react-native';
import React, { useRef, useState } from 'react';
import { useTheme } from "../hooks/ThemeProvider.js";
import { useMemo } from 'react';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const FLOAT_LABEL_ANIMATION_DURATION = 150;
const RsTextInput = ({
value = '',
placeholder = '',
onChangeText = () => {},
onFocus,
onBlur,
containerStyle = undefined,
fontSize = 14,
fontWeight = 'Regular',
textAlign = 'left',
textTransform = 'none',
color,
style,
...props
}) => {
const [isFocused, setIsFocused] = useState(false);
const [inputValue, setInputValue] = useState(value);
const animatedIsFocused = React.useRef(new Animated.Value(value ? 1 : 0)).current;
const theme = useTheme();
const styles = useMemo(() => generateStyles(theme, {
fontSize,
fontWeight,
textAlign,
textTransform,
color
}, isFocused, inputValue), [theme, fontSize, fontWeight, textAlign, textTransform, color, isFocused, inputValue]);
React.useEffect(() => {
Animated.timing(animatedIsFocused, {
toValue: isFocused || inputValue ? 1 : 0,
duration: FLOAT_LABEL_ANIMATION_DURATION,
useNativeDriver: false
}).start();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocused, inputValue]);
const labelStyle = {
position: 'absolute',
left: 8,
top: animatedIsFocused.interpolate({
inputRange: [0, 1],
outputRange: [26 - 8, 8]
}),
fontSize: 14,
color: theme.Text.inputPlaceholder,
zIndex: 2,
fontFamily: 'Cairo-Light-Tight',
includeFontPadding: Platform.OS === 'android' ? false : undefined,
padding: Platform.OS === 'android' ? 0 : undefined,
textAlignVertical: Platform.OS === 'android' ? 'bottom' : undefined
};
const inputRef = useRef(null);
return /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
onPress: () => {
inputRef.current?.focus();
},
children: /*#__PURE__*/_jsxs(View, {
style: containerStyle ?? styles.container,
children: [/*#__PURE__*/_jsx(Animated.Text, {
style: labelStyle,
pointerEvents: "none",
children: placeholder
}), /*#__PURE__*/_jsx(TextInput, {
ref: inputRef,
value: inputValue,
onChangeText: text => {
setInputValue(text);
onChangeText(text);
},
style: [styles.inputText, style ?? styles.input],
onFocus: e => {
setIsFocused(true);
onFocus && onFocus(e);
},
onBlur: e => {
setIsFocused(false);
onBlur && onBlur(e);
},
submitBehavior: "blurAndSubmit",
selectionColor: theme.Borders.inputActive,
...props
})]
})
});
};
export default RsTextInput;
const generateStyles = (theme, style, isFocused, inputValue) => StyleSheet.create({
container: {
width: '100%',
height: 52,
overflow: 'hidden',
padding: 8,
borderWidth: 1,
borderRadius: 10,
borderColor: isFocused ? theme.Borders.inputActive : theme.Borders.input,
backgroundColor: theme.Background.input,
alignItems: 'stretch',
justifyContent: 'center',
position: 'relative'
},
input: {
position: 'absolute',
width: '100%',
maxHeight: style.fontSize ? style.fontSize * 1.2 : 16,
alignItems: 'center',
left: 8,
bottom: isFocused || inputValue.length > 0 ? 8 : 26 - 8,
textAlignVertical: Platform.OS === 'android' ? 'bottom' : undefined,
padding: Platform.OS === 'android' ? 0 : undefined,
includeFontPadding: Platform.OS === 'android' ? false : undefined
},
inputText: {
color: style.color || theme.Text.text,
fontSize: style.fontSize,
textAlign: style.textAlign,
fontFamily: `Cairo-${style.fontWeight}-Tight`,
includeFontPadding: false,
lineHeight: style.fontSize ? style.fontSize * 1.2 : 28,
textTransform: style.textTransform,
textDecorationColor: style.color || theme.Text.text
}
});
//# sourceMappingURL=RsTextInput.js.map