Text Field
A labelled single-line text input with description and error slots.
TextField is the label, input, help text, and error message as one component.
Compose them yourself only when a form needs a layout this does not support.
Variants
Filled
The default. A gray, 40px field with a small gray label, sized for dense product forms and settings.
<TextField label="Name" placeholder="Enter your name" />Outline
A transparent, 36px field with a 1px border, an 8px radius, and a label at the same 12px size as Filled, in the primary text colour instead of gray. Focus thickens the border to the primary text colour; errors and the disabled state look as they do on Filled.
<div className="flex flex-col gap-5">
<TextField variant="outline" label="Work Email" placeholder="[email protected]" />
<TextField variant="outline" label="Website URL" placeholder="https://" isOptional />
<TextField
variant="outline"
label="Company Name"
errorMessage="Enter your company name."
/>
</div>Use one variant per form. A Select takes the
same variant, so a form that mixes text fields and selects still matches.
The label keeps the text you give it: Filled title-cases it, Outline does not,
so a question such as "What are you interested in?" reads as written.
Examples
With description
<TextField
label="Email"
placeholder="[email protected]"
description="We only use this to send receipts."
/>label names the field, description explains it before the user makes a
mistake, and errorMessage explains one after. A placeholder is not a label:
it disappears on first keystroke and is invisible to some assistive tech.
Invalid
<TextField
label="Email"
defaultValue="not-an-email"
isInvalid
errorMessage="Enter a valid email address."
/>Optional
<TextField label="Related PR" isOptional placeholder="https://github.com/…" />isOptional adds an "Optional" hint on the label row, aligned to the input's
end edge in a lighter gray than the label. Mark the few optional fields rather
than every required one, and keep "Optional" out of the label text itself.
For custom fields built from React Aria parts, FieldLabel renders the same
label row.
Read-only
<TextField label="Read-Only" defaultValue="Locked value" isReadOnly />Disabled
<TextField label="Disabled" placeholder="Unavailable" isDisabled />validationBehavior defaults to native, so the field participates in the
browser's form validation and reports on submit. Set it to aria when the form
owns validation and you only want the accessible wiring.
Distinguish the two inert states: isReadOnly keeps the value readable,
selectable, and submitted; isDisabled removes the field from the form and
from the tab order.
Prefixes and suffixes
Prefix
<TextField label="Amount" placeholder="0.00" start={<span>$</span>} />Suffix
<TextField label="Domain" placeholder="myapp" end={<span>.base.org</span>} />start and end render inside the field's border. Use them for units,
prefixes, and icons — not for buttons, which need their own hit target outside
the input.
Leading icon
Wrap a leading icon in InputStartIcon to get the field's icon size, padding,
and focus and error colours. It renders a Label, so clicking the icon focuses
the input.
<TextField
aria-label="Search"
placeholder="Search"
start={
<InputStartIcon>
<SearchIcon />
</InputStartIcon>
}
/>When to use
Use TextField for single-line free text, with its label, help text, and
error message. Use Filled in dense product forms and settings, and Outline in
marketing forms such as the base.org contact form, where fields sit on the
page background with more room around them.
Use something else when:
- The value is a quantity to compute with. Use Number Field.
- The reader picks from a known set. Use Select or Segment.
Usage
Do
Write a description when the requirement is not obvious from the label.
Preventing the error costs the user less than recovering from it.
Don't
Use a placeholder in place of a label. It vanishes as soon as the user types, leaving no way to recall what the field was for.
Do
Pick one variant for the whole form, and set the same variant on its
Selects.
Don't
Mix Filled and Outline fields in one form, or add asterisks to required
fields. Mark the optional ones with isOptional instead.
Props
| Prop | Type | Default |
|---|---|---|
autoCompleteDescribes the type of autocomplete functionality the input should provide if any. See | Typestring | Default— |
autoCorrectAn attribute that takes as its value a space-separated string that describes what, if any, type | Typestring | Default— |
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<TextFieldRenderProps> | Default— |
defaultValueThe default value (uncontrolled). | Typestring | Default— |
description | TypeReactNode | Default— |
end | TypeReactNode | Default— |
enterKeyHintAn enumerated attribute that defines what action label or icon to preset for the enter key on | Type"enter" | "done" | "go" | "next" | "previous" | "search" | "send" | Default— |
errorMessage | TypeChildrenOrFunction<FieldErrorRenderProps> | Default— |
inputModeHints at the type of data that might be entered by the user while editing the element or its | Type"none" | "search" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | Default— |
isDisabledWhether the input is disabled. | Typeboolean | Default— |
isInvalidWhether the value is invalid. | Typeboolean | Default— |
isOptionalShows "Optional" on the label row, aligned to the input's end edge. | Typeboolean | Default— |
isReadOnlyWhether the input can be selected but not changed by the user. | Typeboolean | Default— |
isRequiredWhether user input is required on the input before form submission. | Typeboolean | Default— |
label | TypeReactNode | Default— |
maxLengthThe maximum number of characters supported by the input. See | Typenumber | Default— |
minLengthThe minimum number of characters required by the input. See | Typenumber | Default— |
patternRegex pattern that the value of the input must match to be valid. See | Typestring | Default— |
placeholder | Typestring | Default— |
spellCheckAn enumerated attribute that defines whether the element may be checked for spelling errors. | Typestring | Default— |
start | TypeReactNode | Default— |
typeThe type of input to render. See | Type(string & {}) | "search" | "text" | "tel" | "url" | "email" | "password" | Default'text' |
validateA function that returns an error message if a given value is invalid. | Type((value: string) => true | ValidationError | null) | Default— |
validationBehaviorWhether to use native HTML form validation to prevent form submission | Type"native" | "aria" | Default'native' |
variantGray 40px `filled` field, or transparent, bordered 36px `outline` field. | Type"filled" | "outline" | Defaultfilled |
FieldLabel
Inside a TextField or Select, FieldLabel takes the field's variant. In a
custom field, pass variant to match the input styles: the exported
fieldStyles, labelStyles, inputWrapperStyles, and inputStyles helpers
take the same variant and default to filled.
| Prop | Type | Default |
|---|---|---|
elementType | Typestring | Default— |
isOptionalShows "Optional" at the end of the label row, aligned to the input's end edge. | Typeboolean | Default— |
variantDefaults to the enclosing field's variant, or `filled` outside one. | Type"filled" | "outline" | Default— |
InputStartIcon
| Prop | Type | Default |
|---|---|---|
elementType | Typestring | Default— |
Accessibility
TextField wraps React Aria's TextField, which associates the label,
description, and error message with the input and announces validation changes.
When a field has no visible label, pass aria-label — an unlabelled input is
unusable with a screen reader. In development, a TextField with no label
and no aria-label logs a console warning.
The description and the "Optional" hint use fg-muted, which meets 4.5:1
contrast against the page background in light and dark themes.
Both variants show focus with a 2px ring, Filled in gray and Outline in the primary text colour, and show errors in red and in the error message, not by colour alone.
The focus ring and a leading icon's colour fade in over 150ms, and change at once when the reader prefers reduced motion.