Developer-kit shadcn-ui
Provides complete shadcn/ui component library patterns including installation, configuration, and implementation of accessible React components. Use when setting up shadcn/ui, installing components, building forms with React Hook Form and Zod, customizing themes with Tailwind CSS, or implementing UI patterns like buttons, dialogs, dropdowns, tables, and complex form layouts.
git clone https://github.com/giuseppe-trisciuoglio/developer-kit
T=$(mktemp -d) && git clone --depth=1 https://github.com/giuseppe-trisciuoglio/developer-kit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/developer-kit-typescript/skills/shadcn-ui" ~/.claude/skills/giuseppe-trisciuoglio-developer-kit-shadcn-ui && rm -rf "$T"
plugins/developer-kit-typescript/skills/shadcn-ui/SKILL.mdshadcn/ui Component Patterns
Build accessible, customizable UI components with shadcn/ui, Radix UI, and Tailwind CSS.
Overview
- Components are copied into your project — you own and customize the code
- Built on Radix UI primitives for full accessibility
- Styled with Tailwind CSS and CSS variables for theming
- CLI-based installation:
npx shadcn@latest add <component>
When to Use
Activate when user requests involve:
- "Set up shadcn/ui", "initialize shadcn", "add shadcn components"
- "Install button/input/form/dialog/card/select/toast/table/chart"
- "React Hook Form", "Zod validation", "form with validation"
- "accessible components", "Radix UI", "Tailwind theme"
- "shadcn button", "shadcn dialog", "shadcn sheet", "shadcn table"
- "dark mode", "CSS variables", "custom theme"
- "charts with Recharts", "bar chart", "line chart", "pie chart"
Quick Reference
Available Components
| Component | Install Command | Description |
|---|---|---|
| | Variants: default, destructive, outline, secondary, ghost, link |
| | Text input field |
| | React Hook Form integration with validation |
| | Container with header, content, footer |
| | Modal overlay |
| | Slide-over panel (top/right/bottom/left) |
| | Dropdown select |
| | Notification toasts |
| | Data table |
| | Desktop-style menubar |
| | Recharts wrapper with theming |
| | Multi-line text input |
| | Checkbox input |
| | Accessible form label |
Instructions
Initialize Project
# New Next.js project npx create-next-app@latest my-app --typescript --tailwind --eslint --app cd my-app npx shadcn@latest init # Existing project npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react npx shadcn@latest init # Install components npx shadcn@latest add button input form card dialog select toast
Basic Component Usage
// Button with variants and sizes import { Button } from "@/components/ui/button" <Button variant="default">Default</Button> <Button variant="destructive" size="sm">Delete</Button> <Button variant="outline" disabled>Loading...</Button>
Form with Zod Validation
"use client" 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, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form" import { Input } from "@/components/ui/input" const formSchema = z.object({ email: z.string().email("Invalid email"), password: z.string().min(8, "Password must be at least 8 characters"), }) export function LoginForm() { const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: { email: "", password: "" }, }) return ( <Form {...form}> <form onSubmit={form.handleSubmit(console.log)} className="space-y-4"> <FormField name="email" control={form.control} render={({ field }) => ( <FormItem> <FormLabel>Email</FormLabel> <FormControl><Input type="email" {...field} /></FormControl> <FormMessage /> </FormItem> )} /> <FormField name="password" control={form.control} render={({ field }) => ( <FormItem> <FormLabel>Password</FormLabel> <FormControl><Input type="password" {...field} /></FormControl> <FormMessage /> </FormItem> )} /> <Button type="submit">Login</Button> </form> </Form> ) }
See references/forms-and-validation.md for advanced multi-field forms, contact forms with API submission, and login card patterns.
Dialog (Modal)
import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" <Dialog> <DialogTrigger asChild> <Button variant="outline">Open</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Edit Profile</DialogTitle> </DialogHeader> {/* content */} </DialogContent> </Dialog>
Toast Notification
// 1. Add <Toaster /> to app/layout.tsx import { Toaster } from "@/components/ui/toaster" // 2. Use in components import { useToast } from "@/components/ui/use-toast" const { toast } = useToast() toast({ title: "Success", description: "Changes saved." }) toast({ variant: "destructive", title: "Error", description: "Something went wrong." })
Bar Chart
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts" import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart" const chartConfig = { desktop: { label: "Desktop", color: "var(--chart-1)" }, } satisfies import("@/components/ui/chart").ChartConfig <ChartContainer config={chartConfig} className="min-h-[200px] w-full"> <BarChart data={data}> <CartesianGrid vertical={false} /> <XAxis dataKey="month" /> <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} /> <ChartTooltip content={<ChartTooltipContent />} /> </BarChart> </ChartContainer>
See references/charts-components.md for Line, Area, and Pie chart examples.
Examples
Login Form with Validation
"use client" 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, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form" import { Input } from "@/components/ui/input" const formSchema = z.object({ email: z.string().email("Invalid email"), password: z.string().min(8, "Min 8 characters"), }) export function LoginForm() { const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: { email: "", password: "" }, }) return ( <Form {...form}> <form onSubmit={form.handleSubmit(console.log)} className="space-y-4"> <FormField name="email" control={form.control} render={({ field }) => ( <FormItem> <FormLabel>Email</FormLabel> <FormControl><Input type="email" {...field} /></FormControl> <FormMessage /> </FormItem> )} /> <FormField name="password" control={form.control} render={({ field }) => ( <FormItem> <FormLabel>Password</FormLabel> <FormControl><Input type="password" {...field} /></FormControl> <FormMessage /> </FormItem> )} /> <Button type="submit">Login</Button> </form> </Form> ) }
Data Table with Actions
import { ColumnDef } from "@tanstack/react-table" import { Button } from "@/components/ui/button" import { Checkbox } from "@/components/ui/checkbox" import { DataTable } from "@/components/ui/data-table" const columns: ColumnDef<User>[] = [ { id: "select", header: ({ table }) => ( <Checkbox checked={table.getIsAllPageRowsSelected()} /> ), cell: ({ row }) => ( <Checkbox checked={row.getIsSelected()} /> )}, { accessorKey: "name", header: "Name" }, { accessorKey: "email", header: "Email" }, { id: "actions", cell: ({ row }) => ( <Button variant="ghost" size="sm">Edit</Button> )}, ]
Dialog with Form
import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" <Dialog> <DialogTrigger asChild> <Button variant="outline">Add User</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Add New User</DialogTitle> </DialogHeader> {/* <LoginForm /> */} </DialogContent> </Dialog>
Toast Notifications
import { useToast } from "@/components/ui/use-toast" import { Button } from "@/components/ui/button" const { toast } = useToast() toast({ title: "Saved", description: "Changes saved successfully." }) toast({ variant: "destructive", title: "Error", description: "Failed to save." })
Best Practices
- Accessibility: Use Radix UI primitives — ARIA attributes are built in
- Client Components: Add
for interactive components (hooks, events)"use client" - Type Safety: Use TypeScript and Zod schemas for form validation
- Theming: Configure CSS variables in
for consistent designglobals.css - Customization: Modify component files directly — you own the code
- Path Aliases: Ensure
alias is configured in@tsconfig.json - Registry Security: Only install components from trusted registries; review generated code before production use
- Dark Mode: Set up with CSS variables strategy and
next-themes - Forms: Always use
,Form
,FormField
,FormItem
,FormLabel
togetherFormMessage - Toaster: Add
once to root layout<Toaster />
Constraints and Warnings
- Not an NPM Package: Components are copied to your project; they are not a versioned dependency
- Registry Security: Components from
are fetched remotely; always verify the registry source is trusted before installationnpx shadcn@latest add - Client Components: Most interactive components require
directive"use client" - Radix Dependencies: Ensure all
packages are installed@radix-ui - Tailwind Required: Components rely on Tailwind CSS utilities
- Path Aliases: Configure
alias in@
for importstsconfig.json
References
Consult these files for detailed patterns and code examples:
- references/setup-and-configuration.md — Full installation, tsconfig, tailwind config, CSS variables
- references/ui-components.md — Button, Input, Card, Dialog, Sheet, Select, Toast, Table, Menubar
- references/forms-and-validation.md — React Hook Form + Zod, advanced forms, login card, contact form
- references/charts-components.md — Bar, Line, Area, Pie charts with ChartContainer and theming
- references/nextjs-integration.md — App Router, Server/Client Components, dark mode, metadata
- references/customization.md — Custom variants, CSS variables, cn() utility, extending components