# Input

A text input component with styled border and background for collecting user input.

## Import

```tsx
import { Input } from 'heroui-native';
```

## Usage

### Basic Usage

Input can be used standalone or within a TextField component.

```tsx
import { Input } from 'heroui-native';

<Input placeholder="Enter your email" />;
```

### Within TextField

Input works seamlessly with TextField for complete form structure.

```tsx
import { Input, Label, TextField } from 'heroui-native';

<TextField>
  <Label>Email</Label>
  <Input placeholder="Enter your email" />
</TextField>;
```

### With Validation

Display error state when the input is invalid.

```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';

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

### With Local Invalid State Override

Override the context's invalid state for the input.

```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';

<TextField isInvalid={true}>
  <Label isInvalid={false}>Email</Label>
  <Input placeholder="Enter your email" isInvalid={false} />
  <FieldError>Email format is incorrect</FieldError>
</TextField>;
```

### Disabled State

Disable the input to prevent interaction.

```tsx
import { Input, Label, TextField } from 'heroui-native';

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

### With Variant

Use different variants to style the input based on context.

```tsx
import { Input, Label, TextField } from 'heroui-native';

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

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

### Custom Styling

Customize the input appearance using className.

```tsx
import { Input, Label, TextField } from 'heroui-native';

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

### Inside a BottomSheet

When rendering an Input inside a `BottomSheet`, use the `useBottomSheetAwareHandlers` hook to wire keyboard avoidance handlers. Pass the returned `onFocus` and `onBlur` to the Input.

> **Note**: `useBottomSheetAwareHandlers` must be used inside a `BottomSheet`. Call it from a child component rendered inside `BottomSheet.Content` — outside of a `BottomSheet` context the returned handlers are no-ops.

```tsx
import { Input, TextField, useBottomSheetAwareHandlers } from 'heroui-native';

const BottomSheetTextInput = () => {
  const { onFocus, onBlur } = useBottomSheetAwareHandlers();

  return (
    <TextField>
      <Input placeholder="Type here..." onFocus={onFocus} onBlur={onBlur} />
    </TextField>
  );
};
```

## Example

```tsx
import { Ionicons } from '@expo/vector-icons';
import { Description, Input, Label, 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>
        <Label>Email</Label>
        <Input
          placeholder="Enter your email"
          keyboardType="email-address"
          autoCapitalize="none"
          value={email}
          onChangeText={setEmail}
        />
        <Description>
          We'll never share your email with anyone else.
        </Description>
      </TextField>

      <TextField isRequired>
        <Label>New password</Label>
        <View className="w-full flex-row items-center">
          <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>
        <Description>Password must be at least 6 characters</Description>
      </TextField>
    </View>
  );
};
```

You can find more examples in the [GitHub repository](<https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/(home)/components/input.tsx>).

## API Reference

### Input

| prop                      | type                       | default               | description                                                                                                                                                                                                                                                                       |
| ------------------------- | -------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| isInvalid                 | `boolean`                  | `undefined`           | Whether the input is in an invalid state (overrides context)                                                                                                                                                                                                                      |
| variant                   | `'primary' \| 'secondary'` | `'primary'`           | Variant style for the input                                                                                                                                                                                                                                                       |
| className                 | `string`                   | -                     | Custom class name for the input                                                                                                                                                                                                                                                   |
| selectionColorClassName   | `string`                   | `"accent-accent"`     | Custom className for the selection color                                                                                                                                                                                                                                          |
| placeholderColorClassName | `string`                   | `"field-placeholder"` | Custom className for the placeholder text color                                                                                                                                                                                                                                   |
| animation                 | `AnimationRoot`            | `undefined`           | Animation configuration for the input                                                                                                                                                                                                                                             |
| background                | `React.ReactNode`          | -                     | Background layer behind the text input. `undefined` renders the theme-aware default when the active theme registers default background content (fallback color follows the variant: primary → field token, secondary → default token); custom node replaces it; `null` removes it |
| ...TextInputProps         | `TextInputProps`           | -                     | All standard React Native TextInput props are supported                                                                                                                                                                                                                           |

> **Note**: When used within a TextField component, Input automatically consumes form state (isDisabled, isInvalid) from TextField via the form-item-state context.

### Input.Background

Absolute-fill container rendered behind the text input. With no children, the active library theme decides the default content (e.g. a glass blur layer); pass children to host custom content with the same positioning and clipping.

| prop          | type              | default   | description                                                                                    |
| ------------- | ----------------- | --------- | ---------------------------------------------------------------------------------------------- |
| children      | `React.ReactNode` | -         | Custom content inside the background container                                                 |
| className     | `string`          | -         | Additional CSS classes                                                                         |
| fallbackColor | `ThemeColor`      | `'field'` | Theme color token used as the opaque fallback on platforms without native blur (Android / web) |
| ...ViewProps  | `ViewProps`       | -         | All standard View props are supported                                                          |
