Display
Table.
A plain, responsive table with mono uppercase column heads, hover rows, a footer and a caption. Scrolls sideways on narrow screens.
| Site | Owner | Server | Status |
|---|---|---|---|
| turtle.farm | Mika | Hearth SMP | Online |
| guestbook.hub | Oren | Hearth SMP | Online |
| mine.logs | Juno | Deepstone | Busy |
| rail.map | Pip | Deepstone | Offline |
import { Badge } from "@/components/ui/badge";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
const sites = [
{ name: "turtle.farm", owner: "Mika", server: "Hearth SMP", status: "online" },
{ name: "guestbook.hub", owner: "Oren", server: "Hearth SMP", status: "online" },
{ name: "mine.logs", owner: "Juno", server: "Deepstone", status: "busy" },
{ name: "rail.map", owner: "Pip", server: "Deepstone", status: "offline" },
] as const;
const statusBadge = {
online: <Badge variant="success">Online</Badge>,
busy: <Badge variant="warning">Busy</Badge>,
offline: <Badge variant="outline">Offline</Badge>,
};
export default function TableDemo() {
return (
<Table>
<TableCaption>Sites listed on the Lantern directory</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Site</TableHead>
<TableHead>Owner</TableHead>
<TableHead>Server</TableHead>
<TableHead className="text-right">Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{sites.map((site) => (
<TableRow key={site.name}>
<TableCell className="font-mono text-[13px] text-primary">{site.name}</TableCell>
<TableCell>{site.owner}</TableCell>
<TableCell className="text-muted-foreground">{site.server}</TableCell>
<TableCell className="text-right">{statusBadge[site.status]}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
}Installation#
With the CLI
$npx lanterncn add tableThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/table. See Installation if your project is not set up yet.
Manually
Copy the source into your project
components/ui/table.tsximport * as React from "react"; import { cn } from "@/lib/utils"; function Table({ className, ...props }: React.ComponentProps<"table">) { return ( <div data-slot="table-container" className="relative w-full overflow-x-auto"> <table data-slot="table" className={cn("w-full caption-bottom text-sm", className)} {...props} /> </div> ); } function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />; } function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { return <tbody data-slot="table-body" className={cn("[&_tr:last-child]:border-0", className)} {...props} />; } function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { return ( <tfoot data-slot="table-footer" className={cn("border-t bg-secondary/60 font-medium [&>tr]:last:border-b-0", className)} {...props} /> ); } function TableRow({ className, ...props }: React.ComponentProps<"tr">) { return ( <tr data-slot="table-row" className={cn("border-b transition-colors hover:bg-secondary/50 data-[state=selected]:bg-accent", className)} {...props} /> ); } function TableHead({ className, ...props }: React.ComponentProps<"th">) { return ( <th data-slot="table-head" className={cn( "h-10 px-3 text-left align-middle font-mono text-[10px] font-semibold tracking-[0.2em] whitespace-nowrap text-muted-foreground uppercase [&:has([role=checkbox])]:pr-0", className, )} {...props} /> ); } function TableCell({ className, ...props }: React.ComponentProps<"td">) { return ( <td data-slot="table-cell" className={cn("p-3 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)} {...props} /> ); } function TableCaption({ className, ...props }: React.ComponentProps<"caption">) { return ( <caption data-slot="table-caption" className={cn("mt-4 font-mono text-[10px] tracking-[0.2em] text-muted-foreground uppercase", className)} {...props} /> ); } export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
} from "@/components/ui/table";<Table>
<TableHeader>
<TableRow>
<TableHead>Site</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>turtle.farm</TableCell>
</TableRow>
</TableBody>
</Table>Examples#
Compact data with a footer total
| Turtle | Job | Blocks | Fuel |
|---|---|---|---|
| T-01 | Strip mine | 4,120 | 812 |
| T-02 | Tree farm | 1,386 | 240 |
| T-03 | Wheat harvest | 962 | 95 |
| T-04 | Tunnel | 2,048 | 1530 |
| Total | 8,516 | ||
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
const turtles = [
{ id: "T-01", job: "Strip mine", blocks: 4120, fuel: 812 },
{ id: "T-02", job: "Tree farm", blocks: 1386, fuel: 240 },
{ id: "T-03", job: "Wheat harvest", blocks: 962, fuel: 95 },
{ id: "T-04", job: "Tunnel", blocks: 2048, fuel: 1530 },
];
const total = turtles.reduce((sum, t) => sum + t.blocks, 0);
export default function TableCompact() {
return (
<Table className="text-[13px]">
<TableHeader>
<TableRow>
<TableHead className="h-8 px-2">Turtle</TableHead>
<TableHead className="h-8 px-2">Job</TableHead>
<TableHead className="h-8 px-2 text-right">Blocks</TableHead>
<TableHead className="h-8 px-2 text-right">Fuel</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{turtles.map((t) => (
<TableRow key={t.id}>
<TableCell className="px-2 py-1.5 font-mono">{t.id}</TableCell>
<TableCell className="px-2 py-1.5">{t.job}</TableCell>
<TableCell className="px-2 py-1.5 text-right font-mono tabular-nums">{t.blocks.toLocaleString("en-US")}</TableCell>
<TableCell className="px-2 py-1.5 text-right font-mono tabular-nums text-muted-foreground">{t.fuel}</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={2} className="px-2 py-2 font-mono text-[10px] tracking-[0.2em] uppercase">
Total
</TableCell>
<TableCell className="px-2 py-2 text-right font-mono text-primary tabular-nums">{total.toLocaleString("en-US")}</TableCell>
<TableCell className="px-2 py-2" />
</TableRow>
</TableFooter>
</Table>
);
}