plugins/developer-kit-typescript/skills/shadcn-ui/SKILL.md
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.
npx skillsauth add giuseppe-trisciuoglio/developer-kit shadcn-uiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build accessible, customizable UI components with shadcn/ui, Radix UI, and Tailwind CSS.
npx shadcn@latest add <component>Activate when user requests involve:
| Component | Install Command | Description |
|-----------|----------------|-------------|
| button | npx shadcn@latest add button | Variants: default, destructive, outline, secondary, ghost, link |
| input | npx shadcn@latest add input | Text input field |
| form | npx shadcn@latest add form | React Hook Form integration with validation |
| card | npx shadcn@latest add card | Container with header, content, footer |
| dialog | npx shadcn@latest add dialog | Modal overlay |
| sheet | npx shadcn@latest add sheet | Slide-over panel (top/right/bottom/left) |
| select | npx shadcn@latest add select | Dropdown select |
| toast | npx shadcn@latest add toast | Notification toasts |
| table | npx shadcn@latest add table | Data table |
| menubar | npx shadcn@latest add menubar | Desktop-style menubar |
| chart | npx shadcn@latest add chart | Recharts wrapper with theming |
| textarea | npx shadcn@latest add textarea | Multi-line text input |
| checkbox | npx shadcn@latest add checkbox | Checkbox input |
| label | npx shadcn@latest add label | Accessible form label |
# 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
// 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>
"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.
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>
// 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." })
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.
"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>
)
}
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>
)},
]
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>
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." })
"use client" for interactive components (hooks, events)globals.css for consistent design@ alias is configured in tsconfig.jsonnext-themesForm, FormField, FormItem, FormLabel, FormMessage together<Toaster /> once to root layoutnpx shadcn@latest add are fetched remotely; always verify the registry source is trusted before installation"use client" directive@radix-ui packages are installed@ alias in tsconfig.json for importsConsult these files for detailed patterns and code examples:
development
Explore codebase before committing to a change. Phase executor skill for specs.explore command.
development
Executes real end-to-end verification against a running application after specification implementation. Detects the application type, starts the local runtime (Docker, Node, Spring Boot, etc.), runs real tests (curl for REST APIs, Playwright for web SPAs, computer-use for desktop apps), verifies acceptance criteria from the functional specification, generates a markdown report, and tears down the environment. Use when: user asks to verify a completed spec with real tests, run e2e checks after implementation, validate acceptance criteria in a live environment, or test the feature for real after task completion.
development
Initialize Spec-Driven Development context — detects tech stack, conventions, architecture patterns, and bootstraps persistence backends. Triggers on 'sdd-init', 'init sdd', 'setup sdd', 'initialize sdd', 'setup project', 'initialize project context'. Creates/updates docs/specs/architecture.md & ontology.md (Constitution), and populates knowledge-graph.json.
development
Optimizes raw idea descriptions into structured prompts ready for the brainstorming workflow. TRIGGER when: user says "optimize for brainstorm", "prepare idea for brainstorm", "enhance this idea", "make this ready for brainstorming", "imposta per brainstorm", or wants to improve a feature idea before using /specs.brainstorm. DO NOT TRIGGER for code optimization, refactoring, or general prompt engineering tasks.