# Input

A single-line text box for forms and user data entry.

> Every page: https://constella.aayush.cv/llms.txt

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

## Installation

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

## Usage

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

```tsx
<Input />
```

## Size

Use the `size` prop to match the input to the buttons beside it.

| Size      | Height | Text |
| --------- | ------ | ---- |
| `sm`      | 28px   | 12px |
| `default` | 32px   | 13px |
| `lg`      | 36px   | 13px |

On a touch screen the input renders at 16px, scaled down to that size, so iOS doesn't zoom on focus.

```tsx
<Input aria-label="Small" placeholder="Small" size="sm" />
<Input aria-label="Default" placeholder="Default" />
<Input aria-label="Large" placeholder="Large" size="lg" />
```

## File

Use `type="file"` for a file input.

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

## Inline

Use a horizontal `Field` to put a button beside the input.

```tsx
<Field orientation="horizontal">
  <Input aria-label="Search" placeholder="Search..." type="search" />
  <Button variant="primary">Search</Button>
</Field>
```

## Grid

Give `FieldGroup` a grid to place inputs side by side.

```tsx
const styles = stylex.create({
  grid: { display: "grid", gridTemplateColumns: "1fr 1fr" },
});

<FieldGroup sx={styles.grid}>
  <Field>
    <FieldLabel>First Name</FieldLabel>
    <Input placeholder="Jordan" />
  </Field>
  <Field>
    <FieldLabel>Last Name</FieldLabel>
    <Input placeholder="Lee" />
  </Field>
</FieldGroup>;
```

## Form

Inputs with a [Select](https://constella.aayush.cv/docs/components/select/index.md) in a `FieldGroup`, for a whole form.

```tsx
<form>
  <FieldGroup>
    <Field>
      <FieldLabel>Name</FieldLabel>
      <Input placeholder="Jordan Kim" required />
    </Field>
    <Field>
      <FieldLabel>Country</FieldLabel>
      <Select defaultValue="us" items={countries}>
        <SelectTrigger>
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="us">United States</SelectItem>
        </SelectContent>
      </Select>
    </Field>
    <Field orientation="horizontal">
      <Button type="button" variant="outline">
        Cancel
      </Button>
      <Button type="submit" variant="primary">
        Submit
      </Button>
    </Field>
  </FieldGroup>
</form>
```

## Disabled

Use the `disabled` prop on `Field` to disable the input and dim its label. On a bare input, use `disabled` on the input.

```tsx
<Field disabled>
  <FieldLabel>Email</FieldLabel>
  <Input placeholder="Email" type="email" />
  <FieldDescription>This field is currently disabled.</FieldDescription>
</Field>
```

## Invalid

Use the `invalid` prop on `Field` to mark the input. On a bare input, add `aria-invalid`.

```tsx
<Field invalid>
  <FieldLabel>Invalid Input</FieldLabel>
  <Input placeholder="Error" />
  <FieldDescription>This field contains validation errors.</FieldDescription>
</Field>
```

## Required

Use the `required` prop, and mark the label so the requirement is visible.

```tsx
const styles = stylex.create({
  required: { color: colors.dangerText },
});

<Field>
  <FieldLabel>
    <span>
      Required Field <span {...stylex.props(styles.required)}>*</span>
    </span>
  </FieldLabel>
  <Input placeholder="This field is required" required />
  <FieldDescription>This field must be filled out.</FieldDescription>
</Field>;
```

## Badge

Put a [Badge](https://constella.aayush.cv/docs/components/badge/index.md) in the `FieldLabel` to mark the field.

```tsx
<Field>
  <FieldLabel>
    Webhook URL
    <Badge>Beta</Badge>
  </FieldLabel>
  <Input placeholder="https://api.acme.com/webhook" type="url" />
</Field>
```

## Button Group

Use [Button Group](https://constella.aayush.cv/docs/components/button-group/index.md) to join a button to the input.

```tsx
<Field>
  <FieldLabel>Search</FieldLabel>
  <ButtonGroup>
    <Input placeholder="Type to search..." />
    <Button variant="outline">Search</Button>
  </ButtonGroup>
</Field>
```

## Field

Use `Field`, `FieldLabel` and `FieldDescription` to give the input a label and helper text. They link to the input on their own, so no `id` or `htmlFor` is needed.

```tsx
<Field>
  <FieldLabel>Username</FieldLabel>
  <Input placeholder="Enter your username" />
  <FieldDescription>
    Choose a unique username for your account.
  </FieldDescription>
</Field>
```

### Group

Use `FieldGroup` to stack several fields into a form.

```tsx
<FieldGroup>
  <Field>
    <FieldLabel>Name</FieldLabel>
    <Input placeholder="Jordan Lee" />
  </Field>
  <Field>
    <FieldLabel>Email</FieldLabel>
    <Input placeholder="name@acme.com" type="email" />
    <FieldDescription>We’ll send updates to this address.</FieldDescription>
  </Field>
  <Field orientation="horizontal">
    <Button type="reset" variant="outline">
      Reset
    </Button>
    <Button type="submit" variant="primary">
      Submit
    </Button>
  </Field>
</FieldGroup>
```

## Input Group

Use [Input Group](https://constella.aayush.cv/docs/components/input-group/index.md) to put icons, text or buttons inside the input.

```tsx
<Field>
  <FieldLabel>Website URL</FieldLabel>
  <InputGroup>
    <InputGroupInput placeholder="acme.com" />
    <InputGroupAddon>
      <InputGroupText>https://</InputGroupText>
    </InputGroupAddon>
    <InputGroupAddon align="inline-end">
      <HugeiconsIcon icon={InformationCircleIcon} />
    </InputGroupAddon>
  </InputGroup>
</Field>
```

## API Reference

`Input` is an [Input Group](https://constella.aayush.cv/docs/components/input-group/index.md) box around Base UI's input, so inside a `Field` it takes the field's name, state and validation. It takes `size` in place of the native `size` attribute. `sx` styles the box, applied last. Every other prop, `ref` included, goes to the `<input>`. For the rest, see [Base UI Input](https://base-ui.com/react/components/input).
