Product primitive · Data editing
Data Grid primitive
Headless selection, sorting, sizing, and edit transactions for an application-owned grid.
Choose the right layer
- Use
useDataGridif your product owns its grid markup and appearance. It returns the TanStack table instance pluscommitCells. - Use
@lenso/ui/data-gridfor the ready-made Lenso appearance and interaction surface. Ordinary read-only records still belong in Data Table.
Commit contract
- Provide stable row IDs and immutable
rows. WithoutonRowsChange, edits are rejected. SetreadOnlyto make that intent explicit. commitCellsconstructs the complete candidate rows, then checks every edit before callingonRowsChange. A failed validation rejects the batch without applying a partial update. The validation context includesrows,originalRows,table, and typedvalidationData.- Use
onCellEditCompletefor every cell, a column's callback for that column,cellEventsfor exact row-and-column targets, andonRowEditCompleteonce per affected row in a transaction. - Cell selection follows TanStack Table's range model. Bind a cell's start handler to mouse down and its extend handler to mouse enter if you build custom markup.
- Pass advanced TanStack options through
tableOptionsand individual column options throughtableColumn. The returnedtableis the live TanStack instance for the registered features, including selection atoms, sorting, sizing, and row-model APIs.
Implementation
Use the primitive when the application needs a custom rendering layer.
import { useDataGrid } from "@lenso/primitives/data-grid";
const { table, commitCells } = useDataGrid({
rows,
columns,
getRowId: (row) => row.id,
onRowsChange: (nextRows) => setRows([...nextRows]),
onCellEditComplete: (change) => auditCell(change),
cellEvents: [
{
rowId: "company-42",
columnId: "status",
onEditComplete: (change) => notifyStatusChange(change),
},
],
});
commitCells([{ rowId: "company-42", columnId: "status", value: "Active" }]);