# Input

> A one-line field with a label, hint and error that trade places, a clear button that folds in, and one shake when an error arrives.

Most inputs swap their hint for an error with a jump and leave the clear button popping in over the text. Here the hairline darkens on hover and turns to the ring on focus, the clear button opens its own width so the text never moves, and an error lifts in where the hint was while the field gives one short shake.

## Install

```bash
npx shadcn@latest add https://hairlineui.com/r/input.json
```

Needs React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.

- npm: none
- Hairline UI components it needs (the CLI installs them too): `ui-interaction-motion`
- Docs and live preview: https://hairlineui.com/ui/input
- Registry item (source): https://hairlineui.com/r/input.json

## Usage

```tsx
import { Input } from "@/components/ui/input";

<Input label="Email" type="email" placeholder="you@fernhill.co" hint="We'll send the receipt here." />
<Input label="Workspace" error={error} clearable />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `ReactNode` | – | Shown above; becomes the accessible name. |
| `hint` | `ReactNode` | – | Line under the field while there is no error. |
| `error` | `ReactNode` | – | Turns the field red and takes the hint's place. |
| `leading / trailing` | `ReactNode` | – | Icon or text before and after the value. |
| `clearable` | `boolean` | `false` | A clear button once there is text. |
| `size` | `"sm" \| "md"` | `"md"` | 28px or 36px tall. |
| `onValueChange` | `(value: string) => void` | – | The new text on every change. |
| `...input props` | `InputHTMLAttributes` | – | Everything a native input takes, including ref. |

## States

- **rest**: A hairline pill, 36px or 28px tall; hover darkens the line.
- **focus**: The line turns to the ring with a 3px halo (200ms).
- **typing**: With clearable, a clear button opens its width as the first letter lands (320ms) and folds away when the field is empty.
- **error**: The line turns red, the hint folds away while the error rises from a 4px blur (320ms), and the field shakes once (380ms).

## What it handles

The usual input pushes an error in under itself, moves the layout, and gives no signal when you look away. This one folds the message in, keeps the text still and shakes once.

- **Hint and error in one line**: The hint folds away as the error rises out of a blur, and back when it is fixed.
- **A clear button that makes room**: It opens its own width as you type, so the text never jumps under it.
- **Accessible by default**: Label, aria-invalid and aria-describedby are wired to the right ids.
- **Works with any form library**: Controlled or uncontrolled; onChange and onValueChange both fire, even from the clear button.

## Replaces

label + hint + error wiring, aria-describedby plumbing, clear button, error shake

## Where it fits

- **Sign-up and settings forms**: Name, email and URL fields with hints that turn into errors in place.
- **Filters above a table**: A clearable field that empties with one press.
- **Inline creation rows**: A compact 28px field inside a toolbar or list row.
- **Domain and handle fields**: Leading and trailing text such as https:// or .com.

## Notes

- Shares field.tsx with every text control: one surface, one focus ring, one way of showing hints and errors.
- Reduced motion: the hint and error change in place and nothing shakes.
- The clear button hands focus back to the field.

License: MIT (https://hairlineui.com/license#components)
