# TextField
**Category**: react
**URL**: https://www.heroui.com/docs/react/components/text-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/text-field.mdx
> Composition-friendly text fields with labels, descriptions, and inline validation
***
## Import
```tsx
import { TextField } from '@heroui/react';
```
### Usage
```tsx
import {Input, Label, TextField} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
```tsx
import {TextField, Label, Input, Description, FieldError} from '@heroui/react';
export default () => (
)
```
> **TextField** combines label, input, description, and error into a single accessible component.
For standalone inputs, use **[Input](/docs/components/input)** or **[TextArea](/docs/components/textarea)**.
### With Description
```tsx
import {Description, Input, Label, TextField} from "@heroui/react";
export function WithDescription() {
return (
Choose a unique username for your account
);
}
```
### Required Field
```tsx
import {Description, Input, Label, TextField} from "@heroui/react";
export function Required() {
return (
This field is required
);
}
```
### Validation
Use `isInvalid` together with `FieldError` to surface validation messages.
```tsx
"use client";
import {Description, FieldError, Input, Label, TextArea, TextField} from "@heroui/react";
import React from "react";
export function Validation() {
const [username, setUsername] = React.useState("");
const [bio, setBio] = React.useState("");
const isUsernameInvalid = username.length > 0 && username.length < 3;
const isBioInvalid = bio.length > 0 && bio.length < 20;
return (
{isUsernameInvalid ? (
Username must be at least 3 characters.
) : (
Choose a unique username for your profile.
)}
{isBioInvalid ? (
Bio must contain at least 20 characters.
) : (
Minimum 20 characters ({bio.length}/20).
)}
);
}
```
### Controlled
Control the value to synchronize counters, previews, or formatting.
```tsx
"use client";
import {Description, Input, Label, TextArea, TextField} from "@heroui/react";
import React from "react";
export function Controlled() {
const [name, setName] = React.useState("");
const [bio, setBio] = React.useState("");
return (
);
}
```
### Error Message
```tsx
import {FieldError, Input, Label, TextField} from "@heroui/react";
export function WithError() {
return (
Please enter a valid email address
);
}
```
### Disabled State
```tsx
import {Description, Input, Label, TextField} from "@heroui/react";
export function Disabled() {
return (
This field cannot be edited
);
}
```
### TextArea
Use [TextArea](/docs/components/textarea) instead of [Input](/docs/components/input) for multiline content.
```tsx
import {Description, Label, TextArea, TextField} from "@heroui/react";
export function TextAreaExample() {
return (
Maximum 500 characters
);
}
```
### Input Types
```tsx
import {Input, Label, TextField} from "@heroui/react";
export function InputTypes() {
return (
);
}
```
### Full Width
```tsx
import {FieldError, Input, Label, TextField} from "@heroui/react";
export function FullWidth() {
return (
Password must be longer than 8 characters
);
}
```
### In Surface
When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` on Input or TextArea components to apply the lower emphasis variant suitable for surface backgrounds.
```tsx
import {Description, Input, Label, Surface, TextArea, TextField} from "@heroui/react";
export function OnSurface() {
return (
We'll never share this with anyone elseMinimum 4 rows
);
}
```
## Related Components
- **Input**: Single-line text input built on React Aria
- **TextArea**: Multiline text input with focus management
- **Fieldset**: Group related form controls with legends
### Custom Render Function
```tsx
"use client";
import {Input, Label, TextField} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
type="email"
>
);
}
```
## Styling
### Passing Tailwind CSS classes
```tsx
import {TextField, Label, Input, Description} from '@heroui/react';
function CustomTextField() {
return (
Keep it short and memorable.
);
}
```
### Customizing the component classes
TextField has minimal default styling. Override the `.textfield` class to customize the container styling.
```css
@layer components {
.textfield {
@apply flex flex-col gap-1;
}
/* When invalid, the description is hidden automatically */
.textfield[data-invalid="true"] [data-slot="description"],
.textfield[aria-invalid="true"] [data-slot="description"] {
@apply hidden;
}
/* Description has default padding */
.textfield [data-slot="description"] {
@apply px-1;
}
}
```
### CSS Classes
- `.textfield` – Root container with minimal styling (`flex flex-col gap-1`)
> **Note:** Child components ([Label](/docs/components/label), [Input](/docs/components/input), [TextArea](/docs/components/textarea), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options.
### Interactive States
TextField automatically manages these data attributes based on its state:
- **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid
- **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true
- **Focus Within**: `[data-focus-within="true"]` - Applied when any child input is focused
- **Focus Visible**: `[data-focus-visible="true"]` - Applied when focus is visible (keyboard navigation)
Additional attributes are available through render props (see TextFieldRenderProps below).
## API Reference
### TextField Props
TextField inherits all props from React Aria's [TextField](https://react-spectrum.adobe.com/react-aria/TextField.html) component.
#### Base Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode \| (values: TextFieldRenderProps) => React.ReactNode` | - | Child components (Label, Input, etc.) or render function. |
| `className` | `string \| (values: TextFieldRenderProps) => string` | - | CSS classes for styling, supports render props. |
| `style` | `React.CSSProperties \| (values: TextFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. |
| `fullWidth` | `boolean` | `false` | Whether the text field should take full width of its container |
| `id` | `string` | - | The element's unique identifier. |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.|
#### Validation Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isRequired` | `boolean` | `false` | Whether user input is required before form submission. |
| `isInvalid` | `boolean` | - | Whether the value is invalid. |
| `validate` | `(value: string) => ValidationError \| true \| null \| undefined` | - | Custom validation function. |
| `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. |
| `validationErrors` | `string[]` | - | Server-side validation errors. |
#### Value Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | - | Current value (controlled). |
| `defaultValue` | `string` | - | Default value (uncontrolled). |
| `onChange` | `(value: string) => void` | - | Handler called when the value changes. |
#### State Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isDisabled` | `boolean` | - | Whether the input is disabled. |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. |
#### Form Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | - | Name of the input element, for HTML form submission. |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render. |
#### Accessibility Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `aria-label` | `string` | - | Accessibility label when no visible label is present. |
| `aria-labelledby` | `string` | - | ID of elements that label this field. |
| `aria-describedby` | `string` | - | ID of elements that describe this field. |
| `aria-details` | `string` | - | ID of elements with additional details. |
### Composition Components
TextField works with these separate components that should be imported and used directly:
- **Label** - Field label component from `@heroui/react`
- **Input** - Single-line text input from `@heroui/react`
- **TextArea** - Multi-line text input from `@heroui/react`
- **Description** - Helper text component from `@heroui/react`
- **FieldError** - Validation error message from `@heroui/react`
Each of these components has its own props API. Use them directly within TextField for composition:
```tsx
setEmail(e.target.value)} />
We'll never share your email.Please enter a valid email address.
```
### TextFieldRenderProps
When using render props with `className`, `style`, or `children`, these values are available:
| Prop | Type | Description |
|------|------|-------------|
| `isDisabled` | `boolean` | Whether the field is disabled. |
| `isInvalid` | `boolean` | Whether the field is currently invalid. |
| `isReadOnly` | `boolean` | Whether the field is read-only. |
| `isRequired` | `boolean` | Whether the field is required. |
| `isFocused` | `boolean` | Whether the field is currently focused (DEPRECATED - use `isFocusWithin`). |
| `isFocusWithin` | `boolean` | Whether any child element is focused. |
| `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). |