Single-line text field for capturing short user input such as names, emails, numbers, and queries.
Description
Input renders a native <input> wrapped in a styled shell. From the consumer's perspective it is a single-element component (<Input /> does the right thing on its own), but it also exports InputShell and InputProvider for advanced composition. When nested inside a Field, it inherits size, invalid, disabled, and loading automatically through context, so you rarely set those props directly.
Reach for it whenever a form needs a short, single-line text value: emails, names, search queries, currency amounts, phone numbers, file pickers, and the typical settings-pane controls. Pair it with FieldLabel for accessible labelling and with FieldDescription / FieldError for helper and validation copy; the whole stack sits naturally inside a FieldGroup.
Don't use Input for multi-line text; reach for Textarea. For option pickers use Select or NativeSelect. For binary toggles use Checkbox or Switch. For free-form numeric scrubbers (steppers, sliders) reach for the dedicated numeric components instead of type="number".
Installation
Usage
Examples
Sizes
Three sizes (xs, sm, md) match the surrounding type scale and resize the shell radius. sm is the default. When Input sits inside a Field, the Field’s size is authoritative and cascades through context; set size on the Input only for standalone use.
States
Field propagates invalid, disabled, and loading to the wrapped Input. invalid swaps the border and outline to the error tones, disabled mutes the field, and loading paints the info-tinted outline plus aria-busy on the shell.
With Label
The canonical labelled-input pattern. Wrap the Input in a Field and pair it with a FieldLabel; Field's context drives the label's size, disabled, and invalid styling.
With Description
Add a FieldDescription for inline helper copy: usage hints, format examples, privacy notes. The description tracks Field's invalid and disabled states automatically.
With Error
Set invalid on the Field and render a FieldError with an errors array; the input switches to the error border and the message renders with role="alert". Duplicate messages are de-duplicated automatically.
Composition
Drop Input next to a Button or Select inside a horizontal flex row to build search bars and currency pickers. Set flex-1 on the Input so it fills the remaining space.
Accessibility
Input renders a native <input>, so the browser's text-field semantics, focus order, and IME / autofill behavior come for free. Wrap it in a Field + FieldLabel to give it an accessible name; the label's htmlFor ties to the input's id.
ARIA notes:
- The component does not set an explicit
role; the implicittextboxrole from<input>is what assistive tech announces. aria-invalidis set on the input automatically whenField invalid(or an explicitaria-invalidprop) is in effect; pair it with aFieldErrorso the message is announced.InputShellsetsaria-busywhenloadingistrue; the shell also becomes non-interactive viapointer-events-none.disabledremoves the input from the tab order and disables pointer events.- The accessible name must come from a
FieldLabel, anaria-label, or anaria-labelledbyreference; never rely on the placeholder alone.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the component sets these for CSS targeting:
data-slot="input-shell"on the wrapper div, withdata-size="<size>"and the boolean attributesdata-invalid,data-disabled,data-loading(each present only whentrue).data-slot="input"on the inner<input>element, withdata-size="<size>".
Target a specific state in CSS:
Related Components
- Field: wraps
Inputto providesize,invalid,disabled, andloadingvia context, plus accessible label, description, and error wiring. - Textarea: multi-line equivalent; reach for it when the value can span more than one line.
- NativeSelect: sibling primitive for native option pickers; composes with
Inputinside a shared row. - Select: Radix-based select for richer pickers when the native dropdown isn't enough.
API Reference
Input
Single-line text field. Extends React.ComponentProps<"input"> with size re-typed to the component's size scale, so any standard input attribute (id, name, placeholder, type, value, defaultValue, onChange, onBlur, aria-*, etc.) is accepted. When rendered outside an existing InputProvider, it wraps itself in an InputProvider + InputShell automatically.
Props
Variants
InputShell
Visual shell around Input. Used automatically when Input is rendered standalone; render it explicitly only when composing icons, slot buttons, or other affordances inside the same border. Extends React.ComponentProps<"div">, so any standard div attribute is accepted. (advanced)
Props
InputProvider
Context provider that broadcasts size, invalid, disabled, and loading down to nested Input and InputShell instances. Most apps inherit these from Field and never render InputProvider directly. (advanced)