@mini_7/material-react-table-mcp 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +68 -0
  2. package/data/MIGRATION.md +136 -0
  3. package/data/api.json +5379 -0
  4. package/data/examples/advanced.tsx +309 -0
  5. package/data/examples/aggregation-and-grouping.tsx +153 -0
  6. package/data/examples/aggregation-multi.tsx +105 -0
  7. package/data/examples/alternate-column-filtering.tsx +49 -0
  8. package/data/examples/alternate-detail-panel.tsx +81 -0
  9. package/data/examples/alternate-pagination.tsx +23 -0
  10. package/data/examples/basic.tsx +109 -0
  11. package/data/examples/chart-detail-panel.tsx +89 -0
  12. package/data/examples/column-actions-space.tsx +44 -0
  13. package/data/examples/column-alignment.tsx +70 -0
  14. package/data/examples/custom-column-actions.tsx +109 -0
  15. package/data/examples/custom-column-filtering-ui.tsx +89 -0
  16. package/data/examples/custom-headless.tsx +125 -0
  17. package/data/examples/custom-top-toolbar.tsx +88 -0
  18. package/data/examples/customize-display-columns.tsx +85 -0
  19. package/data/examples/customize-filter-components.tsx +101 -0
  20. package/data/examples/customize-filter-modes.tsx +73 -0
  21. package/data/examples/customize-filter-variants.tsx +116 -0
  22. package/data/examples/customize-global-filter-component.tsx +52 -0
  23. package/data/examples/customize-remove-column-grouping.tsx +94 -0
  24. package/data/examples/customize-row-selection.tsx +54 -0
  25. package/data/examples/customize-table-styles.tsx +100 -0
  26. package/data/examples/disable-column-actions.tsx +37 -0
  27. package/data/examples/disable-column-hiding.tsx +90 -0
  28. package/data/examples/disable-density-toggle.tsx +49 -0
  29. package/data/examples/dynamic-columns.tsx +189 -0
  30. package/data/examples/editing-crud-cell.tsx +377 -0
  31. package/data/examples/editing-crud-modal.tsx +370 -0
  32. package/data/examples/editing-crud-row.tsx +333 -0
  33. package/data/examples/editing-crud-table.tsx +369 -0
  34. package/data/examples/editing-crud-tree.tsx +416 -0
  35. package/data/examples/enable-cell-actions.tsx +76 -0
  36. package/data/examples/enable-click-to-copy.tsx +39 -0
  37. package/data/examples/enable-column-grouping.tsx +120 -0
  38. package/data/examples/enable-column-ordering.tsx +48 -0
  39. package/data/examples/enable-column-pinning.tsx +69 -0
  40. package/data/examples/enable-column-resizing.tsx +56 -0
  41. package/data/examples/enable-column-virtualization.tsx +27 -0
  42. package/data/examples/enable-detail-panel-conditionally.tsx +78 -0
  43. package/data/examples/enable-detail-panel-virtualized.tsx +80 -0
  44. package/data/examples/enable-expanding-tree.tsx +110 -0
  45. package/data/examples/enable-filter-facet-values.tsx +65 -0
  46. package/data/examples/enable-row-dragging.tsx +137 -0
  47. package/data/examples/enable-row-numbers-original.tsx +48 -0
  48. package/data/examples/enable-row-numbers-static.tsx +48 -0
  49. package/data/examples/enable-row-ordering.tsx +57 -0
  50. package/data/examples/enable-row-pinning-select.tsx +76 -0
  51. package/data/examples/enable-row-pinning-static.tsx +50 -0
  52. package/data/examples/enable-row-pinning-sticky.tsx +69 -0
  53. package/data/examples/enable-row-selection.tsx +96 -0
  54. package/data/examples/enable-row-virtualization.tsx +101 -0
  55. package/data/examples/enable-sticky-header.tsx +59 -0
  56. package/data/examples/expanding-tree-expanded.tsx +121 -0
  57. package/data/examples/expanding-tree-flat-parse.tsx +125 -0
  58. package/data/examples/expanding-tree-root-expanded.tsx +151 -0
  59. package/data/examples/export-to-csv.tsx +114 -0
  60. package/data/examples/export-to-pdf.tsx +104 -0
  61. package/data/examples/external-toolbar.tsx +108 -0
  62. package/data/examples/font-awesome-icons.tsx +106 -0
  63. package/data/examples/infinite-scrolling.tsx +208 -0
  64. package/data/examples/lazy-detail-panel.tsx +262 -0
  65. package/data/examples/lazy-sub-rows.tsx +190 -0
  66. package/data/examples/linear-progress.tsx +66 -0
  67. package/data/examples/loading.tsx +50 -0
  68. package/data/examples/localization-i18n-ar.tsx +65 -0
  69. package/data/examples/localization-i18n-az.tsx +60 -0
  70. package/data/examples/localization-i18n-bg.tsx +60 -0
  71. package/data/examples/localization-i18n-cs.tsx +60 -0
  72. package/data/examples/localization-i18n-da.tsx +60 -0
  73. package/data/examples/localization-i18n-de.tsx +60 -0
  74. package/data/examples/localization-i18n-el.tsx +60 -0
  75. package/data/examples/localization-i18n-en.tsx +60 -0
  76. package/data/examples/localization-i18n-es.tsx +60 -0
  77. package/data/examples/localization-i18n-et.tsx +60 -0
  78. package/data/examples/localization-i18n-fa.tsx +66 -0
  79. package/data/examples/localization-i18n-fi.tsx +60 -0
  80. package/data/examples/localization-i18n-fr.tsx +60 -0
  81. package/data/examples/localization-i18n-he.tsx +66 -0
  82. package/data/examples/localization-i18n-hr.tsx +60 -0
  83. package/data/examples/localization-i18n-hu.tsx +60 -0
  84. package/data/examples/localization-i18n-hy.tsx +65 -0
  85. package/data/examples/localization-i18n-id.tsx +60 -0
  86. package/data/examples/localization-i18n-it.tsx +60 -0
  87. package/data/examples/localization-i18n-ja.tsx +60 -0
  88. package/data/examples/localization-i18n-ko.tsx +60 -0
  89. package/data/examples/localization-i18n-nl.tsx +60 -0
  90. package/data/examples/localization-i18n-no.tsx +60 -0
  91. package/data/examples/localization-i18n-np.tsx +60 -0
  92. package/data/examples/localization-i18n-pl.tsx +60 -0
  93. package/data/examples/localization-i18n-pt-BR.tsx +60 -0
  94. package/data/examples/localization-i18n-pt.tsx +60 -0
  95. package/data/examples/localization-i18n-ro.tsx +60 -0
  96. package/data/examples/localization-i18n-ru.tsx +60 -0
  97. package/data/examples/localization-i18n-sk.tsx +60 -0
  98. package/data/examples/localization-i18n-sr-Cyrl-RS.tsx +60 -0
  99. package/data/examples/localization-i18n-sr-Latn-RS.tsx +60 -0
  100. package/data/examples/localization-i18n-sv.tsx +60 -0
  101. package/data/examples/localization-i18n-tr.tsx +60 -0
  102. package/data/examples/localization-i18n-uk.tsx +60 -0
  103. package/data/examples/localization-i18n-vi.tsx +60 -0
  104. package/data/examples/localization-i18n-zh-hans.tsx +60 -0
  105. package/data/examples/localization-i18n-zh-hant.tsx +60 -0
  106. package/data/examples/manual-selection.tsx +105 -0
  107. package/data/examples/minimal.tsx +78 -0
  108. package/data/examples/mui-theme.tsx +136 -0
  109. package/data/examples/multi-sorting.tsx +58 -0
  110. package/data/examples/persistent-state.tsx +184 -0
  111. package/data/examples/react-query.tsx +182 -0
  112. package/data/examples/remote.tsx +150 -0
  113. package/data/examples/row-actions-buttons.tsx +89 -0
  114. package/data/examples/row-actions-menu-items.tsx +64 -0
  115. package/data/examples/single-row-selection.tsx +98 -0
  116. package/data/examples/virtualized.tsx +138 -0
  117. package/data/guides/accessibility.md +119 -0
  118. package/data/guides/aggregation.md +210 -0
  119. package/data/guides/async-loading.md +132 -0
  120. package/data/guides/best-practices.md +363 -0
  121. package/data/guides/cell-actions.md +139 -0
  122. package/data/guides/click-to-copy.md +67 -0
  123. package/data/guides/column-actions.md +69 -0
  124. package/data/guides/column-filtering.md +366 -0
  125. package/data/guides/column-grouping.md +192 -0
  126. package/data/guides/column-hiding.md +133 -0
  127. package/data/guides/column-ordering-dnd.md +99 -0
  128. package/data/guides/column-pinning.md +72 -0
  129. package/data/guides/column-resizing.md +157 -0
  130. package/data/guides/column-size.md +162 -0
  131. package/data/guides/customize-components.md +395 -0
  132. package/data/guides/customize-icons.md +35 -0
  133. package/data/guides/data-columns.md +292 -0
  134. package/data/guides/density-toggle.md +46 -0
  135. package/data/guides/detail-panel.md +195 -0
  136. package/data/guides/display-columns.md +135 -0
  137. package/data/guides/editing.md +367 -0
  138. package/data/guides/expanding-sub-rows.md +194 -0
  139. package/data/guides/full-screen-toggle.md +63 -0
  140. package/data/guides/global-filtering.md +237 -0
  141. package/data/guides/localization.md +57 -0
  142. package/data/guides/memoization.md +157 -0
  143. package/data/guides/pagination.md +171 -0
  144. package/data/guides/row-actions.md +116 -0
  145. package/data/guides/row-numbers.md +24 -0
  146. package/data/guides/row-ordering-dnd.md +51 -0
  147. package/data/guides/row-pinning.md +96 -0
  148. package/data/guides/row-selection.md +237 -0
  149. package/data/guides/sorting.md +190 -0
  150. package/data/guides/state-management.md +165 -0
  151. package/data/guides/sticky-header.md +41 -0
  152. package/data/guides/table-event-listeners.md +103 -0
  153. package/data/guides/toolbar-customization.md +251 -0
  154. package/data/guides/virtualization.md +183 -0
  155. package/data/index.json +1930 -0
  156. package/data/reference/mrt-components.md +183 -0
  157. package/data/reference/mrt-hooks.md +125 -0
  158. package/data/skills/composable-components/SKILL.md +189 -0
  159. package/data/skills/customization/SKILL.md +190 -0
  160. package/data/skills/drag-and-drop-ordering/SKILL.md +227 -0
  161. package/data/skills/editing/SKILL.md +243 -0
  162. package/data/skills/filtering/SKILL.md +213 -0
  163. package/data/skills/getting-started/SKILL.md +213 -0
  164. package/data/skills/localization/SKILL.md +182 -0
  165. package/data/skills/migrate-v3-to-v4/SKILL.md +161 -0
  166. package/data/skills/state-and-server-data/SKILL.md +200 -0
  167. package/data/skills/virtualization/SKILL.md +203 -0
  168. package/dist/data.js +137 -0
  169. package/dist/index.js +232 -0
  170. package/package.json +50 -0
@@ -0,0 +1,309 @@
1
+ import { useMemo } from 'react';
2
+
3
+ //MRT Imports
4
+ import {
5
+ MaterialReactTable,
6
+ useMaterialReactTable,
7
+ type MRT_ColumnDef,
8
+ MRT_GlobalFilterTextField,
9
+ MRT_ToggleFiltersButton,
10
+ } from 'material-react-table';
11
+
12
+ //Material UI Imports
13
+ import {
14
+ Box,
15
+ Button,
16
+ ListItemIcon,
17
+ MenuItem,
18
+ Typography,
19
+ lighten,
20
+ } from '@mui/material';
21
+
22
+ //Icons Imports
23
+ import { AccountCircle, Send } from '@mui/icons-material';
24
+
25
+ //Mock Data
26
+ import { data } from './makeData';
27
+
28
+ export type Employee = {
29
+ firstName: string;
30
+ lastName: string;
31
+ email: string;
32
+ jobTitle: string;
33
+ salary: number;
34
+ startDate: string;
35
+ signatureCatchPhrase: string;
36
+ avatar: string;
37
+ };
38
+
39
+ const Example = () => {
40
+ const columns = useMemo<MRT_ColumnDef<Employee>[]>(
41
+ () => [
42
+ {
43
+ id: 'employee', //id used to define `group` column
44
+ header: 'Employee',
45
+ columns: [
46
+ {
47
+ accessorFn: (row) => `${row.firstName} ${row.lastName}`, //accessorFn used to join multiple data into a single cell
48
+ id: 'name', //id is still required when using accessorFn instead of accessorKey
49
+ header: 'Name',
50
+ size: 250,
51
+ Cell: ({ renderedCellValue, row }) => (
52
+ <Box
53
+ sx={{
54
+ display: 'flex',
55
+ alignItems: 'center',
56
+ gap: '1rem',
57
+ }}
58
+ >
59
+ <img
60
+ alt="avatar"
61
+ height={30}
62
+ src={row.original.avatar}
63
+ loading="lazy"
64
+ style={{ borderRadius: '50%' }}
65
+ />
66
+ {/* using renderedCellValue instead of cell.getValue() preserves filter match highlighting */}
67
+ <span>{renderedCellValue}</span>
68
+ </Box>
69
+ ),
70
+ },
71
+ {
72
+ accessorKey: 'email', //accessorKey used to define `data` column. `id` gets set to accessorKey automatically
73
+ enableClickToCopy: true,
74
+ filterVariant: 'autocomplete',
75
+ header: 'Email',
76
+ size: 300,
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ id: 'id',
82
+ header: 'Job Info',
83
+ columns: [
84
+ {
85
+ accessorKey: 'salary',
86
+ // filterVariant: 'range', //if not using filter modes feature, use this instead of filterFn
87
+ filterFn: 'between',
88
+ header: 'Salary',
89
+ size: 200,
90
+ //custom conditional format and styling
91
+ Cell: ({ cell }) => (
92
+ <Box
93
+ component="span"
94
+ sx={(theme) => ({
95
+ backgroundColor:
96
+ cell.getValue<number>() < 50_000
97
+ ? theme.palette.error.dark
98
+ : cell.getValue<number>() >= 50_000 &&
99
+ cell.getValue<number>() < 75_000
100
+ ? theme.palette.warning.dark
101
+ : theme.palette.success.dark,
102
+ borderRadius: '0.25rem',
103
+ color: '#fff',
104
+ maxWidth: '9ch',
105
+ p: '0.25rem',
106
+ })}
107
+ >
108
+ {cell.getValue<number>()?.toLocaleString?.('en-US', {
109
+ style: 'currency',
110
+ currency: 'USD',
111
+ minimumFractionDigits: 0,
112
+ maximumFractionDigits: 0,
113
+ })}
114
+ </Box>
115
+ ),
116
+ },
117
+ {
118
+ accessorKey: 'jobTitle', //hey a simple column for once
119
+ header: 'Job Title',
120
+ size: 350,
121
+ },
122
+ {
123
+ accessorFn: (row) => new Date(row.startDate), //convert to Date for sorting and filtering
124
+ id: 'startDate',
125
+ header: 'Start Date',
126
+ filterVariant: 'date',
127
+ filterFn: 'lessThan',
128
+ sortFn: 'datetime',
129
+ Cell: ({ cell }) => cell.getValue<Date>()?.toLocaleDateString(), //render Date as a string
130
+ Header: ({ column }) => <em>{column.columnDef.header}</em>, //custom header markup
131
+ muiFilterTextFieldProps: {
132
+ sx: {
133
+ minWidth: '250px',
134
+ },
135
+ },
136
+ },
137
+ ],
138
+ },
139
+ ],
140
+ [],
141
+ );
142
+
143
+ const table = useMaterialReactTable({
144
+ columns,
145
+ data, //data must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
146
+ enableColumnFilterModes: true,
147
+ enableColumnOrdering: true,
148
+ enableGrouping: true,
149
+ enableColumnPinning: true,
150
+ enableFacetedValues: true,
151
+ enableRowActions: true,
152
+ enableRowSelection: true,
153
+ initialState: {
154
+ showColumnFilters: true,
155
+ showGlobalFilter: true,
156
+ columnPinning: {
157
+ end: ['mrt-row-actions'],
158
+ start: ['mrt-row-expand', 'mrt-row-select'],
159
+ },
160
+ },
161
+ paginationDisplayMode: 'pages',
162
+ positionToolbarAlertBanner: 'bottom',
163
+ muiSearchTextFieldProps: {
164
+ size: 'small',
165
+ variant: 'outlined',
166
+ },
167
+ muiPaginationProps: {
168
+ color: 'secondary',
169
+ rowsPerPageOptions: [10, 20, 30],
170
+ shape: 'rounded',
171
+ variant: 'outlined',
172
+ },
173
+ renderDetailPanel: ({ row }) => (
174
+ <Box
175
+ sx={{
176
+ alignItems: 'center',
177
+ display: 'flex',
178
+ justifyContent: 'space-around',
179
+ left: '30px',
180
+ maxWidth: '1000px',
181
+ position: 'sticky',
182
+ width: '100%',
183
+ }}
184
+ >
185
+ <img
186
+ alt="avatar"
187
+ height={200}
188
+ src={row.original.avatar}
189
+ loading="lazy"
190
+ style={{ borderRadius: '50%' }}
191
+ />
192
+ <Box sx={{ textAlign: 'center' }}>
193
+ <Typography variant="h4">Signature Catch Phrase:</Typography>
194
+ <Typography variant="h1">
195
+ &quot;{row.original.signatureCatchPhrase}&quot;
196
+ </Typography>
197
+ </Box>
198
+ </Box>
199
+ ),
200
+ renderRowActionMenuItems: ({ closeMenu }) => [
201
+ <MenuItem
202
+ key={0}
203
+ onClick={() => {
204
+ // View profile logic...
205
+ closeMenu();
206
+ }}
207
+ sx={{ m: 0 }}
208
+ >
209
+ <ListItemIcon>
210
+ <AccountCircle />
211
+ </ListItemIcon>
212
+ View Profile
213
+ </MenuItem>,
214
+ <MenuItem
215
+ key={1}
216
+ onClick={() => {
217
+ // Send email logic...
218
+ closeMenu();
219
+ }}
220
+ sx={{ m: 0 }}
221
+ >
222
+ <ListItemIcon>
223
+ <Send />
224
+ </ListItemIcon>
225
+ Send Email
226
+ </MenuItem>,
227
+ ],
228
+ renderTopToolbar: ({ table }) => {
229
+ const handleDeactivate = () => {
230
+ table.getSelectedRowModel().flatRows.map((row) => {
231
+ alert('deactivating ' + row.getValue('name'));
232
+ });
233
+ };
234
+
235
+ const handleActivate = () => {
236
+ table.getSelectedRowModel().flatRows.map((row) => {
237
+ alert('activating ' + row.getValue('name'));
238
+ });
239
+ };
240
+
241
+ const handleContact = () => {
242
+ table.getSelectedRowModel().flatRows.map((row) => {
243
+ alert('contact ' + row.getValue('name'));
244
+ });
245
+ };
246
+
247
+ return (
248
+ <Box
249
+ sx={(theme) => ({
250
+ backgroundColor: lighten(theme.palette.background.default, 0.05),
251
+ display: 'flex',
252
+ gap: '0.5rem',
253
+ p: '8px',
254
+ justifyContent: 'space-between',
255
+ })}
256
+ >
257
+ <Box sx={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
258
+ {/* import MRT sub-components */}
259
+ <MRT_GlobalFilterTextField table={table} />
260
+ <MRT_ToggleFiltersButton table={table} />
261
+ </Box>
262
+ <Box>
263
+ <Box sx={{ display: 'flex', gap: '0.5rem' }}>
264
+ <Button
265
+ color="error"
266
+ disabled={!table.getIsSomeRowsSelected()}
267
+ onClick={handleDeactivate}
268
+ variant="contained"
269
+ >
270
+ Deactivate
271
+ </Button>
272
+ <Button
273
+ color="success"
274
+ disabled={!table.getIsSomeRowsSelected()}
275
+ onClick={handleActivate}
276
+ variant="contained"
277
+ >
278
+ Activate
279
+ </Button>
280
+ <Button
281
+ color="info"
282
+ disabled={!table.getIsSomeRowsSelected()}
283
+ onClick={handleContact}
284
+ variant="contained"
285
+ >
286
+ Contact
287
+ </Button>
288
+ </Box>
289
+ </Box>
290
+ </Box>
291
+ );
292
+ },
293
+ });
294
+
295
+ return <MaterialReactTable table={table} />;
296
+ };
297
+
298
+ //Date Picker Imports - these should just be in your Context Provider
299
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
300
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
301
+
302
+ const ExampleWithLocalizationProvider = () => (
303
+ //App.tsx or AppProviders file
304
+ <LocalizationProvider dateAdapter={AdapterDayjs}>
305
+ <Example />
306
+ </LocalizationProvider>
307
+ );
308
+
309
+ export default ExampleWithLocalizationProvider;
@@ -0,0 +1,153 @@
1
+ import { useMemo } from 'react';
2
+ import { Box, Stack } from '@mui/material';
3
+ import {
4
+ MaterialReactTable,
5
+ useMaterialReactTable,
6
+ type MRT_ColumnDef,
7
+ } from 'material-react-table';
8
+ import { data, type Person } from './makeData';
9
+
10
+ const Example = () => {
11
+ const averageSalary = useMemo(
12
+ () => data.reduce((acc, curr) => acc + curr.salary, 0) / data.length,
13
+ [],
14
+ );
15
+
16
+ const maxAge = useMemo(
17
+ () => data.reduce((acc, curr) => Math.max(acc, curr.age), 0),
18
+ [],
19
+ );
20
+
21
+ const columns = useMemo<MRT_ColumnDef<Person>[]>(
22
+ () => [
23
+ {
24
+ header: 'First Name',
25
+ accessorKey: 'firstName',
26
+ enableGrouping: false, //do not let this column be grouped
27
+ },
28
+ {
29
+ header: 'Last Name',
30
+ accessorKey: 'lastName',
31
+ },
32
+ {
33
+ header: 'Age',
34
+ accessorKey: 'age',
35
+ aggregationFn: 'max', //show the max age in the group (lots of pre-built aggregationFns to choose from)
36
+ //required to render an aggregated cell
37
+ AggregatedCell: ({ cell, table }) => (
38
+ <>
39
+ Oldest by{' '}
40
+ {table.getColumn(cell.row.groupingColumnId ?? '').columnDef.header}:{' '}
41
+ <Box
42
+ sx={{ color: 'info.main', display: 'inline', fontWeight: 'bold' }}
43
+ >
44
+ {cell.getValue<number>()}
45
+ </Box>
46
+ </>
47
+ ),
48
+ Footer: () => (
49
+ <Stack>
50
+ Max Age:
51
+ <Box
52
+ sx={{
53
+ color: 'warning.main',
54
+ }}
55
+ >
56
+ {Math.round(maxAge)}
57
+ </Box>
58
+ </Stack>
59
+ ),
60
+ },
61
+ {
62
+ header: 'Gender',
63
+ accessorKey: 'gender',
64
+ //optionally, customize the cell render when this column is grouped. Make the text blue and pluralize the word
65
+ GroupedCell: ({ cell, row }) => (
66
+ <Box sx={{ color: 'primary.main' }}>
67
+ <strong>{cell.getValue<string>()}s </strong> ({row.subRows?.length})
68
+ </Box>
69
+ ),
70
+ },
71
+ {
72
+ header: 'State',
73
+ accessorKey: 'state',
74
+ },
75
+ {
76
+ header: 'Salary',
77
+ accessorKey: 'salary',
78
+ aggregationFn: 'mean',
79
+ //required to render an aggregated cell, show the average salary in the group
80
+ AggregatedCell: ({ cell, table }) => (
81
+ <>
82
+ Average by{' '}
83
+ {table.getColumn(cell.row.groupingColumnId ?? '').columnDef.header}:{' '}
84
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
85
+ {cell.getValue<number>()?.toLocaleString?.('en-US', {
86
+ style: 'currency',
87
+ currency: 'USD',
88
+ minimumFractionDigits: 0,
89
+ maximumFractionDigits: 0,
90
+ })}
91
+ </Box>
92
+ </>
93
+ ),
94
+ //customize normal cell render on normal non-aggregated rows
95
+ Cell: ({ cell }) => (
96
+ <>
97
+ {cell.getValue<number>()?.toLocaleString?.('en-US', {
98
+ style: 'currency',
99
+ currency: 'USD',
100
+ minimumFractionDigits: 0,
101
+ maximumFractionDigits: 0,
102
+ })}
103
+ </>
104
+ ),
105
+ Footer: () => (
106
+ <Stack>
107
+ Average Salary:
108
+ <Box
109
+ sx={{
110
+ color: 'warning.main',
111
+ }}
112
+ >
113
+ {averageSalary?.toLocaleString?.('en-US', {
114
+ style: 'currency',
115
+ currency: 'USD',
116
+ minimumFractionDigits: 0,
117
+ maximumFractionDigits: 0,
118
+ })}
119
+ </Box>
120
+ </Stack>
121
+ ),
122
+ },
123
+ ],
124
+ [averageSalary, maxAge],
125
+ );
126
+
127
+ const table = useMaterialReactTable({
128
+ columns,
129
+ data,
130
+ displayColumnDefOptions: {
131
+ 'mrt-row-expand': {
132
+ enableResizing: true,
133
+ },
134
+ },
135
+ enableColumnResizing: true,
136
+ enableGrouping: true,
137
+ enableStickyHeader: true,
138
+ enableStickyFooter: true,
139
+ initialState: {
140
+ density: 'compact',
141
+ expanded: true, //expand all groups by default
142
+ grouping: ['state'], //an array of columns to group by by default (can be multiple)
143
+ pagination: { pageIndex: 0, pageSize: 20 },
144
+ sorting: [{ id: 'state', desc: false }], //sort by state by default
145
+ },
146
+ muiToolbarAlertBannerChipProps: { color: 'primary' },
147
+ muiTableContainerProps: { sx: { maxHeight: 700 } },
148
+ });
149
+
150
+ return <MaterialReactTable table={table} />;
151
+ };
152
+
153
+ export default Example;
@@ -0,0 +1,105 @@
1
+ import { useMemo } from 'react';
2
+ import { Box } from '@mui/material';
3
+ import {
4
+ MaterialReactTable,
5
+ useMaterialReactTable,
6
+ type MRT_ColumnDef,
7
+ } from 'material-react-table';
8
+ import { data, type Person } from './makeData';
9
+
10
+ const localeStringOptions = {
11
+ style: 'currency',
12
+ currency: 'USD',
13
+ minimumFractionDigits: 0,
14
+ maximumFractionDigits: 0,
15
+ } as const;
16
+
17
+ const Example = () => {
18
+ const columns = useMemo<MRT_ColumnDef<Person>[]>(
19
+ () => [
20
+ {
21
+ header: 'First Name',
22
+ accessorKey: 'firstName',
23
+ },
24
+ {
25
+ header: 'Last Name',
26
+ accessorKey: 'lastName',
27
+ },
28
+ {
29
+ header: 'Gender',
30
+ accessorKey: 'gender',
31
+ },
32
+ {
33
+ header: 'State',
34
+ accessorKey: 'state',
35
+ },
36
+ {
37
+ header: 'Salary',
38
+ accessorKey: 'salary',
39
+ aggregationFn: ['count', 'mean', 'median', 'min', 'max'],
40
+ //required to render an aggregated cell, show the average salary in the group
41
+ AggregatedCell: ({ cell }) => (
42
+ <>
43
+ Count:{' '}
44
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
45
+ {cell.getValue<Array<number>>()?.[0]}
46
+ </Box>
47
+ Average:{' '}
48
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
49
+ {cell
50
+ .getValue<Array<number>>()?.[1]
51
+ ?.toLocaleString?.('en-US', localeStringOptions)}
52
+ </Box>
53
+ Median:{' '}
54
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
55
+ {cell
56
+ .getValue<Array<number>>()?.[2]
57
+ ?.toLocaleString?.('en-US', localeStringOptions)}
58
+ </Box>
59
+ Min:{' '}
60
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
61
+ {cell
62
+ .getValue<Array<number>>()?.[3]
63
+ ?.toLocaleString?.('en-US', localeStringOptions)}
64
+ </Box>
65
+ Max:{' '}
66
+ <Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
67
+ {cell
68
+ .getValue<Array<number>>()?.[4]
69
+ ?.toLocaleString?.('en-US', localeStringOptions)}
70
+ </Box>
71
+ </>
72
+ ),
73
+ //customize normal cell render on normal non-aggregated rows
74
+ Cell: ({ cell }) => (
75
+ <>
76
+ {cell
77
+ .getValue<number>()
78
+ ?.toLocaleString?.('en-US', localeStringOptions)}
79
+ </>
80
+ ),
81
+ },
82
+ ],
83
+ [],
84
+ );
85
+
86
+ const table = useMaterialReactTable({
87
+ columns,
88
+ data,
89
+ enableGrouping: true,
90
+ enableStickyHeader: true,
91
+ initialState: {
92
+ density: 'compact',
93
+ expanded: true, //expand all groups by default
94
+ grouping: ['state'], //an array of columns to group by by default (can be multiple)
95
+ pagination: { pageIndex: 0, pageSize: 20 },
96
+ sorting: [{ id: 'state', desc: false }], //sort by state by default
97
+ },
98
+ muiToolbarAlertBannerChipProps: { color: 'primary' },
99
+ muiTableContainerProps: { sx: { maxHeight: 700 } },
100
+ });
101
+
102
+ return <MaterialReactTable table={table} />;
103
+ };
104
+
105
+ export default Example;
@@ -0,0 +1,49 @@
1
+ import { useMemo } from 'react';
2
+ import {
3
+ MaterialReactTable,
4
+ useMaterialReactTable,
5
+ type MRT_ColumnDef,
6
+ } from 'material-react-table';
7
+ import { data, type Person } from './makeData';
8
+
9
+ const Example = () => {
10
+ const columns = useMemo<MRT_ColumnDef<Person>[]>(
11
+ () => [
12
+ {
13
+ accessorKey: 'id',
14
+ header: 'ID',
15
+ },
16
+ {
17
+ accessorKey: 'firstName',
18
+ header: 'First Name',
19
+ },
20
+ {
21
+ accessorKey: 'lastName',
22
+ header: 'Last Name',
23
+ },
24
+ {
25
+ accessorKey: 'gender',
26
+ header: 'Gender',
27
+ filterFn: 'equals',
28
+ filterSelectOptions: ['Male', 'Female', 'Other'],
29
+ filterVariant: 'select',
30
+ },
31
+ {
32
+ accessorKey: 'age',
33
+ header: 'Age',
34
+ filterVariant: 'range',
35
+ },
36
+ ],
37
+ [],
38
+ );
39
+
40
+ const table = useMaterialReactTable({
41
+ columns,
42
+ data,
43
+ columnFilterDisplayMode: 'popover',
44
+ });
45
+
46
+ return <MaterialReactTable table={table} />;
47
+ };
48
+
49
+ export default Example;
@@ -0,0 +1,81 @@
1
+ import { useMemo } from 'react';
2
+ import {
3
+ MaterialReactTable,
4
+ useMaterialReactTable,
5
+ type MRT_ColumnDef,
6
+ } from 'material-react-table';
7
+ import { Box, Typography, useMediaQuery } from '@mui/material';
8
+ import { data, type Person } from './makeData';
9
+
10
+ const Example = () => {
11
+ const isMobile = useMediaQuery('(max-width: 720px)');
12
+
13
+ const columns = useMemo<MRT_ColumnDef<Person>[]>(
14
+ //column definitions...
15
+ () => [
16
+ {
17
+ accessorKey: 'id',
18
+ header: 'ID',
19
+ size: 50,
20
+ },
21
+ {
22
+ accessorKey: 'firstName',
23
+ header: 'First Name',
24
+ },
25
+ {
26
+ accessorKey: 'middleName',
27
+ header: 'Middle Name',
28
+ },
29
+ {
30
+ accessorKey: 'lastName',
31
+ header: 'Last Name',
32
+ },
33
+ ],
34
+ [],
35
+ //end
36
+ );
37
+
38
+ const table = useMaterialReactTable({
39
+ columns,
40
+ data,
41
+ // displayColumnDefOptions: { //built-in now in v2.6.0 when positionExpandColumn is 'last'
42
+ // 'mrt-row-expand': {
43
+ // muiTableHeadCellProps: {
44
+ // align: 'right',
45
+ // },
46
+ // muiTableBodyCellProps: {
47
+ // align: 'right',
48
+ // },
49
+ // },
50
+ // },
51
+ enableColumnPinning: isMobile, //alternative
52
+ initialState: {
53
+ expanded: true,
54
+ },
55
+ state: {
56
+ columnPinning: isMobile
57
+ ? { end: ['mrt-row-expand'], start: [] }
58
+ : { end: [], start: [] }, //alternative
59
+ },
60
+ renderDetailPanel: ({ row }) => (
61
+ <Box
62
+ sx={{
63
+ display: 'grid',
64
+ margin: 'auto',
65
+ gridTemplateColumns: '1fr 1fr',
66
+ width: '100%',
67
+ }}
68
+ >
69
+ <Typography>Address: {row.original.address}</Typography>
70
+ <Typography>City: {row.original.city}</Typography>
71
+ <Typography>State: {row.original.state}</Typography>
72
+ <Typography>Country: {row.original.country}</Typography>
73
+ </Box>
74
+ ),
75
+ positionExpandColumn: 'last',
76
+ });
77
+
78
+ return <MaterialReactTable table={table} />;
79
+ };
80
+
81
+ export default Example;