MRT logoMantine React Table

Custom Headless Example

For advanced use cases where you want to be in 100% control of your UI components, you can use Mantine React Table in a more headless way, kind of like how you would use stock TanStack Table.
The power and flexibility here is almost limitless, as you can combine some already built-in Mantine React Table components alongside your own custom components. For the MRT components to work properly, all you need to do is pass the table object returned from the useMantineReactTable hook.

My Custom Headless Table

First NameLast NameAddressCityState
ChristopherLee555 Cedar StreetSeattleWashington
RachelAnderson987 Walnut CourtNew YorkNew York
DavidGarcia654 Maple AvenueLos AngelesCalifornia
ZacharyDavis261 Battle FordColumbusOhio
RobertSmith566 Brakus InletWestervilleWest Virginia
1
import {
2
flexRender,
3
MRT_GlobalFilterTextInput,
4
MRT_TablePagination,
5
MRT_ToolbarAlertBanner,
6
type MRT_ColumnDef,
7
useMantineReactTable,
8
} from 'mantine-react-table';
9
import { Divider, Flex, Stack, Table, Title } from '@mantine/core';
10
import { type Person, data } from './makeData';
11
12
const columns: MRT_ColumnDef<Person>[] = [
13
{
14
accessorKey: 'name.firstName',
15
header: 'First Name',
16
},
17
{
18
accessorKey: 'name.lastName',
19
header: 'Last Name',
20
},
21
{
22
accessorKey: 'address',
23
header: 'Address',
24
},
25
{
26
accessorKey: 'city',
27
header: 'City',
28
},
29
{
30
accessorKey: 'state',
31
header: 'State',
32
},
33
];
34
35
const Example = () => {
36
const table = useMantineReactTable({
37
columns,
38
data, //must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
39
//MRT display columns can still work, optionally override cell renders with `displayColumnDefOptions`
40
enableRowSelection: true,
41
initialState: {
42
pagination: { pageSize: 5, pageIndex: 0 },
43
showGlobalFilter: true,
44
},
45
//customize the MRT components
46
mantinePaginationProps: {
47
rowsPerPageOptions: ['5', '10', '15'],
48
},
49
paginationDisplayMode: 'pages',
50
});
51
52
return (
53
<Stack>
54
<Divider />
55
<Title order={4}>My Custom Headless Table</Title>
56
<Flex justify="space-between" align="center">
57
{/**
58
* Use MRT components along side your own markup.
59
* They just need the `table` instance passed as a prop to work!
60
*/}
61
<MRT_GlobalFilterTextInput table={table} />
62
<MRT_TablePagination table={table} />
63
</Flex>
64
{/* Using Vanilla Mantine Table component here */}
65
<Table
66
captionSide="top"
67
fontSize="md"
68
highlightOnHover
69
horizontalSpacing="xl"
70
striped
71
verticalSpacing="xs"
72
withBorder
73
withColumnBorders
74
m="0"
75
>
76
{/* Use your own markup, customize however you want using the power of TanStack Table */}
77
<thead>
78
{table.getHeaderGroups().map((headerGroup) => (
79
<tr key={headerGroup.id}>
80
{headerGroup.headers.map((header) => (
81
<th key={header.id}>
82
{header.isPlaceholder
83
? null
84
: flexRender(
85
header.column.columnDef.Header ??
86
header.column.columnDef.header,
87
header.getContext(),
88
)}
89
</th>
90
))}
91
</tr>
92
))}
93
</thead>
94
<tbody>
95
{table.getRowModel().rows.map((row) => (
96
<tr key={row.id}>
97
{row.getVisibleCells().map((cell) => (
98
<td key={cell.id}>
99
{flexRender(
100
cell.column.columnDef.Cell ?? cell.column.columnDef.cell,
101
cell.getContext(),
102
)}
103
</td>
104
))}
105
</tr>
106
))}
107
</tbody>
108
</Table>
109
<MRT_ToolbarAlertBanner stackAlertBanner table={table} />
110
</Stack>
111
);
112
};
113
114
export default Example;
1
import {
2
flexRender,
3
MRT_GlobalFilterTextInput,
4
MRT_TablePagination,
5
MRT_ToolbarAlertBanner,
6
useMantineReactTable,
7
} from 'mantine-react-table';
8
import { Divider, Flex, Stack, Table } from '@mantine/core';
9
import { data } from './makeData';
10
11
const columns = [
12
{
13
accessorKey: 'name.firstName',
14
header: 'First Name',
15
},
16
{
17
accessorKey: 'name.lastName',
18
header: 'Last Name',
19
},
20
{
21
accessorKey: 'address',
22
header: 'Address',
23
},
24
{
25
accessorKey: 'city',
26
header: 'City',
27
},
28
{
29
accessorKey: 'state',
30
header: 'State',
31
},
32
];
33
34
const Example = () => {
35
const table = useMantineReactTable({
36
columns,
37
data, //must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
38
//MRT display columns can still work, optionally override cell renders with `displayColumnDefOptions`
39
enableRowSelection: true,
40
initialState: {
41
pagination: { pageSize: 5, pageIndex: 0 },
42
showGlobalFilter: true,
43
},
44
//customize the MRT components
45
mantinePaginationProps: {
46
rowsPerPageOptions: ['5', '10', '15'],
47
},
48
paginationDisplayMode: 'pages',
49
});
50
51
return (
52
<Stack>
53
<Divider />
54
<Flex justify="space-between" align="center">
55
{/**
56
* Use MRT components along side your own markup.
57
* They just need the `table` instance passed as a prop to work!
58
*/}
59
<MRT_GlobalFilterTextInput table={table} />
60
<MRT_TablePagination table={table} />
61
</Flex>
62
{/* Using Vanilla Mantine Table component here */}
63
<Table
64
captionSide="top"
65
fontSize="md"
66
highlightOnHover
67
horizontalSpacing="xl"
68
striped
69
verticalSpacing="xs"
70
withBorder
71
withColumnBorders
72
>
73
{/* Use your own markup, customize however you want using the power of TanStack Table */}
74
<thead>
75
{table.getHeaderGroups().map((headerGroup) => (
76
<tr key={headerGroup.id}>
77
{headerGroup.headers.map((header) => (
78
<th key={header.id}>
79
{header.isPlaceholder
80
? null
81
: flexRender(
82
header.column.columnDef.Header ??
83
header.column.columnDef.header,
84
header.getContext(),
85
)}
86
</th>
87
))}
88
</tr>
89
))}
90
</thead>
91
<tbody>
92
{table.getRowModel().rows.map((row) => (
93
<tr key={row.id}>
94
{row.getVisibleCells().map((cell) => (
95
<td key={cell.id}>
96
{flexRender(
97
cell.column.columnDef.Cell ?? cell.column.columnDef.cell,
98
cell.getContext(),
99
)}
100
</td>
101
))}
102
</tr>
103
))}
104
</tbody>
105
</Table>
106
<MRT_ToolbarAlertBanner stackAlertBanner table={table} />
107
</Stack>
108
);
109
};
110
111
export default Example;
View Extra Storybook Examples
You can help make these docs better! PRs are Welcome
Using Material-UI instead of Mantine?
Check out Material React Table