{
  "schemaVersion": "1.0",
  "item": {
    "slug": "shadcn",
    "name": "Shadcn UI",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/wpank/shadcn",
    "canonicalUrl": "https://clawhub.ai/wpank/shadcn",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/shadcn",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=shadcn",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "references/learn.md",
      "references/extended-components.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/shadcn"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/shadcn",
    "agentPageUrl": "https://openagent3.xyz/skills/shadcn/agent",
    "manifestUrl": "https://openagent3.xyz/skills/shadcn/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/shadcn/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "shadcn/ui Component Patterns",
        "body": "Expert guide for building accessible, customizable UI components with shadcn/ui."
      },
      {
        "title": "OpenClaw / Moltbot / Clawbot",
        "body": "npx clawhub@latest install shadcn-ui"
      },
      {
        "title": "WHEN",
        "body": "Setting up a new project with shadcn/ui\nInstalling or configuring individual components\nBuilding forms with React Hook Form and Zod validation\nCreating accessible UI components (buttons, dialogs, dropdowns, sheets)\nCustomizing component styling with Tailwind CSS\nImplementing design systems with shadcn/ui\nBuilding Next.js applications with TypeScript"
      },
      {
        "title": "What is shadcn/ui?",
        "body": "A collection of reusable components you copy into your project — not an npm package. You own the code. Built on Radix UI (accessibility) and Tailwind CSS (styling)."
      },
      {
        "title": "Quick Start",
        "body": "# New Next.js project\nnpx create-next-app@latest my-app --typescript --tailwind --eslint --app\ncd my-app\nnpx shadcn@latest init\n\n# Install components\nnpx shadcn@latest add button input form card dialog select toast\nnpx shadcn@latest add --all  # or install everything"
      },
      {
        "title": "The cn Utility",
        "body": "Merges Tailwind classes with conflict resolution — used in every component:\n\nimport { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}"
      },
      {
        "title": "Class Variance Authority (CVA)",
        "body": "Manages component variants — the pattern behind every shadcn/ui component:\n\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n        outline: \"border border-input bg-background hover:bg-accent\",\n        secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/90\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-10 px-4 py-2\",\n        sm: \"h-9 rounded-md px-3\",\n        lg: \"h-11 rounded-md px-8\",\n        icon: \"h-10 w-10\",\n      },\n    },\n    defaultVariants: { variant: \"default\", size: \"default\" },\n  }\n)"
      },
      {
        "title": "Button",
        "body": "import { Button } from \"@/components/ui/button\"\nimport { Loader2 } from \"lucide-react\"\n\n// Variants: default | destructive | outline | secondary | ghost | link\n// Sizes: default | sm | lg | icon\n<Button variant=\"outline\" size=\"sm\">Click me</Button>\n\n// Loading state\n<Button disabled>\n  <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n  Please wait\n</Button>\n\n// As link (uses Radix Slot)\n<Button asChild>\n  <a href=\"/dashboard\">Go to Dashboard</a>\n</Button>"
      },
      {
        "title": "Forms with Validation",
        "body": "The standard pattern: Zod schema + React Hook Form + shadcn Form components.\n\nnpx shadcn@latest add form input select checkbox textarea\n\n\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm } from \"react-hook-form\"\nimport * as z from \"zod\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Form, FormControl, FormDescription,\n  FormField, FormItem, FormLabel, FormMessage,\n} from \"@/components/ui/form\"\nimport { Input } from \"@/components/ui/input\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@/components/ui/select\"\n\nconst formSchema = z.object({\n  username: z.string().min(2, \"Username must be at least 2 characters.\"),\n  email: z.string().email(\"Please enter a valid email.\"),\n  role: z.enum([\"admin\", \"user\", \"guest\"]),\n})\n\nexport function ProfileForm() {\n  const form = useForm<z.infer<typeof formSchema>>({\n    resolver: zodResolver(formSchema),\n    defaultValues: { username: \"\", email: \"\", role: \"user\" },\n  })\n\n  function onSubmit(values: z.infer<typeof formSchema>) {\n    console.log(values)\n  }\n\n  return (\n    <Form {...form}>\n      <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n        <FormField control={form.control} name=\"username\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Username</FormLabel>\n            <FormControl><Input placeholder=\"shadcn\" {...field} /></FormControl>\n            <FormDescription>Your public display name.</FormDescription>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <FormField control={form.control} name=\"email\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Email</FormLabel>\n            <FormControl><Input type=\"email\" {...field} /></FormControl>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <FormField control={form.control} name=\"role\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Role</FormLabel>\n            <Select onValueChange={field.onChange} defaultValue={field.value}>\n              <FormControl>\n                <SelectTrigger><SelectValue placeholder=\"Select a role\" /></SelectTrigger>\n              </FormControl>\n              <SelectContent>\n                <SelectItem value=\"admin\">Admin</SelectItem>\n                <SelectItem value=\"user\">User</SelectItem>\n                <SelectItem value=\"guest\">Guest</SelectItem>\n              </SelectContent>\n            </Select>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <Button type=\"submit\">Submit</Button>\n      </form>\n    </Form>\n  )\n}"
      },
      {
        "title": "Dialog & Sheet",
        "body": "import {\n  Dialog, DialogContent, DialogDescription,\n  DialogFooter, DialogHeader, DialogTitle, DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport {\n  Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger,\n} from \"@/components/ui/sheet\"\n\n// Modal dialog\n<Dialog>\n  <DialogTrigger asChild><Button variant=\"outline\">Edit profile</Button></DialogTrigger>\n  <DialogContent className=\"sm:max-w-[425px]\">\n    <DialogHeader>\n      <DialogTitle>Edit profile</DialogTitle>\n      <DialogDescription>Make changes here. Click save when done.</DialogDescription>\n    </DialogHeader>\n    <div className=\"grid gap-4 py-4\">{/* form fields */}</div>\n    <DialogFooter><Button type=\"submit\">Save changes</Button></DialogFooter>\n  </DialogContent>\n</Dialog>\n\n// Slide-over panel (side: \"left\" | \"right\" | \"top\" | \"bottom\")\n<Sheet>\n  <SheetTrigger asChild><Button variant=\"outline\">Open</Button></SheetTrigger>\n  <SheetContent side=\"right\">\n    <SheetHeader><SheetTitle>Settings</SheetTitle></SheetHeader>\n    {/* content */}\n  </SheetContent>\n</Sheet>"
      },
      {
        "title": "Card",
        "body": "import {\n  Card, CardContent, CardDescription,\n  CardFooter, CardHeader, CardTitle,\n} from \"@/components/ui/card\"\n\n<Card className=\"w-[350px]\">\n  <CardHeader>\n    <CardTitle>Create project</CardTitle>\n    <CardDescription>Deploy your new project in one-click.</CardDescription>\n  </CardHeader>\n  <CardContent>\n    <div className=\"grid w-full items-center gap-4\">\n      <div className=\"flex flex-col space-y-1.5\">\n        <Label htmlFor=\"name\">Name</Label>\n        <Input id=\"name\" placeholder=\"Project name\" />\n      </div>\n    </div>\n  </CardContent>\n  <CardFooter className=\"flex justify-between\">\n    <Button variant=\"outline\">Cancel</Button>\n    <Button>Deploy</Button>\n  </CardFooter>\n</Card>"
      },
      {
        "title": "Toast Notifications",
        "body": "// 1. Add Toaster to root layout\nimport { Toaster } from \"@/components/ui/toaster\"\n\nexport default function RootLayout({ children }) {\n  return (\n    <html lang=\"en\">\n      <body>{children}<Toaster /></body>\n    </html>\n  )\n}\n\n// 2. Use toast in components\nimport { useToast } from \"@/components/ui/use-toast\"\nimport { ToastAction } from \"@/components/ui/toast\"\n\nconst { toast } = useToast()\n\ntoast({ title: \"Success\", description: \"Changes saved.\" })\n\ntoast({\n  variant: \"destructive\",\n  title: \"Error\",\n  description: \"Something went wrong.\",\n  action: <ToastAction altText=\"Try again\">Try again</ToastAction>,\n})"
      },
      {
        "title": "Table",
        "body": "import {\n  Table, TableBody, TableCaption, TableCell,\n  TableHead, TableHeader, TableRow,\n} from \"@/components/ui/table\"\n\nconst invoices = [\n  { invoice: \"INV001\", status: \"Paid\", method: \"Credit Card\", amount: \"$250.00\" },\n  { invoice: \"INV002\", status: \"Pending\", method: \"PayPal\", amount: \"$150.00\" },\n]\n\n<Table>\n  <TableCaption>A list of your recent invoices.</TableCaption>\n  <TableHeader>\n    <TableRow>\n      <TableHead>Invoice</TableHead>\n      <TableHead>Status</TableHead>\n      <TableHead>Method</TableHead>\n      <TableHead className=\"text-right\">Amount</TableHead>\n    </TableRow>\n  </TableHeader>\n  <TableBody>\n    {invoices.map((invoice) => (\n      <TableRow key={invoice.invoice}>\n        <TableCell className=\"font-medium\">{invoice.invoice}</TableCell>\n        <TableCell>{invoice.status}</TableCell>\n        <TableCell>{invoice.method}</TableCell>\n        <TableCell className=\"text-right\">{invoice.amount}</TableCell>\n      </TableRow>\n    ))}\n  </TableBody>\n</Table>"
      },
      {
        "title": "Theming",
        "body": "shadcn/ui uses CSS variables in HSL format. Configure in globals.css:\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 222.2 84% 4.9%;\n    --primary: 222.2 47.4% 11.2%;\n    --primary-foreground: 210 40% 98%;\n    --secondary: 210 40% 96.1%;\n    --muted: 210 40% 96.1%;\n    --muted-foreground: 215.4 16.3% 46.9%;\n    --destructive: 0 84.2% 60.2%;\n    --border: 214.3 31.8% 91.4%;\n    --ring: 222.2 84% 4.9%;\n    --radius: 0.5rem;\n  }\n\n  .dark {\n    --background: 222.2 84% 4.9%;\n    --foreground: 210 40% 98%;\n    --primary: 210 40% 98%;\n    --primary-foreground: 222.2 47.4% 11.2%;\n    /* ... mirror all variables for dark mode */\n  }\n}\n\nColors reference as hsl(var(--primary)) in Tailwind config. Change the CSS variables to retheme the entire app."
      },
      {
        "title": "Customizing Components",
        "body": "Since you own the code, modify components directly:\n\n// Add a custom variant to button.tsx\nconst buttonVariants = cva(\"...\", {\n  variants: {\n    variant: {\n      // ... existing variants\n      gradient: \"bg-gradient-to-r from-purple-500 to-pink-500 text-white\",\n    },\n    size: {\n      // ... existing sizes\n      xl: \"h-14 rounded-md px-10 text-lg\",\n    },\n  },\n})"
      },
      {
        "title": "Component Reference",
        "body": "ComponentInstallKey PropsButtonadd buttonvariant, size, asChildInputadd inputStandard HTML input propsFormadd formReact Hook Form + Zod integrationCardadd cardHeader, Content, Footer compositionDialogadd dialogModal with trigger patternSheetadd sheetSlide-over panel, side propSelectadd selectAccessible dropdownToastadd toastvariant: \"default\" | \"destructive\"Tableadd tableHeader, Body, Row, Cell compositionTabsadd tabsdefaultValue, trigger/content pairsAccordionadd accordiontype: \"single\" | \"multiple\"Commandadd commandCommand palette / searchDropdown Menuadd dropdown-menuContext menus, action menusMenubaradd menubarApplication menus with shortcuts"
      },
      {
        "title": "App Router Setup",
        "body": "For Next.js 13+ with App Router, ensure interactive components use \"use client\":\n\n// src/components/ui/button.tsx\n\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\n// ... rest of component"
      },
      {
        "title": "Layout Integration",
        "body": "Add the Toaster to your root layout:\n\n// app/layout.tsx\nimport { Toaster } from \"@/components/ui/toaster\"\nimport \"./globals.css\"\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    <html lang=\"en\" suppressHydrationWarning>\n      <body className=\"min-h-screen bg-background font-sans antialiased\">\n        {children}\n        <Toaster />\n      </body>\n    </html>\n  )\n}"
      },
      {
        "title": "Server Components",
        "body": "Most shadcn/ui components need \"use client\". For Server Components, wrap them in a client component or use them in client component children."
      },
      {
        "title": "CLI Reference",
        "body": "npx shadcn@latest init              # Initialize project\nnpx shadcn@latest add [component]   # Add specific component\nnpx shadcn@latest add --all         # Add all components\nnpx shadcn@latest diff              # Show upstream changes"
      },
      {
        "title": "Best Practices",
        "body": "PracticeDetailsUse TypeScriptAll components ship with full type definitionsZod for validationPair with React Hook Form for type-safe formsasChild patternUse Radix Slot to render as different elementsServer ComponentsMost shadcn/ui components need \"use client\"Consistent structureFollow the existing component patterns when customizingAccessibilityRadix primitives handle ARIA; don't override without reasonCSS variablesTheme via variables, not by editing component classesTree-shakingOnly install components you need — they're independent"
      },
      {
        "title": "NEVER Do",
        "body": "NeverWhyInsteadInstall shadcn as npm packageIt's not a package — it's source code you ownUse CLI: npx shadcn@latest addOverride ARIA attributesRadix handles accessibility correctlyTrust the primitivesUse inline styles for themingDefeats the design systemModify CSS variablesCopy components from docs manuallyMay miss dependenciesUse CLI for proper installationMix component stylesCreates inconsistencyFollow CVA variant pattern"
      },
      {
        "title": "References",
        "body": "Learning Guide — progression from basics to advanced patterns\nExtended Components — Terminal, Dock, Charts, animations, custom hooks\nOfficial Docs | Radix UI | React Hook Form | Zod"
      }
    ],
    "body": "shadcn/ui Component Patterns\n\nExpert guide for building accessible, customizable UI components with shadcn/ui.\n\nInstallation\nOpenClaw / Moltbot / Clawbot\nnpx clawhub@latest install shadcn-ui\n\nWHEN\nSetting up a new project with shadcn/ui\nInstalling or configuring individual components\nBuilding forms with React Hook Form and Zod validation\nCreating accessible UI components (buttons, dialogs, dropdowns, sheets)\nCustomizing component styling with Tailwind CSS\nImplementing design systems with shadcn/ui\nBuilding Next.js applications with TypeScript\nWhat is shadcn/ui?\n\nA collection of reusable components you copy into your project — not an npm package. You own the code. Built on Radix UI (accessibility) and Tailwind CSS (styling).\n\nQuick Start\n# New Next.js project\nnpx create-next-app@latest my-app --typescript --tailwind --eslint --app\ncd my-app\nnpx shadcn@latest init\n\n# Install components\nnpx shadcn@latest add button input form card dialog select toast\nnpx shadcn@latest add --all  # or install everything\n\nCore Concepts\nThe cn Utility\n\nMerges Tailwind classes with conflict resolution — used in every component:\n\nimport { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nClass Variance Authority (CVA)\n\nManages component variants — the pattern behind every shadcn/ui component:\n\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n        destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n        outline: \"border border-input bg-background hover:bg-accent\",\n        secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/90\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-10 px-4 py-2\",\n        sm: \"h-9 rounded-md px-3\",\n        lg: \"h-11 rounded-md px-8\",\n        icon: \"h-10 w-10\",\n      },\n    },\n    defaultVariants: { variant: \"default\", size: \"default\" },\n  }\n)\n\nEssential Components\nButton\nimport { Button } from \"@/components/ui/button\"\nimport { Loader2 } from \"lucide-react\"\n\n// Variants: default | destructive | outline | secondary | ghost | link\n// Sizes: default | sm | lg | icon\n<Button variant=\"outline\" size=\"sm\">Click me</Button>\n\n// Loading state\n<Button disabled>\n  <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n  Please wait\n</Button>\n\n// As link (uses Radix Slot)\n<Button asChild>\n  <a href=\"/dashboard\">Go to Dashboard</a>\n</Button>\n\nForms with Validation\n\nThe standard pattern: Zod schema + React Hook Form + shadcn Form components.\n\nnpx shadcn@latest add form input select checkbox textarea\n\n\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { useForm } from \"react-hook-form\"\nimport * as z from \"zod\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Form, FormControl, FormDescription,\n  FormField, FormItem, FormLabel, FormMessage,\n} from \"@/components/ui/form\"\nimport { Input } from \"@/components/ui/input\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@/components/ui/select\"\n\nconst formSchema = z.object({\n  username: z.string().min(2, \"Username must be at least 2 characters.\"),\n  email: z.string().email(\"Please enter a valid email.\"),\n  role: z.enum([\"admin\", \"user\", \"guest\"]),\n})\n\nexport function ProfileForm() {\n  const form = useForm<z.infer<typeof formSchema>>({\n    resolver: zodResolver(formSchema),\n    defaultValues: { username: \"\", email: \"\", role: \"user\" },\n  })\n\n  function onSubmit(values: z.infer<typeof formSchema>) {\n    console.log(values)\n  }\n\n  return (\n    <Form {...form}>\n      <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n        <FormField control={form.control} name=\"username\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Username</FormLabel>\n            <FormControl><Input placeholder=\"shadcn\" {...field} /></FormControl>\n            <FormDescription>Your public display name.</FormDescription>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <FormField control={form.control} name=\"email\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Email</FormLabel>\n            <FormControl><Input type=\"email\" {...field} /></FormControl>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <FormField control={form.control} name=\"role\" render={({ field }) => (\n          <FormItem>\n            <FormLabel>Role</FormLabel>\n            <Select onValueChange={field.onChange} defaultValue={field.value}>\n              <FormControl>\n                <SelectTrigger><SelectValue placeholder=\"Select a role\" /></SelectTrigger>\n              </FormControl>\n              <SelectContent>\n                <SelectItem value=\"admin\">Admin</SelectItem>\n                <SelectItem value=\"user\">User</SelectItem>\n                <SelectItem value=\"guest\">Guest</SelectItem>\n              </SelectContent>\n            </Select>\n            <FormMessage />\n          </FormItem>\n        )} />\n\n        <Button type=\"submit\">Submit</Button>\n      </form>\n    </Form>\n  )\n}\n\nDialog & Sheet\nimport {\n  Dialog, DialogContent, DialogDescription,\n  DialogFooter, DialogHeader, DialogTitle, DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport {\n  Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger,\n} from \"@/components/ui/sheet\"\n\n// Modal dialog\n<Dialog>\n  <DialogTrigger asChild><Button variant=\"outline\">Edit profile</Button></DialogTrigger>\n  <DialogContent className=\"sm:max-w-[425px]\">\n    <DialogHeader>\n      <DialogTitle>Edit profile</DialogTitle>\n      <DialogDescription>Make changes here. Click save when done.</DialogDescription>\n    </DialogHeader>\n    <div className=\"grid gap-4 py-4\">{/* form fields */}</div>\n    <DialogFooter><Button type=\"submit\">Save changes</Button></DialogFooter>\n  </DialogContent>\n</Dialog>\n\n// Slide-over panel (side: \"left\" | \"right\" | \"top\" | \"bottom\")\n<Sheet>\n  <SheetTrigger asChild><Button variant=\"outline\">Open</Button></SheetTrigger>\n  <SheetContent side=\"right\">\n    <SheetHeader><SheetTitle>Settings</SheetTitle></SheetHeader>\n    {/* content */}\n  </SheetContent>\n</Sheet>\n\nCard\nimport {\n  Card, CardContent, CardDescription,\n  CardFooter, CardHeader, CardTitle,\n} from \"@/components/ui/card\"\n\n<Card className=\"w-[350px]\">\n  <CardHeader>\n    <CardTitle>Create project</CardTitle>\n    <CardDescription>Deploy your new project in one-click.</CardDescription>\n  </CardHeader>\n  <CardContent>\n    <div className=\"grid w-full items-center gap-4\">\n      <div className=\"flex flex-col space-y-1.5\">\n        <Label htmlFor=\"name\">Name</Label>\n        <Input id=\"name\" placeholder=\"Project name\" />\n      </div>\n    </div>\n  </CardContent>\n  <CardFooter className=\"flex justify-between\">\n    <Button variant=\"outline\">Cancel</Button>\n    <Button>Deploy</Button>\n  </CardFooter>\n</Card>\n\nToast Notifications\n// 1. Add Toaster to root layout\nimport { Toaster } from \"@/components/ui/toaster\"\n\nexport default function RootLayout({ children }) {\n  return (\n    <html lang=\"en\">\n      <body>{children}<Toaster /></body>\n    </html>\n  )\n}\n\n// 2. Use toast in components\nimport { useToast } from \"@/components/ui/use-toast\"\nimport { ToastAction } from \"@/components/ui/toast\"\n\nconst { toast } = useToast()\n\ntoast({ title: \"Success\", description: \"Changes saved.\" })\n\ntoast({\n  variant: \"destructive\",\n  title: \"Error\",\n  description: \"Something went wrong.\",\n  action: <ToastAction altText=\"Try again\">Try again</ToastAction>,\n})\n\nTable\nimport {\n  Table, TableBody, TableCaption, TableCell,\n  TableHead, TableHeader, TableRow,\n} from \"@/components/ui/table\"\n\nconst invoices = [\n  { invoice: \"INV001\", status: \"Paid\", method: \"Credit Card\", amount: \"$250.00\" },\n  { invoice: \"INV002\", status: \"Pending\", method: \"PayPal\", amount: \"$150.00\" },\n]\n\n<Table>\n  <TableCaption>A list of your recent invoices.</TableCaption>\n  <TableHeader>\n    <TableRow>\n      <TableHead>Invoice</TableHead>\n      <TableHead>Status</TableHead>\n      <TableHead>Method</TableHead>\n      <TableHead className=\"text-right\">Amount</TableHead>\n    </TableRow>\n  </TableHeader>\n  <TableBody>\n    {invoices.map((invoice) => (\n      <TableRow key={invoice.invoice}>\n        <TableCell className=\"font-medium\">{invoice.invoice}</TableCell>\n        <TableCell>{invoice.status}</TableCell>\n        <TableCell>{invoice.method}</TableCell>\n        <TableCell className=\"text-right\">{invoice.amount}</TableCell>\n      </TableRow>\n    ))}\n  </TableBody>\n</Table>\n\nTheming\n\nshadcn/ui uses CSS variables in HSL format. Configure in globals.css:\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 222.2 84% 4.9%;\n    --primary: 222.2 47.4% 11.2%;\n    --primary-foreground: 210 40% 98%;\n    --secondary: 210 40% 96.1%;\n    --muted: 210 40% 96.1%;\n    --muted-foreground: 215.4 16.3% 46.9%;\n    --destructive: 0 84.2% 60.2%;\n    --border: 214.3 31.8% 91.4%;\n    --ring: 222.2 84% 4.9%;\n    --radius: 0.5rem;\n  }\n\n  .dark {\n    --background: 222.2 84% 4.9%;\n    --foreground: 210 40% 98%;\n    --primary: 210 40% 98%;\n    --primary-foreground: 222.2 47.4% 11.2%;\n    /* ... mirror all variables for dark mode */\n  }\n}\n\n\nColors reference as hsl(var(--primary)) in Tailwind config. Change the CSS variables to retheme the entire app.\n\nCustomizing Components\n\nSince you own the code, modify components directly:\n\n// Add a custom variant to button.tsx\nconst buttonVariants = cva(\"...\", {\n  variants: {\n    variant: {\n      // ... existing variants\n      gradient: \"bg-gradient-to-r from-purple-500 to-pink-500 text-white\",\n    },\n    size: {\n      // ... existing sizes\n      xl: \"h-14 rounded-md px-10 text-lg\",\n    },\n  },\n})\n\nComponent Reference\nComponent\tInstall\tKey Props\nButton\tadd button\tvariant, size, asChild\nInput\tadd input\tStandard HTML input props\nForm\tadd form\tReact Hook Form + Zod integration\nCard\tadd card\tHeader, Content, Footer composition\nDialog\tadd dialog\tModal with trigger pattern\nSheet\tadd sheet\tSlide-over panel, side prop\nSelect\tadd select\tAccessible dropdown\nToast\tadd toast\tvariant: \"default\" | \"destructive\"\nTable\tadd table\tHeader, Body, Row, Cell composition\nTabs\tadd tabs\tdefaultValue, trigger/content pairs\nAccordion\tadd accordion\ttype: \"single\" | \"multiple\"\nCommand\tadd command\tCommand palette / search\nDropdown Menu\tadd dropdown-menu\tContext menus, action menus\nMenubar\tadd menubar\tApplication menus with shortcuts\nNext.js Integration\nApp Router Setup\n\nFor Next.js 13+ with App Router, ensure interactive components use \"use client\":\n\n// src/components/ui/button.tsx\n\"use client\"\n\nimport * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\n// ... rest of component\n\nLayout Integration\n\nAdd the Toaster to your root layout:\n\n// app/layout.tsx\nimport { Toaster } from \"@/components/ui/toaster\"\nimport \"./globals.css\"\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    <html lang=\"en\" suppressHydrationWarning>\n      <body className=\"min-h-screen bg-background font-sans antialiased\">\n        {children}\n        <Toaster />\n      </body>\n    </html>\n  )\n}\n\nServer Components\n\nMost shadcn/ui components need \"use client\". For Server Components, wrap them in a client component or use them in client component children.\n\nCLI Reference\nnpx shadcn@latest init              # Initialize project\nnpx shadcn@latest add [component]   # Add specific component\nnpx shadcn@latest add --all         # Add all components\nnpx shadcn@latest diff              # Show upstream changes\n\nBest Practices\nPractice\tDetails\nUse TypeScript\tAll components ship with full type definitions\nZod for validation\tPair with React Hook Form for type-safe forms\nasChild pattern\tUse Radix Slot to render as different elements\nServer Components\tMost shadcn/ui components need \"use client\"\nConsistent structure\tFollow the existing component patterns when customizing\nAccessibility\tRadix primitives handle ARIA; don't override without reason\nCSS variables\tTheme via variables, not by editing component classes\nTree-shaking\tOnly install components you need — they're independent\nNEVER Do\nNever\tWhy\tInstead\nInstall shadcn as npm package\tIt's not a package — it's source code you own\tUse CLI: npx shadcn@latest add\nOverride ARIA attributes\tRadix handles accessibility correctly\tTrust the primitives\nUse inline styles for theming\tDefeats the design system\tModify CSS variables\nCopy components from docs manually\tMay miss dependencies\tUse CLI for proper installation\nMix component styles\tCreates inconsistency\tFollow CVA variant pattern\nReferences\nLearning Guide — progression from basics to advanced patterns\nExtended Components — Terminal, Dock, Charts, animations, custom hooks\nOfficial Docs | Radix UI | React Hook Form | Zod"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wpank/shadcn",
    "publisherUrl": "https://clawhub.ai/wpank/shadcn",
    "owner": "wpank",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/shadcn",
    "downloadUrl": "https://openagent3.xyz/downloads/shadcn",
    "agentUrl": "https://openagent3.xyz/skills/shadcn/agent",
    "manifestUrl": "https://openagent3.xyz/skills/shadcn/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/shadcn/agent.md"
  }
}