Input
The Input component is one of the most fundamental components in the UI kit. It supports multiple variants, sizes, and states.
Props
InputRoot
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'base' | 'lg' | 'base' | Input size |
state | 'default' | 'error' | 'default' | Visual state styling |
side | 'left' | 'center' | 'right' | - | Text alignment, also used for cursor placement on container click |
inputClassName | string | - | Additional classes for the inner input |
| ...input props | ComponentProps<'input'> | - | All native input attributes |
InputSlot
| Prop | Type | Default | Description |
|---|---|---|---|
side | 'left' | 'right' | 'left' | Which side to place the slot |
| ...div props | ComponentProps<'div'> | - | All native div props |
Types
interface InputRootProps extends ComponentProps<"div">, VariantProps<typeof inputVariants> {
state?: "default" | "error";
side?: "left" | "right" | "center";
asChild?: boolean;
inputClassName?: string;
size?: "sm" | "base" | "lg";
}
interface InputSlotProps extends ComponentProps<"div"> {
side?: "left" | "right";
}
Text Alignment
The input component supports different text alignment options:
$
// Left-aligned text (default)
<InputRoot size="sm" placeholder="Left text"/>
// Center-aligned text
<InputRoot size="sm" side="center" placeholder="Center text"/>
// Right-aligned text
<InputRoot size="sm" side="right" placeholder="Right text"/>
// With left prefix (currency example)
<InputRoot size="sm" type="number" placeholder="1.300">
<InputSlot side="left">$</InputSlot>
</InputRoot>
// With right suffix (icon example)
<InputRoot size="sm" placeholder="Right suffix">
<InputSlot side="right"><Minus/></InputSlot>
</InputRoot>
States
Inputs can be in different states:
// Error state for validation feedback
<InputRoot size="sm" placeholder="Error" state="error"/>
// Disabled state prevents user interaction
<InputRoot size="sm" placeholder="Disabled" disabled/>
Usage by type
Different input types for various use cases:
$
// Text input (default)
<InputRoot size="sm" placeholder="Text input" />
// Number input with currency prefix
<InputRoot size="sm" type="number" side="right" placeholder="1,234.56">
<InputSlot>$</InputSlot>
</InputRoot>
// Password input with hidden text
<InputRoot size="sm" type="password" placeholder="Password" />
// Email input with validation
<InputRoot size="sm" type="email" placeholder="name@example.com" />
// Search input with icon
<InputRoot size="sm" type="search" placeholder="Search">
<InputSlot side="right"><Search/></InputSlot>
</InputRoot>
Interactive Examples
onChange Events
Handle user input with live feedback:
Characters: 0
const [value, setValue] = useState('');
const [count, setCount] = useState(0);
return (
<InputRoot
size="sm"
placeholder="Type something..."
value={value}
onChange={(e) => {
setValue(e.target.value);
setCount(e.target.value.length);
}}
/>
);
Number Input with Live Calculation
Number input with real-time calculations:
$
qty
Total: $0.00
const [price, setPrice] = useState('');
const [quantity, setQuantity] = useState('');
const total = (parseFloat(price) || 0) * (parseInt(quantity) || 0);
return (
<>
<InputRoot
size="sm"
type="number"
side="right"
placeholder="0.00"
value={price}
onChange={(e) => setPrice(e.target.value)}
>
<InputSlot side="left">$</InputSlot>
</InputRoot>
<InputRoot
size="sm"
type="number"
placeholder="0"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
>
<InputSlot side="right">qty</InputSlot>
</InputRoot>
<div>Total: ${total.toFixed(2)}</div>
</>
);
Form Submission
Complete form example with validation and submission:
const [formData, setFormData] = useState({
name: '', email: '', amount: ''
});
const [errors, setErrors] = useState({});
const handleSubmit = (e) => {
e.preventDefault();
const newErrors = {};
if (!formData.name) newErrors.name = 'Name is required';
if (!formData.email) newErrors.email = 'Email is required';
if (!formData.amount) newErrors.amount = 'Amount is required';
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors);
return;
}
// Submit form data
console.log('Form submitted:', formData);
};
return (
<form onSubmit={handleSubmit}>
<InputRoot
size="sm"
placeholder="Your name"
value={formData.name}
state={errors.name ? 'error' : 'default'}
onChange={(e) => setFormData({...formData, name: e.target.value})}
/>
<InputRoot
size="sm"
type="email"
placeholder="your.email@example.com"
value={formData.email}
state={errors.email ? 'error' : 'default'}
onChange={(e) => setFormData({...formData, email: e.target.value})}
/>
<InputRoot
size="sm"
type="number"
side="right"
placeholder="0.00"
value={formData.amount}
state={errors.amount ? 'error' : 'default'}
onChange={(e) => setFormData({...formData, amount: e.target.value})}
>
<InputSlot side="left">$</InputSlot>
</InputRoot>
<button type="submit">Submit Form</button>
</form>
);