Table

A structured table for dashboards, billing, and admin surfaces.

Loading preview...

Examples

Practical examples and common states for the same installable component.

Sortable

Click column headers to sort ascending or descending.

examples/table-sortable.tsx
"use client";
import * as React from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/wensity/table";
export function SortableTable() {
const [direction, setDirection] = React.useState<"asc" | "desc">("asc");
return (
<Table>
<TableHeader>
<TableRow>
<TableHead
sortable
sortDirection={direction}
onSort={() => setDirection((d) => (d === "asc" ? "desc" : "asc"))}
>
Customer
</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>Northwind Labs</TableCell>
<TableCell>Paid</TableCell>
</TableRow>
</TableBody>
</Table>
);
}

Selectable

Checkbox column with selected row styling.

examples/table-selectable.tsx
"use client";
import * as React from "react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
TableSelectCell,
} from "@/components/wensity/table";
export function SelectableTable() {
const [selected, setSelected] = React.useState<string[]>([]);
return (
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-10" />
<TableHead>Customer</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow selected={selected.includes("northwind")}>
<TableSelectCell
checked={selected.includes("northwind")}
onCheckedChange={(checked) =>
setSelected(checked ? ["northwind"] : [])
}
/>
<TableCell>Northwind Labs</TableCell>
</TableRow>
</TableBody>
</Table>
);
}

Expandable

Reveal row details with a smooth height transition.

examples/table-expandable.tsx
"use client";
import * as React from "react";
import {
Table,
TableBody,
TableCell,
TableExpandableContent,
TableExpandTriggerCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/wensity/table";
export function ExpandableTable() {
const [open, setOpen] = React.useState(true);
return (
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-10" />
<TableHead>Customer</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow expanded={open}>
<TableExpandTriggerCell expanded={open} onToggle={() => setOpen((v) => !v)} />
<TableCell>Northwind Labs</TableCell>
</TableRow>
<TableExpandableContent open={open} colSpan={2}>
Receipt sent to billing@northwind.dev.
</TableExpandableContent>
</TableBody>
</Table>
);
}

Sticky Header

Keep column labels visible while scrolling long tables.

examples/table-sticky-header.tsx
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/wensity/table";
export function StickyHeaderTable() {
return (
<Table stickyHeader className="max-h-56">
<TableHeader>
<TableRow>
<TableHead>Customer</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{/* long list of rows */}
</TableBody>
</Table>
);
}