TextFieldUpdated

A text input component with label, description, and error handling for collecting user input.

Import

import { TextField } from 'heroui-native';

Anatomy

<TextField>
  <TextField.Label>...</TextField.Label>
  <TextField.Input />
  <TextField.Description>...</TextField.Description>
  <TextField.ErrorMessage>...</TextField.ErrorMessage>
</TextField>
  • TextField: Root container that provides spacing and state management
  • TextField.Label: Label with optional asterisk for required fields
  • TextField.Input: Input container with animated border and background
  • TextField.Description: Helper text displayed below the input
  • TextField.ErrorMessage: Error message shown when field is invalid

Usage

Basic Usage

TextField provides a complete form input structure with label and description.

<TextField>
  <TextField.Label>Email</TextField.Label>
  <TextField.Input placeholder="Enter your email" />
  <TextField.Description>We'll never share your email</TextField.Description>
</TextField>

With Required Field

Mark fields as required to show an asterisk in the label.

<TextField isRequired>
  <TextField.Label>Username</TextField.Label>
  <TextField.Input placeholder="Choose a username" />
</TextField>

With Validation

Display error messages when the field is invalid.

<TextField isRequired isInvalid={true}>
  <TextField.Label>Email</TextField.Label>
  <TextField.Input placeholder="Enter your email" />
  <TextField.ErrorMessage>Please enter a valid email</TextField.ErrorMessage>
</TextField>

With Local Invalid State Override

Override the context's invalid state for individual components.

<TextField isInvalid={true}>
  <TextField.Label isInvalid={false}>Email</TextField.Label>
  <TextField.Input placeholder="Enter your email" isInvalid={false} />
  <TextField.Description>
    This shows despite input being invalid
  </TextField.Description>
  <TextField.ErrorMessage>Email format is incorrect</TextField.ErrorMessage>
</TextField>

Multiline Input

Create text areas for longer content.

<TextField>
  <TextField.Label>Message</TextField.Label>
  <TextField.Input
    placeholder="Type your message..."
    multiline
    numberOfLines={4}
  />
  <TextField.Description>Maximum 500 characters</TextField.Description>
</TextField>

Disabled State

Disable the entire field to prevent interaction.

<TextField isDisabled>
  <TextField.Label>Disabled Field</TextField.Label>
  <TextField.Input placeholder="Cannot edit" value="Read only value" />
</TextField>

With Variant

Use different variants to style the input based on context.

<TextField>
  <TextField.Label>Primary Variant</TextField.Label>
  <TextField.Input placeholder="Primary style" variant="primary" />
</TextField>

<TextField>
  <TextField.Label>Secondary Variant</TextField.Label>
  <TextField.Input placeholder="Secondary style" variant="secondary" />
</TextField>

Custom Styling

Customize the input appearance using className.

<TextField>
  <TextField.Label>Custom Styled</TextField.Label>
  <TextField.Input
    placeholder="Custom colors"
    className="bg-blue-50 border-blue-500 focus:border-blue-700"
  />
</TextField>

Example

import { Ionicons } from '@expo/vector-icons';
import { TextField } from 'heroui-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { withUniwind } from 'uniwind';

const StyledIonicons = withUniwind(Ionicons);

export const TextInputContent = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isPasswordVisible, setIsPasswordVisible] = useState(false);

  return (
    <View className="gap-4">
      <TextField isRequired>
        <TextField.Label>Email</TextField.Label>
        <TextField.Input
          placeholder="Enter your email"
          keyboardType="email-address"
          autoCapitalize="none"
          value={email}
          onChangeText={setEmail}
        />
        <TextField.Description>
          We'll never share your email with anyone else.
        </TextField.Description>
      </TextField>

      <TextField isRequired>
        <TextField.Label>New password</TextField.Label>
        <View className="w-full flex-row items-center">
          <TextField.Input
            value={password}
            onChangeText={setPassword}
            className="flex-1 px-10"
            placeholder="Enter your password"
            secureTextEntry={!isPasswordVisible}
          />
          <StyledIonicons
            name="lock-closed-outline"
            size={16}
            className="absolute left-3.5 text-muted"
            pointerEvents="none"
          />
          <Pressable
            className="absolute right-4"
            onPress={() => setIsPasswordVisible(!isPasswordVisible)}
          >
            <StyledIonicons
              name={isPasswordVisible ? 'eye-off-outline' : 'eye-outline'}
              size={16}
              className="text-muted"
            />
          </Pressable>
        </View>
        <TextField.Description>
          Password must be at least 6 characters
        </TextField.Description>
      </TextField>
    </View>
  );
};

You can find more examples in the GitHub repository.

API Reference

TextField

proptypedefaultdescription
childrenReact.ReactNode-Content to render inside the text field
isDisabledbooleanfalseWhether the entire text field is disabled
isInvalidbooleanfalseWhether the text field is in an invalid state
isRequiredbooleanfalseWhether the text field is required (shows asterisk)
classNamestring-Custom class name for the root element
animation"disable-all" | undefinedundefinedAnimation configuration. Use "disable-all" to disable all animations including children
...ViewPropsViewProps-All standard React Native View props are supported

TextField.Label

proptypedefaultdescription
childrenReact.ReactNode-Label text content
isInvalidbooleanundefinedWhether the label is in an invalid state (overrides context)
classNamestring-Custom class name for the label element
classNamesElementSlots<LabelSlots>-Custom class names for different parts of the label
animationTextFieldLabelAnimation-Animation configuration
...Animated.TextPropsAnimatedProps<TextProps>-All Reanimated Animated.Text props are supported

ElementSlots<LabelSlots>

proptypedescription
textstringCustom class name for the label text
asteriskstringCustom class name for the asterisk

TextFieldLabelAnimation

Animation configuration for TextField.Label component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
entering.valueEntryOrExitLayoutTypeFadeIn
.duration(150)
.easing(Easing.out(Easing.ease))
Custom entering animation
exiting.valueEntryOrExitLayoutTypeFadeOut
.duration(150)
.easing(Easing.out(Easing.ease))
Custom exiting animation

TextField.Input

proptypedefaultdescription
isInvalidbooleanundefinedWhether the input is in an invalid state (overrides context)
variant'primary' | 'secondary''primary'Variant style for the input
classNamestring-Custom class name for the input
selectionColorClassNamestring"accent-accent"Custom className for the selection color
placeholderColorClassNamestring"field-placeholder"Custom className for the placeholder text color
...TextInputPropsTextInputProps-All standard React Native TextInput props are supported

TextField.Description

proptypedefaultdescription
childrenReact.ReactNode-Description text content
isInvalidbooleanundefinedWhether the description is in an invalid state (overrides context)
classNamestring-Custom class name for the description element
animationTextFieldDescriptionAnimation-Animation configuration
...Animated.TextPropsAnimatedProps<TextProps>-All Reanimated Animated.Text props are supported

TextFieldDescriptionAnimation

Animation configuration for TextField.Description component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
entering.valueEntryOrExitLayoutTypeFadeIn
.duration(150)
.easing(Easing.out(Easing.ease))
Custom entering animation
exiting.valueEntryOrExitLayoutTypeFadeOut
.duration(150)
.easing(Easing.out(Easing.ease))
Custom exiting animation

TextField.ErrorMessage

Note: TextField.ErrorMessage extends ErrorView component. For complete API reference, see ErrorView documentation.

Hooks

useTextField

Hook to access the TextField context values. Must be used within a TextField component.

import { TextField, useTextField } from 'heroui-native';

function CustomComponent() {
  const { isDisabled, isInvalid, isRequired } = useTextField();

  // Use the context values...
}

Returns

propertytypedescription
isDisabledbooleanWhether the entire text field is disabled
isInvalidbooleanWhether the text field is in an invalid state
isRequiredbooleanWhether the text field is required

On this page