Skip to main content
Mantı UI logoMantı UIv0.12.1
Studio

DataTable

Pass columns and data. DataTable uses TanStack table-core for row models and renders semantic table markup.

import { DataTable } from '@manti-ui/react';
import type { DataTableColumn } from '@manti-ui/react';

interface Member {
  name: string;
  role: string;
  location: string;
}

const data: Member[] = [
  { name: 'Ada Lovelace', role: 'Engineer', location: 'London' },
  { name: 'Alan Turing', role: 'Researcher', location: 'Manchester' },
  { name: 'Grace Hopper', role: 'Architect', location: 'New York' },
];

const columns: DataTableColumn<Member>[] = [
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'role', header: 'Role' },
  { accessorKey: 'location', header: 'Location' },
];

export default function DataTableBasic() {
  return <DataTable columns={columns} data={data} />;
}

Columns and sorting

Columns use the re-exported DataTableColumn<TData> type. Use accessorKey for plain values, cell for custom rendering, and meta.align for alignment.

Set sortable to add accessible sort buttons.

INV-001Acme Corppaid$1,200.00
INV-002Globexpending$450.50
INV-003Initechoverdue$3,120.00
INV-004Umbrellapaid$88.00

Entity stores and row props

Use getRowProps, getCellProps, and getRowId for native, ARIA, and data attributes. When each row must resolve a live entity reference with hooks, pass rowComponent. It is a real React component boundary, unlike a render callback, so hooks remain valid. Spread rowProps onto its semantic <tr> and render children for the generated cells.

Filtering, pagination, and selection

Enable filterable, paginated, or selectable independently or together.

Invoices
INV-001Acme Corppaid$1,200.00
INV-002Globexpending$450.50
INV-003Initechoverdue$3,120.00
INV-004Umbrellapaid$88.00
INV-005Soylentpending$640.00
0 selected

Sizes

NameRoleLocation
Ada LovelaceEngineerLondon
Alan TuringResearcherManchester
Grace HopperArchitectNew York
NameRoleLocation
Ada LovelaceEngineerLondon
Alan TuringResearcherManchester
Grace HopperArchitectNew York
NameRoleLocation
Ada LovelaceEngineerLondon
Alan TuringResearcherManchester
Grace HopperArchitectNew York

API

PropTypeDefaultDescription
columnsDataTableColumn<TData>[]Column definitions (TanStack `ColumnDef`). Set `meta.align` to align a column.
dataTData[]The rows to render.
titleReactNodeA heading shown at the start of the toolbar; also names the table.
sortablebooleanfalseEnable click-to-sort headers (one column at a time).
filterablebooleanfalseAdd a global search box that filters across every column.
filterPlaceholderstring'Search…'Placeholder for the search box.
paginatedbooleanfalsePaginate client-side, with a Pagination control in the footer.
pageSizenumber10Rows per page when `paginated`.
selectablebooleanfalseAdd a leading checkbox column for row selection.
onSelectionChange(rows: TData[]) => voidCalled with the selected rows whenever the selection changes.
size'sm' | 'md' | 'lg''md'Row density.
stickyHeaderbooleanfalsePin the header while the body scrolls (needs a bounded height).
zebrabooleanfalseTint alternating rows.
interactivebooleanfalseHighlight rows on hover.
captionReactNodeOptional caption rendered above the grid.
emptyContentReactNode'No data'Shown in place of rows when `data` is empty.
getRowId(row: TData, index: number) => stringDerive a stable row id (defaults to the row index).
getRowProps(row: TData, index: number) => HTMLAttributes<HTMLTableRowElement>Add native, ARIA, and data props to each row.
getCellProps(row: TData, columnId: string, index: number) => TdHTMLAttributesAdd native, ARIA, and data props to each cell.
rowComponentComponentType<DataTableRowComponentProps<TData>>A hook-safe component boundary for resolving live/normalized row entities.

Styling

Anatomy

PartSelectorDescription
root[data-scope="data-table"][data-part="root"]The panel framing the toolbar, grid, and footer.
toolbar[data-scope="data-table"][data-part="toolbar"]The top bar holding the title and search box.
title[data-scope="data-table"][data-part="title"]The toolbar heading (when `title` is set).
search[data-scope="data-table"][data-part="search"]The search field wrapper.
viewport[data-scope="data-table"][data-part="viewport"]The scrollable region wrapping the table.
table[data-scope="data-table"][data-part="table"]The <table> element.
caption[data-scope="data-table"][data-part="caption"]The <caption>, when provided.
header[data-scope="data-table"][data-part="header"]The <thead>.
header-row[data-scope="data-table"][data-part="header-row"]A header <tr>.
header-cell[data-scope="data-table"][data-part="header-cell"]A header <th>; carries `aria-sort` and `data-align`.
sort-trigger[data-scope="data-table"][data-part="sort-trigger"]The header button toggling sort (sortable columns).
sort-indicator[data-scope="data-table"][data-part="sort-indicator"]The arrow reflecting sort direction.
body[data-scope="data-table"][data-part="body"]The <tbody>.
row[data-scope="data-table"][data-part="row"]A body <tr>; carries `data-selected` when selected.
cell[data-scope="data-table"][data-part="cell"]A body <td>; carries `data-align`.
empty[data-scope="data-table"][data-part="empty"]The cell shown when there are no rows.
footer[data-scope="data-table"][data-part="footer"]The bottom bar holding the selection summary and pager.
selection-summary[data-scope="data-table"][data-part="selection-summary"]The “N selected” count (when selectable).

Tokens

TokenControls
--manti-data-table-radiusradius
--manti-data-table-cell-padding-xcell padding x
--manti-data-table-cell-padding-ycell padding y
--manti-data-table-font-sizefont size
--manti-data-table-header-font-sizeheader font size

Last updated

Built end-to-end with Manti UI components and design tokens. Manti UI is a framework-agnostic design system on Zag.js.

GitHub