Data Table

import { DataTable, DataTableColumnHeader } from '@hanzo/ui'

Basic

A column list bound to an array; each cell falls back to the row's raw value when a column names no `cell`.

Status
Email
Amount
success
$316.00
success
$242.00
processing
$837.00
success
$874.00
failed
$721.00
export function Basic() {
return <DataTable columns={columns} data={payments} pageSize={0} />
}

Sortable and filterable

`DataTableColumnHeader` turns a header into a toggle, and `filterColumnId` wires a text box to one column.

Status
Amount
success
$316.00
success
$242.00
processing
$837.00
success
$874.00
failed
$721.00
export function SortableAndFilterable() {
const sortable: Array<DataTableColumnDef<Payment>> = [
{
id: "email",
accessorKey: "email",
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
},
{
id: "status",
accessorKey: "status",
header: "Status",
cell: ({ row }) => (
<Badge variant={row.original.status === "failed" ? "destructive" : "secondary"}>
{row.original.status}
</Badge>
),
},
columns[2],
]
return (
<DataTable columns={sortable} data={payments} filterColumnId="email" filterPlaceholder="Filter emails…" pageSize={0} />
)
}

Row selection and pagination

A `select` column with no `header`/`cell` gets a checkbox for free, and `pageSize` turns on the Previous/Next footer.

Status
Email
Amount
success
$316.00
success
$242.00
0 of 5 row(s) selected.
export function SelectableAndPaginated() {
const withSelection: Array<DataTableColumnDef<Payment>> = [
{ id: "select", enableSorting: false, enableHiding: false },
...columns,
]
return <DataTable columns={withSelection} data={payments} pageSize={2} />
}

Types

export type DataTableSortDirection = 'asc' | 'desc' | false
export interface DataTableColumnApi {
id: string
getIsSorted: () => DataTableSortDirection
toggleSorting: (desc?: boolean) => void
getCanHide: () => boolean
getIsVisible: () => boolean
toggleVisibility: (visible?: boolean) => void
}
export interface DataTableRow<TData> {
id: string
original: TData
getValue: (columnId: string) => unknown
getIsSelected: () => boolean
toggleSelected: (selected?: boolean) => void
}
export interface DataTableInstance<TData> {
getAllColumns: () => DataTableColumnApi[]
getColumn: (id: string) => DataTableColumnApi | undefined
getIsAllPageRowsSelected: () => boolean
getIsSomePageRowsSelected: () => boolean
toggleAllPageRowsSelected: (selected?: boolean) => void
getFilteredRowModel: () => { rows: Array<DataTableRow<TData>> }
getFilteredSelectedRowModel: () => { rows: Array<DataTableRow<TData>> }
previousPage: () => void
nextPage: () => void
getCanPreviousPage: () => boolean
getCanNextPage: () => boolean
}
export interface DataTableColumnDef<TData> {
/** Stable id. Defaults to `String(accessorKey)` when omitted. */
id?: string
accessorKey?: keyof TData
header?:
| React.ReactNode
| ((ctx: { column: DataTableColumnApi; table: DataTableInstance<TData> }) => React.ReactNode)
cell?: (ctx: { row: DataTableRow<TData>; table: DataTableInstance<TData> }) => React.ReactNode
enableSorting?: boolean
enableHiding?: boolean
align?: 'left' | 'center' | 'right'
}
export interface DataTableProps<TData> {
columns: Array<DataTableColumnDef<TData>>
data: TData[]
/** Column id filtered by the toolbar's text input. Omit to hide it. */
filterColumnId?: string
filterPlaceholder?: string
/** Rows per page. `0` disables pagination (and its footer). Default 10. */
pageSize?: number
emptyMessage?: string
}
export interface DataTableColumnHeaderProps {
column: DataTableColumnApi
title: string
}

Exports

DataTableDataTableColumnHeadertype DataTableColumnApitype DataTableColumnDeftype DataTableColumnHeaderPropstype DataTableInstancetype DataTablePropstype DataTableRowtype DataTableSortDirection