Components
A styled, responsive table primitive with default and card variants. Ships Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell and TableCaption — semantic <table> elements with hover and selected row states, a horizontal-scroll container, and a rounded 'card' layout. Dependency-free (just cn). Compose it for project lists, invoices, inventory, API metrics, server usage, subscriptions or pricing comparisons.
Loading preview...
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/cnippet-table";
import type React from "react";
const badgeStyles: Record<string, string> = {
outline: "text-foreground",
secondary: "border-transparent bg-secondary text-secondary-foreground",
default: "border-transparent bg-primary text-primary-foreground",
success:
"border-transparent bg-emerald-500/15 text-emerald-600 dark:text-emerald-400",
warning:
"border-transparent bg-amber-500/15 text-amber-600 dark:text-amber-400",
destructive: "border-transparent bg-destructive/15 text-destructive",
info: "border-transparent bg-blue-500/15 text-blue-600 dark:text-blue-400",
};
function Badge({
variant = "outline",
className = "",
children,
}: {
variant?: string;
className?: string;
children?: React.ReactNode;
}): React.ReactElement {
return (
<span
className={`inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border px-2 py-0.5 font-medium text-xs [&_svg]:size-3 ${badgeStyles[variant] ?? ""} ${className}`}
>
{children}
</span>
);
}
export default function TableCardFrame() {
return (
<div className="w-full rounded-xl border bg-card p-1 shadow-sm">
<Table variant="card">
<TableHeader>
<TableRow>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead className="text-right">Budget</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-medium">Website Redesign</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-emerald-500"
/>
Paid
</Badge>
</TableCell>
<TableCell>Frontend Team</TableCell>
<TableCell className="text-right">$12,500</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">Mobile App</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-muted-foreground/64"
/>
Unpaid
</Badge>
</TableCell>
<TableCell>Mobile Team</TableCell>
<TableCell className="text-right">$8,750</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">API Integration</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-amber-500"
/>
Pending
</Badge>
</TableCell>
<TableCell>Backend Team</TableCell>
<TableCell className="text-right">$5,200</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">Database Migration</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-emerald-500"
/>
Paid
</Badge>
</TableCell>
<TableCell>DevOps Team</TableCell>
<TableCell className="text-right">$3,800</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">User Dashboard</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-emerald-500"
/>
Paid
</Badge>
</TableCell>
<TableCell>UX Team</TableCell>
<TableCell className="text-right">$7,200</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">Security Audit</TableCell>
<TableCell>
<Badge variant="outline">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-red-500"
/>
Failed
</Badge>
</TableCell>
<TableCell>Security Team</TableCell>
<TableCell className="text-right">$2,100</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={3}>Total Budget</TableCell>
<TableCell className="text-right">$39,550</TableCell>
</TableRow>
</TableFooter>
</Table>
</div>
);
}
Loading preview...
Loading preview...
Loading preview...
Loading preview...
Loading preview...
Loading preview...
Loading preview...
Loading preview...
Loading preview...