# Input

Single-line text field.

```tsx
import { Field, FieldControl, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

<Field required>
  <FieldLabel>Email</FieldLabel>
  <FieldControl>
    <Input type="email" placeholder="you@company.com" />
  </FieldControl>
</Field>
```

## Usage

### What you provide
- A label, always: put the input inside `Field` (or link a `Label` through `htmlFor` / `id`). A placeholder never replaces a label.
- The right `type` (`email`, `tel`, `number`, `password`) for mobile keyboards and autofill.
- An optional `placeholder` with a real example ("you@company.com"), shown in `muted-foreground`.
- Errors: `aria-invalid="true"` plus a message below in `text-destructive` that says how to fix it.

### Layout
- Label and field in `grid gap-2`; fields stacked with `gap-4`.
- Helper text below in `text-sm text-muted-foreground`.
- For validation, pair the fields with `react-hook-form` + `zod`.

## Accessibility

- Wrap the field in `Field` so the label, instructions and error are tied to the input (`aria-describedby`, `aria-invalid`, `required`). The label stays visible after the field is filled; a placeholder is only an extra hint.
- State instructions, required status and limits before the person types. Clicking the label focuses the field.
- `Tab` / `Shift+Tab` follow the page order; native editing, selection, copy and paste always work. `Enter` runs the form's submit action.
- On an invalid value, keep what was typed and explain how to fix it ("Enter an email like name@example.com"), not "Invalid value". Don't show errors before the person had a chance to fill the field.
- `type="email"`: a valid format doesn't prove the address exists; accept one address unless the context needs `multiple`.
- `type="search"`: say whether search runs on submit or while typing; announce the number of results without moving focus; a "Clear search" control empties the field without submitting.
- For passwords, use `PasswordInput`.

_Adapted from Magoo 1.6.0 by Marcelo Sales: [Input "text"](https://magoo.cc/en/components/forms/input-text.html) (`input-text`), [Input "email"](https://magoo.cc/en/components/forms/input-email.html) (`input-email`), [Input "search"](https://magoo.cc/en/components/forms/input-search.html) (`input-search`), [Form validation](https://magoo.cc/en/components/messages/form-validation.html) (`validacao-formularios`). Magoo is educational guidance; test the behavior in your implementation._

## API

Install:

```bash
npx @aline-aroucha/pui add input label
```

```tsx
<Field>
  <FieldLabel />
  <FieldControl>
    <Input />
  </FieldControl>
</Field>
```

### Input

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `"text" \| "email" \| "search" \| "tel" \| "url" \| "number" \| …` | `"text"` | Native type; picks the right mobile keyboard. Use PasswordInput for passwords. |
| `value` | `string` | — | Controlled value. |
| `defaultValue` | `string` | — | Initial value when uncontrolled. |
| `placeholder` | `string` | — | An example value; never a replacement for the label. |
| `disabled` | `boolean` | `false` | Blocks editing. |
| `autoComplete` | `string` | — | Autofill hint, e.g. "email". |
| `onChange` | `(event: ChangeEvent) => void` | — | Runs on every edit. |

## Related pages

- [Field](https://aline-aroucha.github.io/pui/components/field.html)
- [PasswordInput](https://aline-aroucha.github.io/pui/components/password-input.html)
- [Textarea](https://aline-aroucha.github.io/pui/components/textarea.html)

---
PUI documentation · https://aline-aroucha.github.io/pui/components/input.html
