TextField
A labeled text input with support for descriptions and validation errors.
We'll never share your email.
import { TextField } from '@ontoui/react';
<TextField.Root> <TextField.Label>Email</TextField.Label> <TextField.Control type="email" placeholder="you@example.com" /> <TextField.Description>We'll never share your email.</TextField.Description></TextField.Root>;Anatomy
| Part | Description |
|---|---|
TextField.Root | Container that groups all parts and manages field state |
TextField.Label | Accessible label associated with the control |
TextField.Control | The underlying <input> element |
TextField.AnimatedPlaceholder | Types example queries through the control’s placeholder |
TextField.Description | Optional helper text displayed below the control |
TextField.Error | Error message shown when the field is invalid |
Examples
Invalid
Set the invalid prop on TextField.Root to mark the field as invalid and reveal the error message.
<TextField.Root invalid> <TextField.Label>Username</TextField.Label> <TextField.Control placeholder="Enter username" /> <TextField.Error>Username is required.</TextField.Error></TextField.Root>Animated placeholder
A search box says nothing about what it will accept. TextField.AnimatedPlaceholder cycles
example queries through the placeholder with a typing effect, so the field shows what it can
be asked for instead of waiting to be guessed at.
<TextField.Root> <TextField.Label>Search reports</TextField.Label> <TextField.AnimatedPlaceholder prefix="Try: " examples={['March expenses', 'unpaid invoices', 'headcount by team']} /> <TextField.Control placeholder="Search reports" /></TextField.Root>The part renders nothing of its own — it drives the placeholder of TextField.Control, so
the text is a real placeholder and disappears behind a value like any other. Order inside
TextField.Root does not matter.
prefix stays in place while the examples are retyped behind it. typeSpeed,
deleteSpeed and holdDuration set the pace, and caret is the character standing in for
a cursor — pass caret={false} to drop it.
Keep placeholder on TextField.Control as well. It is what shows on the server, before
hydration, and with scripting off; the animation upgrades it once it starts.
The animation stops on a whole example — never mid-word — while the field is focused or
holds a value, and under prefers-reduced-motion: reduce it never starts, leaving the first
example as a still placeholder. Because the text is a placeholder it can end up as the
field’s accessible name, so always render a TextField.Label (or pass aria-label to the
control) to give the field a name that does not move.
Disabled
Set disabled on TextField.Root to disable the entire field group.
<TextField.Root disabled> <TextField.Label>Read-only field</TextField.Label> <TextField.Control placeholder="Disabled input" /></TextField.Root>API Reference
TextField.Root
| Prop | Type | Default |
|---|---|---|
children? | ReactNode | — |
className? | string | — |
style? | CSSProperties | — |
name? | string | — |
disabled? | boolean | — |
invalid? | boolean | — |
ref? | Ref<HTMLDivElement> | — |
TextField.Label
| Prop | Type | Default |
|---|---|---|
children? | ReactNode | — |
className? | string | — |
ref? | Ref<HTMLDivElement> | — |
TextField.Control
| Prop | Type | Default |
|---|---|---|
id? | string | — |
className? | string | — |
placeholder? | string | — |
type? | HTMLInputTypeAttribute | — |
defaultValue? | string | — |
value? | string | — |
disabled? | boolean | — |
required? | boolean | — |
readOnly? | boolean | — |
onChange? | ChangeEventHandler<HTMLInputElement, Element> | — |
onFocus? | FocusEventHandler<HTMLInputElement> | — |
onBlur? | FocusEventHandler<HTMLInputElement> | — |
ref? | Ref<HTMLDivElement> | — |
TextField.AnimatedPlaceholder
| Prop | Type | Default |
|---|---|---|
examples | string[] | — |
prefix? | string | '' |
typeSpeed? | number | 55 |
deleteSpeed? | number | 25 |
holdDuration? | number | 2000 |
caret? | string | false | '|' |
TextField.Description
| Prop | Type | Default |
|---|---|---|
children? | ReactNode | — |
className? | string | — |
ref? | Ref<HTMLDivElement> | — |
TextField.Error
| Prop | Type | Default |
|---|---|---|
children? | ReactNode | — |
className? | string | — |
ref? | Ref<HTMLDivElement> | — |