Text Field

React Text Field components allow users to enter plain text values using a keyboard. They are commonly used in forms to collect names, email addresses, search queries, and other short text inputs where precise keyboard entry is expected.

Use your legal name as it appears on your ID.

Installation

The Text Field relies on the react-aria-components library and class-variance-authority.

Install the component using the Tailgrids CLI.

npx @tailgrids/cli add text-field

Anatomy

import { Label } from "@/components/tailgrids/core/label";
import { Description } from "@/components/tailgrids/core/description";
import { Input } from "@/components/tailgrids/core/input";
import { TextField } from "@/components/tailgrids/core/text-field";

export const TextFieldExample = () => (
  <TextField>
    <Label>Full name</Label>
    <Input placeholder="Enter your full name" />
    <Description>Use your legal name as it appears on your ID.</Description>
  </TextField>
);

Examples

Basic Usage

A standard text field with a label and placeholder text.

Controlled

Manage the value externally using the value and onChange props.

Uncontrolled

An uncontrolled text field with a defaultValue prop.

With Description

Add helper text below the input using the Description and FieldError component.

We'll never share your email with anyone.

Validation

The TextField component supports validation using the required, invalid, and validate props. The FieldError component is used to display validation messages.

API Reference

TextField

The text input component. Wraps React Aria's TextField and maps boolean props (disabled, readOnly, required, invalid) to their is-* equivalents.

PropTypeDefaultDescription
valuestring-The current text value (controlled).
defaultValuestring-The default text value (uncontrolled).
onChange(value: string) => void-Handler called when the value changes.
namestring-The name of the input, used when submitting an HTML form.
type'email' | 'password' | 'search' | 'tel' | 'text' | 'url''text'The type of input to render.
inputMode'decimal' | 'email' | 'none' | 'numeric' | 'search' | 'tel' | 'text' | 'url'-Hints at the type of data that might be entered.
autoCompletestring-Describes the type of autocomplete functionality.
minLengthnumber-The minimum number of characters required.
maxLengthnumber-The maximum number of characters allowed.
patternstring-Regex pattern the value must match to be valid.
formstring-The <form> element to associate the input with.
idstring-The element's unique identifier.
autoFocusbooleanfalseWhether the input should receive focus on mount.
orientation'vertical' | 'horizontal' | 'responsive''vertical'Layout direction of the field container.
disabledbooleanfalseWhether the input is disabled.
readOnlybooleanfalseWhether the input is read only.
requiredbooleanfalseWhether the input is required.
invalidbooleanfalseWhether the input is shown in an invalid state.
validate(value: string) => ValidationResult | true | null | undefined-Custom validation function for the value.
validationBehavior'aria' | 'native''native'Whether to use native HTML or ARIA form validation.
spellCheckboolean-Whether the element may be checked for spelling errors.
enterKeyHint'done' | 'enter' | 'go' | 'next' | 'previous' | 'search' | 'send'-Action label for the enter key on virtual keyboards.
aria-labelstring-Defines a string that labels the current element.
aria-labelledbystring-Identifies the element (or elements) that label the element.
aria-describedbystring-Identifies the element that describes the object.
aria-detailsstring-Identifies the element providing extended description.
onBlur(e: FocusEvent) => void-Handler called when the element loses focus.
onFocus(e: FocusEvent) => void-Handler called when the element receives focus.
onFocusChange(isFocused: boolean) => void-Handler called when the element's focus status changes.
onKeyDown(e: KeyboardEvent) => void-Handler called when a key is pressed.
onKeyUp(e: KeyboardEvent) => void-Handler called when a key is released.
classNamestring-Additional CSS classes to apply to the container.

See the React Aria TextField documentation for more details.

Composition

The Text Field is composed of the root TextField component plus Input for the text input element. It can be combined with shared field components (Label, Description, FieldError) for a complete form control.

TextField                                  — Root container. Manages text value, validation, and ARIA context.
├── Label                                  — Visible label.
├── Input                                  — Native text input element with styling and ARIA integration.
├── Description                            — Helper text.
└── FieldError                             — Validation error message (shown when `invalid` is set).
  • Use TextField as the root. It provides the text value, validation state, and keyboard context to all children.
  • Use Label to label the field. It is automatically linked to the input.
  • Use Input to render the text input element. It handles keyboard input and focus management.
  • Use Description for helper text. It is automatically announced by screen readers.
  • Use FieldError for validation messages. It is linked via aria-errormessage when invalid is set.

Accessibility

  • Label Association: The Label component is automatically associated with the input via ARIA, ensuring screen readers announce the label when focus is on the field.
  • Validation Messages: FieldError is linked to the input via aria-errormessage when the field is in an invalid state.
  • Required Indicator: isRequired applies aria-required to the input, signaling to assistive technology that the field must be filled.
  • Disabled State: When disabled is true, the input receives aria-disabled and does not respond to user interaction.
  • Read Only: The readOnly prop prevents user edits while keeping focus and selection behavior intact.