Prodular UI

Data display

Data gridPro

A dense, virtualized grid for large datasets: resizable and pinnable columns, keyboard navigation like a spreadsheet, inline editing with validation and a totals row.

npx prodular-ui add data-grid

Part of Prodular UI Pro. Preview and read the docs freely, install with a license. See pricing

10,000 rows, editable

Entry is pinned left and Amount right, with row numbers and a sum in the footer. Edits are validated and saved through onCellEdit.

Count10,000
Sum$120,974,155.21

10,000 entries. Click a cell and use the arrow keys; type or press Enter to edit Vendor, Category, Memo or Amount.

No rows

The header stays in place and empty explains what to do next.

No products match. Clear the search or import a CSV.

Anatomy

const table = useDataGrid({ data, columns, initialState: { columnPinning: { start: ["id"], end: [] } } })
<DataGrid table={table} height={480} onCellEdit={save} rowNumbers />

Guidance

Use it when

  • Thousands of rows that people scan, compare and edit in place: ledgers, inventories, price lists, bulk data cleanup.
  • Spreadsheet-style work where the keyboard matters more than the mouse.
  • Pinning the identifying column at the start and the key number at the end, so both stay visible while scrolling.

Avoid

  • Lists under a few hundred rows with row actions, filters and bulk selection. Use Data table.
  • Editing that needs more than one field at a time. Open a sheet or dialog for the record.
  • Rich content in cells, like long text or images. Rows have a fixed height.

Rules for AI agents

Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.

  • Define columns with createDataGridColumnHelper and give each a size. Numbers get meta.align "end".
  • Make a column editable with meta.editor: "text", "number" or "select" (with meta.options), and pass onCellEdit to DataGrid.
  • In onCellEdit, validate and return a message string to reject the value; the editor stays open with the message. Otherwise save, then update your data immutably.
  • Pin columns with initialState.columnPinning { start: [...], end: [...] }. People can pin, sort and hide from each header menu.
  • Add totals with meta.aggregate (sum, avg, count, min, max) and meta.formatAggregate for currency.
  • Set height on DataGrid; only visible rows render, so keep data as a stable array and update it immutably.
  • Keyboard: arrows, Page Up and Down, Home and End move; Enter or F2 edits; typing replaces; Escape cancels; Enter saves and moves down; Tab saves and moves right; Cmd or Ctrl+C copies the cell.

API

useDataGrid

PropTypeDefaultDescription
options{ data, columns, getRowId?, initialState? }Creates the table with sizing, resizing, pinning, visibility and sorting.

DataGrid

PropTypeDefaultDescription
tableDataGridInstanceThe table from useDataGrid.
heightnumber | string480Height of the scroll area.
rowHeightnumber36Fixed row height in pixels.
onCellEdit({ row, rowId, columnId, value }) => void | string | Promise<void | string>Saves an edit. Return a string to reject it.
rowNumbersbooleanfalseA sticky row numbers column.
emptyReactNodeShown when there are no rows.

Column meta

PropTypeDefaultDescription
editor / options / aggregate / alignDataGridColumnMetaPer column editing, totals and alignment.