UNPKG

@naarni/design-system

Version:

Naarni React Native Design System for EV Fleet Apps

107 lines (102 loc) 4.16 kB
import React, { useState, forwardRef } from 'react'; import { View, TextInput, Text, TouchableOpacity, } from 'react-native'; import { useDeviceTheme } from '../../theme/deviceTheme'; import { Icon } from '../Icon/Icon'; import { styles } from './styles'; export const InputBox = forwardRef(({ placeholder, error, type = 'text', leftIcon, rightIcon, onRightIconPress, disabled = false, label, helperText, variant = 'outlined', size = 'medium', fullWidth = true, style, containerStyle, ...props }, ref) => { const { colors } = useDeviceTheme(); const [isFocused, setIsFocused] = useState(false); const [showPassword, setShowPassword] = useState(false); const getKeyboardType = () => { switch (type) { case 'email': return 'email-address'; case 'phone': return 'phone-pad'; case 'number': return 'numeric'; case 'url': return 'url'; default: return 'default'; } }; const getSecureTextEntry = () => { if (type === 'password') { return !showPassword; } return false; }; const getRightIcon = () => { if (type === 'password') { return showPassword ? 'eye-off' : 'eye'; } return rightIcon; }; const handleRightIconPress = () => { if (type === 'password') { setShowPassword(!showPassword); } else if (onRightIconPress) { onRightIconPress(); } }; const getInputStyles = () => { const baseStyles = { borderColor: error ? colors.error.main : isFocused ? colors.primary.main : colors.surface.border, backgroundColor: variant === 'filled' ? colors.surface.card : colors.background.default, }; if (disabled) { baseStyles.backgroundColor = colors.surface.card; baseStyles.borderColor = colors.surface.border; } return baseStyles; }; const getSizeStyles = () => { switch (size) { case 'small': return { height: 36, fontSize: 14 }; case 'large': return { height: 48, fontSize: 16 }; default: return { height: 44, fontSize: 16 }; } }; return (<View style={[styles.container, fullWidth && styles.fullWidth, containerStyle]}> {label && (<Text style={[styles.label, { color: colors.text.primary }]}> {label} </Text>)} <View style={[ styles.inputContainer, getInputStyles(), getSizeStyles(), variant === 'outlined' ? styles.outlined : styles.filled, disabled && styles.disabled ]}> {leftIcon && (<Icon name={leftIcon} size={20} color={disabled ? colors.text.disabled : colors.text.secondary} style={styles.leftIcon}/>)} <TextInput ref={ref} style={[ styles.input, getSizeStyles(), { color: disabled ? colors.text.disabled : colors.text.primary }, leftIcon && styles.inputWithLeftIcon, rightIcon && styles.inputWithRightIcon, style ]} placeholder={placeholder} placeholderTextColor={colors.text.disabled} keyboardType={getKeyboardType()} secureTextEntry={getSecureTextEntry()} editable={!disabled} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} {...props}/> {getRightIcon() && (<TouchableOpacity onPress={handleRightIconPress} disabled={disabled} style={styles.rightIconContainer}> <Icon name={getRightIcon()} size={20} color={disabled ? colors.text.disabled : colors.text.secondary}/> </TouchableOpacity>)} </View> {(error || helperText) && (<Text style={[ styles.helperText, { color: error ? colors.error.main : colors.text.secondary } ]}> {error || helperText} </Text>)} </View>); });