Data Table
PreviewTables purposefully designed for dynamic, application data with features like sorting, filtering, and pagination. Powered by TanStack Table.
import {
DataTable,
DataTableActionCell,
DataTableBody,
DataTableEmptyRow,
DataTableHead,
DataTableHeader,
DataTableHeaderSortButton,
DataTableRows,
createColumnHelper,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@ngrok/mantle/data-table";
type Payment = {
id: string;
amount: number;
status: "pending" | "processing" | "success" | "failed";
email: string;
};
const columnHelper = createColumnHelper<Payment>();
const columns = [
columnHelper.accessor("id", {
id: "id",
header: (props) => (
<DataTableHeader>
<DataTableHeaderSortButton
column={props.column}
sortingMode="alphanumeric"
>
ID
</DataTableHeaderSortButton>
</DataTableHeader>
),
cell: (props) => (
<TableCell key={props.cell.id}>{props.getValue()}</TableCell>
),
}),
columnHelper.accessor("amount", {
id: "amount",
header: (props) => (
<DataTableHeader className="w-[200px]">
<DataTableHeaderSortButton
className="justify-end"
column={props.column}
iconPlacement="start"
sortingMode="alphanumeric"
>
Amount
</DataTableHeaderSortButton>
</DataTableHeader>
),
cell: (props) => (
<TableCell key={props.cell.id} className="text-right">
{props.getValue()}
</TableCell>
),
}),
columnHelper.accessor("status", {
id: "status",
header: (props) => (
<DataTableHeader>
<DataTableHeaderSortButton
column={props.column}
sortingMode="alphanumeric"
>
Status
</DataTableHeaderSortButton>
</DataTableHeader>
),
cell: (props) => (
<TableCell key={props.cell.id}>{props.getValue()}</TableCell>
),
}),
columnHelper.accessor("email", {
id: "email",
header: (props) => (
<DataTableHeader>
<DataTableHeaderSortButton
column={props.column}
sortingMode="alphanumeric"
>
Email
</DataTableHeaderSortButton>
</DataTableHeader>
),
cell: (props) => (
<TableCell key={props.cell.id}>{props.getValue()}</TableCell>
),
}),
columnHelper.display({
id: "actions",
header: () => <DataTableHeader />,
cell: () => (
<DataTableActionCell>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<IconButton
appearance="outlined"
className="max-w rounded"
type="button"
size="sm"
label="Open actions"
icon={<DotsThree weight="bold" />}
/>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem className="flex items-center gap-2">
<Icon svg={<PencilSimple />} /> Edit
</DropdownMenuItem>
<DropdownMenuItem className="text-danger-600 flex items-center gap-2">
<Icon svg={<TrashSimple />} />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</DataTableActionCell>
),
}),
];
function PaymentsExample() {
const data = useMemo(() => examplePayments, []);
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
initialState: {
pagination: {
pageSize: 100,
},
},
});
return (
<DataTable table={table}>
<DataTableHead />
<DataTableBody>
{table.getRowModel().rows.length > 0 ? (
<DataTableRows />
) : (
<DataTableEmptyRow>
<p className="flex items-center justify-center min-h-20">
No results.
</p>
</DataTableEmptyRow>
)}
</DataTableBody>
</DataTable>
);
}
API Reference
The DataTable
accepts the following props in addition to...