🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples shadcn/ui
Exemples de composants shadcn/ui - Composants React beaux, accessibles et personnalisables construits avec Radix UI et Tailwind CSS
💻 Fondamentaux shadcn/ui tsx
🟢 simple
⭐⭐
Composants de base shadcn/ui incluant boutons, cartes, formulaires et éléments UI essentiels
⏱️ 20 min
🏷️ react, typescript, ui components, tailwind, radix ui
Prerequisites:
React basics, TypeScript, Tailwind CSS
// shadcn/ui Fundamentals Examples
// Install required packages:
// npm install @radix-ui/react-slot class-variance-authority clsx tailwind-merge lucide-react
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Checkbox } from "@/components/ui/checkbox"
import { Badge } from "@/components/ui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Separator } from "@/components/ui/separator"
import { Progress } from "@/components/ui/progress"
import { Switch } from "@/components/ui/switch"
import { Slider } from "@/components/ui/slider"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
// 1. Button Examples
export function ButtonExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Button Variants</h3>
{/* Basic variants */}
<div className="flex flex-wrap gap-2">
<Button>Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
{/* Button sizes */}
<div className="flex items-center gap-2">
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
</div>
{/* Button states */}
<div className="flex flex-wrap gap-2">
<Button disabled>Disabled</Button>
<Button loading>Loading</Button>
<Button variant="outline">With Icon</Button>
</div>
</div>
)
}
// 2. Card Examples
export function CardExamples() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{/* Basic card */}
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card Description</CardDescription>
</CardHeader>
<CardContent>
<p>This is the card content area.</p>
</CardContent>
<CardFooter>
<Button>Learn More</Button>
</CardFooter>
</Card>
{/* Card with avatar */}
<Card>
<CardHeader className="flex flex-row items-center space-y-0 pb-2">
<Avatar className="h-8 w-8 mr-2">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div>
<CardTitle className="text-sm">John Doe</CardTitle>
<CardDescription className="text-xs">Software Engineer</CardDescription>
</div>
</CardHeader>
<CardContent>
<p className="text-sm">Building amazing user experiences with React and TypeScript.</p>
</CardContent>
</Card>
{/* Stats card */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">98.5%</CardTitle>
<CardDescription>Uptime this month</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Badge variant="secondary" className="bg-green-100 text-green-800">
+2.1%
</Badge>
<span className="text-sm text-gray-500">from last month</span>
</div>
</CardContent>
</Card>
</div>
)
}
// 3. Form Examples
export function FormExamples() {
return (
<div className="space-y-6">
<Card className="max-w-md">
<CardHeader>
<CardTitle>Profile Form</CardTitle>
<CardDescription>Update your profile information</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="name">Name</Label>
<Input id="name" placeholder="John Doe" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="[email protected]" />
</div>
<div className="space-y-2">
<Label htmlFor="bio">Bio</Label>
<Textarea id="bio" placeholder="Tell us about yourself" />
</div>
<div className="flex items-center space-x-2">
<Checkbox id="newsletter" />
<Label htmlFor="newsletter" className="text-sm">
Subscribe to newsletter
</Label>
</div>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">Cancel</Button>
<Button>Save Changes</Button>
</CardFooter>
</Card>
</div>
)
}
// 4. Badge Examples
export function BadgeExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Badge Variants</h3>
<div className="flex flex-wrap gap-2">
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
</div>
<div className="space-y-2">
<p className="text-sm text-gray-600">Status badges:</p>
<div className="flex flex-wrap gap-2">
<Badge className="bg-green-100 text-green-800">Active</Badge>
<Badge className="bg-yellow-100 text-yellow-800">Pending</Badge>
<Badge className="bg-red-100 text-red-800">Inactive</Badge>
<Badge className="bg-blue-100 text-blue-800">New</Badge>
</div>
</div>
</div>
)
}
// 5. Avatar Examples
export function AvatarExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Avatar Examples</h3>
<div className="flex items-center gap-4">
{/* Basic avatar */}
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
{/* Fallback avatar */}
<Avatar>
<AvatarFallback>JD</AvatarFallback>
</Avatar>
{/* Different sizes */}
<Avatar className="h-8 w-8">
<AvatarFallback>SM</AvatarFallback>
</Avatar>
<Avatar className="h-12 w-12">
<AvatarFallback>MD</AvatarFallback>
</Avatar>
<Avatar className="h-16 w-16">
<AvatarFallback>LG</AvatarFallback>
</Avatar>
</div>
</div>
)
}
// 6. Progress & Status Examples
export function ProgressExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Progress Indicators</h3>
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span>Upload Progress</span>
<span>65%</span>
</div>
<Progress value={65} />
</div>
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span>Loading</span>
<span>30%</span>
</div>
<Progress value={30} className="bg-blue-100" />
</div>
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span>Success</span>
<span>100%</span>
</div>
<Progress value={100} className="bg-green-100" />
</div>
</div>
)
}
// 7. Interactive Examples
export function InteractiveExamples() {
const [notifications, setNotifications] = React.useState(true)
const [darkMode, setDarkMode] = React.useState(false)
const [volume, setVolume] = React.useState([50])
return (
<div className="space-y-6">
<Card>
<CardHeader>
<CardTitle>Settings</CardTitle>
<CardDescription>Configure your preferences</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* Switch examples */}
<div className="flex items-center justify-between">
<Label htmlFor="notifications">Email Notifications</Label>
<Switch
id="notifications"
checked={notifications}
onCheckedChange={setNotifications}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="dark-mode">Dark Mode</Label>
<Switch
id="dark-mode"
checked={darkMode}
onCheckedChange={setDarkMode}
/>
</div>
{/* Slider example */}
<div className="space-y-2">
<Label>Volume: {volume[0]}%</Label>
<Slider
value={volume}
onValueChange={setVolume}
max={100}
step={1}
/>
</div>
</CardContent>
</Card>
</div>
)
}
// 8. Tabs Example
export function TabsExample() {
return (
<Tabs defaultValue="account" className="w-full max-w-md">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
<TabsContent value="account" className="space-y-4">
<Card>
<CardHeader>
<CardTitle>Account Settings</CardTitle>
<CardDescription>
Manage your account information
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="username">Username</Label>
<Input id="username" defaultValue="johndoe" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" defaultValue="[email protected]" />
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="password" className="space-y-4">
<Card>
<CardHeader>
<CardTitle>Change Password</CardTitle>
<CardDescription>
Update your password to keep your account secure
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="current">Current Password</Label>
<Input id="current" type="password" />
</div>
<div className="space-y-2">
<Label htmlFor="new">New Password</Label>
<Input id="new" type="password" />
</div>
<div className="space-y-2">
<Label htmlFor="confirm">Confirm Password</Label>
<Input id="confirm" type="password" />
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="notifications" className="space-y-4">
<Card>
<CardHeader>
<CardTitle>Notification Preferences</CardTitle>
<CardDescription>
Choose how you want to be notified
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="email-notifications">Email Notifications</Label>
<Switch id="email-notifications" defaultChecked />
</div>
<div className="flex items-center justify-between">
<Label htmlFor="push-notifications">Push Notifications</Label>
<Switch id="push-notifications" />
</div>
<div className="flex items-center justify-between">
<Label htmlFor="marketing">Marketing Emails</Label>
<Switch id="marketing" />
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
)
}
// 9. Combined Layout Example
export function DashboardExample() {
return (
<div className="space-y-6 p-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold">Dashboard</h1>
<p className="text-gray-600">Welcome back, John!</p>
</div>
<div className="flex items-center gap-2">
<Badge variant="outline" className="bg-green-50 text-green-700">
Online
</Badge>
<Avatar className="h-8 w-8">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">$45,231</CardTitle>
<CardDescription>Total Revenue</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Badge className="bg-green-100 text-green-800">+20.1%</Badge>
<span className="text-sm text-gray-500">from last month</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">2,350</CardTitle>
<CardDescription>New Customers</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Badge className="bg-green-100 text-green-800">+15.3%</Badge>
<span className="text-sm text-gray-500">from last month</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">89</CardTitle>
<CardDescription>Active Projects</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2">
<Badge className="bg-yellow-100 text-yellow-800">+5</Badge>
<span className="text-sm text-gray-500">this week</span>
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">98.5%</CardTitle>
<CardDescription>Uptime</CardDescription>
</CardHeader>
<CardContent>
<Progress value={98.5} className="bg-green-100" />
</CardContent>
</Card>
</div>
{/* Tabs for content */}
<TabsExample />
</div>
)
}
// Main component showcasing all examples
export function ShadcnUiShowcase() {
return (
<div className="p-6 max-w-6xl mx-auto space-y-8">
<div className="text-center space-y-2">
<h1 className="text-4xl font-bold">shadcn/ui Components</h1>
<p className="text-lg text-gray-600">
Beautiful, accessible, and customizable React components
</p>
</div>
<Separator />
<div className="space-y-8">
<div>
<h2 className="text-2xl font-semibold mb-4">Buttons</h2>
<ButtonExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Cards</h2>
<CardExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Forms</h2>
<FormExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Badges</h2>
<BadgeExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Avatars</h2>
<AvatarExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Progress Indicators</h2>
<ProgressExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Interactive Components</h2>
<InteractiveExamples />
</div>
<Separator />
<div>
<h2 className="text-2xl font-semibold mb-4">Dashboard Example</h2>
<DashboardExample />
</div>
</div>
</div>
)
}
export {
ButtonExamples,
CardExamples,
FormExamples,
BadgeExamples,
AvatarExamples,
ProgressExamples,
InteractiveExamples,
TabsExample,
DashboardExample,
ShadcnUiShowcase
}
💻 Composants Avancés shadcn/ui tsx
🟡 intermediate
⭐⭐⭐⭐
Composants complexes shadcn/ui incluant tables de données, dialogues, menus déroulants et patterns avancés
⏱️ 35 min
🏷️ react, typescript, ui components, advanced patterns
Prerequisites:
React advanced, TypeScript, shadcn/ui basics
// Advanced shadcn/ui Components Examples
// Install additional packages:
// npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-select @radix-ui/react-tabs @radix-ui/react-toast @radix-ui/react-tooltip
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@/components/ui/command"
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
import { Calendar } from "@/components/ui/calendar"
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Toast, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "@/components/ui/toast"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
// 1. Dialog Examples
export function DialogExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Dialog Components</h3>
{/* Basic Dialog */}
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit Profile</DialogTitle>
<DialogDescription>
Make changes to your 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="Pedro Duarte" className="col-span-3" />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="username" className="text-right">
Username
</Label>
<Input id="username" value="@peduarte" className="col-span-3" />
</div>
</div>
<DialogFooter>
<Button type="submit">Save changes</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* Confirmation Dialog */}
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">Delete Item</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
)
}
// 2. Data Table Example
export function DataTableExample() {
const users = [
{
id: "USR001",
name: "John Doe",
email: "[email protected]",
status: "Active",
role: "Developer",
joinDate: "2023-01-15"
},
{
id: "USR002",
name: "Jane Smith",
email: "[email protected]",
status: "Active",
role: "Designer",
joinDate: "2023-02-20"
},
{
id: "USR003",
name: "Bob Johnson",
email: "[email protected]",
status: "Inactive",
role: "Manager",
joinDate: "2022-11-10"
},
{
id: "USR004",
name: "Alice Brown",
email: "[email protected]",
status: "Active",
role: "Developer",
joinDate: "2023-03-05"
}
]
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Data Table</h3>
<Card>
<CardHeader>
<CardTitle>Users</CardTitle>
<CardDescription>A list of all registered users</CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Role</TableHead>
<TableHead>Status</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
<Badge variant="outline">{user.role}</Badge>
</TableCell>
<TableCell>
<Badge
className={
user.status === "Active"
? "bg-green-100 text-green-800"
: "bg-gray-100 text-gray-800"
}
>
{user.status}
</Badge>
</TableCell>
<TableCell className="text-right">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">Open menu</span>
⋮
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>View profile</DropdownMenuItem>
<DropdownMenuItem>Edit user</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600">
Delete user
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</div>
)
}
// 3. Dropdown Menu Examples
export function DropdownExamples() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Dropdown Menus</h3>
<div className="flex flex-wrap gap-4">
{/* User dropdown */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
<Avatar className="h-5 w-5 mr-2">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
John Doe
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Keyboard shortcuts</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Log out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Actions dropdown */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>Actions</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<span className="mr-2">📝</span>
Edit
</DropdownMenuItem>
<DropdownMenuItem>
<span className="mr-2">📋</span>
Duplicate
</DropdownMenuItem>
<DropdownMenuItem>
<span className="mr-2">🏷️</span>
Label
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600">
<span className="mr-2">🗑️</span>
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
)
}
// 4. Command Palette Example
export function CommandPaletteExample() {
const [open, setOpen] = React.useState(false)
React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault()
setOpen((open) => !open)
}
}
document.addEventListener("keydown", down)
return () => document.removeEventListener("keydown", down)
}, [])
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Command Palette</h3>
<div className="flex items-center space-x-2">
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">
<span className="text-xs">⌘</span>K
</kbd>
<span className="text-sm text-muted-foreground">Press to open command palette</span>
</div>
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Suggestions">
<CommandItem>
<span className="mr-2">📅</span>
Calendar
</CommandItem>
<CommandItem>
<span className="mr-2">🔍</span>
Search Emoji
</CommandItem>
<CommandItem>
<span className="mr-2">💡</span>
Calculator
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Settings">
<CommandItem>
<span className="mr-2">👤</span>
Profile
</CommandItem>
<CommandItem>
<span className="mr-2">💳</span>
Billing
</CommandItem>
<CommandItem>
<span className="mr-2">⚙️</span>
Settings
</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>
</div>
)
}
// 5. Accordion Example
export function AccordionExample() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Accordion</h3>
<Accordion type="single" collapsible className="w-full">
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Is it styled?</AccordionTrigger>
<AccordionContent>
Yes. It comes with default styles that matches the other components' aesthetic.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>Is it animated?</AccordionTrigger>
<AccordionContent>
Yes. It's animated by default, but you can disable it if you prefer.
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
)
}
// 6. Calendar Example
export function CalendarExample() {
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Calendar</h3>
<div className="flex justify-center">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="rounded-md border"
/>
</div>
</div>
)
}
// 7. Alert Component
export function AlertExample() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Alerts</h3>
<div className="space-y-4">
<Alert>
<AlertTitle>Information</AlertTitle>
<AlertDescription>
This is an information alert. It provides contextual information to the user.
</AlertDescription>
</Alert>
<Alert className="border-yellow-200 bg-yellow-50">
<AlertTitle>Warning</AlertTitle>
<AlertDescription>
This is a warning alert. It warns the user about something important.
</AlertDescription>
</Alert>
<Alert className="border-red-200 bg-red-50">
<AlertTitle>Error</AlertTitle>
<AlertDescription>
This is an error alert. It indicates that something went wrong.
</AlertDescription>
</Alert>
<Alert className="border-green-200 bg-green-50">
<AlertTitle>Success</AlertTitle>
<AlertDescription>
This is a success alert. It confirms that an action was successful.
</AlertDescription>
</Alert>
</div>
</div>
)
}
// 8. Advanced Layout with Sheet
export function SheetExample() {
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Sheet (Slide-over Panel)</h3>
<Sheet>
<SheetTrigger asChild>
<Button>Open Sheet</Button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're done.
</SheetDescription>
</SheetHeader>
<div className="grid gap-4 py-4">
<div className="space-y-2">
<Label htmlFor="name">Name</Label>
<Input id="name" defaultValue="John Doe" />
</div>
<div className="space-y-2">
<Label htmlFor="username">Username</Label>
<Input id="username" defaultValue="@johndoe" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" defaultValue="[email protected]" />
</div>
</div>
<SheetFooter>
<Button type="submit">Save changes</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</div>
)
}
// 9. Complex Application Layout
export function ApplicationLayout() {
const [sidebarOpen, setSidebarOpen] = React.useState(false)
const [selectedUser, setSelectedUser] = React.useState<string | null>(null)
const navigation = [
{ name: 'Dashboard', icon: '📊' },
{ name: 'Users', icon: '👥' },
{ name: 'Analytics', icon: '📈' },
{ name: 'Settings', icon: '⚙️' },
]
const users = [
{ id: '1', name: 'John Doe', email: '[email protected]', role: 'Developer' },
{ id: '2', name: 'Jane Smith', email: '[email protected]', role: 'Designer' },
{ id: '3', name: 'Bob Johnson', email: '[email protected]', role: 'Manager' },
]
return (
<div className="flex h-screen bg-gray-50">
{/* Sidebar */}
<div className={`${sidebarOpen ? 'translate-x-0' : '-translate-x-full'} fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-lg transform transition-transform lg:translate-x-0 lg:static lg:inset-0`}>
<div className="flex items-center justify-between h-16 px-6 border-b">
<h2 className="text-xl font-semibold">App Name</h2>
<Button
variant="ghost"
size="sm"
onClick={() => setSidebarOpen(false)}
className="lg:hidden"
>
✕
</Button>
</div>
<nav className="mt-6 px-4">
<div className="space-y-2">
{navigation.map((item) => (
<Button
key={item.name}
variant="ghost"
className="w-full justify-start"
>
<span className="mr-3">{item.icon}</span>
{item.name}
</Button>
))}
</div>
</nav>
</div>
{/* Main Content */}
<div className="flex-1 flex flex-col overflow-hidden">
{/* Header */}
<header className="bg-white border-b px-6 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center">
<Button
variant="ghost"
size="sm"
onClick={() => setSidebarOpen(true)}
className="lg:hidden mr-4"
>
☰
</Button>
<h1 className="text-2xl font-semibold">Users</h1>
</div>
<div className="flex items-center space-x-4">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm">
<Avatar className="h-8 w-8 mr-2">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
John Doe
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Log out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</header>
{/* Content */}
<main className="flex-1 overflow-auto p-6">
<div className="max-w-7xl mx-auto">
{/* Stats Cards */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">{users.length}</CardTitle>
<CardDescription>Total Users</CardDescription>
</CardHeader>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">
{users.filter(u => u.role === 'Developer').length}
</CardTitle>
<CardDescription>Developers</CardDescription>
</CardHeader>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-2xl">95%</CardTitle>
<CardDescription>Active Users</CardDescription>
</CardHeader>
</Card>
</div>
{/* Users Table */}
<Card>
<CardHeader>
<CardTitle>User Management</CardTitle>
<CardDescription>Manage all registered users</CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Role</TableHead>
<TableHead>Status</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>
<Badge variant="outline">{user.role}</Badge>
</TableCell>
<TableCell>
<Badge className="bg-green-100 text-green-800">Active</Badge>
</TableCell>
<TableCell className="text-right">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">Open menu</span>
⋮
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => setSelectedUser(user.id)}
>
View Details
</DropdownMenuItem>
<DropdownMenuItem>Edit User</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600">
Delete User
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</div>
</main>
</div>
{/* User Details Sheet */}
{selectedUser && (
<Sheet open={!!selectedUser} onOpenChange={() => setSelectedUser(null)}>
<SheetContent>
<SheetHeader>
<SheetTitle>User Details</SheetTitle>
<SheetDescription>
View and edit user information
</SheetDescription>
</SheetHeader>
<div className="mt-6">
<div className="flex items-center space-x-4 mb-6">
<Avatar className="h-12 w-12">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<div>
<h3 className="font-semibold">
{users.find(u => u.id === selectedUser)?.name}
</h3>
<p className="text-sm text-gray-500">
{users.find(u => u.id === selectedUser)?.email}
</p>
</div>
</div>
<Accordion type="single" collapsible>
<AccordionItem value="profile">
<AccordionTrigger>Profile Information</AccordionTrigger>
<AccordionContent>
<div className="space-y-4">
<div>
<Label>Full Name</Label>
<Input defaultValue={users.find(u => u.id === selectedUser)?.name} />
</div>
<div>
<Label>Email Address</Label>
<Input defaultValue={users.find(u => u.id === selectedUser)?.email} />
</div>
<div>
<Label>Role</Label>
<Select defaultValue={users.find(u => u.id === selectedUser)?.role}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="Developer">Developer</SelectItem>
<SelectItem value="Designer">Designer</SelectItem>
<SelectItem value="Manager">Manager</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</AccordionContent>
</AccordionItem>
<AccordionItem value="activity">
<AccordionTrigger>Recent Activity</AccordionTrigger>
<AccordionContent>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Badge variant="outline">Login</Badge>
<span className="text-sm">2 hours ago</span>
</div>
<div className="flex items-center space-x-2">
<Badge variant="outline">Profile Update</Badge>
<span className="text-sm">1 day ago</span>
</div>
<div className="flex items-center space-x-2">
<Badge variant="outline">Password Change</Badge>
<span className="text-sm">1 week ago</span>
</div>
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
</SheetContent>
</Sheet>
)}
</div>
)
}
// Main showcase component
export function AdvancedShadcnUiShowcase() {
return (
<TooltipProvider>
<div className="p-6 max-w-6xl mx-auto space-y-8">
<div className="text-center space-y-2">
<h1 className="text-4xl font-bold">Advanced shadcn/ui Components</h1>
<p className="text-lg text-gray-600">
Complex patterns and advanced usage examples
</p>
</div>
<div className="space-y-8">
<div>
<h2 className="text-2xl font-semibold mb-4">Dialogs</h2>
<DialogExamples />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Data Tables</h2>
<DataTableExample />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Dropdown Menus</h2>
<DropdownExamples />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Command Palette</h2>
<CommandPaletteExample />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Accordion</h2>
<AccordionExample />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Calendar</h2>
<CalendarExample />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Alerts</h2>
<AlertExample />
</div>
<div>
<h2 className="text-2xl font-semibold mb-4">Sheets</h2>
<SheetExample />
</div>
</div>
</div>
</TooltipProvider>
)
}
export {
DialogExamples,
DataTableExample,
DropdownExamples,
CommandPaletteExample,
AccordionExample,
CalendarExample,
AlertExample,
SheetExample,
ApplicationLayout,
AdvancedShadcnUiShowcase
}