Toolbar Customization Guide
This guide shows you how to hide, customize, or override the top and bottom toolbars in Material React Table.
Relevant Props
# | Prop Name 2 | Type | Default Value | More Info Links | |
---|---|---|---|---|---|
1 |
|
| MRT Customize Toolbars Docs | ||
2 |
|
| |||
3 |
|
| |||
4 |
| Material UI Toolbar Props | |||
5 |
| Material UI LinearProgress Props | |||
6 |
| Material UI Chip Props | |||
7 |
| Material UI Alert Props | |||
8 |
| Material UI Toolbar Props | |||
9 |
| ||||
10 |
| ||||
11 |
| ||||
12 |
| ||||
13 |
| ||||
14 |
| ||||
15 |
| ||||
16 |
| ||||
17 |
| ||||
Relevant State
Hide or Disable Toolbars
There are enableTopToolbar
and enableBottomToolbar
props that you can use to show or hide the toolbars.
<MaterialReactTabledata={data}columns={columns}enableTopToolbar={false} //hide top toolbarenableBottomToolbar={false} //hide bottom toolbar/>
No Toolbars Example
First Name | Last Name | Address | City | State |
---|---|---|---|---|
Dylan | Murray | 261 Erdman Ford | East Daphne | Kentucky |
Raquel | Kohler | 769 Dominic Grove | Columbus | Ohio |
Ervin | Reinger | 566 Brakus Inlet | South Linda | West Virginia |
Brittany | McCullough | 722 Emie Stream | Lincoln | Nebraska |
Branson | Frami | 32188 Larkin Turnpike | Charleston | South Carolina |
1import React, { useMemo } from 'react';2import { MaterialReactTable, type MRT_ColumnDef } from 'material-react-table';3import { data, type Person } from './makeData';45export const Example = () => {6 const columns = useMemo<MRT_ColumnDef<Person>[]>(7 //column definitions...32 );3334 return (35 <MaterialReactTable36 columns={columns}37 data={data}38 enableColumnActions={false}39 enableColumnFilters={false}40 enablePagination={false}41 enableSorting={false}42 enableBottomToolbar={false}43 enableTopToolbar={false}44 muiTableBodyRowProps={{ hover: false }}45 muiTableProps={{46 sx: {47 border: '1px solid rgba(81, 81, 81, 1)',48 },49 }}50 muiTableHeadCellProps={{51 sx: {52 border: '1px solid rgba(81, 81, 81, 1)',53 },54 }}55 muiTableBodyCellProps={{56 sx: {57 border: '1px solid rgba(81, 81, 81, 1)',58 },59 }}60 />61 );62};6364export default Example;65
Customize Toolbar buttons
Everything in the toolbars is customizable. You can add your own buttons or change the order of the built-in buttons.
Customize Built-In Internal Toolbar Button Area
The renderToolbarInternalActions
prop allows you to redefine the built-in buttons that usually reside in the top right of the top toolbar. You can reorder the icon buttons or even insert your own custom buttons. All of the built-in buttons are available to be imported from 'material-react-table'.
import { MaterialReactTable,MRT_ShowHideColumnsButton,MRT_FullScreenToggleButton,} from 'material-react-table';//...return (<MaterialReactTabledata={data}columns={columns}renderToolbarInternalActions={({ table }) => (<>{/* add your own custom print button or something */}<IconButton onClick={() => showPrintPreview(true)}><PrintIcon /></IconButton>{/* built-in buttons (must pass in table prop for them to work!) */}<MRT_ShowHideColumnsButton table={table} /><MRT_FullScreenToggleButton table={table} /></>)}/>);
Add Custom Toolbar Buttons/Components
The renderTopToolbarCustomActions
and renderBottomToolbarCustomActions
props allow you to add your own custom buttons or components to the top and bottom toolbar areas. These props are functions that return a ReactNode. You can add your own buttons or whatever components you want.
In all of these render...
props, you get access to the underlying table
instance that you can use to perform actions or extract data from the table.
<MaterialReactTabledata={data}columns={columns}enableRowSelection//Simply adding a table title to the top-left of the top toolbarrenderTopToolbarCustomActions={() => (<Typography variant="h3">Customer's Table</Typography>)}//Adding a custom button to the bottom toolbarrenderBottomToolbarCustomActions={({ table }) => (<Buttonvariant="contained"color="primary"//extract all selected rows from the table instance and do something with themonClick={() => handleDownloadRows(table.getSelectedRowModel().rows)}>Download Selected Rows</Button>)}/>
Full Custom Top Toolbar Example
First Name | Last Name | Age | Salary | |
---|---|---|---|---|
Homer | Simpson | 39 | 53000 | |
Marge | Simpson | 38 | 60000 | |
Bart | Simpson | 10 | 46000 | |
Lisa | Simpson | 8 | 120883 | |
Maggie | Simpson | 1 | 22 |
1import React, { useMemo } from 'react';2import {3 MaterialReactTable,4 type MRT_ColumnDef,5 MRT_ToggleDensePaddingButton,6 MRT_FullScreenToggleButton,7} from 'material-react-table';8import { Box, Button, IconButton } from '@mui/material';9import PrintIcon from '@mui/icons-material/Print';10import { data, type Person } from './makeData';1112const Example = () => {13 const columns = useMemo<MRT_ColumnDef<Person>[]>(14 //column definitions...35 );3637 return (38 <MaterialReactTable39 columns={columns}40 data={data}41 enableRowSelection42 positionToolbarAlertBanner="bottom" //show selected rows count on bottom toolbar43 //add custom action buttons to top-left of top toolbar44 renderTopToolbarCustomActions={({ table }) => (45 <Box sx={{ display: 'flex', gap: '1rem', p: '4px' }}>46 <Button47 color="secondary"48 onClick={() => {49 alert('Create New Account');50 }}51 variant="contained"52 >53 Create Account54 </Button>55 <Button56 color="error"57 disabled={!table.getIsSomeRowsSelected()}58 onClick={() => {59 alert('Delete Selected Accounts');60 }}61 variant="contained"62 >63 Delete Selected Accounts64 </Button>65 </Box>66 )}67 //customize built-in buttons in the top-right of top toolbar68 renderToolbarInternalActions={({ table }) => (69 <Box>70 {/* add custom button to print table */}71 <IconButton72 onClick={() => {73 window.print();74 }}75 >76 <PrintIcon />77 </IconButton>78 {/* along-side built-in buttons in whatever order you want them */}79 <MRT_ToggleDensePaddingButton table={table} />80 <MRT_FullScreenToggleButton table={table} />81 </Box>82 )}83 />84 );85};8687export default Example;88
Position Toolbar Areas
The positionToolbarAlertBanner
, positionGlobalFilter
, positionPagination
, and positionToolbarDropZone
props allow you to swap the default position of certain areas of the toolbars. Experiment moving them around until you find a layout that works for you.
The props positionToolbarAlertBanner
and positionToolbarDropZone
can be set to none
if you need completely hide them.
<MaterialReactTabledata={data}columns={columns}//if rendering top toolbar buttons, sometimes you want alerts to be at the bottompositionToolbarAlertBanner="bottom"positionGlobalFilter="left" //move the search box to the left of the top toolbarpositionPagination="top"renderTopToolbarCustomActions={() => <Box>...</Box>}/>
Customize Toolbar Props and Styles
The muiTopToolbarProps
, muiBottomToolbarProps
, muiToolbarAlertBannerProps
, and muiToolbarAlertBannerChipProps
props allow you to customize the props and styles of the underlying Material UI components that make up the toolbar components. Remember that you can pass CSS overrides to their sx
or style
props. Some have found this useful for forcing position: absolute
on alerts, etc.
Customize Linear Progress Bars
The progress bars that display in both the top and bottom toolbars become visible when either the isLoading
or showProgressBars
state options are set to true
. You can customize the progress bars by passing in props to the muiLinearProgressProps
prop. By default, the progress bars have an indeterminate state, but you can set the value
prop to a number between 0 and 100 to show real progress values if your table is doing some complicated long running tasks that you want to show progress for. Visit the Material UI Linear Progress docs to learn more.
<MaterialReactTabledata={data}columns={columns}muiLinearProgressProps={({ isTopToolbar }) => ({color: 'secondary',sx: { display: isTopToolbar ? 'block' : 'none' }, //only show top toolbar progress barvalue: fetchProgress, //show precise real progress value if you so desirevariant: 'determinate',})}state={{isLoading,showProgressBars,}}/>
Customize Toolbar Alert Banner
The toolbar alert banner is an internal component used to display alerts to the user. By default, it will automatically show messages around the number of row(s) selected or grouping state.
However, you can repurpose this alert banner to show your own custom messages too. You can force the alert banner to show by setting the showAlertBanner
state option to true
.
By setting the showAlertBanner
to false
, you can hide the alert banner completely, which can be useful in overriding the default state when there are row(s) selected or grouped.
You can then customize the messages and other stylings using the muiToolbarAlertBannerProps
to create your custom message. You probably saw this in the Remote Data or React Query examples.
<MaterialReactTablecolumns={columns}data={data}//show a custom error message if there was an error fetching data in the top toolbarmuiToolbarAlertBannerProps={isError? {color: 'error',children: 'Network Error. Could not fetch data.',}: undefined}state={{showAlertBanner: isError,showProgressBars: isFetching,}}/>
Override with Custom Toolbar Components
If you want to completely override the default toolbar components, you can do so by passing in your own custom components to the renderTopToolbar
and renderBottomToolbar
props.
The drawback to this approach is that you will not get all the automatic features of the default toolbar components, such as the automatic alert banner, progress bars, etc. You will have to implement all of that yourself if you still want those features.
<MaterialReactTablecolumns={columns}data={data}renderTopToolbar={({ table }) => <Box></Box>}renderBottomToolbar={({ table }) => <Box></Box>}/>
Import MRT Components for Custom Toolbars
If you are using a custom toolbar, you can still import some of the built-in MRT components to use in your custom toolbar. For example, you can import all of the built-in internal toolbar icon buttons components and use them in your custom toolbar.
import { MaterialReactTable,MRT_ShowHideColumnsButton, // import the built-in show/hide columns buttonMRT_FullScreenToggleButton, // import the built-in full screen toggle button} from 'material-react-table';//...return (<MaterialReactTablecolumns={columns}data={data}renderTopToolbar={({ table }) => (<Box sx={{ display: 'flex', justifyContent: 'space-between' }}><Typography>Custom Toolbar</Typography><Box><MRT_ShowHideColumnsButton table={table} /><MRT_FullScreenToggleButton table={table} /></Box></Box>)}/>);
Create Your Own External Toolbar Component
You may want to separate out your own toolbar functionality away from the main table component. MRT lets you do this and still connect your custom components to the table instance using the tableInstanceRef
prop.
You can import import the MRT Internal Toolbar button components and use them in your custom toolbar, just like you can when customizing the built-in toolbar, BUT there are some extra re-render hacks that you have to do to make the icon buttons work properly. See the example below:
Passing the
tableInstanceRef
as a prop for thetable
prop that MRT_* components need also requires some weird re-render hacks to make the icon buttons work properly, because refs do not trigger re-renders in React.
Hey I'm some page content. I'm just one of your normal components between your custom toolbar and the MRT Table below
First Name | Last Name | Age | Salary | |
---|---|---|---|---|
Homer | Simpson | 39 | 53000 | |
Marge | Simpson | 38 | 6000 | |
Bart | Simpson | 10 | 460 | |
Lisa | Simpson | 8 | 120883 | |
Maggie | Simpson | 1 | 22 |
1import React, { useReducer, useRef, useState } from 'react';2import {3 MaterialReactTable,4 MRT_FullScreenToggleButton,5 MRT_GlobalFilterTextField,6 MRT_ShowHideColumnsButton,7 MRT_TableInstance,8 MRT_TablePagination,9 MRT_ToggleDensePaddingButton,10 MRT_ToggleFiltersButton,11 MRT_ToolbarAlertBanner,12 type MRT_ColumnDef,13 type MRT_DensityState,14 type MRT_PaginationState,15 type MRT_RowSelectionState,16 type MRT_VisibilityState,17} from 'material-react-table';18import {19 alpha,20 Box,21 Button,22 IconButton,23 Toolbar,24 Tooltip,25 Typography,26} from '@mui/material';27import PrintIcon from '@mui/icons-material/Print';28import { data, type Person } from './makeData';2930//column definitions...5051const Example = () => {52 //we need a table instance ref to pass as a prop to the MRT Toolbar buttons53 const tableInstanceRef = useRef<MRT_TableInstance<Person>>(null);5455 //we will also need some weird re-render hacks to force the MRT_ components to re-render since ref changes do not trigger a re-render56 const rerender = useReducer(() => ({}), {})[1];5758 //we need to manage the state that should trigger the MRT_ components in our custom toolbar to re-render59 const [columnVisibility, setColumnVisibility] = useState<MRT_VisibilityState>(60 {},61 );62 const [density, setDensity] = useState<MRT_DensityState>('comfortable');63 const [pagination, setPagination] = useState<MRT_PaginationState>({64 pageIndex: 0,65 pageSize: 5,66 });67 const [rowSelection, setRowSelection] = useState<MRT_RowSelectionState>({});68 const [showColumnFilters, setShowColumnFilters] = useState(false);6970 return (71 <Box sx={{ border: 'gray 2px dashed', p: '1rem' }}>72 {/* Our Custom External Top Toolbar */}73 {tableInstanceRef.current && (74 <Toolbar75 sx={(theme) => ({76 backgroundColor: alpha(theme.palette.secondary.light, 0.2),77 borderRadius: '4px',78 display: 'flex',79 flexDirection: {80 xs: 'column',81 lg: 'row',82 },83 gap: '1rem',84 justifyContent: 'space-between',85 p: '1.5rem 0',86 })}87 >88 <Box>89 <Button90 color="primary"91 onClick={() => {92 alert('Add User');93 }}94 variant="contained"95 >96 Crete New Account97 </Button>98 </Box>99 <MRT_GlobalFilterTextField table={tableInstanceRef.current} />100 <Box>101 <MRT_ToggleFiltersButton table={tableInstanceRef.current} />102 <MRT_ShowHideColumnsButton table={tableInstanceRef.current} />103 <MRT_ToggleDensePaddingButton table={tableInstanceRef.current} />104 <Tooltip arrow title="Print">105 <IconButton onClick={() => window.print()}>106 <PrintIcon />107 </IconButton>108 </Tooltip>109 <MRT_FullScreenToggleButton table={tableInstanceRef.current} />110 </Box>111 </Toolbar>112 )}113 <Typography padding="1rem 4px">114 {115 "Hey I'm some page content. I'm just one of your normal components between your custom toolbar and the MRT Table below"116 }117 </Typography>118 {/* The MRT Table */}119 <MaterialReactTable120 columns={columns}121 data={data}122 enableBottomToolbar={false}123 enableRowSelection124 enableTopToolbar={false}125 initialState={{ showGlobalFilter: true }}126 // See the Table State Management docs for why we need to use the updater function like this127 onColumnVisibilityChange={(updater) => {128 setColumnVisibility((prev) =>129 updater instanceof Function ? updater(prev) : updater,130 );131 queueMicrotask(rerender); //hack to rerender after state update132 }}133 onDensityChange={(updater) => {134 setDensity((prev) =>135 updater instanceof Function ? updater(prev) : updater,136 );137 queueMicrotask(rerender); //hack to rerender after state update138 }}139 onRowSelectionChange={(updater) => {140 setRowSelection((prev) =>141 updater instanceof Function ? updater(prev) : updater,142 );143 queueMicrotask(rerender); //hack to rerender after state update144 }}145 onPaginationChange={(updater) => {146 setPagination((prev) =>147 updater instanceof Function ? updater(prev) : updater,148 );149 queueMicrotask(rerender); //hack to rerender after state update150 }}151 onShowColumnFiltersChange={(updater) => {152 setShowColumnFilters((prev) =>153 updater instanceof Function ? updater(prev) : updater,154 );155 queueMicrotask(rerender); //hack to rerender after state update156 }}157 state={{158 columnVisibility,159 density,160 rowSelection,161 pagination,162 showColumnFilters,163 }}164 tableInstanceRef={tableInstanceRef} //get access to the underlying table instance ref165 />166 {/* Our Custom Bottom Toolbar */}167 {tableInstanceRef.current && (168 <Toolbar169 sx={{170 display: 'flex',171 justifyContent: 'center',172 flexDirection: 'column',173 }}174 >175 <MRT_TablePagination table={tableInstanceRef.current} />176 <Box sx={{ display: 'grid', width: '100%' }}>177 <MRT_ToolbarAlertBanner178 stackAlertBanner179 table={tableInstanceRef.current}180 />181 </Box>182 </Toolbar>183 )}184 </Box>185 );186};187188export default Example;189