Skip to content
txbrendan/ui

Input

beta

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

Preview

size

states

That name is taken. Try another.

types

field

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/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

    Height, padding, and text size. Density scales them.

    "sm" | "md" | "lg" · default "md"

  • disabled

    Blocks typing and removes the input from the tab order.

    boolean · default false

  • aria-invalid

    Shows the danger border. Set it when validation fails, and link the message with aria-describedby.

    boolean

  • onValueChange

    Called with the new text on every change. Use it with value for a controlled input.

    (value: string, details) => void

  • className

    Extra classes. Later classes win, so className='rounded-none' replaces the radius.

    string

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

<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

<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

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