A labeled text input — label, description, error, and success states all wired through the
shared useFormField hook, so id/aria-describedby/aria-invalid are never hand-rolled per
field. Also takes an explicit pattern prop and an optional leading icon.
tsx
<Input label="Email" />label
Examples
description sets the baseline hint text; error (or success) replaces it entirely once the
field has something to report, rather than stacking both underneath the field at once:
tsx
We'll only use this for order updates.
That doesn't look like a valid email.
Looks good.
<Input label="Email" description="We'll only use this for order updates." />
<Input label="Email" error="That doesn't look like a valid email." />
<Input label="Email" success="Looks good." />A leading icon reads as part of the field, not a decoration bolted on top — useful for a quick
visual hint at what kind of value is expected:
tsx
<Input label="Email" icon="user" />Uncontrolled by default, like any native <input> — pass value/onChange only when you need to
read or drive the value from outside the field itself.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| className | text | — | — |
| description | text | — | — |
| error | text | — | — |
| icon | warning | menu | search | circle | filter | chevron-down | chevron-up | chevron-left | chevron-right | close | check | plus | minus | arrow-right | arrow-left | info | eye | eye-off | trash | edit | copy | download | upload | external-link | star | calendar | clock | user | settings | more-horizontal | refresh | lock | maximize | minimize | — | A leading icon inside the field, e.g. for a labeled filter/amount input. |
| label | text | — | — |
| pattern | text | — | A regular expression the native constraint-validation API checks the value against — already usable today as a plain HTML attribute (this just documents it as a first-class prop). Doesn't produce an error message on its own; pair it with your own `error` + `onBlur` for that. |
| size | s | m | l | "m" | — |
| success | text | — | — |