Form & Input
12 Components: Button, Input, Select, Checkbox, Radio, Form, Label, Textarea, Switch, Slider, Date Picker, Time Picker
A comprehensive collection of 40+ production-ready React components built on Radix UI primitives with Tailwind CSS styling, providing accessibility, customization, and enterprise-grade quality.
shadcn/ui Radix UI 40+ Components TypeScriptForm & Input
12 Components: Button, Input, Select, Checkbox, Radio, Form, Label, Textarea, Switch, Slider, Date Picker, Time Picker
Layout & Structure
10 Components: Card, Dialog, Sheet, Accordion, Tabs, Separator, Aspect Ratio, Scroll Area, Resizable, Collapsible
Navigation
8 Components: Navigation Menu, Breadcrumb, Pagination, Command, Context Menu, Dropdown Menu, Menubar, Sidebar
Feedback & Status
10+ Components: Alert, Badge, Progress, Skeleton, Toast, Alert Dialog, Hover Card, Popover, Tooltip, Avatar
The Button component uses CVA for type-safe variant management with multiple styles and sizes.
import { Button } from '@/components/ui/button'
// Basic button usageexport default function ButtonExample() {return ( <div className="flex items-center gap-4"> {/* Default primary button */} <Button>Primary Action</Button>
{/* Variant examples */} <Button variant="secondary">Secondary</Button> <Button variant="outline">Outline</Button> <Button variant="ghost">Ghost</Button> <Button variant="link">Link Style</Button> <Button variant="destructive">Delete</Button>
{/* Size variations */} <Button size="sm">Small</Button> <Button size="default">Default</Button> <Button size="lg">Large</Button> <Button size="icon">🚀</Button> </div>)}
// Button with asChild pattern (renders as different element)import { Link } from 'react-router-dom'
<Button asChild><Link to="/dashboard">Go to Dashboard</Link></Button>
// Loading state pattern<Button disabled={isLoading}>{isLoading && <LoadingSpinner className="mr-2" />}{isLoading ? 'Saving...' : 'Save Changes'}</Button>
The Card components provide a flexible layout system with multiple composition options.
import {Card,CardContent,CardDescription,CardFooter,CardHeader,CardTitle,CardAction,} from '@/components/ui/card'import { Button } from '@/components/ui/button'import { Badge } from '@/components/ui/badge'
// Basic card structureexport default function UserCard({ user }) {return ( <Card> <CardHeader> <CardTitle>{user.name}</CardTitle> <CardDescription>{user.email}</CardDescription> <CardAction> <Badge variant="secondary">{user.role}</Badge> </CardAction> </CardHeader>
<CardContent> <div className="space-y-2"> <p className="text-sm"> <strong>Department:</strong> {user.department} </p> <p className="text-sm"> <strong>Joined:</strong> {formatDate(user.joinedDate)} </p> </div> </CardContent>
<CardFooter className="gap-2"> <Button variant="outline" size="sm"> View Profile </Button> <Button size="sm"> Edit User </Button> </CardFooter> </Card>)}
// Dashboard stats cardfunction StatsCard({ title, value, change, trend }) {return ( <Card> <CardHeader className="pb-3"> <CardTitle className="text-sm font-medium text-muted-foreground"> {title} </CardTitle> </CardHeader> <CardContent className="pb-3"> <div className="text-2xl font-bold">{value}</div> <p className="text-xs text-muted-foreground"> <span className={trend === 'up' ? 'text-green-600' : 'text-red-600'}> {change} </span>{' '} from last month </p> </CardContent> </Card>)}
Form components with built-in validation states and accessibility features.
import { Input } from '@/components/ui/input'import { Label } from '@/components/ui/label'import { Textarea } from '@/components/ui/textarea'import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'import { Checkbox } from '@/components/ui/checkbox'import { Switch } from '@/components/ui/switch'
// Complete form exampleexport default function ContactForm() {return ( <form className="space-y-6"> {/* Text Input */} <div className="space-y-2"> <Label htmlFor="name">Full Name</Label> <Input id="name" placeholder="Enter your full name" aria-invalid={errors.name ? 'true' : 'false'} /> </div>
{/* Email Input */} <div className="space-y-2"> <Label htmlFor="email">Email Address</Label> <Input id="email" type="email" aria-describedby="email-error" /> </div>
{/* Select Dropdown */} <div className="space-y-2"> <Label htmlFor="department">Department</Label> <Select> <SelectTrigger> <SelectValue placeholder="Select department" /> </SelectTrigger> <SelectContent> <SelectItem value="engineering">Engineering</SelectItem> <SelectItem value="design">Design</SelectItem> <SelectItem value="marketing">Marketing</SelectItem> <SelectItem value="sales">Sales</SelectItem> </SelectContent> </Select> </div>
{/* Textarea */} <div className="space-y-2"> <Label htmlFor="message">Message</Label> <Textarea id="message" placeholder="Enter your message here..." rows={4} /> </div>
{/* Checkbox */} <div className="flex items-center space-x-2"> <Checkbox id="newsletter" /> <Label htmlFor="newsletter" className="text-sm"> Subscribe to our newsletter </Label> </div>
{/* Switch */} <div className="flex items-center space-x-2"> <Switch id="notifications" /> <Label htmlFor="notifications" className="text-sm"> Enable notifications </Label> </div>
<Button type="submit" className="w-full"> Submit Form </Button> </form>)}
Accessible dialog components with flexible composition patterns.
import {Dialog,DialogContent,DialogDescription,DialogFooter,DialogHeader,DialogTitle,DialogTrigger,} from '@/components/ui/dialog'import { Button } from '@/components/ui/button'import { Input } from '@/components/ui/input'import { Label } from '@/components/ui/label'
// User management dialogexport default function UserDialog({ user, onSave }) {const [open, setOpen] = useState(false)const [formData, setFormData] = useState(user)
return ( <Dialog open={open} onOpenChange={setOpen}> <DialogTrigger asChild> <Button variant="outline">Edit User</Button> </DialogTrigger>
<DialogContent className="sm:max-w-[425px]"> <DialogHeader> <DialogTitle>Edit User Profile</DialogTitle> <DialogDescription> Make changes to the user profile here. Click save when you're done. </DialogDescription> </DialogHeader>
<div className="grid gap-4 py-4"> <div className="grid grid-cols-4 items-center gap-4"> <Label htmlFor="name" className="text-right"> Name </Label> <Input id="name" value={formData.name} onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))} className="col-span-3" /> </div>
<div className="grid grid-cols-4 items-center gap-4"> <Label htmlFor="email" className="text-right"> Email </Label> <Input id="email" type="email" value={formData.email} onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))} className="col-span-3" /> </div> </div>
<DialogFooter> <Button variant="outline" onClick={() => setOpen(false)} > Cancel </Button> <Button onClick={() => { onSave(formData) setOpen(false) }} > Save Changes </Button> </DialogFooter> </DialogContent> </Dialog>)}
// Confirmation dialogfunction DeleteConfirmDialog({ itemName, onConfirm }) {return ( <Dialog> <DialogTrigger asChild> <Button variant="destructive" size="sm">Delete</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Are you absolutely sure?</DialogTitle> <DialogDescription> This action cannot be undone. This will permanently delete{' '} <strong>{itemName}</strong> and remove all associated data. </DialogDescription> </DialogHeader> <DialogFooter> <DialogClose asChild> <Button variant="outline">Cancel</Button> </DialogClose> <Button variant="destructive" onClick={onConfirm}> Delete Permanently </Button> </DialogFooter> </DialogContent> </Dialog>)}
Flexible badge system for status indicators and labels.
import { Badge } from '@/components/ui/badge'import { Progress } from '@/components/ui/progress'import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
// Status badges with variantsexport default function StatusExamples() {return ( <div className="space-y-6"> {/* Basic badges */} <div className="flex items-center gap-2"> <Badge>Default</Badge> <Badge variant="secondary">Secondary</Badge> <Badge variant="destructive">Error</Badge> <Badge variant="outline">Outline</Badge> </div>
{/* Status indicators */} <div className="flex items-center gap-3"> <Badge variant="secondary" className="bg-green-100 text-green-800"> ✓ Active </Badge> <Badge variant="secondary" className="bg-yellow-100 text-yellow-800"> ⏳ Pending </Badge> <Badge variant="destructive"> ✗ Inactive </Badge> </div>
{/* User status with avatar */} <div className="flex items-center gap-3"> <Avatar> <AvatarImage src="/avatars/01.png" alt="User" /> <AvatarFallback>JD</AvatarFallback> </Avatar> <div> <p className="font-medium">John Doe</p> <div className="flex items-center gap-2"> <Badge variant="outline" className="text-xs"> 🟢 Online </Badge> <span className="text-xs text-muted-foreground"> Last seen 2 minutes ago </span> </div> </div> </div>
{/* Progress with label */} <div className="space-y-2"> <div className="flex justify-between text-sm"> <span>Upload Progress</span> <span>75%</span> </div> <Progress value={75} className="h-2" /> </div> </div>)}
// Dynamic status badge componentfunction StatusBadge({ status, ...props }) {const variants = { active: { variant: 'default', children: '✓ Active' }, pending: { variant: 'secondary', className: 'bg-yellow-100 text-yellow-800', children: '⏳ Pending' }, inactive: { variant: 'destructive', children: '✗ Inactive' },}
const badgeProps = variants[status] || variants.inactive
return <Badge {...badgeProps} {...props} />}
Accessible navigation components for complex user interfaces.
import {NavigationMenu,NavigationMenuContent,NavigationMenuIndicator,NavigationMenuItem,NavigationMenuLink,NavigationMenuList,NavigationMenuTrigger,NavigationMenuViewport,} from '@/components/ui/navigation-menu'import {Breadcrumb,BreadcrumbItem,BreadcrumbLink,BreadcrumbList,BreadcrumbPage,BreadcrumbSeparator,} from '@/components/ui/breadcrumb'
// Main navigation menuexport default function MainNavigation() {return ( <NavigationMenu> <NavigationMenuList> <NavigationMenuItem> <NavigationMenuTrigger>Products</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]"> <li className="row-span-3"> <NavigationMenuLink asChild> <a className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md" href="/" > <div className="mb-2 mt-4 text-lg font-medium"> Our Platform </div> <p className="text-sm leading-tight text-muted-foreground"> Comprehensive admin dashboard solution for modern applications. </p> </a> </NavigationMenuLink> </li> <ListItem href="/dashboard" title="Dashboard"> Analytics and overview of your application </ListItem> <ListItem href="/users" title="User Management"> Manage users, roles, and permissions </ListItem> <ListItem href="/settings" title="Settings"> Configure your application settings </ListItem> </ul> </NavigationMenuContent> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuTrigger>Documentation</NavigationMenuTrigger> <NavigationMenuContent> <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]"> <ListItem title="Getting Started" href="/docs"> Installation and setup guide </ListItem> <ListItem title="Components" href="/docs/components"> Reusable UI components library </ListItem> <ListItem title="API Reference" href="/docs/api"> Complete API documentation </ListItem> <ListItem title="Examples" href="/docs/examples"> Implementation examples and patterns </ListItem> </ul> </NavigationMenuContent> </NavigationMenuItem>
<NavigationMenuItem> <NavigationMenuLink href="/contact"> Contact </NavigationMenuLink> </NavigationMenuItem> </NavigationMenuList> </NavigationMenu>)}
// Breadcrumb navigationfunction PageBreadcrumb({ items }) {return ( <Breadcrumb> <BreadcrumbList> {items.map((item, index) => ( <React.Fragment key={item.href}> <BreadcrumbItem> {index === items.length - 1 ? ( <BreadcrumbPage>{item.label}</BreadcrumbPage> ) : ( <BreadcrumbLink href={item.href}> {item.label} </BreadcrumbLink> )} </BreadcrumbItem> {index < items.length - 1 && <BreadcrumbSeparator />} </React.Fragment> ))} </BreadcrumbList> </Breadcrumb>)}
// Usage example<PageBreadcrumbitems={[ { label: 'Dashboard', href: '/dashboard' }, { label: 'Users', href: '/dashboard/users' }, { label: 'Profile', href: '/dashboard/users/profile' },]}/>
Components for presenting structured data and information.
import {Table,TableBody,TableCaption,TableCell,TableFooter,TableHead,TableHeader,TableRow,} from '@/components/ui/table'import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
// Data table exampleexport default function UsersTable({ users }) {return ( <Table> <TableCaption>A list of your recent users.</TableCaption> <TableHeader> <TableRow> <TableHead className="w-[100px]">ID</TableHead> <TableHead>Name</TableHead> <TableHead>Email</TableHead> <TableHead>Role</TableHead> <TableHead className="text-right">Actions</TableHead> </TableRow> </TableHeader> <TableBody> {users.map((user) => ( <TableRow key={user.id}> <TableCell className="font-medium">{user.id}</TableCell> <TableCell>{user.name}</TableCell> <TableCell>{user.email}</TableCell> <TableCell> <Badge variant="secondary">{user.role}</Badge> </TableCell> <TableCell className="text-right"> <Button variant="ghost" size="sm">Edit</Button> </TableCell> </TableRow> ))} </TableBody> <TableFooter> <TableRow> <TableCell colSpan={4}>Total Users</TableCell> <TableCell className="text-right">{users.length}</TableCell> </TableRow> </TableFooter> </Table>)}
// Tabs for organized contentfunction UserProfileTabs({ user }) {return ( <Tabs defaultValue="profile" className="w-full"> <TabsList className="grid w-full grid-cols-3"> <TabsTrigger value="profile">Profile</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> <TabsTrigger value="settings">Settings</TabsTrigger> </TabsList>
<TabsContent value="profile" className="space-y-4"> <Card> <CardHeader> <CardTitle>Personal Information</CardTitle> </CardHeader> <CardContent> <div className="space-y-2"> <p><strong>Name:</strong> {user.name}</p> <p><strong>Email:</strong> {user.email}</p> <p><strong>Department:</strong> {user.department}</p> </div> </CardContent> </Card> </TabsContent>
<TabsContent value="activity" className="space-y-4"> <Card> <CardHeader> <CardTitle>Recent Activity</CardTitle> </CardHeader> <CardContent> {/* Activity timeline */} </CardContent> </Card> </TabsContent>
<TabsContent value="settings" className="space-y-4"> <Card> <CardHeader> <CardTitle>Account Settings</CardTitle> </CardHeader> <CardContent> {/* Settings form */} </CardContent> </Card> </TabsContent> </Tabs>)}
// FAQ Accordionfunction FAQSection({ faqs }) {return ( <Accordion type="single" collapsible className="w-full"> {faqs.map((faq, index) => ( <AccordionItem key={index} value={`item-${index}`}> <AccordionTrigger className="text-left"> {faq.question} </AccordionTrigger> <AccordionContent> {faq.answer} </AccordionContent> </AccordionItem> ))} </Accordion>)}
import { cva, type VariantProps } from "class-variance-authority"import { cn } from "@/lib/utils"
// Create custom component with variantsconst alertVariants = cva("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",{ variants: { variant: { default: "bg-background text-foreground", destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", warning: "border-yellow-500/50 text-yellow-900 dark:text-yellow-100 bg-yellow-50 dark:bg-yellow-900/10", success: "border-green-500/50 text-green-900 dark:text-green-100 bg-green-50 dark:bg-green-900/10", }, }, defaultVariants: { variant: "default", },})
function Alert({className,variant,...props}: React.HTMLAttributes<HTMLDivElement> &VariantProps<typeof alertVariants>) {return ( <div role="alert" className={cn(alertVariants({ variant }), className)} {...props} />)}
// Usage with different variants<Alert variant="success"><CheckIcon className="h-4 w-4" /><AlertTitle>Success!</AlertTitle><AlertDescription>Your changes have been saved successfully.</AlertDescription></Alert>
// Create compound component for complex UI patternsfunction DataCard({ children, ...props }) {return ( <Card {...props}> {children} </Card>)}
function DataCardHeader({ title, description, action }) {return ( <CardHeader> <CardTitle>{title}</CardTitle> {description && <CardDescription>{description}</CardDescription>} {action && <CardAction>{action}</CardAction>} </CardHeader>)}
function DataCardMetrics({ metrics }) {return ( <CardContent> <div className="grid grid-cols-2 gap-4"> {metrics.map((metric, index) => ( <div key={index} className="space-y-1"> <p className="text-2xl font-bold">{metric.value}</p> <p className="text-xs text-muted-foreground">{metric.label}</p> </div> ))} </div> </CardContent>)}
// Compound component usage<DataCard><DataCardHeader title="User Analytics" description="Last 30 days" action={<Button variant="outline" size="sm">Export</Button>}/><DataCardMetrics metrics={[ { label: 'Total Users', value: '2,345' }, { label: 'Active Users', value: '1,987' }, { label: 'New Signups', value: '234' }, { label: 'Retention Rate', value: '84.5%' }, ]}/></DataCard>
// Components include accessibility features by default:
// Screen reader support<Button aria-label="Delete user account"><TrashIcon /></Button>
// Keyboard navigation<Dialog><DialogTrigger>Open</DialogTrigger><DialogContent> {/* Focus trap and ESC key handling built-in */} <DialogTitle>Confirm Action</DialogTitle> <DialogDescription> This action cannot be undone. </DialogDescription></DialogContent></Dialog>
// Form validation states<Inputaria-invalid={hasError}aria-describedby="error-message"/>{hasError && (<p id="error-message" className="text-sm text-destructive"> This field is required</p>)}
// Loading states<Button disabled={isLoading} aria-busy={isLoading}>{isLoading && <Spinner className="mr-2" aria-hidden />}{isLoading ? 'Saving...' : 'Save'}</Button>
Prop | Type | Description |
---|---|---|
className | string | Additional CSS classes |
asChild | boolean | Render as child element (Slot pattern) |
variant | string | Component variant (when applicable) |
size | string | Component size (when applicable) |
disabled | boolean | Disable interaction |
Components using Class Variance Authority include:
Component | Variants | Sizes |
---|---|---|
Button | default , destructive , outline , secondary , ghost , link | default , sm , lg , icon |
Badge | default , secondary , destructive , outline | - |
Alert | default , destructive | - |
The shadcn/ui library provides a complete design system with 40+ accessible, customizable components for building professional React applications! 🎨✨