material-react-table 2.11.1 → 2.11.2

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.11.1",
2
+ "version": "2.11.2",
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.",
@@ -64,7 +64,7 @@ export const MRT_TableBody = <TData extends MRT_RowData>({
64
64
  .map((r) => r.id);
65
65
  }, [rowPinning, getRowModel().rows]);
66
66
 
67
- const rows = useMRT_Rows(table, pinnedRowIds);
67
+ const rows = useMRT_Rows(table);
68
68
 
69
69
  const rowVirtualizer = useMRT_RowVirtualizer(table, rows);
70
70
 
@@ -1,4 +1,4 @@
1
- import { type ChangeEvent, type MouseEvent } from 'react';
1
+ import { type MouseEvent } from 'react';
2
2
  import Checkbox, { type CheckboxProps } from '@mui/material/Checkbox';
3
3
  import Radio, { type RadioProps } from '@mui/material/Radio';
4
4
  import Tooltip from '@mui/material/Tooltip';
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  getIsRowSelected,
13
13
  getMRT_RowSelectionHandler,
14
+ getMRT_SelectAllHandler,
14
15
  } from '../../utils/row.utils';
15
16
  import { getCommonTooltipProps } from '../../utils/style.utils';
16
17
  import { parseFromValuesOrFunc } from '../../utils/utils';
@@ -32,22 +33,16 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
32
33
  getState,
33
34
  options: {
34
35
  enableMultiRowSelection,
35
- enableRowPinning,
36
36
  localization,
37
37
  muiSelectAllCheckboxProps,
38
38
  muiSelectCheckboxProps,
39
- rowPinningDisplayMode,
40
39
  selectAllMode,
41
40
  },
42
- refs: { lastSelectedRowId },
43
41
  } = table;
44
42
  const { density, isLoading } = getState();
45
43
 
46
44
  const selectAll = !row;
47
45
 
48
- const isStickySelection =
49
- enableRowPinning && rowPinningDisplayMode?.includes('select');
50
-
51
46
  const allRowsSelected = selectAll
52
47
  ? selectAllMode === 'page'
53
48
  ? table.getIsAllPageRowsSelected()
@@ -68,17 +63,15 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
68
63
  ...rest,
69
64
  };
70
65
 
71
- const onSelectionChange = getMRT_RowSelectionHandler();
66
+ const onSelectionChange = row
67
+ ? getMRT_RowSelectionHandler({
68
+ row,
69
+ staticRowIndex,
70
+ table,
71
+ })
72
+ : undefined;
72
73
 
73
- const onSelectAllChange = (event: ChangeEvent<HTMLInputElement>) => {
74
- selectAllMode === 'all'
75
- ? table.getToggleAllRowsSelectedHandler()(event)
76
- : table.getToggleAllPageRowsSelectedHandler()(event);
77
- if (isStickySelection) {
78
- table.setRowPinning({ bottom: [], top: [] });
79
- }
80
- lastSelectedRowId.current = null;
81
- };
74
+ const onSelectAllChange = getMRT_SelectAllHandler({ table });
82
75
 
83
76
  const commonProps = {
84
77
  'aria-label': selectAll
@@ -94,9 +87,7 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
94
87
  },
95
88
  onChange: (event) => {
96
89
  event.stopPropagation();
97
- row
98
- ? onSelectionChange({ event, row, staticRowIndex, table })
99
- : onSelectAllChange(event);
90
+ row ? onSelectionChange!(event) : onSelectAllChange(event);
100
91
  },
101
92
  size: (density === 'compact' ? 'small' : 'medium') as 'medium' | 'small',
102
93
  ...checkboxProps,
@@ -7,6 +7,7 @@ import Chip from '@mui/material/Chip';
7
7
  import Collapse from '@mui/material/Collapse';
8
8
  import Stack from '@mui/material/Stack';
9
9
  import { type MRT_RowData, type MRT_TableInstance } from '../../types';
10
+ import { getMRT_SelectAllHandler } from '../../utils/row.utils';
10
11
  import { parseFromValuesOrFunc } from '../../utils/utils';
11
12
  import { MRT_SelectCheckbox } from '../inputs/MRT_SelectCheckbox';
12
13
 
@@ -36,7 +37,7 @@ export const MRT_ToolbarAlertBanner = <TData extends MRT_RowData>({
36
37
  renderToolbarAlertBannerContent,
37
38
  rowCount,
38
39
  },
39
- refs: { lastSelectedRowId, tablePaperRef },
40
+ refs: { tablePaperRef },
40
41
  } = table;
41
42
  const { density, grouping, rowSelection, showAlertBanner } = getState();
42
43
 
@@ -51,7 +52,7 @@ export const MRT_ToolbarAlertBanner = <TData extends MRT_RowData>({
51
52
  table,
52
53
  });
53
54
 
54
- const totalRowCount = rowCount ?? getPrePaginationRowModel().rows.length;
55
+ const totalRowCount = rowCount ?? getPrePaginationRowModel().flatRows.length;
55
56
 
56
57
  const selectedRowCount = useMemo(
57
58
  () =>
@@ -67,10 +68,7 @@ export const MRT_ToolbarAlertBanner = <TData extends MRT_RowData>({
67
68
  ?.replace('{selectedCount}', selectedRowCount.toLocaleString())
68
69
  ?.replace('{rowCount}', totalRowCount.toString())}
69
70
  <Button
70
- onClick={() => {
71
- table.toggleAllRowsSelected(false);
72
- lastSelectedRowId.current = null;
73
- }}
71
+ onClick={(event) => getMRT_SelectAllHandler({ table })(event, false)}
74
72
  size="small"
75
73
  sx={{ p: '2px' }}
76
74
  >
@@ -8,7 +8,6 @@ import { getMRT_Rows } from '../utils/row.utils';
8
8
 
9
9
  export const useMRT_Rows = <TData extends MRT_RowData>(
10
10
  table: MRT_TableInstance<TData>,
11
- pinnedRowIds: string[] = [],
12
11
  ): MRT_Row<TData>[] => {
13
12
  const {
14
13
  getRowModel,
@@ -25,7 +24,7 @@ export const useMRT_Rows = <TData extends MRT_RowData>(
25
24
  } = getState();
26
25
 
27
26
  const rows = useMemo(
28
- () => getMRT_Rows(table, pinnedRowIds),
27
+ () => getMRT_Rows(table),
29
28
  [
30
29
  creatingRow,
31
30
  data,
@@ -9,11 +9,9 @@ import { parseFromValuesOrFunc } from './utils';
9
9
 
10
10
  export const getMRT_Rows = <TData extends MRT_RowData>(
11
11
  table: MRT_TableInstance<TData>,
12
- pinnedRowIds: string[] = [],
13
12
  all?: boolean,
14
13
  ): MRT_Row<TData>[] => {
15
14
  const {
16
- getBottomRows,
17
15
  getCenterRows,
18
16
  getPrePaginationRowModel,
19
17
  getRowModel,
@@ -41,6 +39,7 @@ export const getMRT_Rows = <TData extends MRT_RowData>(
41
39
  : getRowModel().rows
42
40
  : getCenterRows();
43
41
  } else {
42
+ // fuzzy ranking adjustments
44
43
  rows = getPrePaginationRowModel().rows.sort((a, b) =>
45
44
  rankGlobalFuzzy(a, b),
46
45
  );
@@ -48,14 +47,23 @@ export const getMRT_Rows = <TData extends MRT_RowData>(
48
47
  const start = pagination.pageIndex * pagination.pageSize;
49
48
  rows = rows.slice(start, start + pagination.pageSize);
50
49
  }
50
+ if (enableRowPinning && !rowPinningDisplayMode?.includes('sticky')) {
51
+ // "re-center-ize" the rows (no top or bottom pinned rows unless sticky)
52
+ rows = rows.filter((row) => !row.getIsPinned());
53
+ }
51
54
  }
55
+ // row pinning adjustments
52
56
  if (enableRowPinning && rowPinningDisplayMode?.includes('sticky')) {
57
+ const centerPinnedRowIds = rows
58
+ .filter((row) => row.getIsPinned())
59
+ .map((r) => r.id);
60
+
53
61
  rows = [
54
- ...getTopRows().filter((row) => !pinnedRowIds.includes(row.id)),
62
+ ...getTopRows().filter((row) => !centerPinnedRowIds.includes(row.id)),
55
63
  ...rows,
56
- ...getBottomRows().filter((row) => !pinnedRowIds.includes(row.id)),
57
64
  ];
58
65
  }
66
+ // blank inserted creating row adjustments
59
67
  if (
60
68
  positionCreatingRow !== undefined &&
61
69
  creatingRow &&
@@ -135,22 +143,24 @@ export const getIsRowSelected = <TData extends MRT_RowData>({
135
143
  };
136
144
 
137
145
  export const getMRT_RowSelectionHandler =
138
- () =>
139
146
  <TData extends MRT_RowData>({
140
- event,
141
147
  row,
142
148
  staticRowIndex = 0,
143
149
  table,
144
150
  }: {
145
- event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLTableRowElement>;
146
151
  row: MRT_Row<TData>;
147
152
  staticRowIndex?: number;
148
153
  table: MRT_TableInstance<TData>;
149
- }) => {
154
+ }) =>
155
+ (
156
+ event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLTableRowElement>,
157
+ value?: boolean,
158
+ ) => {
150
159
  const {
151
160
  getState,
152
161
  options: {
153
162
  enableBatchRowSelection,
163
+ enableMultiRowSelection,
154
164
  enableRowPinning,
155
165
  manualPagination,
156
166
  rowPinningDisplayMode,
@@ -163,21 +173,21 @@ export const getMRT_RowSelectionHandler =
163
173
 
164
174
  const paginationOffset = manualPagination ? 0 : pageSize * pageIndex;
165
175
 
166
- const isCurrentRowChecked = getIsRowSelected({ row, table });
167
-
168
- const isStickySelection =
169
- enableRowPinning && rowPinningDisplayMode?.includes('select');
176
+ const wasCurrentRowChecked = getIsRowSelected({ row, table });
170
177
 
171
178
  // toggle selection of this row
172
- row.getToggleSelectedHandler()(event);
179
+ row.toggleSelected(value ?? !wasCurrentRowChecked);
180
+
181
+ const changedRowIds = new Set<string>([row.id]);
173
182
 
174
183
  // if shift key is pressed, select all rows between last selected and this one
175
184
  if (
176
185
  enableBatchRowSelection &&
186
+ enableMultiRowSelection &&
177
187
  (event as any).nativeEvent.shiftKey &&
178
188
  lastSelectedRowId.current !== null
179
189
  ) {
180
- const rows = getMRT_Rows(table, undefined, true);
190
+ const rows = getMRT_Rows(table, true);
181
191
 
182
192
  const lastIndex = rows.findIndex(
183
193
  (r) => r.id === lastSelectedRowId.current,
@@ -197,9 +207,10 @@ export const getMRT_RowSelectionHandler =
197
207
 
198
208
  // toggle selection of all rows between last selected and this one
199
209
  // but only if the last selected row is not the same as the current one
200
- if (isCurrentRowChecked !== isLastIndexChecked) {
210
+ if (wasCurrentRowChecked !== isLastIndexChecked) {
201
211
  for (let i = start; i <= end; i++) {
202
- rows[i].toggleSelected(!isCurrentRowChecked);
212
+ rows[i].toggleSelected(!wasCurrentRowChecked);
213
+ changedRowIds.add(rows[i].id);
203
214
  }
204
215
  }
205
216
  }
@@ -213,13 +224,36 @@ export const getMRT_RowSelectionHandler =
213
224
  row.subRows?.forEach((r) => r.toggleSelected(false));
214
225
  }
215
226
 
216
- if (isStickySelection) {
217
- row.pin(
218
- !row.getIsPinned() && isCurrentRowChecked
219
- ? rowPinningDisplayMode?.includes('bottom')
220
- ? 'bottom'
221
- : 'top'
222
- : false,
223
- );
227
+ if (enableRowPinning && rowPinningDisplayMode?.includes('select')) {
228
+ changedRowIds.forEach((rowId) => {
229
+ const rowToTogglePin = table.getRow(rowId);
230
+ rowToTogglePin.pin(
231
+ !wasCurrentRowChecked //was not previously pinned or selected
232
+ ? rowPinningDisplayMode?.includes('bottom')
233
+ ? 'bottom'
234
+ : 'top'
235
+ : false,
236
+ );
237
+ });
238
+ }
239
+ };
240
+
241
+ export const getMRT_SelectAllHandler =
242
+ <TData extends MRT_RowData>({ table }: { table: MRT_TableInstance<TData> }) =>
243
+ (
244
+ event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLButtonElement>,
245
+ value?: boolean,
246
+ ) => {
247
+ const {
248
+ options: { enableRowPinning, rowPinningDisplayMode, selectAllMode },
249
+ refs: { lastSelectedRowId },
250
+ } = table;
251
+
252
+ selectAllMode === 'all'
253
+ ? table.toggleAllRowsSelected(value ?? (event as any).target.checked)
254
+ : table.toggleAllPageRowsSelected(value ?? (event as any).target.checked);
255
+ if (enableRowPinning && rowPinningDisplayMode?.includes('select')) {
256
+ table.setRowPinning({ bottom: [], top: [] });
224
257
  }
258
+ lastSelectedRowId.current = null;
225
259
  };