Use cases
- Single-line text entry — email, search, URL, username.
- Form fields that need explicit invalid styling tied to ARIA.
- Inputs with a leading or trailing affordance: search glyph, clear button, validation checkmark.
When NOT to use
- Multi-line input — use a
Textareaprimitive (planned). - A toggle — use
SwitchorToggle(planned). - Date / time pickers, comboboxes — separate primitives where the text field is one part of a larger widget.
Anatomy
The component is a styled wrapper around the platform input. The wrapper owns the border, padding, and focus ring; the input is transparent and inherits the wrapper's text color so leading/trailing icons compose cleanly.
┌──────────────────────────────────────────────┐
│ [leadingIcon] input element [trailingIcon] │
└──────────────────────────────────────────────┘
Use the wrapper's className for layout (max-width, full-width) and inputClassName for the input itself (font, letter-spacing). Most consumers never need inputClassName.
Variants
| Variant | Use when |
|---|---|
default | Standard text entry. |
destructive | The field has a validation error. Use invalid instead of toggling the variant by hand — it drives the visual and the ARIA state in one prop. |
Sizes
| Size | Height | Use when |
|---|---|---|
sm | 36 px | Dense forms, table-cell editors, secondary fields. |
md | 40 px | Default for most desktop forms. |
lg | 48 px | Primary mobile fields and high-emphasis form rows. |
Validation pattern
Pair the input with a label and an error message element. Wire them with htmlFor and aria-describedby — Input deliberately doesn't render the label or the message itself so consumers can put them wherever the layout calls for.
<label htmlFor="email" className="text-sm font-medium">
Email <span className="text-destructive">*</span>
</label>
<Input
id="email"
type="email"
required
invalid={!!error}
aria-describedby={error ? 'email-error' : undefined}
/>
{error && (
<p id="email-error" className="mt-1 text-sm text-destructive">
{error}
</p>
)}Composition
- Pair
leadingIconwith alucide-reactglyph (e.g.<Mail />) for affordance. - Use
trailingIconfor a clear button or a validation checkmark. - For password fields, set
type="password". Show/hide affordances are a consumer concern — Input keeps its surface small on purpose.