react data grid · row grouping
React Grid: Row Grouping
Nest rows by account, then by service inside it, and every group carries its own subtotal. Grouping, sorting and filtering compose: a filter narrows the rows inside every group rather than replacing the grouping.
Also in: Angular
Install and import
npm install @toclocoinc/lattice-grid
# free on localhost; a production domain needs a licence key (see /pricing/)
The files
lattice.ts
// lattice.ts
import React from 'react';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { createLatticeGrid } from '@toclocoinc/lattice-grid/modules/react';
export const LatticeGrid = createLatticeGrid({ React, createGrid });
CloudCosts.tsx
// CloudCosts.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import { LatticeGrid } from './lattice';
// group nests by account, then by service inside it, in the order given by
// index. showTotalInHeader puts each group's own reduction on its heading
// row, so the "Monthly cost" heading names its group's total, not just the
// column.
const columns = [
{ field: 'account', title: 'Account', filter: { type: 'set' }, group: { enabled: true, index: 0 } },
{ field: 'service', title: 'Service', filter: { type: 'set' }, group: { enabled: true, index: 1 } },
{ field: 'resource', title: 'Resource', layout: { flex: 1, min: 200, max: 320 } },
{ field: 'environment', title: 'Env', filter: { type: 'set' },
cell: { decoration: 'pill', variant: { map: {
prod: 'danger', 'prod-2': 'danger', 'definitely-prod': 'danger',
staging: 'warning', untagged: 'warning', test: 'info',
dev: 'success', 'not-prod': 'neutral',
} } } },
{ field: 'cost', title: 'Monthly cost', type: 'number', layout: { width: 170 },
format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum' },
];
const rows = [/* 10,000 cloud cost records */];
function CloudCosts() {
return (
<LatticeGrid
rowKey="id"
selection="multiple"
showTotalInHeader
toolPanel={{ side: 'left', panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'], exportName: 'lattice-demo' }}
columns={columns}
rows={rows}
style={{ height: '480px' }}
/>
);
}
createRoot(document.getElementById('cloud-costs')!).render(<CloudCosts />);
See it running
Working in React
Grouping is column configuration, not extra markup. There is no separate
"group row" component to render: group.index on a column is the whole configuration,
and the grid draws the nested headers and footers itself.
columns is mount-time. Like every array prop here, hoist it outside the component or memoise it; an inline array literal is a new reference on every render and reconfigures grouping on every render along with it.
Group state survives a re-render. Expanding or collapsing a group is grid state, not React state, so a parent re-rendering for an unrelated reason does not collapse what a reader already opened.
Related
Read the docs React data grid overview Free on localhost. See pricing.