React table pinned summary rows — independent totals
▶ Try it live: open a Mantine starter in StackBlitz — compose pinnedSummaryRows. Other UI kits →
▶ See it working: pinned summaries and group totals in Mantine — host-owned totals stick above and below the list, and they are not data rows. The same page exists for MUI, Chakra, antd, Radix, Base UI, shadcn and Tailwind.
These are not lifted data rows. You pass separate objects
(pinnedRows: { top, bottom }) that never enter sort, filter, grouping,
pagination or selection. Cells still run through the ordinary column
pipeline — formatters, sparklines, spanning — and the rows stick above
or below the scroll window, including on grouped and tree tables where
lift-a-data-row pinning stays refused.
import { DataTable } from "@adapttable/mantine";import { pinnedSummaryRows } from "@adapttable/mantine/pinned-summary-rows";
const totals = { id: "totals", name: "Team total", budget: 128_000 };
<DataTable data={rows} columns={columns} rowKey={(row) => row.id} features={[ pinnedSummaryRows({ top: [totals], bottom: [{ id: "grand", name: "Grand total", budget: 128_000 }], }), ]}/>;The objects are host data. Nothing is written to the URL or a Saved View — a shared link does not have to invent totals the next load cannot recompute. They are not exported, selected, edited, reordered, or given pin / row-action menus.
Desktop rows use data-adapttable-part="pinned-summary-top" /
"pinned-summary-bottom" and aria-label from pinnedSummaryRow.
Keyboard cell navigation reaches them. Mobile cards keep the same order
and announcement; a card list has no sticky chrome.
Identities are namespaced (adapttable:pinned-summary:top:0) so they
never collide with a data-row id.
Lift a real person with rowPinning. Stick a total
that is not in the dataset with this factory.
Labels: pinnedSummaryRow, pinnedSummaryTop, pinnedSummaryBottom.