NativeTemplates

Input

A customizable text input component with multiple style variants, error handling, and icon support.

Input

The Input component is a versatile text input field with multiple style variants, error handling, and support for right icons. It enhances the standard React Native TextInput with additional features and styling to create a cohesive and user-friendly form experience.

Features

  • Multiple Variants: Choose from three style variants:
    • animated: Floating label that animates from placeholder to top position
    • classic: Traditional input with label positioned above
    • underlined: Minimalist input with only a bottom border
  • Error Handling: Displays error messages with distinct styling
  • Password Support: Toggle visibility option for password fields
  • Right Icon: Optional icon on the right side with customizable press behavior
  • Multiline Support: Can be used for both single-line and multiline text input
  • Dark Mode Support: Automatic light/dark mode styles

Import

import Input from '@/components/forms/Input';

Props

PropTypeDefaultDescription
valuestringThe current value of the input
onChangeText(text: string) => voidFunction called when the text changes
labelstringText label for the input field
errorstringError message to display below the input
variant'animated' | 'classic' | 'underlined''animated'Style variant of the input
isPasswordbooleanfalseIf true, treats the input as a password field with visibility toggle
rightIconIconNameIcon to display on the right side of the input
onRightIconPress() => voidFunction called when the right icon is pressed
isMultilinebooleanfalseIf true, enables multiline input mode
classNamestring''Additional Tailwind classes for the input
containerClassNamestring''Additional Tailwind classes for the container
...TextInputPropsAll standard React Native TextInput props are supported

Usage Examples

Input Variants

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [bio, setBio] = useState('');
 
// Default animated input with floating label
<Input
  label="Name"
  value={name}
  onChangeText={setName}
/>
 
// Classic input with label above
<Input
  label="Email"
  value={email}
  onChangeText={setEmail}
  variant="classic"
  keyboardType="email-address"
/>
 
// Underlined input with animated label
<Input
  label="Bio"
  value={bio}
  onChangeText={setBio}
  variant="underlined"
  isMultiline={true}
/>

Input with Error and Password

const [password, setPassword] = useState('');
const [passwordError, setPasswordError] = useState('');
 
const validatePassword = (text) => {
  setPassword(text);
  setPasswordError(text.length < 8 ? 'Password must be at least 8 characters' : '');
};
 
<Input
  label="Password"
  value={password}
  onChangeText={validatePassword}
  error={passwordError}
  isPassword={true}
/>

Input with Icon

const [search, setSearch] = useState('');
 
<Input
  label="Search"
  value={search}
  onChangeText={setSearch}
  rightIcon="Search"
  onRightIconPress={() => console.log('Searching:', search)}
/>

Form Example

Here's a simplified form example using different input variants:

const [formData, setFormData] = useState({
  name: '',
  email: '',
  password: '',
  message: ''
});
 
const updateField = (field, value) => {
  setFormData(prev => ({ ...prev, [field]: value }));
};
 
return (
  <View className="p-4">
    <Input
      label="Full Name"
      value={formData.name}
      onChangeText={(text) => updateField('name', text)}
      variant="animated"
    />
    
    <Input
      label="Email Address"
      value={formData.email}
      onChangeText={(text) => updateField('email', text)}
      variant="classic"
      keyboardType="email-address"
    />
    
    <Input
      label="Password"
      value={formData.password}
      onChangeText={(text) => updateField('password', text)}
      isPassword={true}
      variant="underlined"
    />
    
    <Input
      label="Message"
      value={formData.message}
      onChangeText={(text) => updateField('message', text)}
      isMultiline={true}
      variant="underlined"
    />
    
    <Button
      title="Submit"
      onPress={() => console.log('Form submitted:', formData)}
      className="mt-4"
    />
  </View>
);

Best Practices

  • Choose the right variant for your use case:

    • Use animated for forms where you want to save space while maintaining clarity
    • Use classic for traditional forms with simple, predictable behavior
    • Use underlined for a modern, minimal aesthetic or when you want to reduce visual noise
  • Use appropriate keyboard types for different inputs (email-address, numeric, phone-pad)

  • Provide clear error messages that help users understand how to correct their input

  • Match variant to context: For example, use the underlined variant for search functionality or within cards, and the classic variant for more complex forms

Variant Comparison

VariantDescriptionBest Used For
animatedDefault floating label that animates to the top when focusedStandard forms, registration flows
classicTraditional input with label fixed above the fieldComplex forms, when clarity is priority
underlinedMinimalist input with only a bottom borderSearch fields, clean designs, in-line editing

Implementation Details

The Input component uses React Native's TextInput, View, and Animated components to create a polished input experience. The floating label is implemented using an animated value that transitions based on focus state and input value.

For password inputs, the component automatically adds a toggle icon to show/hide the password text.

The component uses the useThemeColors hook to apply appropriate color schemes for both light and dark modes.

Notes

  • The floating label animation occurs when the input is focused or has a value
  • The input border color changes based on focus state and error state
  • For password fields, a visibility toggle icon is automatically added
  • The component supports all standard TextInput props like placeholder, keyboardType, etc.
  • The input height adjusts automatically when in multiline mode
  • Clicking on the label will focus the input field

On this page