Table
A semantic table with engraved hairline rules, an etched header strip, and tint-first hover rows.
@emboss/table
| Channel | Level | Status |
|---|---|---|
| Drum bus | −6.2 dB | Calibrated |
| Bass DI | −8.4 dB | Calibrated |
| Vox lead | −2.1 dB | Clipping |
Installation
pnpm dlx shadcn@latest add @emboss/tableUsage
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
export function Example() {
return (
<Table>
<TableHeader>
<TableRow>
<TableHead>Channel</TableHead>
<TableHead className="text-right">Level</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Drum bus</TableCell>
<TableCell className="text-right font-mono tabular-nums">
−6.2 dB
</TableCell>
</TableRow>
</TableBody>
</Table>
);
}API reference
Table / TableHeader / TableBody / TableFooter / TableRow / TableHead / TableCell / TableCaption
Semantic table parts; the container scrolls horizontally when columns overflow. Numeric columns should use font-mono tabular-nums.
| Data attribute | Description |
|---|---|
| data-selected | Set it on a TableRow to latch the row into the surface. |
Source
View source — table.tsxHide source — table.tsx
import { cn } from "@/lib/utils";
/**
* A semantic table with engraved hairline rules and a flush header strip.
* Numeric columns should use `font-mono tabular-nums` so values align.
*
* @example
* <Table>
* <TableHeader>
* <TableRow>
* <TableHead>Channel</TableHead>
* <TableHead className="text-right">Level</TableHead>
* </TableRow>
* </TableHeader>
* <TableBody>
* <TableRow>
* <TableCell>Drum bus</TableCell>
* <TableCell className="text-right font-mono tabular-nums">−6.2 dB</TableCell>
* </TableRow>
* </TableBody>
* </Table>
*/
function Table({ className, ...props }: React.ComponentProps<"table">) {
return (
<div
data-slot="table-container"
className="relative w-full overflow-x-auto rounded-md bg-surface-1 shadow-flush"
>
<table
data-slot="table"
className={cn(
"w-full caption-bottom border-collapse text-sm",
className,
)}
{...props}
/>
</div>
);
}
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
return (
<thead
data-slot="table-header"
className={cn("border-b border-edge-line", className)}
{...props}
/>
);
}
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
return (
<tbody
data-slot="table-body"
className={cn("divide-y divide-edge-line", className)}
{...props}
/>
);
}
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
return (
<tfoot
data-slot="table-footer"
className={cn(
"border-t border-edge-line bg-surface-2 font-medium",
className,
)}
{...props}
/>
);
}
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
return (
<tr
data-slot="table-row"
className={cn(
"transition-colors hover:bg-surface-2 data-selected:bg-well data-selected:shadow-deboss-1",
className,
)}
{...props}
/>
);
}
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
return (
<th
data-slot="table-head"
className={cn(
"tracking-label px-4 py-2.5 text-left align-middle font-mono text-label text-ink-faint uppercase text-engraved",
className,
)}
{...props}
/>
);
}
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
return (
<td
data-slot="table-cell"
className={cn("px-4 py-2.5 align-middle text-ink", className)}
{...props}
/>
);
}
function TableCaption({
className,
...props
}: React.ComponentProps<"caption">) {
return (
<caption
data-slot="table-caption"
className={cn("mt-3 text-sm text-ink-muted", className)}
{...props}
/>
);
}
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableRow,
TableHead,
TableCell,
TableCaption,
};