material-react-table 0.40.2 → 0.40.5

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.
@@ -4,7 +4,7 @@ import { MRT_Localization } from '../localization';
4
4
  export declare const mrtFilterOptions: (localization: MRT_Localization) => MRT_InternalFilterOption[];
5
5
  interface Props<TData extends Record<string, any> = {}> {
6
6
  anchorEl: HTMLElement | null;
7
- header?: MRT_Header;
7
+ header?: MRT_Header<TData>;
8
8
  onSelect?: () => void;
9
9
  setAnchorEl: (anchorEl: HTMLElement | null) => void;
10
10
  table: MRT_TableInstance<TData>;
@@ -1,8 +1,8 @@
1
- import { FC } from 'react';
1
+ import { FC, MouseEvent } from 'react';
2
2
  import type { MRT_Row, MRT_TableInstance } from '..';
3
3
  interface Props {
4
4
  anchorEl: HTMLElement | null;
5
- handleEdit: () => void;
5
+ handleEdit: (event: MouseEvent) => void;
6
6
  row: MRT_Row;
7
7
  setAnchorEl: (anchorEl: HTMLElement | null) => void;
8
8
  table: MRT_TableInstance;
package/dist/index.d.ts CHANGED
@@ -408,9 +408,16 @@ declare type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<Column
408
408
  table: MRT_TableInstance<TData>;
409
409
  column: MRT_Column<TData>;
410
410
  }) => TableCellProps);
411
- renderColumnFilterModeMenuItems?: ({ table, column, }: {
411
+ renderColumnActionsMenuItems?: ({ closeMenu, column, table, }: {
412
+ closeMenu: () => void;
413
+ column: MRT_Column<TData>;
412
414
  table: MRT_TableInstance<TData>;
415
+ }) => ReactNode[];
416
+ renderColumnFilterModeMenuItems?: ({ column, internalFilterOptions, onSelectFilterMode, table, }: {
413
417
  column: MRT_Column<TData>;
418
+ internalFilterOptions: MRT_InternalFilterOption[];
419
+ onSelectFilterMode: (filterMode: MRT_FilterOption) => void;
420
+ table: MRT_TableInstance<TData>;
414
421
  }) => ReactNode[];
415
422
  sortingFn?: MRT_SortingFn;
416
423
  };
@@ -662,12 +669,17 @@ declare type MaterialReactTableProps<TData extends Record<string, any> = {}> = O
662
669
  renderBottomToolbarCustomActions?: ({ table, }: {
663
670
  table: MRT_TableInstance<TData>;
664
671
  }) => ReactNode;
672
+ renderColumnActionsMenuItems?: ({ column, closeMenu, table, }: {
673
+ column: MRT_Column<TData>;
674
+ closeMenu: () => void;
675
+ table: MRT_TableInstance<TData>;
676
+ }) => ReactNode[];
665
677
  renderColumnFilterModeMenuItems?: ({ column, internalFilterOptions, onSelectFilterMode, table, }: {
666
678
  column: MRT_Column<TData>;
667
679
  internalFilterOptions: MRT_InternalFilterOption[];
668
680
  onSelectFilterMode: (filterMode: MRT_FilterOption) => void;
669
681
  table: MRT_TableInstance<TData>;
670
- }) => ReactNode;
682
+ }) => ReactNode[];
671
683
  renderDetailPanel?: ({ row, table, }: {
672
684
  row: MRT_Row<TData>;
673
685
  table: MRT_TableInstance<TData>;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.40.2",
2
+ "version": "0.40.5",
3
3
  "license": "MIT",
4
4
  "name": "material-react-table",
5
5
  "description": "A fully featured Material UI V5 implementation of TanStack React Table V8, written from the ground up in TypeScript.",
@@ -362,12 +362,25 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
362
362
  table: MRT_TableInstance<TData>;
363
363
  column: MRT_Column<TData>;
364
364
  }) => TableCellProps);
365
- renderColumnFilterModeMenuItems?: ({
366
- table,
365
+ renderColumnActionsMenuItems?: ({
366
+ closeMenu,
367
367
  column,
368
+ table,
368
369
  }: {
370
+ closeMenu: () => void;
371
+ column: MRT_Column<TData>;
369
372
  table: MRT_TableInstance<TData>;
373
+ }) => ReactNode[];
374
+ renderColumnFilterModeMenuItems?: ({
375
+ column,
376
+ internalFilterOptions,
377
+ onSelectFilterMode,
378
+ table,
379
+ }: {
370
380
  column: MRT_Column<TData>;
381
+ internalFilterOptions: MRT_InternalFilterOption[];
382
+ onSelectFilterMode: (filterMode: MRT_FilterOption) => void;
383
+ table: MRT_TableInstance<TData>;
371
384
  }) => ReactNode[];
372
385
  sortingFn?: MRT_SortingFn;
373
386
  };
@@ -782,6 +795,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
782
795
  }: {
783
796
  table: MRT_TableInstance<TData>;
784
797
  }) => ReactNode;
798
+ renderColumnActionsMenuItems?: ({
799
+ column,
800
+ closeMenu,
801
+ table,
802
+ }: {
803
+ column: MRT_Column<TData>;
804
+ closeMenu: () => void;
805
+ table: MRT_TableInstance<TData>;
806
+ }) => ReactNode[];
785
807
  renderColumnFilterModeMenuItems?: ({
786
808
  column,
787
809
  internalFilterOptions,
@@ -792,7 +814,7 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
792
814
  internalFilterOptions: MRT_InternalFilterOption[];
793
815
  onSelectFilterMode: (filterMode: MRT_FilterOption) => void;
794
816
  table: MRT_TableInstance<TData>;
795
- }) => ReactNode;
817
+ }) => ReactNode[];
796
818
  renderDetailPanel?: ({
797
819
  row,
798
820
  table,
@@ -1,4 +1,4 @@
1
- import React, { FC, RefObject, useEffect, useMemo } from 'react';
1
+ import React, { FC, RefObject, useMemo } from 'react';
2
2
  import { useVirtual } from 'react-virtual'; //stuck on v2 for now
3
3
  // import { useVirtualizer, Virtualizer } from '@tanstack/react-virtual';
4
4
  import { TableBody } from '@mui/material';
@@ -20,9 +20,11 @@ export const MRT_TableBody: FC<Props> = ({ table, tableContainerRef }) => {
20
20
  enableGlobalFilterRankedResults,
21
21
  enablePagination,
22
22
  enableRowVirtualization,
23
+ manualFiltering,
24
+ manualSorting,
23
25
  muiTableBodyProps,
24
- virtualizerProps,
25
26
  virtualizerInstanceRef,
27
+ virtualizerProps,
26
28
  },
27
29
  } = table;
28
30
  const { globalFilter, pagination, sorting } = getState();
@@ -41,6 +43,8 @@ export const MRT_TableBody: FC<Props> = ({ table, tableContainerRef }) => {
41
43
  if (
42
44
  enableGlobalFilterRankedResults &&
43
45
  globalFilter &&
46
+ !manualFiltering &&
47
+ !manualSorting &&
44
48
  !Object.values(sorting).some(Boolean)
45
49
  ) {
46
50
  const rankedRows = getPrePaginationRowModel().rows.sort((a, b) =>
@@ -72,11 +76,9 @@ export const MRT_TableBody: FC<Props> = ({ table, tableContainerRef }) => {
72
76
  })
73
77
  : ({} as any);
74
78
 
75
- useEffect(() => {
76
- if (virtualizerInstanceRef) {
77
- virtualizerInstanceRef.current = virtualizer;
78
- }
79
- }, [virtualizer]);
79
+ if (virtualizerInstanceRef) {
80
+ virtualizerInstanceRef.current = virtualizer;
81
+ }
80
82
 
81
83
  // const virtualizer: Virtualizer = enableRowVirtualization
82
84
  // ? useVirtualizer({
@@ -1,4 +1,4 @@
1
- import React, { ReactNode, useState } from 'react';
1
+ import React, { MouseEvent, ReactNode, useState } from 'react';
2
2
  import { Button, Tooltip } from '@mui/material';
3
3
  import { MRT_Cell, MRT_TableInstance } from '..';
4
4
 
@@ -21,7 +21,8 @@ export const MRT_CopyButton = <TData extends Record<string, any> = {}>({
21
21
 
22
22
  const [copied, setCopied] = useState(false);
23
23
 
24
- const handleCopy = (text: unknown) => {
24
+ const handleCopy = (event: MouseEvent, text: unknown) => {
25
+ event.stopPropagation();
25
26
  navigator.clipboard.writeText(text as string);
26
27
  setCopied(true);
27
28
  setTimeout(() => setCopied(false), 4000);
@@ -54,7 +55,7 @@ export const MRT_CopyButton = <TData extends Record<string, any> = {}>({
54
55
  title={copied ? localization.copiedToClipboard : localization.clickToCopy}
55
56
  >
56
57
  <Button
57
- onClick={() => handleCopy(cell.getValue())}
58
+ onClick={(e) => handleCopy(e, cell.getValue())}
58
59
  size="small"
59
60
  type="button"
60
61
  variant="text"
@@ -47,7 +47,10 @@ export const MRT_EditActionButtons = <TData extends Record<string, any> = {}>({
47
47
  };
48
48
 
49
49
  return (
50
- <Box sx={{ display: 'flex', gap: '0.75rem' }}>
50
+ <Box
51
+ onClick={(e) => e.stopPropagation()}
52
+ sx={{ display: 'flex', gap: '0.75rem' }}
53
+ >
51
54
  {variant === 'icon' ? (
52
55
  <>
53
56
  <Tooltip arrow title={localization.cancel}>
@@ -1,4 +1,4 @@
1
- import React, { FC } from 'react';
1
+ import React, { FC, MouseEvent } from 'react';
2
2
  import { IconButton, Tooltip } from '@mui/material';
3
3
  import type { MRT_Row, MRT_TableInstance } from '..';
4
4
 
@@ -24,8 +24,10 @@ export const MRT_ExpandButton: FC<Props> = ({ row, table }) => {
24
24
  ? muiExpandButtonProps({ table, row })
25
25
  : muiExpandButtonProps;
26
26
 
27
- const handleToggleExpand = () => {
27
+ const handleToggleExpand = (event: MouseEvent<HTMLButtonElement>) => {
28
+ event.stopPropagation();
28
29
  row.toggleExpanded();
30
+ iconButtonProps?.onClick?.(event);
29
31
  };
30
32
 
31
33
  return (
@@ -39,8 +41,8 @@ export const MRT_ExpandButton: FC<Props> = ({ row, table }) => {
39
41
  <IconButton
40
42
  aria-label={localization.expand}
41
43
  disabled={!row.getCanExpand() && !renderDetailPanel}
42
- onClick={handleToggleExpand}
43
44
  {...iconButtonProps}
45
+ onClick={handleToggleExpand}
44
46
  sx={(theme) => ({
45
47
  height: density === 'compact' ? '1.75rem' : '2.25rem',
46
48
  width: density === 'compact' ? '1.75rem' : '2.25rem',
@@ -37,6 +37,10 @@ export const MRT_GrabHandleButton = <TData extends Record<string, any> = {}>({
37
37
  onDragEnd={onDragEnd}
38
38
  size="small"
39
39
  {...iconButtonProps}
40
+ onClick={(e) => {
41
+ e.stopPropagation();
42
+ iconButtonProps?.onClick?.(e);
43
+ }}
40
44
  sx={(theme) => ({
41
45
  cursor: 'grab',
42
46
  m: 0,
@@ -16,12 +16,16 @@ const commonIconButtonStyles = {
16
16
  };
17
17
 
18
18
  interface Props {
19
- cell: MRT_Cell
19
+ cell: MRT_Cell;
20
20
  row: MRT_Row;
21
21
  table: MRT_TableInstance;
22
22
  }
23
23
 
24
- export const MRT_ToggleRowActionMenuButton: FC<Props> = ({ cell, row, table }) => {
24
+ export const MRT_ToggleRowActionMenuButton: FC<Props> = ({
25
+ cell,
26
+ row,
27
+ table,
28
+ }) => {
25
29
  const {
26
30
  getState,
27
31
  options: {
@@ -45,7 +49,8 @@ export const MRT_ToggleRowActionMenuButton: FC<Props> = ({ cell, row, table }) =
45
49
  setAnchorEl(event.currentTarget);
46
50
  };
47
51
 
48
- const handleStartEditMode = () => {
52
+ const handleStartEditMode = (event: MouseEvent) => {
53
+ event.stopPropagation();
49
54
  setEditingRow({ ...row });
50
55
  setAnchorEl(null);
51
56
  };
@@ -2,7 +2,6 @@ import React, {
2
2
  ChangeEvent,
3
3
  FocusEvent,
4
4
  KeyboardEvent,
5
- MouseEvent,
6
5
  useState,
7
6
  } from 'react';
8
7
  import { TextField, TextFieldProps } from '@mui/material';
@@ -101,11 +100,14 @@ export const MRT_EditCellTextField = <TData extends Record<string, any> = {}>({
101
100
  label={showLabel ? column.columnDef.header : undefined}
102
101
  margin="none"
103
102
  name={column.id}
104
- onClick={(e: MouseEvent<HTMLInputElement>) => e.stopPropagation()}
105
103
  placeholder={columnDef.header}
106
104
  value={value}
107
105
  variant="standard"
108
106
  {...textFieldProps}
107
+ onClick={(e) => {
108
+ e.stopPropagation();
109
+ textFieldProps?.onClick?.(e);
110
+ }}
109
111
  onBlur={handleBlur}
110
112
  onChange={handleChange}
111
113
  onKeyDown={handleEnterKeyDown}
@@ -58,6 +58,10 @@ export const MRT_SelectCheckbox: FC<Props> = ({ row, selectAll, table }) => {
58
58
  }
59
59
  size={density === 'compact' ? 'small' : 'medium'}
60
60
  {...checkboxProps}
61
+ onClick={(e) => {
62
+ e.stopPropagation();
63
+ checkboxProps?.onClick?.(e);
64
+ }}
61
65
  sx={(theme) => ({
62
66
  height: density === 'compact' ? '1.75rem' : '2.5rem',
63
67
  width: density === 'compact' ? '1.75rem' : '2.5rem',
@@ -34,6 +34,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
34
34
  toggleAllColumnsVisible,
35
35
  setColumnOrder,
36
36
  options: {
37
+ columnFilterModeOptions,
37
38
  enableColumnFilterModes,
38
39
  enableColumnFilters,
39
40
  enableColumnResizing,
@@ -41,7 +42,6 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
41
42
  enableHiding,
42
43
  enablePinning,
43
44
  enableSorting,
44
- columnFilterModeOptions,
45
45
  icons: {
46
46
  ArrowRightIcon,
47
47
  ClearAllIcon,
@@ -55,6 +55,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
55
55
  VisibilityOffIcon,
56
56
  },
57
57
  localization,
58
+ renderColumnActionsMenuItems,
58
59
  },
59
60
  refs: { filterInputRefs },
60
61
  setShowFilters,
@@ -153,55 +154,67 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
153
154
  dense: density === 'compact',
154
155
  }}
155
156
  >
156
- {enableSorting &&
157
- column.getCanSort() && [
158
- <MenuItem
159
- disabled={!column.getIsSorted()}
160
- key={0}
161
- onClick={handleClearSort}
162
- sx={commonMenuItemStyles}
163
- >
164
- <Box sx={commonListItemStyles}>
165
- <ListItemIcon>
166
- <ClearAllIcon />
167
- </ListItemIcon>
168
- {localization.clearSort}
169
- </Box>
170
- </MenuItem>,
171
- <MenuItem
172
- disabled={column.getIsSorted() === 'asc'}
173
- key={1}
174
- onClick={handleSortAsc}
175
- sx={commonMenuItemStyles}
176
- >
177
- <Box sx={commonListItemStyles}>
178
- <ListItemIcon>
179
- <SortIcon style={{ transform: 'rotate(180deg) scaleX(-1)' }} />
180
- </ListItemIcon>
181
- {localization.sortByColumnAsc?.replace(
182
- '{column}',
183
- String(columnDef.header),
184
- )}
185
- </Box>
186
- </MenuItem>,
187
- <MenuItem
188
- divider={enableColumnFilters || enableGrouping || enableHiding}
189
- key={2}
190
- disabled={column.getIsSorted() === 'desc'}
191
- onClick={handleSortDesc}
192
- sx={commonMenuItemStyles}
193
- >
194
- <Box sx={commonListItemStyles}>
195
- <ListItemIcon>
196
- <SortIcon />
197
- </ListItemIcon>
198
- {localization.sortByColumnDesc?.replace(
199
- '{column}',
200
- String(columnDef.header),
201
- )}
202
- </Box>
203
- </MenuItem>,
204
- ]}
157
+ {columnDef.renderColumnActionsMenuItems?.({
158
+ closeMenu: () => setAnchorEl(null),
159
+ column,
160
+ table,
161
+ }) ??
162
+ renderColumnActionsMenuItems?.({
163
+ closeMenu: () => setAnchorEl(null),
164
+ column,
165
+ table,
166
+ }) ??
167
+ (enableSorting &&
168
+ column.getCanSort() && [
169
+ <MenuItem
170
+ disabled={!column.getIsSorted()}
171
+ key={0}
172
+ onClick={handleClearSort}
173
+ sx={commonMenuItemStyles}
174
+ >
175
+ <Box sx={commonListItemStyles}>
176
+ <ListItemIcon>
177
+ <ClearAllIcon />
178
+ </ListItemIcon>
179
+ {localization.clearSort}
180
+ </Box>
181
+ </MenuItem>,
182
+ <MenuItem
183
+ disabled={column.getIsSorted() === 'asc'}
184
+ key={1}
185
+ onClick={handleSortAsc}
186
+ sx={commonMenuItemStyles}
187
+ >
188
+ <Box sx={commonListItemStyles}>
189
+ <ListItemIcon>
190
+ <SortIcon
191
+ style={{ transform: 'rotate(180deg) scaleX(-1)' }}
192
+ />
193
+ </ListItemIcon>
194
+ {localization.sortByColumnAsc?.replace(
195
+ '{column}',
196
+ String(columnDef.header),
197
+ )}
198
+ </Box>
199
+ </MenuItem>,
200
+ <MenuItem
201
+ divider={enableColumnFilters || enableGrouping || enableHiding}
202
+ key={2}
203
+ disabled={column.getIsSorted() === 'desc'}
204
+ onClick={handleSortDesc}
205
+ sx={commonMenuItemStyles}
206
+ >
207
+ <Box sx={commonListItemStyles}>
208
+ <ListItemIcon>
209
+ <SortIcon />
210
+ </ListItemIcon>
211
+ {localization.sortByColumnDesc?.replace(
212
+ '{column}',
213
+ String(columnDef.header),
214
+ )}
215
+ </Box>
216
+ </MenuItem>,
217
+ ])}
205
218
  {enableColumnFilters &&
206
219
  column.getCanFilter() &&
207
220
  [
@@ -99,7 +99,7 @@ export const mrtFilterOptions = (
99
99
 
100
100
  interface Props<TData extends Record<string, any> = {}> {
101
101
  anchorEl: HTMLElement | null;
102
- header?: MRT_Header;
102
+ header?: MRT_Header<TData>;
103
103
  onSelect?: () => void;
104
104
  setAnchorEl: (anchorEl: HTMLElement | null) => void;
105
105
  table: MRT_TableInstance<TData>;
@@ -177,8 +177,14 @@ export const MRT_FilterOptionMenu = <TData extends Record<string, any> = {}>({
177
177
  dense: density === 'compact',
178
178
  }}
179
179
  >
180
- {(header && column
181
- ? renderColumnFilterModeMenuItems?.({
180
+ {(header && column && columnDef
181
+ ? columnDef.renderColumnFilterModeMenuItems?.({
182
+ column: column as any,
183
+ internalFilterOptions,
184
+ onSelectFilterMode: handleSelectFilterMode,
185
+ table,
186
+ }) ??
187
+ renderColumnFilterModeMenuItems?.({
182
188
  column: column as any,
183
189
  internalFilterOptions,
184
190
  onSelectFilterMode: handleSelectFilterMode,
@@ -1,4 +1,4 @@
1
- import React, { FC } from 'react';
1
+ import React, { FC, MouseEvent } from 'react';
2
2
  import { Box, ListItemIcon, Menu, MenuItem } from '@mui/material';
3
3
  import type { MRT_Row, MRT_TableInstance } from '..';
4
4
  import {
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  interface Props {
10
10
  anchorEl: HTMLElement | null;
11
- handleEdit: () => void;
11
+ handleEdit: (event: MouseEvent) => void;
12
12
  row: MRT_Row;
13
13
  setAnchorEl: (anchorEl: HTMLElement | null) => void;
14
14
  table: MRT_TableInstance;
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useRef, useState } from 'react';
1
+ import React, { useMemo, useRef, useState } from 'react';
2
2
  import {
3
3
  TableState,
4
4
  getCoreRowModel,
@@ -303,11 +303,9 @@ export const MRT_TableRoot = <TData extends Record<string, any> = {}>(
303
303
  setShowGlobalFilter: props.onShowGlobalFilterChange ?? setShowGlobalFilter,
304
304
  } as MRT_TableInstance<TData>;
305
305
 
306
- useEffect(() => {
307
- if (props.tableInstanceRef) {
308
- props.tableInstanceRef.current = table;
309
- }
310
- }, [table]);
306
+ if (props.tableInstanceRef) {
307
+ props.tableInstanceRef.current = table;
308
+ }
311
309
 
312
310
  return (
313
311
  <>