Components
A generic, accessible data table whose rows animate into place when you sort a column, with an optional follow toggle that keeps one row marked across reorders.

"use client";
import { SortableTable } from "@/components/ui/sortable-table";
type Deploy = {
id: string;
service: string;
duration: number;
status: string;
rank: number;
};
const DEPLOYS: Deploy[] = [
{
id: "d1",
service: "checkout-api",
duration: 184,
status: "passed",
rank: 0,
},
{ id: "d2", service: "web", duration: 62, status: "failed", rank: 2 },
{
id: "d3",
service: "search-index",
duration: 431,
status: "passed",
rank: 0,
},
];
export default function DeployTableDemo() {
return (
<div className="mx-auto w-full max-w-md p-6">
<SortableTable
label="Recent deploys"
rows={DEPLOYS}
getRowId={(d) => d.id}
getRowLabel={(d) => d.service}
defaultSort={{ columnId: "duration", direction: "desc" }}
markable
maxHeight={320}
columns={[
{ id: "service", header: "Service", value: (d) => d.service },
{
id: "duration",
header: "Build",
width: "88px",
align: "end",
numeric: true,
value: (d) => d.duration,
cell: (d) => `${d.duration}s`,
},
{
id: "status",
header: "Status",
width: "92px",
align: "end",
value: (d) => d.rank,
cell: (d) => d.status,
},
]}
/>
</div>
);
}
Part of interior.dev — browse the full library on 21st.dev.