shadcn/ui Integration¶
Navigation: Home → Features & Components → shadcn/ui Integration
Table of Contents¶
- Introduction
- Configuration
- Style System
- Component Catalog
- Customization
- Theme Integration
- Best Practices
- Component Usage Examples
- See Also
- Next Steps
Introduction¶
This project uses shadcn/ui, a collection of re-usable components built with Radix UI and Tailwind CSS. Unlike traditional component libraries, shadcn/ui components are copied directly into your project, giving you full ownership and customization control.
Why shadcn/ui?¶
- ✅ Full Control: Components live in your codebase
- ✅ TypeScript First: Strongly typed components
- ✅ Accessible: Built on Radix UI primitives
- ✅ Customizable: Modify any component as needed
- ✅ Modern: Uses latest React patterns (Server Components, Suspense)
- ✅ Framework Agnostic: Works with Next.js, Remix, Vite, etc.
Configuration¶
components.json¶
The project configuration defines the shadcn/ui setup:
```json:1:21:components.json { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": true, "tsx": true, "tailwind": { "config": "tailwind.config.ts", "css": "app/globals.css", "baseColor": "slate", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "iconLibrary": "lucide" }
### Key Configuration Options
| Option | Value | Description |
| -------------- | ------------ | --------------------------------------------------------------------- |
| `style` | `"new-york"` | Component style variant (alternatives: `default`) |
| `rsc` | `true` | React Server Components support |
| `baseColor` | `"slate"` | Base color palette (alternatives: `gray`, `zinc`, `neutral`, `stone`) |
| `cssVariables` | `true` | Use CSS variables for theming |
| `iconLibrary` | `"lucide"` | Icon library for components |
### Installing Components
Add new shadcn/ui components using the CLI:
```bash
# Install a single component
npx shadcn@latest add button
# Install multiple components
npx shadcn@latest add card dialog table
# Install all components (not recommended)
npx shadcn@latest add --all
Components are added to components/ui/ directory.
Style System¶
New York Style¶
The New York style variant provides:
- Rounded corners with subtle shadows
- Refined spacing and padding
- Modern, professional aesthetic
- Optimized for dashboard and portfolio layouts
Slate Color Scheme¶
The Slate base color provides neutral gray tones that:
- Work well with both light and dark themes
- Provide excellent contrast ratios for accessibility
- Pair nicely with accent colors
- Create a professional, polished look
CSS Variables¶
Theme colors are defined as CSS variables in app/globals.css:
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-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%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
/* ... more variables */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark theme variables */
}
}
This approach enables seamless theme switching without component modifications.
Component Catalog¶
Installed Components¶
The project includes these shadcn/ui components:
Layout & Structure¶
| Component | File | Purpose | Documentation |
|---|---|---|---|
| Card | ui/card.tsx |
Content containers with header/footer | Docs |
| Separator | ui/separator.tsx |
Visual dividers | Docs |
| Tabs | ui/tabs.tsx |
Tabbed interfaces | Docs |
Interactive Elements¶
| Component | File | Purpose | Documentation |
|---|---|---|---|
| Button | ui/button.tsx |
Buttons with variants | Docs |
| Dialog | ui/dialog.tsx |
Modal dialogs | Docs |
| Sheet | ui/sheet.tsx |
Side panels (mobile menu) | Docs |
| Dropdown Menu | ui/dropdown-menu.tsx |
Dropdown menus | Docs |
| Tooltip | ui/tooltip.tsx |
Hover tooltips | Docs |
Forms & Input¶
| Component | File | Purpose | Documentation |
|---|---|---|---|
| Input | ui/input.tsx |
Text input fields | Docs |
Data Display¶
| Component | File | Purpose | Documentation |
|---|---|---|---|
| Table | ui/table.tsx |
Data tables | Docs |
| Badge | ui/badge.tsx |
Tag badges | Docs |
| Carousel | ui/carousel.tsx |
Image carousels (Embla) | Docs |
Navigation¶
| Component | File | Purpose | Documentation |
|---|---|---|---|
| Navigation Menu | ui/navigation-menu.tsx |
Complex navigation menus | Docs |
Customization¶
Modifying Components¶
Since components live in your codebase, you can customize them directly:
// components/ui/button.tsx - Add custom variants
const buttonVariants = cva("inline-flex items-center justify-center...", {
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
// Add custom variant
gradient: "bg-gradient-to-r from-purple-500 to-pink-500 text-white",
},
// ... other variants
},
});
Adding Custom Styles¶
Extend component styles using className prop:
<Button
variant="secondary"
className="custom-gradient shadow-xl hover:scale-105 transition-transform"
>
Enhanced Button
</Button>
Creating Composed Components¶
Build higher-level components from shadcn/ui primitives:
// components/project-card.tsx
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
export default function ProjectCard({ project }) {
return (
<Card>
<CardHeader>
<CardTitle>{project.title}</CardTitle>
</CardHeader>
<CardContent>
{project.technologies.map(tech => (
<Badge key={tech} variant="secondary">{tech}</Badge>
))}
</CardContent>
</Card>
);
}
Theme Integration¶
Dark Mode Support¶
All shadcn/ui components automatically support dark mode through CSS variables:
The ThemeProvider from next-themes manages theme state:
// app/layout.tsx
import { ThemeProvider } from "next-themes";
export default function RootLayout({ children }) {
return (
<html suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
See: Theme System for complete theme documentation
Best Practices¶
Import Patterns¶
// ✅ Import multiple components from same file
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
// ✅ Use absolute imports
import { Button } from "@/components/ui/button";
// ❌ Avoid relative imports
import { Button } from "../../components/ui/button";
Component Composition¶
// ✅ Compose components logically
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
Content here
</CardContent>
</Card>
// ❌ Don't skip semantic structure
<Card>
<div>Title</div>
<div>Content</div>
</Card>
Accessibility¶
// ✅ Include proper ARIA labels
<Button
variant="ghost"
size="icon"
aria-label="Close menu"
>
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</Button>
// ✅ Use semantic variants
<Badge variant="destructive">Error</Badge>
<Badge variant="success">Success</Badge>
Performance¶
// ✅ Use server components when possible
export default function ProjectList({ projects }) {
return (
<div>
{projects.map(project => (
<ProjectCard key={project.slug} project={project} />
))}
</div>
);
}
// ⚠️ Only use "use client" when necessary
"use client";
import { useState } from "react";
Component Usage Examples¶
Button Variants¶
import { Button } from "@/components/ui/button";
<Button variant="default">Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
<Button variant="destructive">Destructive</Button>
// With sizes
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon">🔔</Button>
Card Structure¶
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter
} from "@/components/ui/card";
<Card>
<CardHeader>
<CardTitle>Project Title</CardTitle>
<CardDescription>A brief description</CardDescription>
</CardHeader>
<CardContent>
<p>Main content goes here</p>
</CardContent>
<CardFooter>
<Button>View Details</Button>
</CardFooter>
</Card>
Dialog Pattern¶
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter
} from "@/components/ui/dialog";
<Dialog>
<DialogTrigger asChild>
<Button>Open Modal</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
Description text here
</DialogDescription>
</DialogHeader>
<div>Modal content</div>
<DialogFooter>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
Dropdown Menu¶
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuLabel
} from "@/components/ui/dropdown-menu";
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Options</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
Table Structure¶
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from "@/components/ui/table";
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Project A</TableCell>
<TableCell>Active</TableCell>
</TableRow>
</TableBody>
</Table>
See Also¶
- Components Overview - Component architecture
- Theme System - Dark mode implementation
- Styling Guide - Tailwind CSS patterns
- Official shadcn/ui Docs - Complete component reference
Next Steps¶
- Browse Examples: Review component usage in
components/directory - Add Components: Install additional shadcn/ui components as needed
- Customize Themes: Modify CSS variables in
app/globals.css - Build Composed Components: Create domain-specific components using UI primitives
Last Updated: 2024-02-09
Related Docs: Components | Theming | Architecture