Legacy (shadcn-uikit)Components
DataTable
A feature-rich table with sorting, filtering, and pagination.
Usage
import { DataTable } from '@acronis-platform/shadcn-uikit';Full example
A complete data table with column sorting, filtering, pagination, and row selection.
success | ken99@yahoo.com | $316.00 | 1/15/2024 | ||
success | Abe45@gmail.com | $242.00 | 1/14/2024 | ||
processing | Monserrat44@gmail.com | $837.00 | 1/13/2024 | ||
success | Silas22@gmail.com | $874.00 | 1/12/2024 | ||
failed | carmella@hotmail.com | $721.00 | 1/11/2024 | ||
pending | john.doe@example.com | $456.00 | 1/10/2024 | ||
success | sarah.smith@company.com | $923.00 | 1/9/2024 | ||
processing | mike.jones@email.com | $189.00 | 1/8/2024 | ||
success | lisa.brown@test.com | $634.00 | 1/7/2024 | ||
failed | david.wilson@mail.com | $512.00 | 1/6/2024 |
0 of 15 row(s) selected.
Rows per page
Page 1 of 2
View sourceHide source
import {
ColumnDef,
useReactTable,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
getFilteredRowModel,
flexRender,
} from '@tanstack/react-table';
import { useState } from 'react';
import { Button } from '@acronis-platform/shadcn-uikit/react';
import { Checkbox } from '@acronis-platform/shadcn-uikit/react';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@acronis-platform/shadcn-uikit/react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@acronis-platform/shadcn-uikit/react';
import { Badge } from '@acronis-platform/shadcn-uikit/react';
import {
DataTableColumnHeader,
DataTablePagination,
DataTableToolbar,
} from '@acronis-platform/shadcn-uikit/react';
import { EllipsisHIcon } from '@acronis-platform/shadcn-uikit';
export type Payment = {
id: string;
amount: number;
status: 'pending' | 'processing' | 'success' | 'failed';
email: string;
date: string;
};
const data: Payment[] = [
{
id: 'm5gr84i9',
amount: 316,
status: 'success',
email: 'ken99@yahoo.com',
date: '2024-01-15',
},
{
id: '3u1reuv4',
amount: 242,
status: 'success',
email: 'Abe45@gmail.com',
date: '2024-01-14',
},
{
id: 'derv1ws0',
amount: 837,
status: 'processing',
email: 'Monserrat44@gmail.com',
date: '2024-01-13',
},
{
id: '5kma53ae',
amount: 874,
status: 'success',
email: 'Silas22@gmail.com',
date: '2024-01-12',
},
{
id: 'bhqecj4p',
amount: 721,
status: 'failed',
email: 'carmella@hotmail.com',
date: '2024-01-11',
},
{
id: 'xk3j9d2s',
amount: 456,
status: 'pending',
email: 'john.doe@example.com',
date: '2024-01-10',
},
{
id: 'p9m2k1l3',
amount: 923,
status: 'success',
email: 'sarah.smith@company.com',
date: '2024-01-09',
},
{
id: 'q4w5e6r7',
amount: 189,
status: 'processing',
email: 'mike.jones@email.com',
date: '2024-01-08',
},
{
id: 't8y9u0i1',
amount: 634,
status: 'success',
email: 'lisa.brown@test.com',
date: '2024-01-07',
},
{
id: 'a2s3d4f5',
amount: 512,
status: 'failed',
email: 'david.wilson@mail.com',
date: '2024-01-06',
},
{
id: 'g6h7j8k9',
amount: 298,
status: 'pending',
email: 'emma.davis@inbox.com',
date: '2024-01-05',
},
{
id: 'l0z1x2c3',
amount: 745,
status: 'success',
email: 'robert.taylor@domain.com',
date: '2024-01-04',
},
{
id: 'v4b5n6m7',
amount: 421,
status: 'processing',
email: 'jennifer.anderson@web.com',
date: '2024-01-03',
},
{
id: 'q8w9e0r1',
amount: 867,
status: 'success',
email: 'william.thomas@site.com',
date: '2024-01-02',
},
{
id: 't2y3u4i5',
amount: 156,
status: 'failed',
email: 'olivia.jackson@email.net',
date: '2024-01-01',
},
];
const columns: ColumnDef<Payment>[] = [
{
id: 'select',
header: ({ table }) => (
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() ? 'indeterminate' : false)
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: 'status',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Status" />
),
cell: ({ row }) => {
const status = row.getValue('status') as string;
const variant =
status === 'success'
? 'default'
: status === 'processing'
? 'secondary'
: status === 'pending'
? 'outline'
: 'destructive';
return (
<Badge variant={variant} className="capitalize">
{status}
</Badge>
);
},
},
{
accessorKey: 'email',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Email" />
),
},
{
accessorKey: 'amount',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Amount" />
),
cell: ({ row }) => {
const amount = parseFloat(row.getValue('amount'));
const formatted = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(amount);
return <div className="font-medium">{formatted}</div>;
},
},
{
accessorKey: 'date',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Date" />
),
cell: ({ row }) => {
const date = new Date(row.getValue('date'));
return <div>{date.toLocaleDateString()}</div>;
},
},
{
id: 'actions',
cell: ({ row }) => {
const payment = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger
render={<Button variant="ghost" className="h-8 w-8 p-0" />}
>
<span className="sr-only">Open menu</span>
<EllipsisHIcon className="h-4 w-4" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => navigator.clipboard.writeText(payment.id)}
>
Copy payment ID
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>View customer</DropdownMenuItem>
<DropdownMenuItem>View payment details</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
export function DataTableFull() {
const [tableData] = useState<Payment[]>(data);
const [sorting, setSorting] = useState<any[]>([]);
const [columnFilters, setColumnFilters] = useState<any[]>([]);
const [columnVisibility, setColumnVisibility] = useState({});
const [rowSelection, setRowSelection] = useState({});
const table = useReactTable({
data: tableData,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
return (
<div className="space-y-4">
<DataTableToolbar
table={table}
searchKey="email"
searchPlaceholder="Filter emails..."
/>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<DataTablePagination table={table} />
</div>
);
}
API Reference
DataTable
Prop
Type
The DataTable component is built on @tanstack/react-table and provides sorting, filtering, pagination, and row selection out of the box.