Input
TextInput wrapper with label, error state, password visibility toggle, and keyboard type support.
Input
The Input component wraps React Native's TextInput with consistent styling, labels, error messages, and common patterns like password visibility toggles.
Basic Usage
import { Input } from "@/components/ui/Input";
export default function LoginScreen() {
const [email, setEmail] = useState("");
return (
<Input
label="Email"
value={email}
onChangeText={setEmail}
placeholder="you@example.com"
keyboardType="email-address"
/>
);
}Labels and Placeholders
Every input should have a label for accessibility:
<Input
label="Full Name"
value={name}
onChangeText={setName}
placeholder="John Doe"
/>The label renders above the input with proper spacing and font weight.
Error State
Pass an error string to display validation feedback:
<Input
label="Email"
value={email}
onChangeText={setEmail}
error={emailError}
/>When error is set:
- The input border turns red
- The error message appears below the input
- Screen readers announce the error
Password Input
Use secureTextEntry with the built-in visibility toggle:
<Input
label="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
showToggle
/>The showToggle prop adds an eye icon that toggles password visibility. The component manages the toggle state internally.
// Implementation inside the Input component
const [visible, setVisible] = useState(false);
<TouchableOpacity onPress={() => setVisible(!visible)}>
<Ionicons
name={visible ? "eye-off" : "eye"}
size={20}
color="#9CA3AF"
/>
</TouchableOpacity>Keyboard Types
Set the appropriate keyboard for the input type:
<Input label="Email" keyboardType="email-address" autoCapitalize="none" />
<Input label="Phone" keyboardType="phone-pad" />
<Input label="Amount" keyboardType="numeric" />
<Input label="Website" keyboardType="url" autoCapitalize="none" />| Keyboard Type | Shows |
|---|---|
default | Standard keyboard |
email-address | Keyboard with @ and . |
phone-pad | Numeric keypad |
numeric | Number keyboard |
url | Keyboard with / and .com |
Multiline
For longer text inputs, enable multiline mode:
<Input
label="Bio"
value={bio}
onChangeText={setBio}
multiline
numberOfLines={4}
style={{ height: 100, textAlignVertical: "top" }}
/>Auto-Complete Hints
Help password managers and autofill:
<Input
label="Email"
textContentType="emailAddress"
autoComplete="email"
value={email}
onChangeText={setEmail}
/>
<Input
label="Password"
textContentType="password"
autoComplete="password"
secureTextEntry
showToggle
value={password}
onChangeText={setPassword}
/>Customization
Override container, input, or label styles:
<Input
label="Custom"
containerStyle={{ marginBottom: 24 }}
inputStyle={{ fontSize: 18, paddingVertical: 14 }}
labelStyle={{ color: "#6B7280" }}
value={value}
onChangeText={setValue}
/>Component Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Label text above input |
error | string | — | Error message below input |
secureTextEntry | boolean | false | Hide text (password) |
showToggle | boolean | false | Show password visibility toggle |
containerStyle | ViewStyle | — | Wrapper style |
inputStyle | TextStyle | — | TextInput style |
labelStyle | TextStyle | — | Label style |