Initial commit
This commit is contained in:
424
skills/ui-styling/references/shadcn-components.md
Normal file
424
skills/ui-styling/references/shadcn-components.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# shadcn/ui Component Reference
|
||||
|
||||
Complete catalog of shadcn/ui components with usage patterns and installation.
|
||||
|
||||
## Installation
|
||||
|
||||
**Add specific components:**
|
||||
```bash
|
||||
npx shadcn@latest add button
|
||||
npx shadcn@latest add button card dialog # Multiple
|
||||
npx shadcn@latest add --all # All components
|
||||
```
|
||||
|
||||
Components install to `components/ui/` with automatic dependency management.
|
||||
|
||||
## Form & Input Components
|
||||
|
||||
### Button
|
||||
```tsx
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
<Button variant="default">Default</Button>
|
||||
<Button variant="destructive">Delete</Button>
|
||||
<Button variant="outline" size="sm">Small Outline</Button>
|
||||
<Button variant="ghost" size="icon"><Icon /></Button>
|
||||
<Button variant="link">Link Style</Button>
|
||||
```
|
||||
|
||||
Variants: `default | destructive | outline | secondary | ghost | link`
|
||||
Sizes: `default | sm | lg | icon`
|
||||
|
||||
### Input
|
||||
```tsx
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input id="email" type="email" placeholder="you@example.com" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### Form (with React Hook Form + Zod)
|
||||
```tsx
|
||||
import { useForm } from "react-hook-form"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import * as z from "zod"
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
const schema = z.object({
|
||||
username: z.string().min(2).max(50),
|
||||
email: z.string().email()
|
||||
})
|
||||
|
||||
function ProfileForm() {
|
||||
const form = useForm({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: { username: "", email: "" }
|
||||
})
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(console.log)} className="space-y-8">
|
||||
<FormField control={form.control} name="username" render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="shadcn" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)} />
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Select
|
||||
```tsx
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
|
||||
<Select>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<SelectValue placeholder="Theme" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">Light</SelectItem>
|
||||
<SelectItem value="dark">Dark</SelectItem>
|
||||
<SelectItem value="system">System</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
```
|
||||
|
||||
### Checkbox
|
||||
```tsx
|
||||
import { Checkbox } from "@/components/ui/checkbox"
|
||||
import { Label } from "@/components/ui/label"
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox id="terms" />
|
||||
<Label htmlFor="terms">Accept terms</Label>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Radio Group
|
||||
```tsx
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
import { Label } from "@/components/ui/label"
|
||||
|
||||
<RadioGroup defaultValue="option-one">
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="option-one" id="option-one" />
|
||||
<Label htmlFor="option-one">Option One</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="option-two" id="option-two" />
|
||||
<Label htmlFor="option-two">Option Two</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
```
|
||||
|
||||
### Textarea
|
||||
```tsx
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
|
||||
<Textarea placeholder="Type your message here." />
|
||||
```
|
||||
|
||||
### Switch
|
||||
```tsx
|
||||
import { Switch } from "@/components/ui/switch"
|
||||
import { Label } from "@/components/ui/label"
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch id="airplane-mode" />
|
||||
<Label htmlFor="airplane-mode">Airplane Mode</Label>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Date Picker
|
||||
```tsx
|
||||
import { Calendar } from "@/components/ui/calendar"
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { CalendarIcon } from "lucide-react"
|
||||
import { format } from "date-fns"
|
||||
import { useState } from "react"
|
||||
|
||||
const [date, setDate] = useState<Date>()
|
||||
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{date ? format(date, "PPP") : "Pick a date"}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar mode="single" selected={date} onSelect={setDate} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
```
|
||||
|
||||
## Layout & Navigation
|
||||
|
||||
### Card
|
||||
```tsx
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Card Title</CardTitle>
|
||||
<CardDescription>Card Description</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p>Card Content</p>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button>Action</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
### Tabs
|
||||
```tsx
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
|
||||
<Tabs defaultValue="account">
|
||||
<TabsList>
|
||||
<TabsTrigger value="account">Account</TabsTrigger>
|
||||
<TabsTrigger value="password">Password</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="account">Account settings</TabsContent>
|
||||
<TabsContent value="password">Password settings</TabsContent>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
### Accordion
|
||||
```tsx
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
|
||||
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes. It adheres to WAI-ARIA design pattern.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-2">
|
||||
<AccordionTrigger>Is it styled?</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes. Comes with default styles customizable with Tailwind.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
```
|
||||
|
||||
### Navigation Menu
|
||||
```tsx
|
||||
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from "@/components/ui/navigation-menu"
|
||||
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<NavigationMenuLink>Introduction</NavigationMenuLink>
|
||||
<NavigationMenuLink>Installation</NavigationMenuLink>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
```
|
||||
|
||||
## Overlays & Dialogs
|
||||
|
||||
### Dialog
|
||||
```tsx
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button>Open</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Are you sure?</DialogTitle>
|
||||
<DialogDescription>This action cannot be undone.</DialogDescription>
|
||||
</DialogHeader>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
```
|
||||
|
||||
### Drawer
|
||||
```tsx
|
||||
import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "@/components/ui/drawer"
|
||||
|
||||
<Drawer>
|
||||
<DrawerTrigger>Open</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>Title</DrawerTitle>
|
||||
<DrawerDescription>Description</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<DrawerFooter>
|
||||
<Button>Submit</Button>
|
||||
<DrawerClose>Cancel</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
```
|
||||
|
||||
### Popover
|
||||
```tsx
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
||||
|
||||
<Popover>
|
||||
<PopoverTrigger>Open</PopoverTrigger>
|
||||
<PopoverContent>Content here</PopoverContent>
|
||||
</Popover>
|
||||
```
|
||||
|
||||
### Toast
|
||||
```tsx
|
||||
import { useToast } from "@/hooks/use-toast"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
const { toast } = useToast()
|
||||
|
||||
<Button onClick={() => {
|
||||
toast({
|
||||
title: "Scheduled: Catch up",
|
||||
description: "Friday, February 10, 2023 at 5:57 PM"
|
||||
})
|
||||
}}>
|
||||
Show Toast
|
||||
</Button>
|
||||
```
|
||||
|
||||
### Command
|
||||
```tsx
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"
|
||||
|
||||
<Command>
|
||||
<CommandInput placeholder="Type a command or search..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No results found.</CommandEmpty>
|
||||
<CommandGroup heading="Suggestions">
|
||||
<CommandItem>Calendar</CommandItem>
|
||||
<CommandItem>Search Emoji</CommandItem>
|
||||
<CommandItem>Calculator</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
```
|
||||
|
||||
### Alert Dialog
|
||||
```tsx
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive">Delete</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This permanently deletes your account and removes data from servers.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction>Continue</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
```
|
||||
|
||||
## Feedback & Status
|
||||
|
||||
### Alert
|
||||
```tsx
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||||
|
||||
<Alert>
|
||||
<AlertTitle>Heads up!</AlertTitle>
|
||||
<AlertDescription>You can add components using CLI.</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
<Alert variant="destructive">
|
||||
<AlertTitle>Error</AlertTitle>
|
||||
<AlertDescription>Session expired. Please log in.</AlertDescription>
|
||||
</Alert>
|
||||
```
|
||||
|
||||
### Progress
|
||||
```tsx
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
|
||||
<Progress value={33} />
|
||||
```
|
||||
|
||||
### Skeleton
|
||||
```tsx
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<Skeleton className="h-12 w-12 rounded-full" />
|
||||
<div className="space-y-2">
|
||||
<Skeleton className="h-4 w-[250px]" />
|
||||
<Skeleton className="h-4 w-[200px]" />
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Display Components
|
||||
|
||||
### Table
|
||||
```tsx
|
||||
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||
|
||||
<Table>
|
||||
<TableCaption>Recent invoices</TableCaption>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Invoice</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Amount</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>INV001</TableCell>
|
||||
<TableCell>Paid</TableCell>
|
||||
<TableCell>$250.00</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
```
|
||||
|
||||
### Avatar
|
||||
```tsx
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
|
||||
<Avatar>
|
||||
<AvatarImage src="https://github.com/shadcn.png" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
</Avatar>
|
||||
```
|
||||
|
||||
### Badge
|
||||
```tsx
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
|
||||
<Badge>Default</Badge>
|
||||
<Badge variant="secondary">Secondary</Badge>
|
||||
<Badge variant="destructive">Destructive</Badge>
|
||||
<Badge variant="outline">Outline</Badge>
|
||||
```
|
||||
Reference in New Issue
Block a user