Input

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

View as Markdown

Your API key is encrypted and stored securely.

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

Installation

$ npx shadcn@latest add @constella/input

Usage

import { Input } from "@/components/primitives/input";
<Input />

Size

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

SizeHeightText
sm28px12px
default32px13px
lg36px13px

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

<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.

Select a picture to upload.

<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.

<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.

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 in a FieldGroup, for a whole form.

We'll never share your email with anyone.

<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.

This field is currently disabled.

<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.

This field contains validation errors.

<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.

This field must be filled out.

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 in the FieldLabel to mark the field.

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

Button Group

Use Button Group to join a button to the input.

<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.

Choose a unique username for your account.

<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.

We’ll send updates to this address.

<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 to put icons, text or buttons inside the input.

https://
<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 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.