Input
Form input component with error state, placeholder, and type support.
Overview
The Input component from packages/ui is a styled wrapper around the native <input> element. It provides consistent styling, focus rings, and an error state.
Import
import { Input } from "@saas/ui";Basic Usage
<Input type="email" placeholder="you@example.com" />Types
The component supports all standard HTML input types:
<Input type="text" placeholder="Full name" />
<Input type="email" placeholder="you@example.com" />
<Input type="password" placeholder="Password" />
<Input type="number" placeholder="0" />
<Input type="url" placeholder="https://..." />
<Input type="search" placeholder="Search..." />Error State
Display validation errors by combining the input with an error message:
<div>
<Input
type="email"
placeholder="you@example.com"
className="border-red-500 focus-visible:ring-red-500"
aria-invalid="true"
/>
<p className="mt-1 text-sm text-red-500">Please enter a valid email address.</p>
</div>Add border-red-500 and focus-visible:ring-red-500 classes to visually indicate the error.
With Labels
Always pair inputs with labels for accessibility:
<div className="space-y-2">
<label htmlFor="email" className="text-sm font-medium text-gray-700">
Email
</label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>Controlled Input
const [value, setValue] = useState("");
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Type here..."
/>Disabled State
<Input disabled placeholder="Cannot edit" />The input is visually dimmed and non-interactive when disabled is set.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | string | "text" | HTML input type |
placeholder | string | — | Placeholder text |
disabled | boolean | false | Disables the input |
className | string | — | Additional CSS classes |
All standard <input> HTML attributes are also accepted (e.g., onChange, value, name, required, aria-*).
Default Styles
| Class | Purpose |
|---|---|
flex h-10 w-full rounded-md border | Full-width input with consistent height |
border-gray-300 | Default border color |
px-3 py-2 text-sm | Inner padding and font size |
focus-visible:outline-none focus-visible:ring-2 | Focus ring on keyboard navigation |
disabled:cursor-not-allowed disabled:opacity-50 | Disabled appearance |
Tips
- Use
type="search"for search fields; some browsers add a clear button automatically. - For file uploads, use
type="file"but consider a custom dropzone for better UX. - Combine with a form library like React Hook Form for validation and submission handling.
Done reading? Mark this page as complete.