Components / Inputs

Input

A single line field with clear labels and useful states.

Install

npx shadcn@latest add https://irisui.dev/r/input.json
import { Input } from "@/components/iris/input/input";
Registry item inputBrings in foundationRegistry JSON

Preview

Input

A labelled single-line text field with optional helper copy and an animated error row.

When to use

  • Short free-text values: names, emails, URLs, IDs.
  • When the field needs inline validation feedback (error) or a live hint such as a character count.
  • Not for multiline text (use Textarea), secrets (use PasswordField), search (use SearchField) or bounded numbers (use NumberField).

Usage

import { Input } from "@/components/iris/input/input";
function EmailField() {
  const [email, setEmail] = React.useState("");
  return h(Input, {
    label: "Contact email",
    type: "email",
    value: email,
    onChange: (e) => setEmail(e.target.value),
    description: "Room seekers reply to this address.",
    error: email && !email.includes("@") ? "Enter a valid email" : undefined,
  });
}

Props

Prop Type Default Description
label string required Visible label, tied to the input with htmlFor.
description string – Helper copy under the field, linked through aria-describedby.
error string – Error copy. Sets aria-invalid and renders in a role="alert" row.
...props InputHTMLAttributes<HTMLInputElement> – Forwarded to the native input (ref, type, value, onChange, name, placeholder, disabled…).

Notes

  • The label is always visible; there is no floating-label mode. id is generated with useId when omitted.
  • Helper and error rows open their height on a spring and changed words blur in; numbers in the copy (such as a character count) roll digit by digit. With prefers-reduced-motion the rows mount at full height and words only crossfade.
  • Reads --surface, --ink, --line-strong, --ink-3, --red, --radius-control, --control-height-md.
  • The field is display: grid and fills its container; constrain width with a wrapper.