Install
$ agentstack add skill-jh941213-codex-lattice-shadcn-ui ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
shadcn/ui Component Patterns
Expert guide for building accessible, customizable UI components with shadcn/ui, Radix UI, and Tailwind CSS.
Table of Contents
- [When to Use](#when-to-use)
- [Quick Start](#quick-start)
- [Installation & Setup](#installation--setup)
- [Project Configuration](#project-configuration)
- [Core Components](#core-components)
- [Button](#button-component)
- [Input & Form Fields](#input--form-fields)
- [Forms with Validation](#forms-with-validation)
- [Card](#card-component)
- [Dialog (Modal)](#dialog-modal-component)
- [Select (Dropdown)](#select-dropdown-component)
- [Sheet (Slide-over)](#sheet-slide-over-component)
- [Menubar & Navigation](#menubar--navigation)
- [Table](#table-component)
- [Toast Notifications](#toast-notifications)
- [Advanced Patterns](#advanced-patterns)
- [Customization](#customization)
- [Next.js Integration](#nextjs-integration)
- [Best Practices](#best-practices)
- [Common Component Combinations](#common-component-combinations)
When to Use
- Setting up a new project with shadcn/ui
- Installing or configuring individual components
- Building forms with React Hook Form and Zod validation
- Creating accessible UI components (buttons, dialogs, dropdowns, sheets)
- Customizing component styling with Tailwind CSS
- Implementing design systems with shadcn/ui
- Building Next.js applications with TypeScript
- Creating complex layouts and data displays
Quick Start
For new projects, use the automated setup:
# Create Next.js project with shadcn/ui
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
cd my-app
npx shadcn@latest init
# Install essential components
npx shadcn@latest add button input form card dialog select
For existing projects:
# Install dependencies
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
# Initialize shadcn/ui
npx shadcn@latest init
What is shadcn/ui?
shadcn/ui is not a traditional component library or npm package. Instead:
- It's a collection of reusable components that you can copy into your project
- Components are yours to customize - you own the code
- Built with Radix UI primitives for accessibility
- Styled with Tailwind CSS utilities
- Includes CLI tool for easy component installation
Installation & Setup
Initial Setup
# Initialize shadcn/ui in your project
npx shadcn@latest init
During setup, you'll configure:
- TypeScript or JavaScript
- Style (Default, New York, etc.)
- Base color theme
- CSS variables or Tailwind CSS classes
- Component installation path
Installing Individual Components
# Install a single component
npx shadcn@latest add button
# Install multiple components
npx shadcn@latest add button input form
# Install all components
npx shadcn@latest add --all
Manual Installation
If you prefer manual setup:
# Install dependencies for a specific component
npm install @radix-ui/react-slot
# Copy component code from ui.shadcn.com
# Place in src/components/ui/
Project Configuration
Required Dependencies
{
"dependencies": {
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"lucide-react": "^0.294.0",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7"
}
}
TSConfig Configuration
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"baseUrl": ".",
"paths": {
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Tailwind Configuration
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
'./pages/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
'./app/**/*.{ts,tsx}',
'./src/**/*.{ts,tsx}',
],
prefix: "",
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
}
CSS Variables (globals.css)
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
Core Components
Button Component
Installation:
npx shadcn@latest add button
Basic usage:
import { Button } from "@/components/ui/button";
export function ButtonDemo() {
return Click me;
}
Button variants:
import { Button } from "@/components/ui/button";
export function ButtonVariants() {
return (
Default
Destructive
Outline
Secondary
Ghost
Link
);
}
Button sizes:
Default
Small
Large
With loading state:
import { Button } from "@/components/ui/button";
import { Loader2 } from "lucide-react";
export function ButtonLoading() {
return (
Please wait
);
}
Input & Form Fields
Input Component
Installation:
npx shadcn@latest add input
Basic input:
import { Input } from "@/components/ui/input";
export function InputDemo() {
return ;
}
Input with label:
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
export function InputWithLabel() {
return (
Email
);
}
Input with button:
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
export function InputWithButton() {
return (
Subscribe
);
}
Forms with Validation
Installation:
npx shadcn@latest add form
This installs React Hook Form, Zod, and form components.
Complete form example:
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { toast } from "@/components/ui/use-toast"
const formSchema = z.object({
username: z.string().min(2, {
message: "Username must be at least 2 characters.",
}),
email: z.string().email({
message: "Please enter a valid email address.",
}),
})
export function ProfileForm() {
const form = useForm>({
resolver: zodResolver(formSchema),
defaultValues: {
username: "",
email: "",
},
})
function onSubmit(values: z.infer) {
toast({
title: "You submitted the following values:",
description: (
{JSON.stringify(values, null, 2)}
),
})
}
return (
(
Username
This is your public display name.
)}
/>
(
Email
)}
/>
Submit
)
}
Card Component
Installation:
npx shadcn@latest add card
Basic card:
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
export function CardDemo() {
return (
Card Title
Card Description
Card Content
Card Footer
)
}
Card with form:
import { Button } from "@/components/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export function CardWithForm() {
return (
Create project
Deploy your new project in one-click.
Name
Cancel
Deploy
)
}
Dialog (Modal) Component
Installation:
npx shadcn@latest add dialog
Basic dialog:
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
export function DialogDemo() {
return (
Open Dialog
Edit profile
Make changes to your profile here. Click save when you're done.
Name
Save changes
)
}
Sheet (Slide-over) Component
Installation:
npx shadcn@latest add sheet
Basic sheet:
import { Button } from "@/components/ui/button"
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
export function SheetDemo() {
return (
Open Sheet
Edit profile
Make changes to your profile here. Click save when you're done.
Name
Username
)
}
Sheet with side placement:
Open Right Sheet
Settings
Configure your application settings here.
{/* Settings content */}
Menubar & Navigation
Menubar Component
Installation:
npx shadcn@latest add menubar
Basic menubar:
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarShortcut,
MenubarSub,
MenubarSubContent,
MenubarSubTrigger,
MenubarTrigger,
} from "@/components/ui/menubar"
export function MenubarDemo() {
return (
File
New Tab ⌘T
New Window ⌘N
Share
Print
Edit
Undo ⌘Z
Redo ⌘Y
Find
Search the web
Find...
Find Next
Find Previous
)
}
Select (Dropdown) Component
Installation:
npx shadcn@latest add select
Basic select:
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export function SelectDemo() {
return (
Apple
Banana
Orange
)
}
Select in form:
(
Role
Admin
User
Guest
)}
/>
Toast Notifications
Installation:
npx shadcn@latest add toast
Setup toast provider in root layout:
import { Toaster } from "@/components/ui/toaster"
export default function RootLayout({ children }) {
return (
{children}
)
}
Using toast:
import { useToast } from "@/components/ui/use-toast"
import { Button } from "@/components/ui/button"
export function ToastDemo() {
const { toast } = useToast()
return (
{
toast({
title: "Scheduled: Catch up",
description: "Friday, February 10, 2023 at 5:57 PM
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [jh941213](https://github.com/jh941213)
- **Source:** [jh941213/codex-lattice](https://github.com/jh941213/codex-lattice)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.