# Input

> A one-line text field with sizes and an error state.

- Name: `input`
- Status: beta
- Categories: forms
- File: the install writes `input.tsx` to your `ui` alias, `@/components/ui` by default.
- npm packages: `@base-ui/react`, `class-variance-authority`. The install adds them.
- Gallery: https://arbokui.com/components/input
- Registry item: https://arbokui.com/r/input.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/input
   ```

## Use it for

- Short free text: a name, an email address, a search, a number.
- Name it with a visible label. Give the input an id and point the label's htmlFor at it.
- Set the type that fits the value, like email, tel, url, or search, so phones show the right keyboard.
- Show errors with aria-invalid plus a message under the input, linked with aria-describedby.

## Avoid it for

- Text that can run past one line, like a comment or a bio. Use a textarea.
- Choosing from a fixed list. Use a select or a radio group.
- Turning a setting on and off. Use a checkbox or a switch.
- Using placeholder as the label. It disappears as soon as someone types.

## Props

- `size`: `"sm" | "md" | "lg"`. Default `"md"`. Height and text size. Horizontal padding stays aligned across sizes. Density scales them.
- `disabled`: `boolean`. Default `false`. Blocks typing and removes the input from the tab order.
- `aria-invalid`: `boolean`. Shows the danger border. Set it when validation fails, and link the message with aria-describedby.
- `onValueChange`: `(value: string, details) => void`. Called with the new text on every change. Use it with value for a controlled input.
- `className`: `string`. Extra classes. Later classes win, so className='rounded-none' replaces the radius.

## Accessibility

- Renders a native \<input>, so typing, selection, autofill, and form submission work as usual.
- It has no name on its own. Pair it with a \<label htmlFor>, or wrap it in a label.
- aria-invalid="true" tells screen readers the value is wrong. Put the reason in text next to the input, not only in the red border.
- The border uses --input, which the theme tests hold to 3:1 against the page and cards.
- The focus ring uses --ring, which the theme tests hold to 3:1 against the page and cards.
- On touch screens the text is 16px, so iOS Safari does not zoom in when the input gets focus.

## Examples

### With a label

```tsx
<div className="grid gap-2">
  <label htmlFor="email" className="text-sm font-medium">
    Email
  </label>
  <Input id="email" type="email" autoComplete="email" placeholder="you@example.com" />
</div>
```

### Error message the input points to

```tsx
<div className="grid gap-2">
  <label htmlFor="handle" className="text-sm font-medium">
    Username
  </label>
  <Input id="handle" defaultValue="admin" aria-invalid aria-describedby="handle-error" />
  <p id="handle-error" className="text-sm text-destructive-soft-foreground">
    That name is taken. Try another.
  </p>
</div>
```

### Small, in a toolbar

```tsx
<Input size="sm" type="search" aria-label="Search projects" placeholder="Search" />
```
