MRT logoMaterial React Table

On This Page

    Column Grouping Feature Guide

    Material React Table has built-in column grouping features. There are options for both automatic client-side grouping as well as manual server-side grouping. This guide will walk you through the different options and how to use and customize them.

    Relevant Table Options

    1
    boolean
    true
    MRT Expanding Sub Rows Docs
    2
    boolean
    MRT Aggregation and Grouping Docs
    3
    (table: Table<TData>) => () => RowModel<TData>
    TanStack Table Grouping Docs
    4
    false | 'reorder' | 'remove'
    reorder
    TanStack Table Grouping Docs
    5
    boolean
    TanStack Table Grouping Docs
    6
    ChipProps| ({ table }} => ChipProps
    Material UI Chip Props
    7
    OnChangeFn<GroupingState>
    TanStack Table Grouping Docs
    8
    'bottom' | 'top' | 'none'
    'top'
    9
    ({ table, groupedAlert, selectedAlert }) => ReactNode

    Relevant Column Options

    1
    ({ cell, column, row, table }) => ReactNode
    2
    ({ cell, column, row, table }) => ReactNode
    3
    ({ cell, column, row, table }) => ReactNode
    4
    boolean

    Relevant State

    1
    Record<string, boolean> | boolean
    {}
    TanStack Table Expanding Docs
    2
    Array<string>
    []
    TanStack Table Grouping Docs

    Enable Grouping

    To enable grouping, set the enableGrouping table option to true. This will both add a drag handle button so that columns can be dragged to the dropzone to be grouped and will add an entry column actions menu to group or ungroup a column.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    });

    Grouped Column Mode

    New in v2.5.0, The "remove" columnGroupMode now has an official UI implementation

    The groupedColumnMode table option controls how grouped columns are displayed once a column has been grouped. There are three options:

    1. "reorder" (default) - Grouped columns will be displayed as the first columns in the table, followed by the 'mrt-row-expand' display column, followed by the remaining columns in their original order.

    2. "remove" - Grouped columns will be removed from the table and only their aggregate values will be displayed alongside the expand button in the 'mrt-row-expand' display column, followed by the remaining columns in their original order.

    3. false - Grouping columns will have no effect on the column order. The 'mrt-row-expand' display column will be displayed as the first column in the table, followed by the remaining columns in their original order.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    groupedColumnMode: 'remove', //instead of default "reorder"
    });

    Demo

    Open StackblitzOpen Code SandboxOpen on GitHub
    Utah (1)
    Male (5)
    DanikaRodriguez5731404
    AlfonzoAbernathy4053374
    AntwanZieme2156638
    KathrynLangworth3925720
    HayleePrice5759047
    Alaska (2)
    Male (4)
    EloisaKohler3145801
    KianHand5681062
    MichaleCollier5975197
    EldridgeStroman4259594
    Female (4)
    LoyceSchmidt2976295
    AlveraBalistreri2579844
    KaydenEmard3598252
    DomingoBauch3635159
    Arizona (1)
    Male (1)
    1-20 of 342

    Source Code

    1import { useMemo, useState } from 'react';
    2import {
    3 MaterialReactTable,
    4 useMaterialReactTable,
    5 type MRT_ColumnDef,
    6} from 'material-react-table';
    7import { data, type Person } from './makeData';
    8import {
    9 FormControl,
    10 FormControlLabel,
    11 FormLabel,
    12 Radio,
    13 RadioGroup,
    14 Stack,
    15} from '@mui/material';
    16
    17const Example = () => {
    18 const columns = useMemo<MRT_ColumnDef<Person>[]>(
    19 //column definitions...
    48 );
    49
    50 //demo state
    51 const [groupedColumnMode, setGroupedColumnMode] = useState<
    52 false | 'remove' | 'reorder'
    53 >('reorder'); //default is 'reorder
    54
    55 const table = useMaterialReactTable({
    56 columns,
    57 data,
    58 enableGrouping: true,
    59 groupedColumnMode,
    60 initialState: {
    61 expanded: true, //expand all groups by default
    62 grouping: ['state', 'gender'], //an array of columns to group by by default (can be multiple)
    63 pagination: { pageIndex: 0, pageSize: 20 },
    64 },
    65 muiTableContainerProps: { sx: { maxHeight: '800px' } },
    66 });
    67
    68 return (
    69 <Stack gap="1rem">
    70 <DemoRadioGroup
    71 groupedColumnMode={groupedColumnMode}
    72 setGroupedColumnMode={setGroupedColumnMode}
    73 />
    74 <MaterialReactTable table={table} />
    75 </Stack>
    76 );
    77};
    78
    79export default Example;
    80
    81//demo...
    117

    Disable Grouping Per Column

    const columns = [
    {
    accessorKey: 'name',
    header: 'Name',
    enableGrouping: false, // disable grouping for this column
    },
    {
    accessorKey: 'age',
    header: 'Age',
    },
    ];
    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    });
    return <MaterialReactTable table={table} />;

    Hide Drag Buttons for Grouping

    If you do not want the drag buttons that come with the grouping feature, you can independently disable them without disabling the grouping feature entirely by setting the enableColumnDragging table option to false.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    enableColumnDragging: false, //do not show drag handle buttons, but still show grouping options in column actions menu
    });
    return <MaterialReactTable table={table} />;

    Group Columns by Default

    If you want columns to be grouped by default, you can set the grouping state in either the initialState or state table option.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    initialState: { grouping: ['location', 'department'] }, //group by location and department by default
    });
    return <MaterialReactTable table={table} />;

    Expand Grouped Rows by Default

    In addition to grouping columns by default, you may also want those grouped rows to be expanded and visible by default, too. You can do this by setting the expanded state to true in either the initialState or state table option.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    initialState: {
    grouping: ['location', 'department'], //group by location and department by default and expand grouped rows
    expanded: true, //show grouped rows by default
    },
    });
    return <MaterialReactTable table={table} />;

    Customize Expand Column

    You can customize the expand column by using the displayColumnDefOptions table option.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    displayColumnDefOptions: {
    'mrt-row-expand': {
    size: 120, //make the expand column wider
    },
    },
    });

    Going further, you can completely overhaul how the expand column renders using custom Cell and Header renders here for advanced use cases.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGrouping: true,
    displayColumnDefOptions: {
    'mrt-row-expand': {
    Cell: ({ row, table }) => {
    return (
    <>
    <MRT_ExpandButton row={row} table={table} />
    {/*custom content*/}
    </>
    );
    },
    Header: ({ table }) => {
    return (
    <>
    <MRT_ExpandAllButton table={table} />
    {/*custom content*/}
    </>
    );
    },
    },
    },
    });

    Demo

    Alabama(3)
    Female(4)
    FemaleThadWiegand6456146
    FemaleReinholdReichel3030531
    FemaleLurlineKoepp5910645
    FemaleKodyBraun3863733
    Male(2)
    MaleAliviaLedner5612591
    MaleDanykaGleason3671238
    Nonbinary(1)
    NonbinaryLionelHartmann3058743
    Alaska(2)
    Male(4)
    MaleEloisaKohler3145801
    MaleKianHand5681062
    MaleMichaleCollier5975197
    MaleEldridgeStroman4259594
    Female(4)
    FemaleLoyceSchmidt2976295
    FemaleAlveraBalistreri2579844
    1-20 of 342

    Source Code

    1import { useMemo, useState } from 'react';
    2import {
    3 MaterialReactTable,
    4 useMaterialReactTable,
    5 type MRT_ColumnDef,
    6 type MRT_Row,
    7 MRT_ExpandAllButton,
    8} from 'material-react-table';
    9import { data, type Person } from './makeData';
    10import { Box, Stack } from '@mui/material';
    11
    12const Example = () => {
    13 const columns = useMemo<MRT_ColumnDef<Person>[]>(
    14 //column definitions...
    43 );
    44
    45 const table = useMaterialReactTable({
    46 columns,
    47 data,
    48 displayColumnDefOptions: {
    49 'mrt-row-expand': {
    50 Header: () => (
    51 <Stack direction="row" alignItems="center">
    52 <MRT_ExpandAllButton table={table} />
    53 <Box>Groups</Box>
    54 </Stack>
    55 ),
    56 GroupedCell: ({ row, table }) => {
    57 const { grouping } = table.getState();
    58 return row.getValue(grouping[grouping.length - 1]);
    59 },
    60 enableResizing: true,
    61 muiTableBodyCellProps: ({ row }) => ({
    62 sx: (theme) => ({
    63 color:
    64 row.depth === 0
    65 ? theme.palette.primary.main
    66 : row.depth === 1
    67 ? theme.palette.secondary.main
    68 : undefined,
    69 }),
    70 }),
    71 size: 200,
    72 },
    73 },
    74 enableGrouping: true,
    75 enableColumnResizing: true,
    76 groupedColumnMode: 'remove',
    77 initialState: {
    78 density: 'compact',
    79 expanded: true, //expand all groups by default
    80 grouping: ['state', 'gender'], //an array of columns to group by by default (can be multiple)
    81 pagination: { pageIndex: 0, pageSize: 20 },
    82 sorting: [{ id: 'state', desc: false }],
    83 },
    84 });
    85
    86 return <MaterialReactTable table={table} />;
    87};
    88
    89export default Example;
    90

    Manual Grouping

    Manual Grouping means that the data that you pass to the table is already grouped and aggregated, and you do not want Material React Table to do any of the grouping or aggregation for you. This is useful if you are using a backend API to do the grouping and aggregation for you, and you just want to display the results. However, you will need to put your data in the specific format that the expanding features understand.

    Learn more about Expanding Sub Rows and Aggregation Features in their own dedicated guides.