bw-expo-app/components/forms/form-fields/text-input.tsx

90 lines
2.3 KiB
TypeScript

import { TextInput, View, StyleSheet } from 'react-native';
import { ThemedText } from '@/components/themed-text';
import { useThemeColor } from '@/hooks/use-theme-color';
import { FormFieldSchema } from '@/lib/types/template-run';
interface TextInputFieldProps {
field: FormFieldSchema;
value: string;
onChange: (value: string) => void;
error?: string;
}
export function TextInputField({ field, value, onChange, error }: TextInputFieldProps) {
const textColor = useThemeColor({}, 'text');
const borderColor = useThemeColor({}, 'border');
const errorColor = useThemeColor({}, 'error');
const placeholderColor = useThemeColor({}, 'textPlaceholder');
const backgroundColor = useThemeColor({}, 'background');
return (
<View style={styles.container}>
{field.label && (
<ThemedText style={styles.label}>
{field.label}
{field.required && <ThemedText style={[styles.required, { color: errorColor }]}> *</ThemedText>}
</ThemedText>
)}
<TextInput
style={[
styles.input,
{
color: textColor,
borderColor: error ? errorColor : borderColor,
backgroundColor,
}
]}
value={value || ''}
onChangeText={onChange}
placeholder={field.placeholder}
placeholderTextColor={placeholderColor}
multiline={field.type === 'textarea'}
numberOfLines={field.type === 'textarea' ? 4 : 1}
textAlignVertical={field.type === 'textarea' ? 'top' : 'center'}
/>
{field.description && (
<ThemedText style={styles.description}>{field.description}</ThemedText>
)}
{error && (
<ThemedText style={[styles.errorText, { color: errorColor }]}>
{error}
</ThemedText>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
marginBottom: 16,
},
label: {
fontSize: 16,
fontWeight: '600',
marginBottom: 8,
},
required: {
fontSize: 16,
fontWeight: '600',
},
input: {
borderWidth: 1,
borderRadius: 8,
paddingHorizontal: 12,
paddingVertical: 10,
fontSize: 16,
minHeight: 44,
},
description: {
fontSize: 12,
opacity: 0.7,
marginTop: 4,
},
errorText: {
fontSize: 12,
marginTop: 4,
},
});