Card.tsx
Compound card component for displaying content in a structured layout
The Card component is a compound component system for creating structured content containers with header, content, and footer sections.
Features
- Compound component pattern
- Flexible layout with grid-based header
- Optional action slot in header
- Consistent spacing and styling
- Fully customizable with className
Basic Usage
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/Card';
export default function Page() {
return (
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description goes here</CardDescription>
</CardHeader>
<CardContent>
<p>Card content</p>
</CardContent>
</Card>
);
}With Footer
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
<Card>
<CardHeader>
<CardTitle>Confirm Action</CardTitle>
</CardHeader>
<CardContent>
<p>Are you sure you want to proceed?</p>
</CardContent>
<CardFooter>
<Button variant="outline">Cancel</Button>
<Button>Confirm</Button>
</CardFooter>
</Card>With Action Button
The CardAction component positions an element in the top-right corner:
import { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { MoreVertical } from 'lucide-react';
<Card>
<CardHeader>
<CardTitle>Settings</CardTitle>
<CardDescription>Manage your preferences</CardDescription>
<CardAction>
<Button variant="ghost" size="icon">
<MoreVertical className="h-4 w-4" />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<p>Settings content</p>
</CardContent>
</Card>Custom Styling
<Card className="border-brand">
<CardHeader className="bg-brand/10">
<CardTitle className="text-brand">Custom Styled Card</CardTitle>
</CardHeader>
<CardContent>
<p>Content with custom styling</p>
</CardContent>
</Card>Grid Layout
Cards work well in grid layouts:
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<Card>
<CardHeader>
<CardTitle>Card 1</CardTitle>
</CardHeader>
<CardContent>Content 1</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Card 2</CardTitle>
</CardHeader>
<CardContent>Content 2</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Card 3</CardTitle>
</CardHeader>
<CardContent>Content 3</CardContent>
</Card>
</div>Implementation
The Card uses a compound component pattern:
function Card({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
className={cn(
'bg-neutral/40 text-foreground flex flex-col gap-6 rounded-md border border-neutral py-6 shadow-sm',
className
)}
{...props}
/>
);
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
className={cn(
'grid auto-rows-min items-start gap-1.5 px-6',
className
)}
{...props}
/>
);
}Components
Card
Main container with background, border, and shadow.
CardHeader
Header section with grid layout. Automatically adjusts when CardAction is present.
CardTitle
Title text with semibold font weight.
CardDescription
Muted description text below the title.
CardAction
Action button positioned in top-right corner of header.
CardContent
Main content area with horizontal padding.
CardFooter
Footer section for actions or additional info.
Data Slots
Components use data-slot attributes for styling hooks:
data-slot="card"data-slot="card-header"data-slot="card-title"data-slot="card-description"data-slot="card-action"data-slot="card-content"data-slot="card-footer"
How is this guide ?
Last updated on