Input Component
** Last Built**: September 2, 2025 at 4:19 PM The Input component is a versatile text input field that provides a consistent interface for user data entry. It supports various input types, validation states, and integrates seamlessly with form systems.
Import
// Input component is available in the live scope
Basic Usage
Live Editor
<Input type="text" placeholder="Enter your name" />
Result
Loading...
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | string | 'text' | HTML input type (text, email, password, etc.) |
value | string | - | Current input value |
onChange | (e: ChangeEvent<HTMLInputElement>) => void | - | Change handler function |
placeholder | string | - | Placeholder text |
disabled | boolean | false | Whether the input is disabled |
readOnly | boolean | false | Whether the input is read-only |
required | boolean | false | Whether the input is required |
name | string | - | Input name attribute |
id | string | - | Input ID attribute |
className | string | - | Additional CSS classes |
size | 'sm' | 'md' | 'lg' | 'md' | Input size variant |
variant | 'default' | 'error' | 'success' | 'default' | Visual state variant |
error | string | - | Error message to display |
helperText | string | - | Helper text below the input |
leftIcon | ReactNode | - | Icon to display on the left side |
rightIcon | ReactNode | - | Icon to display on the right side |
Input Types
The Input component supports all standard HTML input types:
Live Editor
<div className="space-y-4"> <Input type="text" placeholder="Enter text" /> <Input type="email" placeholder="Enter email" /> <Input type="password" placeholder="Enter password" /> <Input type="number" placeholder="Enter number" /> <Input type="search" placeholder="Search..." /> <Input type="url" placeholder="Enter URL" /> <Input type="tel" placeholder="Enter phone number" /> </div>
Result
Loading...
Sizes
The Input component comes in three size variants:
Live Editor
<div className="space-y-4"> <Input size="sm" placeholder="Small input" /> <Input size="md" placeholder="Medium input (default)" /> <Input size="lg" placeholder="Large input" /> </div>
Result
Loading...
Variants
Different visual states for different input conditions:
Live Editor
<div className="space-y-4"> <Input placeholder="Normal input" /> <Input variant="success" placeholder="Valid input" /> <Input variant="error" placeholder="Invalid input" error="This field is required" /> </div>
Result
Loading...
With Icons
You can add icons to the left or right side of the input:
import { SearchIcon, EyeIcon, EyeOffIcon } from '@heroicons/react/outline';
// Left icon
<Input
leftIcon={<SearchIcon className="w-5 h-5" />}
placeholder="Search users..."
/>
// Right icon
<Input
type="password"
rightIcon={<EyeIcon className="w-5 h-5" />}
placeholder="Enter password"
/>
// Both icons
<Input
leftIcon={<SearchIcon className="w-5 h-5" />}
rightIcon={<EyeIcon className="w-5 h-5" />}
placeholder="Search with icon"
/>
Form Integration
The Input component works seamlessly with form libraries and validation:
import { useState } from 'react';
function FormExample() {
const [formData, setFormData] = useState({
name: '',
email: '',
password: ''
});
const [errors, setErrors] = useState({});
const handleChange = (field, value) => {
setFormData(prev => ({ ...prev, [field]: value }));
// Clear error when user starts typing
if (errors[field]) {
setErrors(prev => ({ ...prev, [field]: '' }));
};
const handleSubmit = (e) => {
e.preventDefault();
// Validation logic here
const newErrors = {};
if (!formData.name) newErrors.name = 'Name is required';
if (!formData.email) newErrors.email = 'Email is required';
if (!formData.password) newErrors.password = 'Password is required';
setErrors(newErrors);
if (Object.keys(newErrors).length === 0) {
// Submit form
console.log('Form submitted:', formData);
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<Input
type="text"
placeholder="Enter your name"
value={formData.name}
onChange={(e) => handleChange('name', e.target.value)}
error={errors.name}
required
/>
</div>
<div>
<Input
type="email"
placeholder="Enter your email"
value={formData.email}
onChange={(e) => handleChange('email', e.target.value)}
error={errors.email}
required
/>
</div>
<div>
<Input
type="password"
placeholder="Enter your password"
value={formData.password}
onChange={(e) => handleChange('password', e.target.value)}
error={errors.password}
required
/>
</div>
<Button type="submit">Submit</Button>
</form>
);
}
Validation States
The Input component provides clear visual feedback for validation states:
function ValidationExample() {
const [email, setEmail] = useState('');
const [isValid, setIsValid] = useState(null);
const validateEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const handleEmailChange = (e) => {
const value = e.target.value;
setEmail(value);
if (value === '') {
setIsValid(null);
} else {
setIsValid(validateEmail(value));
};
return (
<div>
<Input
type="email"
placeholder="Enter email address"
value={email}
onChange={handleEmailChange}
variant={isValid === null ? 'default' : isValid ? 'success' : 'error'}
error={isValid === false ? 'Please enter a valid email address' : ''}
helperText={isValid === true ? 'Email format is valid' : ''}
/>
</div>
);
}
Accessibility
The Input component includes comprehensive accessibility features:
- Proper ARIA labels and descriptions
- Error state announcements for screen readers
- Keyboard navigation support
- Focus management
- Screen reader compatibility
<Input
id="username"
name="username"
aria-describedby="username-help username-error"
aria-invalid={!!errors.username}
placeholder="Enter username"
error={errors.username}
helperText="Username must be at least 3 characters long"
/>
Custom Styling
You can customize the appearance using Tailwind CSS classes:
<Input
className="border-2 border-blue-300 focus:border-blue-500 focus:ring-blue-200"
placeholder="Custom styled input"
/>
<Input
className="bg-gray-50 border-gray-300 text-gray-900 placeholder-gray-500"
placeholder="Gray themed input"
/>
Examples
Search Input with Clear Button
function SearchInput() {
const [searchTerm, setSearchTerm] = useState('');
const [showClear, setShowClear] = useState(false);
const handleChange = (e) => {
const value = e.target.value;
setSearchTerm(value);
setShowClear(value.length > 0);
};
const handleClear = () => {
setSearchTerm('');
setShowClear(false);
};
return (
<div className="relative">
<Input
type="search"
placeholder="Search..."
value={searchTerm}
onChange={handleChange}
leftIcon={<SearchIcon className="w-5 h-5" />}
rightIcon={
showClear && (
<button
onClick={handleClear}
className="text-gray-400 hover:text-gray-600"
>
<XIcon className="w-5 h-5" />
</button>
)
}
/>
</div>
);
}
Password Input with Toggle
function PasswordInput() {
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
return (
<Input
type={showPassword ? 'text' : 'password'}
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
rightIcon={
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="text-gray-400 hover:text-gray-600"
>
{showPassword ? (
<EyeOffIcon className="w-5 h-5" />
) : (
<EyeIcon className="w-5 h-5" />
)}
</button>
}
/>
);
}
Form Field with Label
function FormField({ label, error, helperText, ...inputProps }) {
return (
<div className="space-y-2">
<Label htmlFor={inputProps.id}>{label}</Label>
<Input {...inputProps} />
{helperText && (
<p className="text-sm text-gray-600">{helperText}</p>
)}
{error && (
<p className="text-sm text-red-600">{error}</p>
)}
</div>
);
}
// Usage
<FormField
id="username"
label="Username"
placeholder="Enter username"
helperText="Username must be unique"
error={errors.username}
/>
Best Practices
- Always provide labels - Use the Label component or aria-label for accessibility
- Use appropriate input types - Leverage HTML5 input types for better UX
- Provide clear error messages - Help users understand what went wrong
- Use helper text sparingly - Only when additional context is needed
- Consider validation timing - Validate on blur or submit, not on every keystroke
- Test with screen readers - Ensure all states are properly announced
Related Components
- Label - For form field labels
- Button - For form submission and actions
- Form - For form containers and validation
- SelectInput - For dropdown selection
- DateInput - For date selection