Modern SaaS data table with TanStack Table, inset-card layout, selection, sorting, search, pagination, and expandable rows.
| Status | Confidence | Assignee | |
|---|---|---|---|
| Researcher | Running | 94% | |
| Proposal Drafter | Idle | 87% | |
| Data Extractor | Error | 61 | AG |
| UX Reviewer | Running | 91% | |
| Composer | Running | 88% | |
| Code Reviewer | Scheduled | 96% |
SHOWING: 6 of 35 items
pnpm dlx shadcn@latest add https://matos-ui.com/r/data-table.jsonimport type { ColumnDef } from "@tanstack/react-table"
import {
DataTable,
DataTableBadge,
DataTableColumnHeader
} from "@/components/matos-ui/data-table"
import { BriefcaseBusiness, Building2, Hash, Mail } from "lucide-react"type Employee = {
id: string
department: "Finance" | "HR" | "Marketing" | "Sales" | "Engineering"
email: string
employment: "Active" | "Inactive"
firstName: string
lastName: string
}
const columns: ColumnDef<Employee>[] = [
{
accessorKey: "id",
header: ({ column }) => (
<DataTableColumnHeader
column={column}
title="ID"
icon={<Hash aria-hidden="true" />}
/>
)
},
{
accessorKey: "department",
header: ({ column }) => (
<DataTableColumnHeader
column={column}
title="Department"
icon={<Building2 aria-hidden="true" />}
/>
),
cell: ({ row }) => (
<DataTableBadge tone="engineering">
{row.getValue("department")}
</DataTableBadge>
)
},
{
accessorKey: "email",
header: ({ column }) => (
<DataTableColumnHeader
column={column}
title="Email"
icon={<Mail aria-hidden="true" />}
/>
)
},
{
accessorKey: "employment",
header: ({ column }) => (
<DataTableColumnHeader
column={column}
title="Employment"
icon={<BriefcaseBusiness aria-hidden="true" />}
/>
)
}
]<DataTable
data={employees}
columns={columns}
/>| Prop | Type | Default | Description |
|---|---|---|---|
data | TData[] | - | Records rendered by TanStack Table. |
columns | ColumnDef<TData, TValue>[] | - | Column definitions passed to TanStack Table. |
title | string? | - | Loose header title. |
description | string? | - | Loose header description. |
searchKey | string? | - | Column id/accessor key used by the search input. |
searchPlaceholder | string? | "Search records..." | Placeholder for the search input. |
pageSize | number? | 10 | Initial page size. |
pageSizeOptions | number[]? | [5, 10, 20, 50] | Options shown in the rows-per-page select. |
loading | boolean? | false | Shows table skeleton rows. |
emptyTitle | string? | "No records found" | Empty state title. |
emptyDescription | string? | "Try adjusting..." | Empty state description. |
toolbarActions | ReactNode? | - | Optional actions rendered beside search. |
getRowState | (row: TData) => DataTableRowState | undefined | Inferred from row fields | Controls inactive/deleted row visuals. |
DataTable can infer row state from deleted, disabled, inactive, status, or employment fields. You can override this with getRowState.
| State | Visual treatment |
|---|---|
"default" | Normal row with subtle hover. |
"inactive" | Reduced opacity and muted text. |
"deleted" | Reduced opacity plus a soft diagonal stripe fill. |
Also exported: DataTableToolbar, DataTablePagination, DataTableEmpty, DataTableBadge, DataTableColumnHeader, DataTableRowState, and the semantic table primitives Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, and TableCaption.
Install Matos UI
Choose a package manager and copy one command for every component.