@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.
- package/README.md +68 -0
- package/data/MIGRATION.md +136 -0
- package/data/api.json +5379 -0
- package/data/examples/advanced.tsx +309 -0
- package/data/examples/aggregation-and-grouping.tsx +153 -0
- package/data/examples/aggregation-multi.tsx +105 -0
- package/data/examples/alternate-column-filtering.tsx +49 -0
- package/data/examples/alternate-detail-panel.tsx +81 -0
- package/data/examples/alternate-pagination.tsx +23 -0
- package/data/examples/basic.tsx +109 -0
- package/data/examples/chart-detail-panel.tsx +89 -0
- package/data/examples/column-actions-space.tsx +44 -0
- package/data/examples/column-alignment.tsx +70 -0
- package/data/examples/custom-column-actions.tsx +109 -0
- package/data/examples/custom-column-filtering-ui.tsx +89 -0
- package/data/examples/custom-headless.tsx +125 -0
- package/data/examples/custom-top-toolbar.tsx +88 -0
- package/data/examples/customize-display-columns.tsx +85 -0
- package/data/examples/customize-filter-components.tsx +101 -0
- package/data/examples/customize-filter-modes.tsx +73 -0
- package/data/examples/customize-filter-variants.tsx +116 -0
- package/data/examples/customize-global-filter-component.tsx +52 -0
- package/data/examples/customize-remove-column-grouping.tsx +94 -0
- package/data/examples/customize-row-selection.tsx +54 -0
- package/data/examples/customize-table-styles.tsx +100 -0
- package/data/examples/disable-column-actions.tsx +37 -0
- package/data/examples/disable-column-hiding.tsx +90 -0
- package/data/examples/disable-density-toggle.tsx +49 -0
- package/data/examples/dynamic-columns.tsx +189 -0
- package/data/examples/editing-crud-cell.tsx +377 -0
- package/data/examples/editing-crud-modal.tsx +370 -0
- package/data/examples/editing-crud-row.tsx +333 -0
- package/data/examples/editing-crud-table.tsx +369 -0
- package/data/examples/editing-crud-tree.tsx +416 -0
- package/data/examples/enable-cell-actions.tsx +76 -0
- package/data/examples/enable-click-to-copy.tsx +39 -0
- package/data/examples/enable-column-grouping.tsx +120 -0
- package/data/examples/enable-column-ordering.tsx +48 -0
- package/data/examples/enable-column-pinning.tsx +69 -0
- package/data/examples/enable-column-resizing.tsx +56 -0
- package/data/examples/enable-column-virtualization.tsx +27 -0
- package/data/examples/enable-detail-panel-conditionally.tsx +78 -0
- package/data/examples/enable-detail-panel-virtualized.tsx +80 -0
- package/data/examples/enable-expanding-tree.tsx +110 -0
- package/data/examples/enable-filter-facet-values.tsx +65 -0
- package/data/examples/enable-row-dragging.tsx +137 -0
- package/data/examples/enable-row-numbers-original.tsx +48 -0
- package/data/examples/enable-row-numbers-static.tsx +48 -0
- package/data/examples/enable-row-ordering.tsx +57 -0
- package/data/examples/enable-row-pinning-select.tsx +76 -0
- package/data/examples/enable-row-pinning-static.tsx +50 -0
- package/data/examples/enable-row-pinning-sticky.tsx +69 -0
- package/data/examples/enable-row-selection.tsx +96 -0
- package/data/examples/enable-row-virtualization.tsx +101 -0
- package/data/examples/enable-sticky-header.tsx +59 -0
- package/data/examples/expanding-tree-expanded.tsx +121 -0
- package/data/examples/expanding-tree-flat-parse.tsx +125 -0
- package/data/examples/expanding-tree-root-expanded.tsx +151 -0
- package/data/examples/export-to-csv.tsx +114 -0
- package/data/examples/export-to-pdf.tsx +104 -0
- package/data/examples/external-toolbar.tsx +108 -0
- package/data/examples/font-awesome-icons.tsx +106 -0
- package/data/examples/infinite-scrolling.tsx +208 -0
- package/data/examples/lazy-detail-panel.tsx +262 -0
- package/data/examples/lazy-sub-rows.tsx +190 -0
- package/data/examples/linear-progress.tsx +66 -0
- package/data/examples/loading.tsx +50 -0
- package/data/examples/localization-i18n-ar.tsx +65 -0
- package/data/examples/localization-i18n-az.tsx +60 -0
- package/data/examples/localization-i18n-bg.tsx +60 -0
- package/data/examples/localization-i18n-cs.tsx +60 -0
- package/data/examples/localization-i18n-da.tsx +60 -0
- package/data/examples/localization-i18n-de.tsx +60 -0
- package/data/examples/localization-i18n-el.tsx +60 -0
- package/data/examples/localization-i18n-en.tsx +60 -0
- package/data/examples/localization-i18n-es.tsx +60 -0
- package/data/examples/localization-i18n-et.tsx +60 -0
- package/data/examples/localization-i18n-fa.tsx +66 -0
- package/data/examples/localization-i18n-fi.tsx +60 -0
- package/data/examples/localization-i18n-fr.tsx +60 -0
- package/data/examples/localization-i18n-he.tsx +66 -0
- package/data/examples/localization-i18n-hr.tsx +60 -0
- package/data/examples/localization-i18n-hu.tsx +60 -0
- package/data/examples/localization-i18n-hy.tsx +65 -0
- package/data/examples/localization-i18n-id.tsx +60 -0
- package/data/examples/localization-i18n-it.tsx +60 -0
- package/data/examples/localization-i18n-ja.tsx +60 -0
- package/data/examples/localization-i18n-ko.tsx +60 -0
- package/data/examples/localization-i18n-nl.tsx +60 -0
- package/data/examples/localization-i18n-no.tsx +60 -0
- package/data/examples/localization-i18n-np.tsx +60 -0
- package/data/examples/localization-i18n-pl.tsx +60 -0
- package/data/examples/localization-i18n-pt-BR.tsx +60 -0
- package/data/examples/localization-i18n-pt.tsx +60 -0
- package/data/examples/localization-i18n-ro.tsx +60 -0
- package/data/examples/localization-i18n-ru.tsx +60 -0
- package/data/examples/localization-i18n-sk.tsx +60 -0
- package/data/examples/localization-i18n-sr-Cyrl-RS.tsx +60 -0
- package/data/examples/localization-i18n-sr-Latn-RS.tsx +60 -0
- package/data/examples/localization-i18n-sv.tsx +60 -0
- package/data/examples/localization-i18n-tr.tsx +60 -0
- package/data/examples/localization-i18n-uk.tsx +60 -0
- package/data/examples/localization-i18n-vi.tsx +60 -0
- package/data/examples/localization-i18n-zh-hans.tsx +60 -0
- package/data/examples/localization-i18n-zh-hant.tsx +60 -0
- package/data/examples/manual-selection.tsx +105 -0
- package/data/examples/minimal.tsx +78 -0
- package/data/examples/mui-theme.tsx +136 -0
- package/data/examples/multi-sorting.tsx +58 -0
- package/data/examples/persistent-state.tsx +184 -0
- package/data/examples/react-query.tsx +182 -0
- package/data/examples/remote.tsx +150 -0
- package/data/examples/row-actions-buttons.tsx +89 -0
- package/data/examples/row-actions-menu-items.tsx +64 -0
- package/data/examples/single-row-selection.tsx +98 -0
- package/data/examples/virtualized.tsx +138 -0
- package/data/guides/accessibility.md +119 -0
- package/data/guides/aggregation.md +210 -0
- package/data/guides/async-loading.md +132 -0
- package/data/guides/best-practices.md +363 -0
- package/data/guides/cell-actions.md +139 -0
- package/data/guides/click-to-copy.md +67 -0
- package/data/guides/column-actions.md +69 -0
- package/data/guides/column-filtering.md +366 -0
- package/data/guides/column-grouping.md +192 -0
- package/data/guides/column-hiding.md +133 -0
- package/data/guides/column-ordering-dnd.md +99 -0
- package/data/guides/column-pinning.md +72 -0
- package/data/guides/column-resizing.md +157 -0
- package/data/guides/column-size.md +162 -0
- package/data/guides/customize-components.md +395 -0
- package/data/guides/customize-icons.md +35 -0
- package/data/guides/data-columns.md +292 -0
- package/data/guides/density-toggle.md +46 -0
- package/data/guides/detail-panel.md +195 -0
- package/data/guides/display-columns.md +135 -0
- package/data/guides/editing.md +367 -0
- package/data/guides/expanding-sub-rows.md +194 -0
- package/data/guides/full-screen-toggle.md +63 -0
- package/data/guides/global-filtering.md +237 -0
- package/data/guides/localization.md +57 -0
- package/data/guides/memoization.md +157 -0
- package/data/guides/pagination.md +171 -0
- package/data/guides/row-actions.md +116 -0
- package/data/guides/row-numbers.md +24 -0
- package/data/guides/row-ordering-dnd.md +51 -0
- package/data/guides/row-pinning.md +96 -0
- package/data/guides/row-selection.md +237 -0
- package/data/guides/sorting.md +190 -0
- package/data/guides/state-management.md +165 -0
- package/data/guides/sticky-header.md +41 -0
- package/data/guides/table-event-listeners.md +103 -0
- package/data/guides/toolbar-customization.md +251 -0
- package/data/guides/virtualization.md +183 -0
- package/data/index.json +1930 -0
- package/data/reference/mrt-components.md +183 -0
- package/data/reference/mrt-hooks.md +125 -0
- package/data/skills/composable-components/SKILL.md +189 -0
- package/data/skills/customization/SKILL.md +190 -0
- package/data/skills/drag-and-drop-ordering/SKILL.md +227 -0
- package/data/skills/editing/SKILL.md +243 -0
- package/data/skills/filtering/SKILL.md +213 -0
- package/data/skills/getting-started/SKILL.md +213 -0
- package/data/skills/localization/SKILL.md +182 -0
- package/data/skills/migrate-v3-to-v4/SKILL.md +161 -0
- package/data/skills/state-and-server-data/SKILL.md +200 -0
- package/data/skills/virtualization/SKILL.md +203 -0
- package/dist/data.js +137 -0
- package/dist/index.js +232 -0
- package/package.json +50 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
## MRT Best Practices
|
|
2
|
+
|
|
3
|
+
Here are some best practices to follow when using Material React Table. We'll cover Type-Safety (even if you are not using TypeScript) and how to best create re-usable MRT components.
|
|
4
|
+
|
|
5
|
+
### Stay Up-To-Date
|
|
6
|
+
|
|
7
|
+
Run this command in your terminal every few weeks to make sure you are using the latest version of Material React Table and MUI
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx npm-check-updates -u material-react-table @mui/material @mui/x-date-pickers @mui/icons-material @emotion/react @emotion/styled
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Type-Safety
|
|
14
|
+
|
|
15
|
+
TanStack Table itself is written in TypeScript, and Material React Table builds on top of its great type definitions for a best-in-class TypeScript experience.
|
|
16
|
+
|
|
17
|
+
If, however, you cannot use TypeScript in your project for some reason, checkout down below for [how to use JSDoc instead of TypeScript](#use-jsdoc-instead-of-typescript) to get the same type hints.
|
|
18
|
+
|
|
19
|
+
#### Is TypeScript Required?
|
|
20
|
+
|
|
21
|
+
No, TypeScript is not required to use Material React Table. You can just use JavaScript and everything will work just fine, but you will be missing out on a lot of great type hints and type safety that can help you build your app faster and with less bugs.
|
|
22
|
+
|
|
23
|
+
There are a couple of ways to still get type hints without TypeScript with the [`createMRTColumnHelper`](#createmrtcolumnhelper-utility) utility function or by using [JSDoc](#use-jsdoc-instead-of-typescript), so you can still get some of the benefits of type safety without TypeScript.
|
|
24
|
+
|
|
25
|
+
#### Defining TData Type
|
|
26
|
+
|
|
27
|
+
Material React Table makes use of generics to make working with your specific row data structures easier. You will see that most of the `MRT_*` types that you can use accept a `TData` generic.
|
|
28
|
+
|
|
29
|
+
Let's say that the data in your table is an array of users that looks like this:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
const data: User[] = [
|
|
33
|
+
{ id: 1, name: 'John', age: 23 },
|
|
34
|
+
{ id: 2, name: 'Alice', age: 17 },
|
|
35
|
+
{ id: 3, name: 'Bob', age: 32 },
|
|
36
|
+
];
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then your `TData` type can be defined as:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
export type User = {
|
|
43
|
+
id: number;
|
|
44
|
+
name: string;
|
|
45
|
+
age: number;
|
|
46
|
+
};
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You will often pass this `TData` type as a generic to the `MRT_*` types that you use so that you can get type hints for your specific data structure.
|
|
50
|
+
|
|
51
|
+
#### Define Your Columns With Type-Safety
|
|
52
|
+
|
|
53
|
+
Material React Table provides a couple of ways to define your columns with type safety. You can either simply use the `MRT_ColumnDef` type or use the new `createMRTColumnHelper` utility function.
|
|
54
|
+
|
|
55
|
+
#### MRT_ColumnDef Type
|
|
56
|
+
|
|
57
|
+
The most straightforward way to define your columns with type-safety is to just type your columns as `Array<MRT_ColumnDef<TData>>`.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import {
|
|
61
|
+
MaterialReactTable,
|
|
62
|
+
useMaterialReactTable,
|
|
63
|
+
type MRT_ColumnDef, // <--- import MRT_ColumnDef
|
|
64
|
+
} from 'material-react-table';
|
|
65
|
+
import { type User } from './types'; // <--- import your TData type from wherever you defined it
|
|
66
|
+
|
|
67
|
+
// define your columns, pass User as a generic to MRT_ColumnDef
|
|
68
|
+
const columns: Array<MRT_ColumnDef<User>> = [
|
|
69
|
+
{
|
|
70
|
+
accessorKey: 'id', //you should get type hints for all of your keys if you defined your TData type correctly
|
|
71
|
+
header: 'ID',
|
|
72
|
+
enableSorting: false, //you should get type hints for all possible column options that you can define here
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
accessorKey: 'name',
|
|
76
|
+
header: 'Name',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
accessorFn: (originalRow) => Number(originalRow.age), //you should also get type hints for your accessorFn
|
|
80
|
+
header: 'Age',
|
|
81
|
+
Cell: ({ cell }) => <span>{cell.getValue<number>()}</span>, //cell.getValue() will be typed as `unknown` by default, but you can pass a generic to get the correct type
|
|
82
|
+
//see the createMRTColumnHelper example below for a better way to get type safety with cell.getValue()
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### createMRTColumnHelper Utility
|
|
88
|
+
|
|
89
|
+
> New in V3 (After many requests)
|
|
90
|
+
|
|
91
|
+
Alternatively you can use the `createMRTColumnHelper` utility function to define your columns. This works the same way as the TanStack `createColumnHelper`.
|
|
92
|
+
|
|
93
|
+
Additional `TValue` type-safety is provided by using this utility. That means that when you call `cell.getValue()` in either a custom `Cell` render, or in any of the `mui*Props`, you will get the correct type for the data in that column instead of `unknown`.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import {
|
|
97
|
+
MaterialReactTable,
|
|
98
|
+
useMaterialReactTable,
|
|
99
|
+
createMRTColumnHelper, // <--- import createMRTColumnHelper
|
|
100
|
+
} from 'material-react-table';
|
|
101
|
+
import { type User } from './types'; // <--- import your TData type from wherever you defined it (if using TS)
|
|
102
|
+
|
|
103
|
+
const columnHelper = createMRTColumnHelper<User>(); // <--- pass your TData type as a generic to createMRTColumnHelper (if using TS)
|
|
104
|
+
|
|
105
|
+
//columns will be inferred as Array<MRT_ColumnDef<User>>
|
|
106
|
+
const columns = [
|
|
107
|
+
//accessorKey as first argument, rest of column options as second argument
|
|
108
|
+
columnHelper.accessor('name', {
|
|
109
|
+
header: 'Last Name',
|
|
110
|
+
}),
|
|
111
|
+
//accessorFn as first argument, rest of column options as second argument
|
|
112
|
+
columnHelper.accessor((row) => Number(row.age), {
|
|
113
|
+
id; 'age', //id required for accessorFn
|
|
114
|
+
header: 'Age',
|
|
115
|
+
filterVariant: 'range-slider', //you should get type hints for all possible column options that you can define here
|
|
116
|
+
Cell: ({ cell }) => <span>{cell.getValue()}</span>, //cell.getValue() will be typed as number instead of unknown
|
|
117
|
+
}),
|
|
118
|
+
//display column (no accessor needed)
|
|
119
|
+
columnHelper.display({
|
|
120
|
+
header: 'Contact',
|
|
121
|
+
Cell: ({ row }) => (
|
|
122
|
+
<Button onClick={() => sendEmail(row.original.email)}>Send Email</Button>
|
|
123
|
+
),
|
|
124
|
+
}),
|
|
125
|
+
];
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Use JSDoc instead of TypeScript
|
|
129
|
+
|
|
130
|
+
If you are in a situation where you are not able to install TypeScript in your project, you can technically do the same thing as up above in JavaScript using JSDoc.
|
|
131
|
+
|
|
132
|
+
```jsx
|
|
133
|
+
import {
|
|
134
|
+
MaterialReactTable,
|
|
135
|
+
useMaterialReactTable,
|
|
136
|
+
} from 'material-react-table';
|
|
137
|
+
|
|
138
|
+
//define TData type with JSDoc
|
|
139
|
+
/**
|
|
140
|
+
* @typedef {Object} User
|
|
141
|
+
* @property {number} id
|
|
142
|
+
* @property {string} name
|
|
143
|
+
* @property {number} age
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
//import MRT_ColumnDef type with JSDoc
|
|
147
|
+
/**
|
|
148
|
+
* @type {import('material-react-table').MRT_ColumnDef<User>[]}
|
|
149
|
+
*/
|
|
150
|
+
const columns = [
|
|
151
|
+
{
|
|
152
|
+
accessorKey: 'id', //you should get type hints for all of your keys if you defined your TData type correctly
|
|
153
|
+
header: 'ID',
|
|
154
|
+
enableSorting: false, //you should get type hints for all possible column options that you can define here
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
accessorKey: 'name',
|
|
158
|
+
header: 'Name',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
accessorFn: (originalRow) => Number(originalRow.age), //you should also get type hints for your accessorFn
|
|
162
|
+
header: 'Age',
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Re-Usable MRT Components
|
|
168
|
+
|
|
169
|
+
If you are going to have multiple tables in your app, chances are that you will want to make a re-usable component built on top of Material React Table. This is a good idea and good practice, but here are a few suggestions to maintain type safety with some TypeScript generics.
|
|
170
|
+
|
|
171
|
+
#### Re-usable Components or Options?
|
|
172
|
+
|
|
173
|
+
In my opinion, instead of creating a re-usable component, it is instead actually best to define your default options and share them between all of your tables.
|
|
174
|
+
|
|
175
|
+
##### Re-usable Default Options
|
|
176
|
+
|
|
177
|
+
In this example, we are simply creating a factory function that creates all of the default options that you want all of your tables to start with.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { type MRT_RowData, type MRT_TableOptions } from 'material-react-table';
|
|
181
|
+
|
|
182
|
+
//define re-useable default table options for all tables in your app
|
|
183
|
+
export const getDefaultMRTOptions = <TData extends MRT_RowData>(): Partial<
|
|
184
|
+
MRT_TableOptions<TData>
|
|
185
|
+
> => ({
|
|
186
|
+
//list all of your default table options here
|
|
187
|
+
enableGlobalFilter: false,
|
|
188
|
+
enableRowPinning: true,
|
|
189
|
+
initialState: { showColumnFilters: true },
|
|
190
|
+
manualFiltering: true,
|
|
191
|
+
manualPagination: true,
|
|
192
|
+
manualSorting: true,
|
|
193
|
+
muiTableHeadCellProps: {
|
|
194
|
+
sx: { fontSize: '1.1rem' },
|
|
195
|
+
},
|
|
196
|
+
paginationDisplayMode: 'pages',
|
|
197
|
+
//etc...
|
|
198
|
+
defaultColumn: {
|
|
199
|
+
//you can even list default column options here
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Then you can use these options in every new table that you create:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
import {
|
|
208
|
+
MaterialReactTable,
|
|
209
|
+
useMaterialReactTable,
|
|
210
|
+
type MRT_ColumnDef,
|
|
211
|
+
} from 'material-react-table';
|
|
212
|
+
import { getDefaultMRTOptions } from './utils'; //your default options
|
|
213
|
+
|
|
214
|
+
interface User {
|
|
215
|
+
id: number;
|
|
216
|
+
name: string;
|
|
217
|
+
age: number;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const defaultMRTOptions = getDefaultMRTOptions<User>(); //get your default options
|
|
221
|
+
|
|
222
|
+
export const OneOfYourTableComponents = () => {
|
|
223
|
+
const columns: MRT_ColumnDef<User>[] = [
|
|
224
|
+
//...
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const { data } = useQuery({
|
|
228
|
+
//...
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const table = useMaterialReactTable({
|
|
232
|
+
...defaultMRTOptions, //spread your default options
|
|
233
|
+
columns,
|
|
234
|
+
data,
|
|
235
|
+
enableGlobalFilter: true, //override default options
|
|
236
|
+
initialState: {
|
|
237
|
+
...defaultMRTOptions.initialState, //spread default initial state
|
|
238
|
+
showColumnFilters: false, //override default initial state for just this table
|
|
239
|
+
},
|
|
240
|
+
//...
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
//you will have access to the entire table instance where you need it
|
|
244
|
+
console.log(table.getState());
|
|
245
|
+
|
|
246
|
+
return <MaterialReactTable table={table} />;
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Doing it this way, you maintain 100% control of your table instance and any state that you are managing in each table component.
|
|
251
|
+
|
|
252
|
+
I believe this is by far the best way to work with Material React Table in your application code, and how I personally use it in my own apps.
|
|
253
|
+
|
|
254
|
+
##### Re-usable MRT Component
|
|
255
|
+
|
|
256
|
+
If you still want to just create a re-usable MRT component instead, you can do that too, of course. Here is a type-safe way to do that:
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
import {
|
|
260
|
+
MaterialReactTable,
|
|
261
|
+
useMaterialReactTable,
|
|
262
|
+
type MRT_ColumnDef,
|
|
263
|
+
type MRT_RowData, //default shape of TData (Record<string, any>)
|
|
264
|
+
type MRT_TableOptions,
|
|
265
|
+
} from 'material-react-table';
|
|
266
|
+
|
|
267
|
+
interface Props<TData extends MRT_RowData> extends MRT_TableOptions<TData> {
|
|
268
|
+
columns: MRT_ColumnDef<TData>[];
|
|
269
|
+
data: TData[];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export const CustomMRTTable = <TData extends MRT_RowData>({
|
|
273
|
+
columns,
|
|
274
|
+
data,
|
|
275
|
+
...rest
|
|
276
|
+
}: Props<TData>) => {
|
|
277
|
+
const table = useMaterialReactTable({
|
|
278
|
+
columns,
|
|
279
|
+
data,
|
|
280
|
+
//your custom table options...
|
|
281
|
+
...rest, //accept props to override default table options
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
return <MaterialReactTable table={table} />;
|
|
285
|
+
};
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
By using the `TData` generic correctly, you can maintain type-safety in your re-usable component that will adapt to different types of data you will have throughout your application.
|
|
289
|
+
|
|
290
|
+
Though, be aware that the weakness of this approach is that it will be more annoying to get access to the `table` instance or read table state where you need it.
|
|
291
|
+
|
|
292
|
+
When re-using your MRT table component, it will just look something like this:
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
import { CustomMRTTable } from './CustomMRTTable';
|
|
296
|
+
|
|
297
|
+
const columns: MRT_ColumnDef<User>[] = [
|
|
298
|
+
//...
|
|
299
|
+
];
|
|
300
|
+
|
|
301
|
+
export const YourComponent = () => {
|
|
302
|
+
//no easy access to the table instance or table state here unless you manage all of the state in this component
|
|
303
|
+
const [pagination, setPagination] = useState<MRT_PaginationState>({
|
|
304
|
+
pageIndex: 0,
|
|
305
|
+
pageSize: 10,
|
|
306
|
+
});
|
|
307
|
+
const [sorting, setSorting] = useState<MRT_SortingState[]>([]);
|
|
308
|
+
//etc...
|
|
309
|
+
|
|
310
|
+
const { data } = useQuery({
|
|
311
|
+
//...
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<CustomMRTTable
|
|
316
|
+
columns={columns}
|
|
317
|
+
data={data}
|
|
318
|
+
enableRowPinning
|
|
319
|
+
//manage states to get access to them
|
|
320
|
+
onPaginationChange={setPagination}
|
|
321
|
+
onSortingChange={setSorting}
|
|
322
|
+
//etc...
|
|
323
|
+
state={{
|
|
324
|
+
pagination,
|
|
325
|
+
sorting,
|
|
326
|
+
//etc...
|
|
327
|
+
}}
|
|
328
|
+
/>
|
|
329
|
+
);
|
|
330
|
+
};
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Debugging Material React Table
|
|
334
|
+
|
|
335
|
+
Material React Table _(though really TanStack Table)_ can be a lot easier to debug than other data grid libraries. This is because you are often in charge of the state that you care about, and the entire table instance is available to you in your own scope if you are using the `useMaterialReactTable` hook. There are also some advanced TanStack Table Dev Tools that you can optionally install.
|
|
336
|
+
|
|
337
|
+
#### Console Logging from the Table Instance
|
|
338
|
+
|
|
339
|
+
When in doubt, console log it! There are a lot of things you can easily console log. Here are some examples:
|
|
340
|
+
|
|
341
|
+
##### Console Log All Internal Table State
|
|
342
|
+
|
|
343
|
+
```jsx
|
|
344
|
+
const table = useMaterialReactTable({
|
|
345
|
+
columns,
|
|
346
|
+
data,
|
|
347
|
+
//** */
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log(table.getState());
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
##### Console Log Current Rendering Rows
|
|
354
|
+
|
|
355
|
+
```jsx
|
|
356
|
+
const table = useMaterialReactTable({
|
|
357
|
+
columns,
|
|
358
|
+
data,
|
|
359
|
+
//** */
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
console.log(table.getRowModel().rows);
|
|
363
|
+
```
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
## Cell Actions Feature Guide
|
|
2
|
+
|
|
3
|
+
> New in v2.10.0
|
|
4
|
+
|
|
5
|
+
Material React Table provides you an easy shell to render a context menu for when a table cell/row is right clicked or otherwise activated. This is useful for providing additional actions that can be performed on a cell or row.
|
|
6
|
+
|
|
7
|
+
### Relevant Table Options
|
|
8
|
+
|
|
9
|
+
Relevant table options (get_mrt_api has full details):
|
|
10
|
+
|
|
11
|
+
- `enableCellActions` - type `((cell: MRT_Cell<TData>) => boolean) | boolean`
|
|
12
|
+
- `enableClickToCopy` - type `boolean | 'context-menu' | ((cell: MRT_Cell<TData>) => 'context-menu' | boolean)` - default `false`
|
|
13
|
+
- `renderCellActionMenuItems` - type `{ cell, closeMenu, column, internalMenuItems, row, staticColumnIndex, staticRowIndex, table }) => ReactNode[]`
|
|
14
|
+
|
|
15
|
+
### Relevant Column Options
|
|
16
|
+
|
|
17
|
+
Relevant column options (get_mrt_api has full details):
|
|
18
|
+
|
|
19
|
+
- `enableClickToCopy` - type `boolean | 'context-menu' | ((cell: MRT_Cell<TData>) => 'context-menu' | boolean)` - Enable the click to copy feature for this column.
|
|
20
|
+
- `renderCellActionMenuItems` - type `{ cell, closeMenu, column, internalMenuItems, row, staticColumnIndex, staticRowIndex, table }) => ReactNode[]`
|
|
21
|
+
|
|
22
|
+
### Enable Cell Actions
|
|
23
|
+
|
|
24
|
+
To enable cell actions, you need to set the `enableCellActions` option to `true` for the cells that you want to have access to the context menu. This can be done at the table level or at the column level, and accepts a boolean or a function that returns a boolean.
|
|
25
|
+
|
|
26
|
+
```jsx
|
|
27
|
+
const table = useMaterialReactTable({
|
|
28
|
+
columns,
|
|
29
|
+
data,
|
|
30
|
+
enableCellActions: true,
|
|
31
|
+
//or
|
|
32
|
+
enableCellActions: (cell) => (cell.row.original.someCondition ? true : false),
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Render Cell Action Menu Items
|
|
37
|
+
|
|
38
|
+
The cell actions context menu will only appear if there are items to display. You can provide the `renderCellActionMenuItems` table option or column option to render the appropriate items in the context menu for each cell.
|
|
39
|
+
|
|
40
|
+
MRT also provides a `MRT_ActionMenuItem` component that you can use to render the menu items. This just a wrapper for the MUI MenuItem component that also provides consistent CSS for styling the icons, spacing, and optional sub-menu items. Use it if you want to have a consistent look and feel with all of the other built-in MRT Menus.
|
|
41
|
+
|
|
42
|
+
```jsx
|
|
43
|
+
const table = useMaterialReactTable({
|
|
44
|
+
columns,
|
|
45
|
+
data,
|
|
46
|
+
enableCellActions: true,
|
|
47
|
+
renderCellActionMenuItems: ({ closeMenu, cell, row, table }) => [
|
|
48
|
+
//array required
|
|
49
|
+
<MRT_ActionMenuItem //or just use the normal MUI MenuItem
|
|
50
|
+
icon={<Email />}
|
|
51
|
+
key={1}
|
|
52
|
+
label="Item 1"
|
|
53
|
+
onClick={() => {
|
|
54
|
+
//your logic here
|
|
55
|
+
closeMenu(); //close the menu after the action is performed
|
|
56
|
+
}}
|
|
57
|
+
table={table}
|
|
58
|
+
/>,
|
|
59
|
+
<MRT_ActionMenuItem
|
|
60
|
+
icon={<PersonOffOutlined />}
|
|
61
|
+
key={2}
|
|
62
|
+
label="Item 2"
|
|
63
|
+
onClick={async () => {
|
|
64
|
+
//await your logic here
|
|
65
|
+
closeMenu(); //close the menu after the async action is performed
|
|
66
|
+
}}
|
|
67
|
+
table={table}
|
|
68
|
+
/>,
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Include Automatic Cell Actions
|
|
74
|
+
|
|
75
|
+
A few cell actions are included by default when certain other features are enabled.
|
|
76
|
+
|
|
77
|
+
- A "Copy" action will be included when the `enableClickToCopy` option is set to `"context-menu"` (instead of `true`) for the table or column.
|
|
78
|
+
|
|
79
|
+
- An "Edit" action will be included when the `enableEditing` option is set to `true` and the `editDisplayMode` option is set to `"cell"`. This will not disable the default double-click to edit behavior, but will provide an additional way to edit the cell.
|
|
80
|
+
|
|
81
|
+
More built-in cell actions may be added in the future.
|
|
82
|
+
|
|
83
|
+
```jsx
|
|
84
|
+
const table = useMaterialReactTable({
|
|
85
|
+
columns,
|
|
86
|
+
data,
|
|
87
|
+
enableCellActions: true,
|
|
88
|
+
enableClickToCopy: 'context-menu',
|
|
89
|
+
enableEditing: true,
|
|
90
|
+
editDisplayMode: 'cell',
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If you want to render these actions alongside your custom actions, you will just need to include the `internalMenuItems` parameter in your `renderCellActionMenuItems` function.
|
|
95
|
+
|
|
96
|
+
```jsx
|
|
97
|
+
const table = useMaterialReactTable({
|
|
98
|
+
columns,
|
|
99
|
+
data,
|
|
100
|
+
enableCellActions: true,
|
|
101
|
+
enableClickToCopy: 'context-menu',
|
|
102
|
+
enableEditing: true,
|
|
103
|
+
editDisplayMode: 'cell',
|
|
104
|
+
renderCellActionMenuItems: ({
|
|
105
|
+
closeMenu,
|
|
106
|
+
cell,
|
|
107
|
+
row,
|
|
108
|
+
table,
|
|
109
|
+
internalMenuItems,
|
|
110
|
+
}) => [
|
|
111
|
+
...internalMenuItems, //render the copy and edit actions wherever you want in the list
|
|
112
|
+
<Divider />, //optionally place a Menu Divider to separate groups of actions
|
|
113
|
+
<MRT_ActionMenuItem
|
|
114
|
+
icon={<Email />}
|
|
115
|
+
key={1}
|
|
116
|
+
label="Item 1"
|
|
117
|
+
onClick={() => {
|
|
118
|
+
//your logic here
|
|
119
|
+
closeMenu(); //close the menu after the action is performed
|
|
120
|
+
}}
|
|
121
|
+
table={table}
|
|
122
|
+
/>,
|
|
123
|
+
<MRT_ActionMenuItem
|
|
124
|
+
icon={<PersonOffOutlined />}
|
|
125
|
+
key={2}
|
|
126
|
+
label="Item 2"
|
|
127
|
+
onClick={async () => {
|
|
128
|
+
//await your logic here
|
|
129
|
+
closeMenu(); //close the menu after the async action is performed
|
|
130
|
+
}}
|
|
131
|
+
table={table}
|
|
132
|
+
/>,
|
|
133
|
+
],
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
> Live example: `enable-cell-actions` (call get_mrt_example with that id).
|
|
138
|
+
|
|
139
|
+
View Extra Storybook **[Examples](https://www.material-react-table.dev/?path=/story/features-cell-action-examples)**
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
## Click to Copy Feature Guide
|
|
2
|
+
|
|
3
|
+
Material React Table has an easy-to-implement feature that allows a user to copy a cell's value to the clipboard.
|
|
4
|
+
|
|
5
|
+
### Relevant Table Options
|
|
6
|
+
|
|
7
|
+
Relevant table options (get_mrt_api has full details):
|
|
8
|
+
|
|
9
|
+
- `enableClickToCopy` - type `boolean | 'context-menu' | ((cell: MRT_Cell<TData>) => 'context-menu' | boolean)` - default `false`
|
|
10
|
+
- `muiCopyButtonProps` - type `ButtonProps | ({ cell, column, row, table }) => ButtonProps`
|
|
11
|
+
|
|
12
|
+
### Relevant Column Options
|
|
13
|
+
|
|
14
|
+
Relevant column options (get_mrt_api has full details):
|
|
15
|
+
|
|
16
|
+
- `enableClickToCopy` - type `boolean | 'context-menu' | ((cell: MRT_Cell<TData>) => 'context-menu' | boolean)` - Enable the click to copy feature for this column.
|
|
17
|
+
- `muiCopyButtonProps` - type `ButtonProps | ({ cell, column, row, table }) => ButtonProps`
|
|
18
|
+
|
|
19
|
+
### Enable Click to Copy Per Column
|
|
20
|
+
|
|
21
|
+
Most likely, there will just be a couple columns that you want to enable click to copy for. You can do this by setting the `enableClickToCopy` option to `true` per column on the column definition.
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
const columns = [
|
|
25
|
+
//...
|
|
26
|
+
{
|
|
27
|
+
accessorKey: 'email',
|
|
28
|
+
header: 'Email',
|
|
29
|
+
enableClickToCopy: true,
|
|
30
|
+
},
|
|
31
|
+
//...
|
|
32
|
+
];
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Enable Click to Copy For All Cells
|
|
36
|
+
|
|
37
|
+
Alternatively, you can enable click to copy globally by setting the `enableClickToCopy` table option to `true`. You could then opt out per column by setting the `enableClickToCopy` option to `false` on the column definition.
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
const table = useMaterialReactTable({
|
|
41
|
+
columns,
|
|
42
|
+
data,
|
|
43
|
+
enableClickToCopy: true,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Customize Copy Buttons
|
|
48
|
+
|
|
49
|
+
The click to copy feature is built on top of the Material UnstyledButton and CopyButton components. You can customize the copy button by passing in the `muiCopyButtonProps` table or column option.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
const table = useMaterialReactTable({
|
|
53
|
+
columns,
|
|
54
|
+
data,
|
|
55
|
+
enableClickToCopy: true,
|
|
56
|
+
muiCopyButtonProps: {
|
|
57
|
+
sx: { width: '100%' },
|
|
58
|
+
startIcon: <ContentCopy />,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Click to Copy Example
|
|
64
|
+
|
|
65
|
+
> Live example: `enable-click-to-copy` (call get_mrt_example with that id).
|
|
66
|
+
|
|
67
|
+
View Extra Storybook **[Examples](https://www.material-react-table.dev/?path=/story/features-click-to-copy-examples)**
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
## Column Actions Feature Guide
|
|
2
|
+
|
|
3
|
+
By default, Material React Table renders a column actions button for each column header. It contains a drop-down menu to help your users use the other features of the table. All of these actions can be triggered in some other way other than from this drop-down menu, so this serves as a UI/UX alternative to make sure your users can find many of the table features easily.
|
|
4
|
+
|
|
5
|
+
### Relevant Table Options
|
|
6
|
+
|
|
7
|
+
Relevant table options (get_mrt_api has full details):
|
|
8
|
+
|
|
9
|
+
- `enableColumnActions` - type `boolean` - default `true`
|
|
10
|
+
- `muiColumnActionsButtonProps` - type `IconButtonProps | (({table, column}) => IconButtonProps);`
|
|
11
|
+
- `renderColumnActionsMenuItems` - type `({ closeMenu, column, internalColumnMenuItems, table }) => ReactNode[]`
|
|
12
|
+
|
|
13
|
+
### Relevant Column Options
|
|
14
|
+
|
|
15
|
+
Relevant column options (get_mrt_api has full details):
|
|
16
|
+
|
|
17
|
+
- `enableColumnActions` - type `boolean` - Enable or disable column actions for this column.
|
|
18
|
+
- `muiColumnActionsButtonProps` - type `IconButtonProps | ({ column, table }) => IconButtonProps`
|
|
19
|
+
- `renderColumnActionsMenuItems` - type `({ closeMenu, column, internalColumnMenuItems, table }) => ReactNode[]`
|
|
20
|
+
|
|
21
|
+
### Disable or Hide Column Actions Buttons
|
|
22
|
+
|
|
23
|
+
You can set the `enableColumnActions` table option to `false` in the table to disable this feature and hide the button in each column header completely.
|
|
24
|
+
|
|
25
|
+
```jsx
|
|
26
|
+
const table = useMaterialReactTable({
|
|
27
|
+
data,
|
|
28
|
+
columns,
|
|
29
|
+
enableColumnActions: false,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return <MaterialReactTable table={table} />;
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Alternatively, if you only want to hide the column actions button in specific columns, you can set the `enableColumnActions` option for the desired column definition to `false` instead.
|
|
36
|
+
|
|
37
|
+
In this demo, we disable the column actions button for the 'ID' column.
|
|
38
|
+
|
|
39
|
+
> Live example: `disable-column-actions` (call get_mrt_example with that id).
|
|
40
|
+
|
|
41
|
+
### Custom Column Actions Menu
|
|
42
|
+
|
|
43
|
+
If you do not like the default column actions menu items that Material React Table generates, you can provide your own custom menu items with the `renderColumnActionsMenuItems` table or column option. You can choose whether or not to include the internal menu items by using the `internalColumnMenuItems` parameter.
|
|
44
|
+
|
|
45
|
+
```jsx
|
|
46
|
+
const table = useMaterialReactTable({
|
|
47
|
+
data,
|
|
48
|
+
columns,
|
|
49
|
+
renderColumnActionsMenuItems: ({ internalColumnMenuItems }) => {
|
|
50
|
+
return [
|
|
51
|
+
...internalColumnMenuItems, //optionally include the internal menu items above or below your custom menu items
|
|
52
|
+
<MenuItem key="custom-menu-item-1">Custom Menu Item 1</MenuItem>,
|
|
53
|
+
<MenuItem key="custom-menu-item-2">Custom Menu Item 2</MenuItem>,
|
|
54
|
+
];
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return <MaterialReactTable table={table} />;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
> Live example: `custom-column-actions` (call get_mrt_example with that id).
|
|
62
|
+
|
|
63
|
+
### Justify Column Actions Button
|
|
64
|
+
|
|
65
|
+
By default, the column actions button is left aligned directly after the column header text and any sort or filter labels that may be present. If you want to change this, you can use a CSS selector in `muiTableHeadCellProps` to change the `justify-content` property of the column header container.
|
|
66
|
+
|
|
67
|
+
> Live example: `column-actions-space` (call get_mrt_example with that id).
|
|
68
|
+
|
|
69
|
+
View Extra Storybook **[Examples](https://www.material-react-table.dev/?path=/story/features-column-action-examples)**
|