---
type: doc
title: Input
description: Displays a form input field or a component that looks like an input field.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/input/input-demo.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="input-demo-api-key">API Key</FieldLabel>
  <Input id="input-demo-api-key" type="password" placeholder="sk-..." />
  <FieldDescription>
    Your API key is encrypted and stored securely.
  </FieldDescription>
</Field>
```

## Installation

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

## Usage

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

```astro
<Input />
```

`Input` renders a native `input` and passes every attribute through, so use
`type`, `name`, `required`, and `disabled` as in HTML. Pair it with
[Field](/astro/components/field/) for a label, description, and error.

## Basic

```astro title="src/components/examples/input/input-basic.astro"
---
import { Input } from "@/components/ui/input"
---

<Input placeholder="Enter text" />
```

## Field

Use `Field`, `FieldLabel`, and `FieldDescription` to create an input with a label and description.

```astro title="src/components/examples/input/input-field.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="input-field-username">Username</FieldLabel>
  <Input
    id="input-field-username"
    type="text"
    placeholder="Enter your username"
  />
  <FieldDescription>
    Choose a unique username for your account.
  </FieldDescription>
</Field>
```

## Field Group

Use `FieldGroup` to show multiple `Field` blocks and to build forms.

```astro title="src/components/examples/input/input-fieldgroup.astro"
---
import { Button } from "@/components/ui/button"
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<FieldGroup>
  <Field>
    <FieldLabel for="fieldgroup-name">Name</FieldLabel>
    <Input id="fieldgroup-name" placeholder="Jordan Lee" />
  </Field>
  <Field>
    <FieldLabel for="fieldgroup-email">Email</FieldLabel>
    <Input id="fieldgroup-email" type="email" placeholder="name@example.com" />
    <FieldDescription>
      We&apos;ll send updates to this address.
    </FieldDescription>
  </Field>
  <Field orientation="horizontal">
    <Button type="reset" variant="outline">
      Reset
    </Button>
    <Button type="submit">Submit</Button>
  </Field>
</FieldGroup>
```

## Disabled

Use the `disabled` attribute to disable the input. To style the disabled state, add `data-disabled="true"` to the `Field` component.

```astro title="src/components/examples/input/input-disabled.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field data-disabled="true">
  <FieldLabel for="input-demo-disabled">Email</FieldLabel>
  <Input id="input-demo-disabled" type="email" placeholder="Email" disabled />
  <FieldDescription>This field is currently disabled.</FieldDescription>
</Field>
```

## Invalid

Use `aria-invalid="true"` to mark the input as invalid. To style the invalid state, add `data-invalid="true"` to the `Field` component.

```astro title="src/components/examples/input/input-invalid.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field data-invalid="true">
  <FieldLabel for="input-invalid">Invalid Input</FieldLabel>
  <Input id="input-invalid" placeholder="Error" aria-invalid="true" />
  <FieldDescription>This field contains validation errors.</FieldDescription>
</Field>
```

## File

Use `type="file"` to create a file input.

```astro title="src/components/examples/input/input-file.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="picture">Picture</FieldLabel>
  <Input id="picture" type="file" />
  <FieldDescription>Select a picture to upload.</FieldDescription>
</Field>
```

## Inline

Use `Field` with `orientation="horizontal"` to create an inline input. Pair with `Button` to create a search input with a button.

```astro title="src/components/examples/input/input-inline.astro"
---
import { Button } from "@/components/ui/button"
import { Field } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field orientation="horizontal">
  <Input type="search" placeholder="Search..." />
  <Button>Search</Button>
</Field>
```

## Grid

Use a grid layout to place multiple inputs side by side.

```astro title="src/components/examples/input/input-grid.astro"
---
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<FieldGroup class="grid max-w-sm grid-cols-2">
  <Field>
    <FieldLabel for="first-name">First Name</FieldLabel>
    <Input id="first-name" placeholder="Jordan" />
  </Field>
  <Field>
    <FieldLabel for="last-name">Last Name</FieldLabel>
    <Input id="last-name" placeholder="Lee" />
  </Field>
</FieldGroup>
```

## Required

Use the `required` attribute to indicate required inputs.

```astro title="src/components/examples/input/input-required.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="input-required">
    Required Field <span class="text-destructive">*</span>
  </FieldLabel>
  <Input id="input-required" placeholder="This field is required" required />
  <FieldDescription>This field must be filled out.</FieldDescription>
</Field>
```

## Badge

Use `Badge` in the label to highlight a recommended field.

```astro title="src/components/examples/input/input-badge.astro"
---
import { Badge } from "@/components/ui/badge"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="input-badge">
    Webhook URL{" "}
    <Badge variant="secondary" class="ml-auto">
      Beta
    </Badge>
  </FieldLabel>
  <Input
    id="input-badge"
    type="url"
    placeholder="https://api.example.com/webhook"
  />
</Field>
```

## Input Group

To add icons, text, or buttons inside an input, use [Input Group](/astro/components/input-group/).

```astro title="src/components/examples/input/input-input-group.astro"
---
import InfoIcon from "@lucide/astro/icons/info"

import { Field, FieldLabel } from "@/components/ui/field"
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"
---

<Field>
  <FieldLabel for="input-group-url">Website URL</FieldLabel>
  <InputGroup>
    <InputGroupInput id="input-group-url" placeholder="example.com" />
    <InputGroupAddon>
      <InputGroupText>https://</InputGroupText>
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <InfoIcon />
    </InputGroupAddon>
  </InputGroup>
</Field>
```

## Button Group

To add buttons to an input, use [Button Group](/astro/components/button-group/).

```astro title="src/components/examples/input/input-button-group.astro"
---
import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
---

<Field>
  <FieldLabel for="input-button-group">Search</FieldLabel>
  <ButtonGroup>
    <Input id="input-button-group" placeholder="Type to search..." />
    <Button variant="outline">Search</Button>
  </ButtonGroup>
</Field>
```

## Form

A full form example with multiple inputs, a select, and a button.

```astro title="src/components/examples/input/input-form.astro"
---
import { Button } from "@/components/ui/button"
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"

const countries = [
  { label: "United States", value: "us" },
  { label: "United Kingdom", value: "uk" },
  { label: "Canada", value: "ca" },
]
---

<form class="w-full max-w-sm">
  <FieldGroup>
    <Field>
      <FieldLabel for="form-name">Name</FieldLabel>
      <Input id="form-name" type="text" placeholder="Evil Rabbit" required />
    </Field>
    <Field>
      <FieldLabel for="form-email">Email</FieldLabel>
      <Input id="form-email" type="email" placeholder="john@example.com" />
      <FieldDescription>
        We&apos;ll never share your email with anyone.
      </FieldDescription>
    </Field>
    <div class="grid grid-cols-2 gap-4">
      <Field>
        <FieldLabel for="form-phone">Phone</FieldLabel>
        <Input id="form-phone" type="tel" placeholder="+1 (555) 123-4567" />
      </Field>
      <Field>
        <FieldLabel for="form-country">Country</FieldLabel>
        <Select defaultValue="us">
          <SelectTrigger id="form-country" class="w-full">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              {countries.map((country) => (
                <SelectItem value={country.value}>{country.label}</SelectItem>
              ))}
            </SelectGroup>
          </SelectContent>
        </Select>
      </Field>
    </div>
    <Field>
      <FieldLabel for="form-address">Address</FieldLabel>
      <Input id="form-address" type="text" placeholder="123 Main St" />
    </Field>
    <Field orientation="horizontal">
      <Button type="button" variant="outline">
        Cancel
      </Button>
      <Button type="submit">Submit</Button>
    </Field>
  </FieldGroup>
</form>
```

## RTL

```astro title="src/components/examples/input/input-rtl.astro"
---
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

const translations = {
  en: {
    dir: "ltr",
    values: {
      apiKey: "API Key",
      placeholder: "sk-...",
      description: "Your API key is encrypted and stored securely.",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      apiKey: "مفتاح API",
      placeholder: "sk-...",
      description: "مفتاح API الخاص بك مشفر ومخزن بأمان.",
    },
  },
  he: {
    dir: "rtl",
    values: {
      apiKey: "מפתח API",
      placeholder: "sk-...",
      description: "מפתח ה-API שלך מוצפן ונשמר בצורה מאובטחת.",
    },
  },
}

const { dir, values: t } = translations.ar
---

<Field dir={dir}>
  <FieldLabel for="input-rtl-api-key">{t.apiKey}</FieldLabel>
  <Input
    id="input-rtl-api-key"
    type="password"
    placeholder={t.placeholder}
    dir={dir}
  />
  <FieldDescription>{t.description}</FieldDescription>
</Field>
```

## API Reference

Source: [`src/components/ui/input`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/input)

`Input` accepts all native `input` attributes and `class`. It sets
`data-slot="input"` (override it with `data-slot`) and renders `multiple` only
when it is truthy.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/input-examples
```
