Display Components
Components for presenting information, data, and content.
Card
Container component for grouping related content.
Preview
Live Editor
function CardDemo() { return ( <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}> <div style={{ width: '300px', borderRadius: '12px', border: '1px solid #e2e8f0', background: 'white', overflow: 'hidden', boxShadow: '0 2px 8px rgba(0,0,0,0.04)', }}> <div style={{ padding: '20px 20px 12px' }}> <h3 style={{ margin: 0, fontSize: '18px', fontWeight: 600 }}>Project Overview</h3> <p style={{ margin: '4px 0 0', color: '#64748b', fontSize: '14px' }}> View and manage your active projects </p> </div> <div style={{ padding: '0 20px 20px' }}> <p style={{ margin: 0, fontSize: '14px', color: '#374151' }}> You have 3 active projects and 2 pending reviews. </p> </div> <div style={{ padding: '16px 20px', borderTop: '1px solid #f1f5f9', display: 'flex', gap: '8px', }}> <button style={{ padding: '8px 16px', borderRadius: '6px', background: 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)', color: 'white', border: 'none', cursor: 'pointer', fontWeight: 600, fontSize: '14px', }}> View Details </button> <button style={{ padding: '8px 16px', borderRadius: '6px', background: 'white', border: '1px solid #e2e8f0', cursor: 'pointer', fontWeight: 500, fontSize: '14px', }}> Cancel </button> </div> </div> </div> ); }
Result
Loading...
Usage
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@cpod/react";
import { Button } from "@cpod/react";
<Card>
<CardHeader>
<CardTitle>Project Overview</CardTitle>
<CardDescription>
View and manage your active projects
</CardDescription>
</CardHeader>
<CardContent>
<p>You have 3 active projects and 2 pending reviews.</p>
</CardContent>
<CardFooter>
<Button>View Details</Button>
<Button variant="outline">Cancel</Button>
</CardFooter>
</Card>
// Simple card
<Card className="p-6">
<p>Simple content card</p>
</Card>
// Interactive card
<Card className="hover:shadow-lg transition-shadow cursor-pointer">
<CardContent>
<p>Clickable card</p>
</CardContent>
</Card>
Sub-components
| Component | Description |
|---|---|
Card | Main container with border and shadow |
CardHeader | Header section with padding |
CardTitle | Title text (h3 by default) |
CardDescription | Subtitle/description text |
CardContent | Main content area |
CardFooter | Footer section for actions |
Badge
Small labels for status indicators, tags, and counts.
Preview
Live Editor
function BadgeDemo() { const badges = [ { label: 'Default', bg: '#8b5cf6', color: 'white' }, { label: 'Secondary', bg: '#f1f5f9', color: '#374151' }, { label: 'Destructive', bg: '#ef4444', color: 'white' }, { label: 'Outline', bg: 'white', color: '#374151', border: '1px solid #e2e8f0' }, { label: 'Success', bg: '#dcfce7', color: '#16a34a' }, { label: 'Warning', bg: '#fef3c7', color: '#ca8a04' }, { label: 'Info', bg: '#dbeafe', color: '#2563eb' }, ]; return ( <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}> {badges.map((badge) => ( <span key={badge.label} style={{ padding: '4px 10px', borderRadius: '9999px', background: badge.bg, color: badge.color, fontSize: '12px', fontWeight: 500, border: badge.border || 'none', }} > {badge.label} </span> ))} </div> ); }
Result
Loading...
Usage
import { Badge } from "@cpod/react";
// Basic badge
<Badge>New</Badge>
// Variants
<Badge variant="default">Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Error</Badge>
<Badge variant="outline">Outline</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="info">Info</Badge>
// In context
<div className="flex items-center gap-2">
<span>Status:</span>
<Badge variant="success">Active</Badge>
</div>
// With count
<Badge variant="secondary">3 new</Badge>
// In a button
<Button>
Messages <Badge className="ml-2">5</Badge>
</Button>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | default | secondary | destructive | outline | success | warning | info | default | Badge color |
className | string | - | Additional CSS classes |
Alert
Displays important messages and feedback.
Preview
Live Editor
function AlertDemo() { return ( <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxWidth: '500px' }}> <div style={{ padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0', background: '#f8fafc', }}> <div style={{ fontWeight: 600, marginBottom: '4px' }}>Heads up!</div> <div style={{ fontSize: '14px', color: '#64748b' }}> You can add components to your app using the CLI. </div> </div> <div style={{ padding: '16px', borderRadius: '8px', border: '1px solid rgba(239, 68, 68, 0.3)', background: '#fef2f2', }}> <div style={{ fontWeight: 600, marginBottom: '4px', color: '#ef4444' }}>Error</div> <div style={{ fontSize: '14px', color: '#ef4444' }}> Your session has expired. Please log in again. </div> </div> </div> ); }
Result
Loading...
Usage
import { Alert, AlertTitle, AlertDescription } from "@cpod/react";
// Default alert
<Alert>
<AlertTitle>Heads up!</AlertTitle>
<AlertDescription>
You can add components to your app using the CLI.
</AlertDescription>
</Alert>
// Destructive alert
<Alert variant="destructive">
<AlertTitle>Error</AlertTitle>
<AlertDescription>
Your session has expired. Please log in again.
</AlertDescription>
</Alert>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | default | destructive | default | Alert style |
Avatar
Displays user avatars with fallback support.
Preview
Live Editor
function AvatarDemo() { return ( <div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}> <div style={{ width: '40px', height: '40px', borderRadius: '50%', overflow: 'hidden', background: '#8b5cf6', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 600, }}> JD </div> <div style={{ width: '48px', height: '48px', borderRadius: '50%', overflow: 'hidden', background: '#06b6d4', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 600, }}> AB </div> <div style={{ width: '56px', height: '56px', borderRadius: '50%', overflow: 'hidden', background: '#22c55e', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontWeight: 600, fontSize: '18px', }}> CP </div> </div> ); }
Result
Loading...
Usage
import { Avatar, AvatarImage, AvatarFallback } from "@cpod/react";
// With image
<Avatar>
<AvatarImage src="/avatar.jpg" alt="@username" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
// Fallback only
<Avatar>
<AvatarFallback>CP</AvatarFallback>
</Avatar>
// Custom size
<Avatar className="h-16 w-16">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
Skeleton
Loading placeholder for content.
Preview
Live Editor
function SkeletonDemo() { return ( <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '350px' }}> <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}> <div style={{ width: '48px', height: '48px', borderRadius: '50%', background: 'linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%)', backgroundSize: '200% 100%', animation: 'shimmer 1.5s ease-in-out infinite', }} /> <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '8px' }}> <div style={{ height: '16px', width: '50%', borderRadius: '4px', background: 'linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%)', backgroundSize: '200% 100%', animation: 'shimmer 1.5s ease-in-out infinite', }} /> <div style={{ height: '12px', width: '80%', borderRadius: '4px', background: 'linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%)', backgroundSize: '200% 100%', animation: 'shimmer 1.5s ease-in-out infinite', }} /> </div> </div> <style>{` @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } `}</style> </div> ); }
Result
Loading...
Usage
import { Skeleton } from "@cpod/react";
// Basic skeleton
<Skeleton className="w-[100px] h-[20px]" />
// Card skeleton
<div className="flex items-center space-x-4">
<Skeleton className="h-12 w-12 rounded-full" />
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />
<Skeleton className="h-4 w-[200px]" />
</div>
</div>
// Custom styling
<Skeleton width="100%" height="200px" rounded />
Progress
Progress bar for loading states.
Preview
Live Editor
function ProgressDemo() { const [progress, setProgress] = React.useState(45); React.useEffect(() => { const timer = setInterval(() => { setProgress((prev) => (prev >= 100 ? 0 : prev + 5)); }, 500); return () => clearInterval(timer); }, []); return ( <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '400px' }}> <div> <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}> <span style={{ fontSize: '14px', fontWeight: 500 }}>Uploading...</span> <span style={{ fontSize: '14px', color: '#64748b' }}>{progress}%</span> </div> <div style={{ height: '8px', borderRadius: '4px', background: '#e2e8f0', overflow: 'hidden', }}> <div style={{ height: '100%', width: `${progress}%`, background: 'linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)', borderRadius: '4px', transition: 'width 0.3s ease', }} /> </div> </div> </div> ); }
Result
Loading...
Usage
import { Progress } from "@cpod/react";
// Basic progress
<Progress value={33} />
// Custom styling
<Progress value={60} className="h-2" indicatorClassName="bg-green-500" />
// Controlled
const [progress, setProgress] = useState(0);
<Progress value={progress} />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | 0 | Progress value (0-100) |
indicatorClassName | string | - | Custom indicator styles |
Table
Data table component.
Preview
Live Editor
function TableDemo() { const data = [ { id: 'INV-001', status: 'Paid', method: 'Credit Card', amount: '$250.00' }, { id: 'INV-002', status: 'Pending', method: 'PayPal', amount: '$150.00' }, { id: 'INV-003', status: 'Unpaid', method: 'Bank Transfer', amount: '$350.00' }, ]; return ( <div style={{ border: '1px solid #e2e8f0', borderRadius: '8px', overflow: 'hidden', fontSize: '14px', }}> <table style={{ width: '100%', borderCollapse: 'collapse' }}> <thead style={{ background: '#f8fafc' }}> <tr> <th style={{ padding: '12px 16px', textAlign: 'left', fontWeight: 600, fontSize: '12px', textTransform: 'uppercase', color: '#64748b' }}>Invoice</th> <th style={{ padding: '12px 16px', textAlign: 'left', fontWeight: 600, fontSize: '12px', textTransform: 'uppercase', color: '#64748b' }}>Status</th> <th style={{ padding: '12px 16px', textAlign: 'left', fontWeight: 600, fontSize: '12px', textTransform: 'uppercase', color: '#64748b' }}>Method</th> <th style={{ padding: '12px 16px', textAlign: 'right', fontWeight: 600, fontSize: '12px', textTransform: 'uppercase', color: '#64748b' }}>Amount</th> </tr> </thead> <tbody> {data.map((row, i) => ( <tr key={row.id} style={{ borderTop: '1px solid #e2e8f0' }}> <td style={{ padding: '12px 16px', fontWeight: 500 }}>{row.id}</td> <td style={{ padding: '12px 16px' }}> <span style={{ padding: '2px 8px', borderRadius: '9999px', fontSize: '12px', fontWeight: 500, background: row.status === 'Paid' ? '#dcfce7' : row.status === 'Pending' ? '#fef3c7' : '#fee2e2', color: row.status === 'Paid' ? '#16a34a' : row.status === 'Pending' ? '#ca8a04' : '#dc2626', }}> {row.status} </span> </td> <td style={{ padding: '12px 16px', color: '#64748b' }}>{row.method}</td> <td style={{ padding: '12px 16px', textAlign: 'right', fontWeight: 500 }}>{row.amount}</td> </tr> ))} </tbody> </table> </div> ); }
Result
Loading...
Usage
import {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
} from "@cpod/react";
<Table>
<TableCaption>A list of recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead>Method</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{invoices.map((invoice) => (
<TableRow key={invoice.id}>
<TableCell className="font-medium">{invoice.id}</TableCell>
<TableCell>{invoice.status}</TableCell>
<TableCell>{invoice.method}</TableCell>
<TableCell className="text-right">{invoice.amount}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
Tabs
Tab navigation component.
Preview
Live Editor
function TabsDemo() { const [activeTab, setActiveTab] = React.useState('account'); return ( <div style={{ maxWidth: '400px' }}> <div style={{ display: 'inline-flex', padding: '4px', background: '#f1f5f9', borderRadius: '8px', marginBottom: '16px', }}> {['account', 'password'].map((tab) => ( <button key={tab} onClick={() => setActiveTab(tab)} style={{ padding: '8px 16px', borderRadius: '6px', border: 'none', background: activeTab === tab ? 'white' : 'transparent', boxShadow: activeTab === tab ? '0 1px 3px rgba(0,0,0,0.1)' : 'none', cursor: 'pointer', fontWeight: 500, fontSize: '14px', textTransform: 'capitalize', }} > {tab} </button> ))} </div> <div style={{ padding: '16px', border: '1px solid #e2e8f0', borderRadius: '8px' }}> {activeTab === 'account' && ( <div> <h4 style={{ margin: 0, marginBottom: '8px' }}>Account</h4> <p style={{ margin: 0, color: '#64748b', fontSize: '14px' }}> Make changes to your account here. </p> </div> )} {activeTab === 'password' && ( <div> <h4 style={{ margin: 0, marginBottom: '8px' }}>Password</h4> <p style={{ margin: 0, color: '#64748b', fontSize: '14px' }}> Change your password here. </p> </div> )} </div> </div> ); }
Result
Loading...
Usage
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@cpod/react";
<Tabs defaultValue="account" className="w-[400px]">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<p>Make changes to your account here.</p>
</TabsContent>
<TabsContent value="password">
<p>Change your password here.</p>
</TabsContent>
</Tabs>
Breadcrumb
Navigation breadcrumb trail.
Preview
Live Editor
function BreadcrumbDemo() { const items = ['Home', 'Components', 'Breadcrumb']; return ( <nav> <ol style={{ display: 'flex', alignItems: 'center', gap: '8px', listStyle: 'none', margin: 0, padding: 0, fontSize: '14px', }}> {items.map((item, i) => ( <React.Fragment key={item}> <li> <a href="#" style={{ color: i === items.length - 1 ? '#1e293b' : '#64748b', textDecoration: 'none', fontWeight: i === items.length - 1 ? 500 : 400, }} > {item} </a> </li> {i < items.length - 1 && ( <li style={{ color: '#94a3b8' }}>/</li> )} </React.Fragment> ))} </ol> </nav> ); }
Result
Loading...
Usage
import {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
} from "@cpod/react";
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
ScrollArea
Custom scrollbar container.
Preview
Live Editor
function ScrollAreaDemo() { const items = Array.from({ length: 15 }, (_, i) => `Item ${i + 1}`); return ( <div style={{ height: '200px', width: '200px', border: '1px solid #e2e8f0', borderRadius: '8px', overflow: 'auto', }}> <div style={{ padding: '16px' }}> <h4 style={{ margin: 0, marginBottom: '16px', fontSize: '14px', fontWeight: 600 }}>Tags</h4> {items.map((item) => ( <div key={item} style={{ padding: '8px 0', borderBottom: '1px solid #f1f5f9', fontSize: '14px', }} > {item} </div> ))} </div> </div> ); }
Result
Loading...
Usage
import { ScrollArea, ScrollBar } from "@cpod/react";
<ScrollArea className="h-72 w-48 rounded-md border">
<div className="p-4">
<h4 className="mb-4 text-sm font-medium">Tags</h4>
{tags.map((tag) => (
<div key={tag} className="text-sm py-2">
{tag}
</div>
))}
</div>
</ScrollArea>
// Horizontal scroll
<ScrollArea className="w-96 whitespace-nowrap rounded-md border">
<div className="flex w-max space-x-4 p-4">
{items.map((item) => (
<div key={item} className="shrink-0">
{item}
</div>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>