gridcn1.2.2

Status bar

The data-grid-status-bar add-on: count, sum, avg, min, and max of the selected cells under the grid.

Users read totals of a selection without exporting it. data-grid-status-bar computes them from the grid's own data: <DataGridStatusBar /> renders the bar, and useDataGridSelectionStats is the headless hook. It reads committed values only, never the open editor's draft, and writes nothing, so readOnly grids work unchanged.

Select a range — Shift+click, a row header, or a column header — and the bar below aggregates the selection.

Name
Age
Score
Silent Tiger
63
4
Quick Lion
67
89
Swift Wolf
40
80
Eager Lion
50
51
Eager Tiger
45
83
Silent Wolf
24
15
Swift Lion
34
62
Eager Lion
21
42
Eager Eagle
25
35
Bold Tiger
19
52
Bold Bear
42
28
Swift Wolf
47
9
Swift Bear
41
45
Eager Wolf
35
44
Swift Eagle
65
51
Quick Lion
22
28
Bold Wolf
30
76
Swift Eagle
19
26
Eager Eagle
35
70
Eager Bear
33
67
Silent Lion
48
89
Silent Tiger
62
40
Eager Tiger
51
82
Silent Lion
26
16
Bold Eagle
26
38
Bold Lion
49
3
Quick Tiger
26
41
Bold Eagle
50
10
Swift Tiger
55
6
Silent Lion
35
42
pnpm dlx shadcn@latest add @gridcn/data-grid-status-bar

Place the bar inside DataGridProvider, next to DataGridRoot, like the pagination bar:

import { DataGridStatusBar } from "@/components/data-grid-status-bar/data-grid-status-bar";

<DataGridProvider {...grid} columns={columns}>
  <DataGridRoot>
    <DataGridHeader />
    <DataGridBody />
  </DataGridRoot>
  <DataGridStatusBar />
</DataGridProvider>;

Which cells count

The bar aggregates the union of every selection channel: the primary range, the stacked Ctrl+click ranges, whole-row selections, and whole-column selections. A cell that sits in two channels counts once. Hidden columns, filtered rows, and unloaded lazy rows are never in the view, so they never count.

Which values count

A cell is numeric when its raw value is a finite number. Detection reads the value, so a custom numeric type aggregates without configuration. count counts the non-empty cells, where empty means the column's cell type isEmpty returns true. sum, avg, min, and max run over the numeric cells; the sum uses Neumaier-compensated summation, so 0.1 + 0.2 shows 0.3.

Display and formatting

The bar renders nothing while fewer than 2 cells are selected. count always shows; sum, avg, min, and max show only while at least one numeric cell is selected.

When every numeric cell comes from one column, that column's toDisplayText formats sum, avg, min, and max. A number column with a format option shows currency. Otherwise the default Intl.NumberFormat(locale, { maximumFractionDigits: 4 }) applies. formatValue overrides both.

When it computes

The hook recomputes after the selection settles: at once for a selection of up to 5,000 cells, otherwise on a 150 ms trailing timer, so dragging a large range does not walk the whole selection on every frame. A walk stops at 200,000 cells (MAX_STATUS_CELLS); above the cap, every value gets a ≈ prefix and the bar's title says how many cells the values cover.

Props

PropTypeDefaultDescription
aggregatesreadonly ("count" | "sum" | "avg" | "min" | "max")[]all five, in this orderWhich aggregates to show, and in which order.
formatValue(value: number, aggregate: StatusBarAggregate) => stringthe single-column rule, else the Intl defaultFormats the shown aggregate values.
localestring"en-US"Locale for the default number format.
labelsPartial<DataGridStatusBarLabels>merged over labels.statusBari18n override for this bar's strings.
classNamestringnoneExtra classes on the bar element.
childrenReactNodenoneExtra items, rendered after the aggregates.

The bar is a polite live region

The bar is role="status" with aria-live="polite" and aria-atomic="true". Its text changes only when a computation finishes, so a drag does not flood the screen reader. Each value carries its label ("Sum 1,234").

On this page