Documentation Index
Fetch the complete documentation index at: https://mintlify.com/shadcn-ui/ui/llms.txt
Use this file to discover all available pages before exploring further.
Installation
No external dependencies required.
Or use the CLI:
npx shadcn@latest add input
import { Input } from "@/components/ui/input"
Component API
A styled input component built on the native HTML <input> element.
Props:
- All standard HTML input attributes
type - Input type (default: "text")
disabled - Disable the input
placeholder - Placeholder text
className - Additional CSS classes
aria-invalid - Mark as invalid for error states
Examples
A simple input field:
import { Input } from "@/components/ui/input"
export function BasicInput() {
return <Input placeholder="Enter your email" />
}
With Label
Combine with a label:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function LabeledInput() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
</div>
)
}
With Description
Add a description below the input:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function InputWithDescription() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Email" />
<p className="text-sm text-muted-foreground">
We'll never share your email with anyone else.
</p>
</div>
)
}
Disabled
Disable the input:
import { Input } from "@/components/ui/input"
export function DisabledInput() {
return <Input placeholder="Email" disabled />
}
Invalid State
Show an error state:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function InvalidInput() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email" className="text-destructive">
Email
</Label>
<Input
type="email"
id="email"
placeholder="Email"
aria-invalid
/>
<p className="text-sm text-destructive">
Please enter a valid email address.
</p>
</div>
)
}
File Input
Create a file input:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function FileInput() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="picture">Picture</Label>
<Input id="picture" type="file" />
</div>
)
}
With Button
Combine input with a button:
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
export function InputWithButton() {
return (
<div className="flex w-full max-w-sm items-center space-x-2">
<Input type="email" placeholder="Email" />
<Button type="submit">Subscribe</Button>
</div>
)
}
Use in a form with React Hook Form:
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
})
export function InputForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
username: "",
},
})
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
Different Types
With Icon
Add an icon to the input using Input Group:
import { Search } from "lucide-react"
import { Input } from "@/components/ui/input"
export function InputWithIcon() {
return (
<div className="relative">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<Input placeholder="Search" className="pl-8" />
</div>
)
}
Required
Mark input as required:
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function RequiredInput() {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="email">
Email <span className="text-destructive">*</span>
</Label>
<Input type="email" id="email" placeholder="Email" required />
</div>
)
}
Accessibility
- Built on native HTML input element
- Supports all standard input attributes
- Proper focus styles
- Error states with
aria-invalid
- Works with label associations
- Keyboard accessible