Input
A versatile input component for collecting user data. Supports various input types, states, and styling options for forms and user interfaces.
Installation
Add the Input component to your project:
npx @elixir-labs/ui add input
Usage
import { Input } from "@/components/ui/input";
export default function MyComponent() {
return <Input placeholder="Enter your name" />;
}
Examples
Basic Input
<Input placeholder="Enter your name" />
Input Types
<Input type="email" placeholder="john@example.com" />
<Input type="password" placeholder="••••••••" />
<Input type="number" placeholder="123" />
<Input type="date" />
<Input type="time" />
<Input type="tel" placeholder="+1 (555) 000-0000" />
Controlled Input
Value: (empty)
const [inputValue, setInputValue] = useState("");
<Input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="Type something..."
/>
Input with Labels
<div className="space-y-2">
<label htmlFor="email" className="block text-sm font-medium">
Email Address
</label>
<Input
id="email"
type="email"
placeholder="Enter your email"
/>
</div>
<div className="space-y-2">
<label htmlFor="password" className="block text-sm font-medium">
Password
</label>
<Input
id="password"
type="password"
placeholder="Enter your password"
/>
</div>
Input States
<Input placeholder="Normal state" />
<Input placeholder="Disabled state" disabled />
<Input value="Readonly value" readOnly />
Input with Validation
✓ Email is valid
✗ Please enter a valid email
// Valid input
<Input
className="border-green-600 focus-visible:ring-green-500"
placeholder="Valid input"
defaultValue="valid@example.com"
/>
// Invalid input
<Input
className="border-red-600 focus-visible:ring-red-500"
placeholder="Invalid input"
defaultValue="invalid-email"
/>
Input Sizes
<Input className="h-8 text-xs" placeholder="Small input" />
<Input placeholder="Default input" />
<Input className="h-12 text-base" placeholder="Large input" />
API Reference
Prop | Type | Default | Description |
---|---|---|---|
type | string | "text" | HTML input type |
placeholder | string | - | Placeholder text |
value | string | - | Input value (controlled) |
defaultValue | string | - | Default value (uncontrolled) |
onChange | function | - | Change event handler |
disabled | boolean | false | Whether input is disabled |
readOnly | boolean | false | Whether input is read-only |
className | string | - | Additional CSS classes |
Source Code
import React from 'react';
import { clsx } from 'clsx';
const Input = React.forwardRef(({ className, type = 'text', ...props }, ref) => {
return (
<input
type={type}
className={clsx(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
});
Input.displayName = 'Input';
export { Input };
Accessibility
The Input component follows accessibility best practices:
- Uses semantic HTML input elements
- Supports proper labeling with htmlFor/id associations
- Includes focus-visible styles for keyboard navigation
- Handles disabled and readonly states appropriately
- Works with screen readers and assistive technologies
- Supports all standard HTML input attributes
Best Practices
✅ Do
- Always provide descriptive labels for inputs
- Use appropriate input types (email, tel, number, etc.)
- Provide clear placeholder text when helpful
- Include validation feedback for form inputs
- Use controlled components for form state management
❌ Don't
- Use placeholder text as a replacement for labels
- Make inputs too small or difficult to click
- Forget to handle loading and error states
- Use generic input types when specific ones are available
💡 Pro Tip
Consider using a form library like React Hook Form or Formik for complex forms with validation. The Input component works seamlessly with these libraries.