Shadcn React Table

Search documentation

Search the docs

Grouping & aggregation

Set enableGrouping: true to let users group rows by a column. Once enabled, users can drag a column header onto the drop-to-group zone, or pick Group by from a column's actions menu.

Grouping & aggregation
GitHub
Department
ID
~38$840,825Mon Jan 02 2023 00:00:00 GMT+0000 (Coordinated Universal Time),Sat May 11 2024 00:00:00 GMT+0000 (Coordinated Universal Time)409
AvaThompsonOwneractive22$45,000Jan 2, 2023
0%
WilliamWalkerAdminpending37$55,685Feb 26, 2023
45%
MiaJohanssonEditorinactive52$66,370Apr 22, 2023
90%
JackDiazVieweractive27$77,055Jun 16, 2023
34%
AvaThompsonOwnerpending42$87,740Aug 10, 2023
79%
WilliamWalkerAdmininactive57$98,425Oct 4, 2023
23%
MiaJohanssonEditoractive32$109,110Nov 28, 2023
68%
JackDiazViewerpending47$119,795Jan 22, 2024
12%
AvaThompsonOwnerinactive22$130,480Mar 17, 2024
57%
WilliamWalkerAdminactive37$51,165May 11, 2024
1%
~41$862,195Fri Jan 13 2023 00:00:00 GMT+0000 (Coordinated Universal Time),Wed May 22 2024 00:00:00 GMT+0000 (Coordinated Universal Time)499
LiamNguyenAdmininactive25$47,137Jan 13, 2023
9%
SophiaPatelEditoractive40$57,822Mar 9, 2023
54%
BenjaminCostaViewerpending55$68,507May 3, 2023
99%
HarperDuboisOwnerinactive30$79,192Jun 27, 2023
43%
LiamNguyenAdminactive45$89,877Aug 21, 2023
88%
SophiaPatelEditorpending60$100,562Oct 15, 2023
32%
BenjaminCostaViewerinactive35$111,247Dec 9, 2023
77%
HarperDuboisOwneractive50$121,932Feb 2, 2024
21%
LiamNguyenAdminpending25$132,617Mar 28, 2024
66%
SophiaPatelEditorinactive40$53,302May 22, 2024
10%
~40$883,565Tue Jan 24 2023 00:00:00 GMT+0000 (Coordinated Universal Time),Sun Jun 02 2024 00:00:00 GMT+0000 (Coordinated Universal Time)488
NoahSilvaEditorpending28$49,274Jan 24, 2023
18%
JamesMullerViewerinactive43$59,959Mar 20, 2023
63%
CharlotteChenOwneractive58$70,644May 14, 2023
7%
LeoHaddadAdminpending33$81,329Jul 8, 2023
52%
NoahSilvaEditorinactive48$92,014Sep 1, 2023
97%
JamesMullerVieweractive23$102,699Oct 26, 2023
41%
CharlotteChenOwnerpending38$113,384Dec 20, 2023
86%
LeoHaddadAdmininactive53$124,069Feb 13, 2024
30%
NoahSilvaEditoractive28$134,754Apr 8, 2024
75%
JamesMullerViewerpending43$55,439Jun 2, 2024
19%
~42$757,359Sat Feb 04 2023 00:00:00 GMT+0000 (Coordinated Universal Time),Fri Apr 19 2024 00:00:00 GMT+0000 (Coordinated Universal Time)449
EmmaCarterVieweractive31$51,411Feb 4, 2023
27%
IsabellaParkOwnerpending46$62,096Mar 31, 2023
72%
HenryCohenAdmininactive61$72,781May 25, 2023
16%
EllaKhanEditoractive36$83,466Jul 19, 2023
61%
EmmaCarterViewerpending51$94,151Sep 12, 2023
5%
IsabellaParkOwnerinactive26$104,836Nov 6, 2023
50%
HenryCohenAdminactive41$115,521Dec 31, 2023
95%
EllaKhanEditorpending56$126,206Feb 24, 2024
39%
EmmaCarterViewerinactive31$46,891Apr 19, 2024
84%
~41$776,592Wed Feb 15 2023 00:00:00 GMT+0000 (Coordinated Universal Time),Tue Apr 30 2024 00:00:00 GMT+0000 (Coordinated Universal Time)429
OliviaRossiOwnerinactive34$53,548Feb 15, 2023
36%
LucasReyesAdminactive49$64,233Apr 11, 2023
81%
AmeliaNovakEditorpending24$74,918Jun 5, 2023
25%
MasonTanakaViewerinactive39$85,603Jul 30, 2023
70%
OliviaRossiOwneractive54$96,288Sep 23, 2023
14%
LucasReyesAdminpending29$106,973Nov 17, 2023
59%
$4,120,536
Rows per page
1–50 of 53

Initial groups

Seed the grouped state with initialState.grouping and expand all groups on first render with initialState.expanded.

const table = useDataTable({
  data,
  columns,
  getRowId: (row) => row.id,
  enableGrouping: true,
  initialState: {
    grouping: ["department"],
    expanded: true,
  },
})

return <DataTable table={table} />

Aggregations

Aggregations use the standard TanStack Table column options. Set aggregationFn to a built-in ("sum", "mean", ...) or a custom function, render the rolled-up value with aggregatedCell, and add a footer for a grand total.

const columns = [
  {
    accessorKey: "salary",
    header: "Salary",
    aggregationFn: "sum",
    aggregatedCell: ({ getValue }) => (
      <strong>{formatCurrency(getValue<number>())}</strong>
    ),
    footer: ({ table }) => {
      const total = table
        .getRowModel()
        .rows.reduce((sum, row) => sum + row.getValue<number>("salary"), 0)
      return <strong>{formatCurrency(total)}</strong>
    },
  },
]

Keep totals in view

Grouping pairs well with a pinned footer. Add enableStickyFooter: true so the grand total stays visible while scrolling long groups.

Custom group cells

For finer control over how grouped rows render, the column meta exposes render hooks that receive the full table instance: renderGroupedCell (the group-header cell), renderAggregatedCell (overrides aggregatedCell), and renderPlaceholderCell (cells with no value because another column owns the group; empty by default).

{
  accessorKey: "department",
  header: "Department",
  meta: {
    renderGroupedCell: ({ row }) => (
      <span className="font-medium">
        {row.getValue("department")} · {row.subRows.length}
      </span>
    ),
  },
}