material-react-table 2.11.1 → 2.11.2

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/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
  };