shadcn-ui by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill shadcn-ui使用 shadcn/ui、Radix UI 和 Tailwind CSS 构建可访问、可定制的 UI 组件。
npx shadcn@latest add <component>当用户请求涉及以下内容时激活:
| 组件 | 安装命令 | 描述 |
|---|---|---|
button |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
npx shadcn@latest add button |
| 变体:default, destructive, outline, secondary, ghost, link |
input | npx shadcn@latest add input | 文本输入字段 |
form | npx shadcn@latest add form | 集成验证的 React Hook Form |
card | npx shadcn@latest add card | 包含 header, content, footer 的容器 |
dialog | npx shadcn@latest add dialog | 模态叠加层 |
sheet | npx shadcn@latest add sheet | 滑动面板 (top/right/bottom/left) |
select | npx shadcn@latest add select | 下拉选择器 |
toast | npx shadcn@latest add toast | 通知提示 |
table | npx shadcn@latest add table | 数据表格 |
menubar | npx shadcn@latest add menubar | 桌面风格菜单栏 |
chart | npx shadcn@latest add chart | 支持主题化的 Recharts 包装器 |
textarea | npx shadcn@latest add textarea | 多行文本输入 |
checkbox | npx shadcn@latest add checkbox | 复选框输入 |
label | npx shadcn@latest add label | 可访问的表单标签 |
# 新建 Next.js 项目
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
cd my-app
npx shadcn@latest init
# 现有项目
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
npx shadcn@latest init
# 安装组件
npx shadcn@latest add button input form card dialog select toast
// 带变体和尺寸的按钮
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>
)
}
查看 references/forms-and-validation.md 以获取高级多字段表单、带 API 提交的联系表单和登录卡片模式。
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. 将 <Toaster /> 添加到 app/layout.tsx
import { Toaster } from "@/components/ui/toaster"
// 2. 在组件中使用
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>
查看 references/charts-components.md 以获取折线图、面积图和饼图示例。
"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"globals.css 中配置 CSS 变量以实现一致的设计tsconfig.json 中配置了 @ 别名next-themes 进行设置Form、FormField、FormItem、FormLabel、FormMessage<Toaster /> 添加到根布局一次即可npx shadcn@latest add 的组件是远程获取的;在安装前务必验证注册表来源是否可信"use client" 指令@radix-ui 包都已安装tsconfig.json 中配置 @ 别名以用于导入查阅以下文件以获取详细的模式和代码示例:
每周安装量
12.1K
仓库
GitHub 星标
173
首次出现
Jan 20, 2026
安全审计
安装于
opencode8.3K
gemini-cli8.0K
codex7.9K
claude-code7.9K
github-copilot7.5K
cursor6.9K
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, , , togethernpx 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:
Weekly Installs
12.1K
Repository
GitHub Stars
173
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode8.3K
gemini-cli8.0K
codex7.9K
claude-code7.9K
github-copilot7.5K
cursor6.9K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
FormItemFormLabelFormMessage<Toaster /> once to root layout