eletrotupi / tcc/ frontend/components/ui/Input.tsxfa5bcca41e5cdfcb856af45b84338a6fd1760069
2.8 KB | 111 lines Raw
1
import React from 'react';
2
import {
3
  TextInput,
4
  TextInputProps,
5
  StyleSheet,
6
  View,
7
  Text,
8
  TouchableOpacity,
9
  Platform
10
} from 'react-native';
11
import { useThemeColor } from '@/hooks/use-theme-color';
12
import { Ionicons } from '@expo/vector-icons';
13

14
interface InputProps extends TextInputProps {
15
  label?: string;
16
  error?: string;
17
  type?: 'text' | 'email' | 'password';
18
  showPasswordToggle?: boolean;
19
}
20

21
export const Input: React.FC<InputProps> = ({
22
  label,
23
  error,
24
  type = 'text',
25
  showPasswordToggle = false,
26
  style,
27
  ...props
28
}) => {
29
  const [showPassword, setShowPassword] = React.useState(false);
30
  const textColor = useThemeColor({}, 'text');
31
  const backgroundColor = useThemeColor({}, 'inputBackgroundColor');
32
  const borderColor = useThemeColor({}, 'inputBorderColor');
33
  const errorColor = '#ef4444';
34
  const placeholderColor = useThemeColor({ light: '#9ca3af', dark: '#6b7280' }, 'placeholder');
35

36
  const keyboardType = type === 'email' ? 'email-address' : 'default';
37
  const secureTextEntry = type === 'password' && !showPassword;
38

39
  return (
40
    <View style={styles.container}>
41
      {label && (
42
        <Text style={[styles.label, { color: textColor }]}>{label}</Text>
43
      )}
44
      <View style={styles.inputContainer}>
45
        <TextInput
46
          style={[
47
            styles.input,
48
            {
49
              color: textColor,
50
              backgroundColor,
51
              borderColor: error ? errorColor : borderColor,
52
            },
53
            style,
54
          ]}
55
          placeholderTextColor={placeholderColor}
56
          keyboardType={keyboardType}
57
          secureTextEntry={secureTextEntry}
58
          autoCapitalize={type === 'email' ? 'none' : props.autoCapitalize}
59
          autoCorrect={type === 'email' || type === 'password' ? false : props.autoCorrect}
60
          {...props}
61
        />
62
        {type === 'password' && showPasswordToggle && (
63
          <TouchableOpacity
64
            style={styles.passwordToggle}
65
            onPress={() => setShowPassword(!showPassword)}
66
          >
67
            <Ionicons
68
              name={showPassword ? 'eye-off' : 'eye'}
69
              size={22}
70
              color={placeholderColor}
71
            />
72
          </TouchableOpacity>
73
        )}
74
      </View>
75
      {error && (
76
        <Text style={[styles.error, { color: errorColor }]}>{error}</Text>
77
      )}
78
    </View>
79
  );
80
};
81

82
const styles = StyleSheet.create({
83
  container: {
84
    marginBottom: 16,
85
  },
86
  label: {
87
    fontSize: 14,
88
    fontWeight: '500',
89
    marginBottom: 6,
90
  },
91
  inputContainer: {
92
    position: 'relative',
93
  },
94
  input: {
95
    height: 48,
96
    paddingHorizontal: 12,
97
    paddingRight: 44,
98
    borderWidth: 1,
99
    borderRadius: 8,
100
    fontSize: 16,
101
  },
102
  passwordToggle: {
103
    position: 'absolute',
104
    right: 12,
105
    top: 13,
106
  },
107
  error: {
108
    fontSize: 12,
109
    marginTop: 4,
110
  },
111
});