@mini_7/material-react-table-mcp 4.0.0 → 4.0.1
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.
- package/README.md +1 -1
- package/data/examples/advanced.js +215 -0
- package/data/examples/aggregation-and-grouping.js +116 -0
- package/data/examples/aggregation-multi.js +89 -0
- package/data/examples/alternate-column-filtering.js +38 -0
- package/data/examples/alternate-detail-panel.js +65 -0
- package/data/examples/alternate-pagination.js +17 -0
- package/data/examples/basic.js +86 -0
- package/data/examples/chart-detail-panel.js +69 -0
- package/data/examples/column-actions-space.js +34 -0
- package/data/examples/column-alignment.js +58 -0
- package/data/examples/custom-column-actions.js +74 -0
- package/data/examples/custom-column-filtering-ui.js +59 -0
- package/data/examples/custom-headless.js +85 -0
- package/data/examples/custom-top-toolbar.js +60 -0
- package/data/examples/customize-display-columns.js +72 -0
- package/data/examples/customize-filter-components.js +78 -0
- package/data/examples/customize-filter-modes.js +59 -0
- package/data/examples/customize-filter-variants.js +98 -0
- package/data/examples/customize-global-filter-component.js +37 -0
- package/data/examples/customize-remove-column-grouping.js +75 -0
- package/data/examples/customize-row-selection.js +43 -0
- package/data/examples/customize-table-styles.js +81 -0
- package/data/examples/disable-column-actions.js +26 -0
- package/data/examples/disable-column-hiding.js +74 -0
- package/data/examples/disable-density-toggle.js +37 -0
- package/data/examples/dynamic-columns.js +124 -0
- package/data/examples/editing-crud-cell.js +288 -0
- package/data/examples/editing-crud-modal.js +275 -0
- package/data/examples/editing-crud-row.js +255 -0
- package/data/examples/editing-crud-table.js +280 -0
- package/data/examples/editing-crud-tree.js +328 -0
- package/data/examples/enable-cell-actions.js +52 -0
- package/data/examples/enable-click-to-copy.js +33 -0
- package/data/examples/enable-column-grouping.js +69 -0
- package/data/examples/enable-column-ordering.js +37 -0
- package/data/examples/enable-column-pinning.js +58 -0
- package/data/examples/enable-column-resizing.js +45 -0
- package/data/examples/enable-column-virtualization.js +19 -0
- package/data/examples/enable-detail-panel-conditionally.js +61 -0
- package/data/examples/enable-detail-panel-virtualized.js +64 -0
- package/data/examples/enable-expanding-tree.js +87 -0
- package/data/examples/enable-filter-facet-values.js +52 -0
- package/data/examples/enable-row-dragging.js +102 -0
- package/data/examples/enable-row-numbers-original.js +37 -0
- package/data/examples/enable-row-numbers-static.js +37 -0
- package/data/examples/enable-row-ordering.js +40 -0
- package/data/examples/enable-row-pinning-select.js +64 -0
- package/data/examples/enable-row-pinning-static.js +39 -0
- package/data/examples/enable-row-pinning-sticky.js +57 -0
- package/data/examples/enable-row-selection.js +71 -0
- package/data/examples/enable-row-virtualization.js +85 -0
- package/data/examples/enable-sticky-header.js +47 -0
- package/data/examples/expanding-tree-expanded.js +98 -0
- package/data/examples/expanding-tree-flat-parse.js +102 -0
- package/data/examples/expanding-tree-root-expanded.js +120 -0
- package/data/examples/export-to-csv.js +84 -0
- package/data/examples/export-to-pdf.js +76 -0
- package/data/examples/external-toolbar.js +82 -0
- package/data/examples/font-awesome-icons.js +62 -0
- package/data/examples/infinite-scrolling.js +137 -0
- package/data/examples/lazy-detail-panel.js +164 -0
- package/data/examples/lazy-sub-rows.js +118 -0
- package/data/examples/linear-progress.js +48 -0
- package/data/examples/loading.js +34 -0
- package/data/examples/localization-i18n-ar.js +40 -0
- package/data/examples/localization-i18n-az.js +38 -0
- package/data/examples/localization-i18n-bg.js +38 -0
- package/data/examples/localization-i18n-cs.js +38 -0
- package/data/examples/localization-i18n-da.js +38 -0
- package/data/examples/localization-i18n-de.js +38 -0
- package/data/examples/localization-i18n-el.js +38 -0
- package/data/examples/localization-i18n-en.js +38 -0
- package/data/examples/localization-i18n-es.js +38 -0
- package/data/examples/localization-i18n-et.js +38 -0
- package/data/examples/localization-i18n-fa.js +40 -0
- package/data/examples/localization-i18n-fi.js +38 -0
- package/data/examples/localization-i18n-fr.js +38 -0
- package/data/examples/localization-i18n-he.js +40 -0
- package/data/examples/localization-i18n-hr.js +38 -0
- package/data/examples/localization-i18n-hu.js +38 -0
- package/data/examples/localization-i18n-hy.js +40 -0
- package/data/examples/localization-i18n-id.js +38 -0
- package/data/examples/localization-i18n-it.js +38 -0
- package/data/examples/localization-i18n-ja.js +38 -0
- package/data/examples/localization-i18n-ko.js +38 -0
- package/data/examples/localization-i18n-nl.js +38 -0
- package/data/examples/localization-i18n-no.js +38 -0
- package/data/examples/localization-i18n-np.js +38 -0
- package/data/examples/localization-i18n-pl.js +38 -0
- package/data/examples/localization-i18n-pt-BR.js +38 -0
- package/data/examples/localization-i18n-pt.js +38 -0
- package/data/examples/localization-i18n-ro.js +38 -0
- package/data/examples/localization-i18n-ru.js +38 -0
- package/data/examples/localization-i18n-sk.js +38 -0
- package/data/examples/localization-i18n-sr-Cyrl-RS.js +38 -0
- package/data/examples/localization-i18n-sr-Latn-RS.js +38 -0
- package/data/examples/localization-i18n-sv.js +38 -0
- package/data/examples/localization-i18n-tr.js +38 -0
- package/data/examples/localization-i18n-uk.js +38 -0
- package/data/examples/localization-i18n-vi.js +38 -0
- package/data/examples/localization-i18n-zh-hans.js +38 -0
- package/data/examples/localization-i18n-zh-hant.js +38 -0
- package/data/examples/manual-selection.js +81 -0
- package/data/examples/minimal.js +66 -0
- package/data/examples/mui-theme.js +109 -0
- package/data/examples/multi-sorting.js +48 -0
- package/data/examples/persistent-state.js +126 -0
- package/data/examples/react-query.js +122 -0
- package/data/examples/remote.js +113 -0
- package/data/examples/row-actions-buttons.js +54 -0
- package/data/examples/row-actions-menu-items.js +36 -0
- package/data/examples/single-row-selection.js +74 -0
- package/data/examples/virtualized.js +122 -0
- package/dist/data.js +31 -9
- package/dist/index.js +18 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ It serves the same data as the docs site: the API pages, every feature guide, th
|
|
|
15
15
|
| `search_mrt_docs` | Find which guide, reference page, skill, or example covers a topic, and which tool returns it. |
|
|
16
16
|
| `get_mrt_guide` | One of the 38 feature guides as Markdown, with its relevant options expanded and its live examples named. Call without a name to list them. |
|
|
17
17
|
| `get_mrt_reference` | The MRT components or MRT hooks reference page. |
|
|
18
|
-
| `get_mrt_example` | The
|
|
18
|
+
| `get_mrt_example` | The source of one of the 113 docs examples, as TypeScript or JavaScript. Call without an id to list them with the guides that embed each one. |
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
//MRT Imports
|
|
3
|
+
import { MaterialReactTable, useMaterialReactTable, MRT_GlobalFilterTextField, MRT_ToggleFiltersButton, } from 'material-react-table';
|
|
4
|
+
//Material UI Imports
|
|
5
|
+
import { Box, Button, ListItemIcon, MenuItem, Typography, lighten, } from '@mui/material';
|
|
6
|
+
//Icons Imports
|
|
7
|
+
import { AccountCircle, Send } from '@mui/icons-material';
|
|
8
|
+
//Mock Data
|
|
9
|
+
import { data } from './makeData';
|
|
10
|
+
const Example = () => {
|
|
11
|
+
const columns = useMemo(() => [
|
|
12
|
+
{
|
|
13
|
+
id: 'employee', //id used to define `group` column
|
|
14
|
+
header: 'Employee',
|
|
15
|
+
columns: [
|
|
16
|
+
{
|
|
17
|
+
accessorFn: (row) => `${row.firstName} ${row.lastName}`, //accessorFn used to join multiple data into a single cell
|
|
18
|
+
id: 'name', //id is still required when using accessorFn instead of accessorKey
|
|
19
|
+
header: 'Name',
|
|
20
|
+
size: 250,
|
|
21
|
+
Cell: ({ renderedCellValue, row }) => (<Box sx={{
|
|
22
|
+
display: 'flex',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
gap: '1rem',
|
|
25
|
+
}}>
|
|
26
|
+
<img alt="avatar" height={30} src={row.original.avatar} loading="lazy" style={{ borderRadius: '50%' }}/>
|
|
27
|
+
{/* using renderedCellValue instead of cell.getValue() preserves filter match highlighting */}
|
|
28
|
+
<span>{renderedCellValue}</span>
|
|
29
|
+
</Box>),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
accessorKey: 'email', //accessorKey used to define `data` column. `id` gets set to accessorKey automatically
|
|
33
|
+
enableClickToCopy: true,
|
|
34
|
+
filterVariant: 'autocomplete',
|
|
35
|
+
header: 'Email',
|
|
36
|
+
size: 300,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'id',
|
|
42
|
+
header: 'Job Info',
|
|
43
|
+
columns: [
|
|
44
|
+
{
|
|
45
|
+
accessorKey: 'salary',
|
|
46
|
+
// filterVariant: 'range', //if not using filter modes feature, use this instead of filterFn
|
|
47
|
+
filterFn: 'between',
|
|
48
|
+
header: 'Salary',
|
|
49
|
+
size: 200,
|
|
50
|
+
//custom conditional format and styling
|
|
51
|
+
Cell: ({ cell }) => (<Box component="span" sx={(theme) => ({
|
|
52
|
+
backgroundColor: cell.getValue() < 50000
|
|
53
|
+
? theme.palette.error.dark
|
|
54
|
+
: cell.getValue() >= 50000 &&
|
|
55
|
+
cell.getValue() < 75000
|
|
56
|
+
? theme.palette.warning.dark
|
|
57
|
+
: theme.palette.success.dark,
|
|
58
|
+
borderRadius: '0.25rem',
|
|
59
|
+
color: '#fff',
|
|
60
|
+
maxWidth: '9ch',
|
|
61
|
+
p: '0.25rem',
|
|
62
|
+
})}>
|
|
63
|
+
{cell.getValue()?.toLocaleString?.('en-US', {
|
|
64
|
+
style: 'currency',
|
|
65
|
+
currency: 'USD',
|
|
66
|
+
minimumFractionDigits: 0,
|
|
67
|
+
maximumFractionDigits: 0,
|
|
68
|
+
})}
|
|
69
|
+
</Box>),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
accessorKey: 'jobTitle', //hey a simple column for once
|
|
73
|
+
header: 'Job Title',
|
|
74
|
+
size: 350,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
accessorFn: (row) => new Date(row.startDate), //convert to Date for sorting and filtering
|
|
78
|
+
id: 'startDate',
|
|
79
|
+
header: 'Start Date',
|
|
80
|
+
filterVariant: 'date',
|
|
81
|
+
filterFn: 'lessThan',
|
|
82
|
+
sortFn: 'datetime',
|
|
83
|
+
Cell: ({ cell }) => cell.getValue()?.toLocaleDateString(), //render Date as a string
|
|
84
|
+
Header: ({ column }) => <em>{column.columnDef.header}</em>, //custom header markup
|
|
85
|
+
muiFilterTextFieldProps: {
|
|
86
|
+
sx: {
|
|
87
|
+
minWidth: '250px',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
], []);
|
|
94
|
+
const table = useMaterialReactTable({
|
|
95
|
+
columns,
|
|
96
|
+
data, //data must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
|
|
97
|
+
enableColumnFilterModes: true,
|
|
98
|
+
enableColumnOrdering: true,
|
|
99
|
+
enableGrouping: true,
|
|
100
|
+
enableColumnPinning: true,
|
|
101
|
+
enableFacetedValues: true,
|
|
102
|
+
enableRowActions: true,
|
|
103
|
+
enableRowSelection: true,
|
|
104
|
+
initialState: {
|
|
105
|
+
showColumnFilters: true,
|
|
106
|
+
showGlobalFilter: true,
|
|
107
|
+
columnPinning: {
|
|
108
|
+
end: ['mrt-row-actions'],
|
|
109
|
+
start: ['mrt-row-expand', 'mrt-row-select'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
paginationDisplayMode: 'pages',
|
|
113
|
+
positionToolbarAlertBanner: 'bottom',
|
|
114
|
+
muiSearchTextFieldProps: {
|
|
115
|
+
size: 'small',
|
|
116
|
+
variant: 'outlined',
|
|
117
|
+
},
|
|
118
|
+
muiPaginationProps: {
|
|
119
|
+
color: 'secondary',
|
|
120
|
+
rowsPerPageOptions: [10, 20, 30],
|
|
121
|
+
shape: 'rounded',
|
|
122
|
+
variant: 'outlined',
|
|
123
|
+
},
|
|
124
|
+
renderDetailPanel: ({ row }) => (<Box sx={{
|
|
125
|
+
alignItems: 'center',
|
|
126
|
+
display: 'flex',
|
|
127
|
+
justifyContent: 'space-around',
|
|
128
|
+
left: '30px',
|
|
129
|
+
maxWidth: '1000px',
|
|
130
|
+
position: 'sticky',
|
|
131
|
+
width: '100%',
|
|
132
|
+
}}>
|
|
133
|
+
<img alt="avatar" height={200} src={row.original.avatar} loading="lazy" style={{ borderRadius: '50%' }}/>
|
|
134
|
+
<Box sx={{ textAlign: 'center' }}>
|
|
135
|
+
<Typography variant="h4">Signature Catch Phrase:</Typography>
|
|
136
|
+
<Typography variant="h1">
|
|
137
|
+
"{row.original.signatureCatchPhrase}"
|
|
138
|
+
</Typography>
|
|
139
|
+
</Box>
|
|
140
|
+
</Box>),
|
|
141
|
+
renderRowActionMenuItems: ({ closeMenu }) => [
|
|
142
|
+
<MenuItem key={0} onClick={() => {
|
|
143
|
+
// View profile logic...
|
|
144
|
+
closeMenu();
|
|
145
|
+
}} sx={{ m: 0 }}>
|
|
146
|
+
<ListItemIcon>
|
|
147
|
+
<AccountCircle />
|
|
148
|
+
</ListItemIcon>
|
|
149
|
+
View Profile
|
|
150
|
+
</MenuItem>,
|
|
151
|
+
<MenuItem key={1} onClick={() => {
|
|
152
|
+
// Send email logic...
|
|
153
|
+
closeMenu();
|
|
154
|
+
}} sx={{ m: 0 }}>
|
|
155
|
+
<ListItemIcon>
|
|
156
|
+
<Send />
|
|
157
|
+
</ListItemIcon>
|
|
158
|
+
Send Email
|
|
159
|
+
</MenuItem>,
|
|
160
|
+
],
|
|
161
|
+
renderTopToolbar: ({ table }) => {
|
|
162
|
+
const handleDeactivate = () => {
|
|
163
|
+
table.getSelectedRowModel().flatRows.map((row) => {
|
|
164
|
+
alert('deactivating ' + row.getValue('name'));
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
const handleActivate = () => {
|
|
168
|
+
table.getSelectedRowModel().flatRows.map((row) => {
|
|
169
|
+
alert('activating ' + row.getValue('name'));
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
const handleContact = () => {
|
|
173
|
+
table.getSelectedRowModel().flatRows.map((row) => {
|
|
174
|
+
alert('contact ' + row.getValue('name'));
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
return (<Box sx={(theme) => ({
|
|
178
|
+
backgroundColor: lighten(theme.palette.background.default, 0.05),
|
|
179
|
+
display: 'flex',
|
|
180
|
+
gap: '0.5rem',
|
|
181
|
+
p: '8px',
|
|
182
|
+
justifyContent: 'space-between',
|
|
183
|
+
})}>
|
|
184
|
+
<Box sx={{ display: 'flex', gap: '0.5rem', alignItems: 'center' }}>
|
|
185
|
+
{/* import MRT sub-components */}
|
|
186
|
+
<MRT_GlobalFilterTextField table={table}/>
|
|
187
|
+
<MRT_ToggleFiltersButton table={table}/>
|
|
188
|
+
</Box>
|
|
189
|
+
<Box>
|
|
190
|
+
<Box sx={{ display: 'flex', gap: '0.5rem' }}>
|
|
191
|
+
<Button color="error" disabled={!table.getIsSomeRowsSelected()} onClick={handleDeactivate} variant="contained">
|
|
192
|
+
Deactivate
|
|
193
|
+
</Button>
|
|
194
|
+
<Button color="success" disabled={!table.getIsSomeRowsSelected()} onClick={handleActivate} variant="contained">
|
|
195
|
+
Activate
|
|
196
|
+
</Button>
|
|
197
|
+
<Button color="info" disabled={!table.getIsSomeRowsSelected()} onClick={handleContact} variant="contained">
|
|
198
|
+
Contact
|
|
199
|
+
</Button>
|
|
200
|
+
</Box>
|
|
201
|
+
</Box>
|
|
202
|
+
</Box>);
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
return <MaterialReactTable table={table}/>;
|
|
206
|
+
};
|
|
207
|
+
//Date Picker Imports - these should just be in your Context Provider
|
|
208
|
+
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
209
|
+
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
210
|
+
const ExampleWithLocalizationProvider = () => (
|
|
211
|
+
//App.tsx or AppProviders file
|
|
212
|
+
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
213
|
+
<Example />
|
|
214
|
+
</LocalizationProvider>);
|
|
215
|
+
export default ExampleWithLocalizationProvider;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { Box, Stack } from '@mui/material';
|
|
3
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
4
|
+
import { data } from './makeData';
|
|
5
|
+
const Example = () => {
|
|
6
|
+
const averageSalary = useMemo(() => data.reduce((acc, curr) => acc + curr.salary, 0) / data.length, []);
|
|
7
|
+
const maxAge = useMemo(() => data.reduce((acc, curr) => Math.max(acc, curr.age), 0), []);
|
|
8
|
+
const columns = useMemo(() => [
|
|
9
|
+
{
|
|
10
|
+
header: 'First Name',
|
|
11
|
+
accessorKey: 'firstName',
|
|
12
|
+
enableGrouping: false, //do not let this column be grouped
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
header: 'Last Name',
|
|
16
|
+
accessorKey: 'lastName',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
header: 'Age',
|
|
20
|
+
accessorKey: 'age',
|
|
21
|
+
aggregationFn: 'max', //show the max age in the group (lots of pre-built aggregationFns to choose from)
|
|
22
|
+
//required to render an aggregated cell
|
|
23
|
+
AggregatedCell: ({ cell, table }) => (<>
|
|
24
|
+
Oldest by{' '}
|
|
25
|
+
{table.getColumn(cell.row.groupingColumnId ?? '').columnDef.header}:{' '}
|
|
26
|
+
<Box sx={{ color: 'info.main', display: 'inline', fontWeight: 'bold' }}>
|
|
27
|
+
{cell.getValue()}
|
|
28
|
+
</Box>
|
|
29
|
+
</>),
|
|
30
|
+
Footer: () => (<Stack>
|
|
31
|
+
Max Age:
|
|
32
|
+
<Box sx={{
|
|
33
|
+
color: 'warning.main',
|
|
34
|
+
}}>
|
|
35
|
+
{Math.round(maxAge)}
|
|
36
|
+
</Box>
|
|
37
|
+
</Stack>),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
header: 'Gender',
|
|
41
|
+
accessorKey: 'gender',
|
|
42
|
+
//optionally, customize the cell render when this column is grouped. Make the text blue and pluralize the word
|
|
43
|
+
GroupedCell: ({ cell, row }) => (<Box sx={{ color: 'primary.main' }}>
|
|
44
|
+
<strong>{cell.getValue()}s </strong> ({row.subRows?.length})
|
|
45
|
+
</Box>),
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
header: 'State',
|
|
49
|
+
accessorKey: 'state',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
header: 'Salary',
|
|
53
|
+
accessorKey: 'salary',
|
|
54
|
+
aggregationFn: 'mean',
|
|
55
|
+
//required to render an aggregated cell, show the average salary in the group
|
|
56
|
+
AggregatedCell: ({ cell, table }) => (<>
|
|
57
|
+
Average by{' '}
|
|
58
|
+
{table.getColumn(cell.row.groupingColumnId ?? '').columnDef.header}:{' '}
|
|
59
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
60
|
+
{cell.getValue()?.toLocaleString?.('en-US', {
|
|
61
|
+
style: 'currency',
|
|
62
|
+
currency: 'USD',
|
|
63
|
+
minimumFractionDigits: 0,
|
|
64
|
+
maximumFractionDigits: 0,
|
|
65
|
+
})}
|
|
66
|
+
</Box>
|
|
67
|
+
</>),
|
|
68
|
+
//customize normal cell render on normal non-aggregated rows
|
|
69
|
+
Cell: ({ cell }) => (<>
|
|
70
|
+
{cell.getValue()?.toLocaleString?.('en-US', {
|
|
71
|
+
style: 'currency',
|
|
72
|
+
currency: 'USD',
|
|
73
|
+
minimumFractionDigits: 0,
|
|
74
|
+
maximumFractionDigits: 0,
|
|
75
|
+
})}
|
|
76
|
+
</>),
|
|
77
|
+
Footer: () => (<Stack>
|
|
78
|
+
Average Salary:
|
|
79
|
+
<Box sx={{
|
|
80
|
+
color: 'warning.main',
|
|
81
|
+
}}>
|
|
82
|
+
{averageSalary?.toLocaleString?.('en-US', {
|
|
83
|
+
style: 'currency',
|
|
84
|
+
currency: 'USD',
|
|
85
|
+
minimumFractionDigits: 0,
|
|
86
|
+
maximumFractionDigits: 0,
|
|
87
|
+
})}
|
|
88
|
+
</Box>
|
|
89
|
+
</Stack>),
|
|
90
|
+
},
|
|
91
|
+
], [averageSalary, maxAge]);
|
|
92
|
+
const table = useMaterialReactTable({
|
|
93
|
+
columns,
|
|
94
|
+
data,
|
|
95
|
+
displayColumnDefOptions: {
|
|
96
|
+
'mrt-row-expand': {
|
|
97
|
+
enableResizing: true,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
enableColumnResizing: true,
|
|
101
|
+
enableGrouping: true,
|
|
102
|
+
enableStickyHeader: true,
|
|
103
|
+
enableStickyFooter: true,
|
|
104
|
+
initialState: {
|
|
105
|
+
density: 'compact',
|
|
106
|
+
expanded: true, //expand all groups by default
|
|
107
|
+
grouping: ['state'], //an array of columns to group by by default (can be multiple)
|
|
108
|
+
pagination: { pageIndex: 0, pageSize: 20 },
|
|
109
|
+
sorting: [{ id: 'state', desc: false }], //sort by state by default
|
|
110
|
+
},
|
|
111
|
+
muiToolbarAlertBannerChipProps: { color: 'primary' },
|
|
112
|
+
muiTableContainerProps: { sx: { maxHeight: 700 } },
|
|
113
|
+
});
|
|
114
|
+
return <MaterialReactTable table={table}/>;
|
|
115
|
+
};
|
|
116
|
+
export default Example;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { Box } from '@mui/material';
|
|
3
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
4
|
+
import { data } from './makeData';
|
|
5
|
+
const localeStringOptions = {
|
|
6
|
+
style: 'currency',
|
|
7
|
+
currency: 'USD',
|
|
8
|
+
minimumFractionDigits: 0,
|
|
9
|
+
maximumFractionDigits: 0,
|
|
10
|
+
};
|
|
11
|
+
const Example = () => {
|
|
12
|
+
const columns = useMemo(() => [
|
|
13
|
+
{
|
|
14
|
+
header: 'First Name',
|
|
15
|
+
accessorKey: 'firstName',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
header: 'Last Name',
|
|
19
|
+
accessorKey: 'lastName',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
header: 'Gender',
|
|
23
|
+
accessorKey: 'gender',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
header: 'State',
|
|
27
|
+
accessorKey: 'state',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
header: 'Salary',
|
|
31
|
+
accessorKey: 'salary',
|
|
32
|
+
aggregationFn: ['count', 'mean', 'median', 'min', 'max'],
|
|
33
|
+
//required to render an aggregated cell, show the average salary in the group
|
|
34
|
+
AggregatedCell: ({ cell }) => (<>
|
|
35
|
+
Count:{' '}
|
|
36
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
37
|
+
{cell.getValue()?.[0]}
|
|
38
|
+
</Box>
|
|
39
|
+
Average:{' '}
|
|
40
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
41
|
+
{cell
|
|
42
|
+
.getValue()?.[1]
|
|
43
|
+
?.toLocaleString?.('en-US', localeStringOptions)}
|
|
44
|
+
</Box>
|
|
45
|
+
Median:{' '}
|
|
46
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
47
|
+
{cell
|
|
48
|
+
.getValue()?.[2]
|
|
49
|
+
?.toLocaleString?.('en-US', localeStringOptions)}
|
|
50
|
+
</Box>
|
|
51
|
+
Min:{' '}
|
|
52
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
53
|
+
{cell
|
|
54
|
+
.getValue()?.[3]
|
|
55
|
+
?.toLocaleString?.('en-US', localeStringOptions)}
|
|
56
|
+
</Box>
|
|
57
|
+
Max:{' '}
|
|
58
|
+
<Box sx={{ color: 'success.main', fontWeight: 'bold' }}>
|
|
59
|
+
{cell
|
|
60
|
+
.getValue()?.[4]
|
|
61
|
+
?.toLocaleString?.('en-US', localeStringOptions)}
|
|
62
|
+
</Box>
|
|
63
|
+
</>),
|
|
64
|
+
//customize normal cell render on normal non-aggregated rows
|
|
65
|
+
Cell: ({ cell }) => (<>
|
|
66
|
+
{cell
|
|
67
|
+
.getValue()
|
|
68
|
+
?.toLocaleString?.('en-US', localeStringOptions)}
|
|
69
|
+
</>),
|
|
70
|
+
},
|
|
71
|
+
], []);
|
|
72
|
+
const table = useMaterialReactTable({
|
|
73
|
+
columns,
|
|
74
|
+
data,
|
|
75
|
+
enableGrouping: true,
|
|
76
|
+
enableStickyHeader: true,
|
|
77
|
+
initialState: {
|
|
78
|
+
density: 'compact',
|
|
79
|
+
expanded: true, //expand all groups by default
|
|
80
|
+
grouping: ['state'], //an array of columns to group by by default (can be multiple)
|
|
81
|
+
pagination: { pageIndex: 0, pageSize: 20 },
|
|
82
|
+
sorting: [{ id: 'state', desc: false }], //sort by state by default
|
|
83
|
+
},
|
|
84
|
+
muiToolbarAlertBannerChipProps: { color: 'primary' },
|
|
85
|
+
muiTableContainerProps: { sx: { maxHeight: 700 } },
|
|
86
|
+
});
|
|
87
|
+
return <MaterialReactTable table={table}/>;
|
|
88
|
+
};
|
|
89
|
+
export default Example;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
3
|
+
import { data } from './makeData';
|
|
4
|
+
const Example = () => {
|
|
5
|
+
const columns = useMemo(() => [
|
|
6
|
+
{
|
|
7
|
+
accessorKey: 'id',
|
|
8
|
+
header: 'ID',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
accessorKey: 'firstName',
|
|
12
|
+
header: 'First Name',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
accessorKey: 'lastName',
|
|
16
|
+
header: 'Last Name',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
accessorKey: 'gender',
|
|
20
|
+
header: 'Gender',
|
|
21
|
+
filterFn: 'equals',
|
|
22
|
+
filterSelectOptions: ['Male', 'Female', 'Other'],
|
|
23
|
+
filterVariant: 'select',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
accessorKey: 'age',
|
|
27
|
+
header: 'Age',
|
|
28
|
+
filterVariant: 'range',
|
|
29
|
+
},
|
|
30
|
+
], []);
|
|
31
|
+
const table = useMaterialReactTable({
|
|
32
|
+
columns,
|
|
33
|
+
data,
|
|
34
|
+
columnFilterDisplayMode: 'popover',
|
|
35
|
+
});
|
|
36
|
+
return <MaterialReactTable table={table}/>;
|
|
37
|
+
};
|
|
38
|
+
export default Example;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
3
|
+
import { Box, Typography, useMediaQuery } from '@mui/material';
|
|
4
|
+
import { data } from './makeData';
|
|
5
|
+
const Example = () => {
|
|
6
|
+
const isMobile = useMediaQuery('(max-width: 720px)');
|
|
7
|
+
const columns = useMemo(
|
|
8
|
+
//column definitions...
|
|
9
|
+
() => [
|
|
10
|
+
{
|
|
11
|
+
accessorKey: 'id',
|
|
12
|
+
header: 'ID',
|
|
13
|
+
size: 50,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
accessorKey: 'firstName',
|
|
17
|
+
header: 'First Name',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
accessorKey: 'middleName',
|
|
21
|
+
header: 'Middle Name',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
accessorKey: 'lastName',
|
|
25
|
+
header: 'Last Name',
|
|
26
|
+
},
|
|
27
|
+
], []);
|
|
28
|
+
const table = useMaterialReactTable({
|
|
29
|
+
columns,
|
|
30
|
+
data,
|
|
31
|
+
// displayColumnDefOptions: { //built-in now in v2.6.0 when positionExpandColumn is 'last'
|
|
32
|
+
// 'mrt-row-expand': {
|
|
33
|
+
// muiTableHeadCellProps: {
|
|
34
|
+
// align: 'right',
|
|
35
|
+
// },
|
|
36
|
+
// muiTableBodyCellProps: {
|
|
37
|
+
// align: 'right',
|
|
38
|
+
// },
|
|
39
|
+
// },
|
|
40
|
+
// },
|
|
41
|
+
enableColumnPinning: isMobile, //alternative
|
|
42
|
+
initialState: {
|
|
43
|
+
expanded: true,
|
|
44
|
+
},
|
|
45
|
+
state: {
|
|
46
|
+
columnPinning: isMobile
|
|
47
|
+
? { end: ['mrt-row-expand'], start: [] }
|
|
48
|
+
: { end: [], start: [] }, //alternative
|
|
49
|
+
},
|
|
50
|
+
renderDetailPanel: ({ row }) => (<Box sx={{
|
|
51
|
+
display: 'grid',
|
|
52
|
+
margin: 'auto',
|
|
53
|
+
gridTemplateColumns: '1fr 1fr',
|
|
54
|
+
width: '100%',
|
|
55
|
+
}}>
|
|
56
|
+
<Typography>Address: {row.original.address}</Typography>
|
|
57
|
+
<Typography>City: {row.original.city}</Typography>
|
|
58
|
+
<Typography>State: {row.original.state}</Typography>
|
|
59
|
+
<Typography>Country: {row.original.country}</Typography>
|
|
60
|
+
</Box>),
|
|
61
|
+
positionExpandColumn: 'last',
|
|
62
|
+
});
|
|
63
|
+
return <MaterialReactTable table={table}/>;
|
|
64
|
+
};
|
|
65
|
+
export default Example;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
2
|
+
import { columns, data } from './makeData';
|
|
3
|
+
const Example = () => {
|
|
4
|
+
const table = useMaterialReactTable({
|
|
5
|
+
columns,
|
|
6
|
+
data,
|
|
7
|
+
muiPaginationProps: {
|
|
8
|
+
color: 'primary',
|
|
9
|
+
shape: 'rounded',
|
|
10
|
+
showRowsPerPage: false,
|
|
11
|
+
variant: 'outlined',
|
|
12
|
+
},
|
|
13
|
+
paginationDisplayMode: 'pages',
|
|
14
|
+
});
|
|
15
|
+
return <MaterialReactTable table={table}/>;
|
|
16
|
+
};
|
|
17
|
+
export default Example;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { MaterialReactTable, useMaterialReactTable, } from 'material-react-table';
|
|
3
|
+
//nested data is ok, see accessorKeys in ColumnDef below
|
|
4
|
+
const data = [
|
|
5
|
+
{
|
|
6
|
+
name: {
|
|
7
|
+
firstName: 'John',
|
|
8
|
+
lastName: 'Doe',
|
|
9
|
+
},
|
|
10
|
+
address: '261 Erdman Ford',
|
|
11
|
+
city: 'East Daphne',
|
|
12
|
+
state: 'Kentucky',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: {
|
|
16
|
+
firstName: 'Jane',
|
|
17
|
+
lastName: 'Doe',
|
|
18
|
+
},
|
|
19
|
+
address: '769 Dominic Grove',
|
|
20
|
+
city: 'Columbus',
|
|
21
|
+
state: 'Ohio',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: {
|
|
25
|
+
firstName: 'Joe',
|
|
26
|
+
lastName: 'Doe',
|
|
27
|
+
},
|
|
28
|
+
address: '566 Brakus Inlet',
|
|
29
|
+
city: 'South Linda',
|
|
30
|
+
state: 'West Virginia',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: {
|
|
34
|
+
firstName: 'Kevin',
|
|
35
|
+
lastName: 'Vandy',
|
|
36
|
+
},
|
|
37
|
+
address: '722 Emie Stream',
|
|
38
|
+
city: 'Lincoln',
|
|
39
|
+
state: 'Nebraska',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: {
|
|
43
|
+
firstName: 'Joshua',
|
|
44
|
+
lastName: 'Rolluffs',
|
|
45
|
+
},
|
|
46
|
+
address: '32188 Larkin Turnpike',
|
|
47
|
+
city: 'Omaha',
|
|
48
|
+
state: 'Nebraska',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const Example = () => {
|
|
52
|
+
//should be memoized or stable
|
|
53
|
+
const columns = useMemo(() => [
|
|
54
|
+
{
|
|
55
|
+
accessorKey: 'name.firstName', //access nested data with dot notation
|
|
56
|
+
header: 'First Name',
|
|
57
|
+
size: 150,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
accessorKey: 'name.lastName',
|
|
61
|
+
header: 'Last Name',
|
|
62
|
+
size: 150,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
accessorKey: 'address', //normal accessorKey
|
|
66
|
+
header: 'Address',
|
|
67
|
+
size: 200,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
accessorKey: 'city',
|
|
71
|
+
header: 'City',
|
|
72
|
+
size: 150,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
accessorKey: 'state',
|
|
76
|
+
header: 'State',
|
|
77
|
+
size: 150,
|
|
78
|
+
},
|
|
79
|
+
], []);
|
|
80
|
+
const table = useMaterialReactTable({
|
|
81
|
+
columns,
|
|
82
|
+
data, //data must be memoized or stable (useState, useMemo, defined outside of this component, etc.)
|
|
83
|
+
});
|
|
84
|
+
return <MaterialReactTable table={table}/>;
|
|
85
|
+
};
|
|
86
|
+
export default Example;
|