@cutting/material-react-table 5.0.0 → 5.1.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.
Files changed (190) hide show
  1. package/README.md +1 -4
  2. package/dist/index.d.ts +186 -524
  3. package/dist/index.js +323 -342
  4. package/dist/index.js.map +1 -1
  5. package/locales/ar/index.mjs +1 -2
  6. package/locales/az/index.mjs +1 -2
  7. package/locales/bg/index.mjs +1 -2
  8. package/locales/cs/index.mjs +1 -2
  9. package/locales/da/index.mjs +1 -2
  10. package/locales/de/index.mjs +1 -2
  11. package/locales/el/index.mjs +1 -2
  12. package/locales/en/index.mjs +1 -2
  13. package/locales/es/index.mjs +1 -2
  14. package/locales/et/index.mjs +1 -2
  15. package/locales/fa/index.mjs +1 -2
  16. package/locales/fi/index.mjs +1 -2
  17. package/locales/fr/index.mjs +1 -2
  18. package/locales/he/index.mjs +1 -2
  19. package/locales/hr/index.mjs +1 -2
  20. package/locales/hu/index.mjs +1 -2
  21. package/locales/hy/index.mjs +1 -2
  22. package/locales/id/index.mjs +1 -2
  23. package/locales/it/index.mjs +1 -2
  24. package/locales/ja/index.mjs +1 -2
  25. package/locales/ko/index.mjs +1 -2
  26. package/locales/nl/index.mjs +1 -2
  27. package/locales/no/index.mjs +1 -2
  28. package/locales/np/index.mjs +1 -2
  29. package/locales/pl/index.mjs +1 -2
  30. package/locales/pt/index.mjs +1 -2
  31. package/locales/pt-BR/index.mjs +1 -2
  32. package/locales/ro/index.mjs +1 -2
  33. package/locales/ru/index.mjs +1 -2
  34. package/locales/sk/index.mjs +1 -2
  35. package/locales/sr-Cyrl-RS/index.mjs +1 -2
  36. package/locales/sr-Latn-RS/index.mjs +1 -2
  37. package/locales/sv/index.mjs +1 -2
  38. package/locales/tr/index.mjs +1 -2
  39. package/locales/uk/index.mjs +1 -2
  40. package/locales/vi/index.mjs +1 -2
  41. package/locales/zh-Hans/index.mjs +1 -2
  42. package/locales/zh-Hant/index.mjs +1 -2
  43. package/package.json +19 -27
  44. package/src/MaterialReactTable.smoke.test.tsx +3 -9
  45. package/src/components/MaterialReactTable.tsx +13 -21
  46. package/src/components/body/MRT_TableBody.tsx +67 -82
  47. package/src/components/body/MRT_TableBodyCell.tsx +38 -80
  48. package/src/components/body/MRT_TableBodyCellValue.tsx +5 -14
  49. package/src/components/body/MRT_TableBodyRow.tsx +55 -102
  50. package/src/components/body/MRT_TableBodyRowGrabHandle.test.tsx +2 -6
  51. package/src/components/body/MRT_TableBodyRowGrabHandle.tsx +4 -9
  52. package/src/components/body/MRT_TableBodyRowPinButton.tsx +8 -14
  53. package/src/components/body/MRT_TableDetailPanel.test.tsx +3 -9
  54. package/src/components/body/MRT_TableDetailPanel.tsx +8 -14
  55. package/src/components/buttons/MRT_ColumnPinningButtons.test.tsx +6 -16
  56. package/src/components/buttons/MRT_ColumnPinningButtons.tsx +6 -12
  57. package/src/components/buttons/MRT_CopyButton.tsx +7 -15
  58. package/src/components/buttons/MRT_EditActionButtons.test.tsx +2 -6
  59. package/src/components/buttons/MRT_EditActionButtons.tsx +15 -37
  60. package/src/components/buttons/MRT_ExpandAllButton.tsx +8 -16
  61. package/src/components/buttons/MRT_ExpandButton.tsx +9 -21
  62. package/src/components/buttons/MRT_GrabHandleButton.tsx +6 -10
  63. package/src/components/buttons/MRT_RowPinButton.tsx +8 -23
  64. package/src/components/buttons/MRT_ShowHideColumnsButton.tsx +5 -18
  65. package/src/components/buttons/MRT_ToggleDensePaddingButton.test.tsx +4 -12
  66. package/src/components/buttons/MRT_ToggleDensePaddingButton.tsx +4 -11
  67. package/src/components/buttons/MRT_ToggleFiltersButton.test.tsx +4 -13
  68. package/src/components/buttons/MRT_ToggleFiltersButton.tsx +3 -5
  69. package/src/components/buttons/MRT_ToggleFullScreenButton.test.tsx +3 -11
  70. package/src/components/buttons/MRT_ToggleFullScreenButton.tsx +4 -9
  71. package/src/components/buttons/MRT_ToggleGlobalFilterButton.tsx +3 -5
  72. package/src/components/buttons/MRT_ToggleRowActionMenuButton.tsx +7 -15
  73. package/src/components/footer/MRT_TableFooter.tsx +9 -16
  74. package/src/components/footer/MRT_TableFooterCell.tsx +9 -32
  75. package/src/components/footer/MRT_TableFooterRow.tsx +18 -32
  76. package/src/components/head/MRT_TableHead.tsx +8 -18
  77. package/src/components/head/MRT_TableHeadCell.tsx +46 -100
  78. package/src/components/head/MRT_TableHeadCellColumnActionsButton.tsx +10 -30
  79. package/src/components/head/MRT_TableHeadCellFilterContainer.tsx +4 -15
  80. package/src/components/head/MRT_TableHeadCellFilterLabel.tsx +20 -54
  81. package/src/components/head/MRT_TableHeadCellGrabHandle.test.tsx +5 -19
  82. package/src/components/head/MRT_TableHeadCellGrabHandle.tsx +9 -38
  83. package/src/components/head/MRT_TableHeadCellResizeHandle.test.tsx +3 -13
  84. package/src/components/head/MRT_TableHeadCellResizeHandle.tsx +10 -24
  85. package/src/components/head/MRT_TableHeadCellSortLabel.tsx +10 -26
  86. package/src/components/head/MRT_TableHeadRow.tsx +24 -36
  87. package/src/components/inputs/MRT_EditCellTextField.test.tsx +2 -9
  88. package/src/components/inputs/MRT_EditCellTextField.tsx +9 -28
  89. package/src/components/inputs/MRT_FilterCheckbox.tsx +9 -23
  90. package/src/components/inputs/MRT_FilterRangeFields.tsx +6 -15
  91. package/src/components/inputs/MRT_FilterRangeSlider.tsx +24 -32
  92. package/src/components/inputs/MRT_FilterTextField.test.tsx +72 -14
  93. package/src/components/inputs/MRT_FilterTextField.tsx +77 -138
  94. package/src/components/inputs/MRT_GlobalFilterTextField.tsx +10 -32
  95. package/src/components/inputs/MRT_SelectCheckbox.test.tsx +4 -11
  96. package/src/components/inputs/MRT_SelectCheckbox.tsx +17 -36
  97. package/src/components/menus/MRT_ActionMenuItem.tsx +6 -15
  98. package/src/components/menus/MRT_CellActionMenu.tsx +6 -9
  99. package/src/components/menus/MRT_ColumnActionMenu.tsx +22 -57
  100. package/src/components/menus/MRT_FilterOptionMenu.tsx +38 -65
  101. package/src/components/menus/MRT_RowActionMenu.tsx +33 -22
  102. package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +29 -65
  103. package/src/components/menus/MRT_ShowHideColumnsMenuItems.test.tsx +43 -0
  104. package/src/components/menus/MRT_ShowHideColumnsMenuItems.tsx +14 -50
  105. package/src/components/modals/MRT_EditRowModal.test.tsx +5 -21
  106. package/src/components/modals/MRT_EditRowModal.tsx +8 -26
  107. package/src/components/table/MRT_Table.tsx +12 -20
  108. package/src/components/table/MRT_TableContainer.test.tsx +147 -0
  109. package/src/components/table/MRT_TableContainer.tsx +33 -37
  110. package/src/components/table/MRT_TableLoadingOverlay.tsx +3 -5
  111. package/src/components/table/MRT_TablePaper.tsx +7 -14
  112. package/src/components/toolbar/MRT_BottomToolbar.tsx +11 -23
  113. package/src/components/toolbar/MRT_LinearProgressBar.tsx +4 -11
  114. package/src/components/toolbar/MRT_TablePagination.tsx +33 -40
  115. package/src/components/toolbar/MRT_ToolbarAlertBanner.tsx +21 -50
  116. package/src/components/toolbar/MRT_ToolbarDropZone.test.tsx +26 -10
  117. package/src/components/toolbar/MRT_ToolbarDropZone.tsx +23 -21
  118. package/src/components/toolbar/MRT_ToolbarInternalButtons.tsx +11 -21
  119. package/src/components/toolbar/MRT_TopToolbar.tsx +12 -28
  120. package/src/fns/aggregationFns.test.tsx +1 -3
  121. package/src/fns/filterFns.test.tsx +8 -37
  122. package/src/fns/filterFns.ts +71 -96
  123. package/src/fns/sortingFns.test.tsx +5 -21
  124. package/src/fns/sortingFns.ts +10 -14
  125. package/src/fns/tableFeatures.test.tsx +6 -29
  126. package/src/fns/tableFeatures.ts +5 -4
  127. package/src/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +2 -11
  128. package/src/hooks/display-columns/getMRT_RowDragColumnDef.tsx +2 -10
  129. package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +8 -17
  130. package/src/hooks/display-columns/getMRT_RowNumbersColumnDef.tsx +3 -8
  131. package/src/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +2 -8
  132. package/src/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +3 -13
  133. package/src/hooks/display-columns/getMRT_RowSpacerColumnDef.tsx +1 -5
  134. package/src/hooks/useMRT_ColumnVirtualizer.ts +28 -49
  135. package/src/hooks/useMRT_Effects.test.tsx +114 -0
  136. package/src/hooks/useMRT_Effects.ts +26 -27
  137. package/src/hooks/useMRT_RowVirtualizer.ts +18 -33
  138. package/src/hooks/useMRT_Rows.ts +3 -42
  139. package/src/hooks/useMRT_TableInstance.ts +63 -129
  140. package/src/hooks/useMRT_TableOptions.ts +15 -29
  141. package/src/hooks/useMaterialReactTable.ts +2 -7
  142. package/src/icons.ts +38 -1
  143. package/src/index.ts +0 -4
  144. package/src/locales/ar.ts +1 -2
  145. package/src/locales/az.ts +1 -2
  146. package/src/locales/bg.ts +1 -2
  147. package/src/locales/cs.ts +2 -4
  148. package/src/locales/da.ts +1 -2
  149. package/src/locales/de.ts +1 -2
  150. package/src/locales/el.ts +1 -2
  151. package/src/locales/en.ts +1 -2
  152. package/src/locales/es.ts +1 -2
  153. package/src/locales/et.ts +2 -4
  154. package/src/locales/fa.ts +1 -2
  155. package/src/locales/fi.ts +2 -4
  156. package/src/locales/fr.ts +1 -2
  157. package/src/locales/he.ts +1 -2
  158. package/src/locales/hr.ts +1 -2
  159. package/src/locales/hu.ts +1 -2
  160. package/src/locales/hy.ts +1 -2
  161. package/src/locales/id.ts +2 -4
  162. package/src/locales/it.ts +1 -2
  163. package/src/locales/ja.ts +1 -2
  164. package/src/locales/ko.ts +1 -2
  165. package/src/locales/nl.ts +1 -2
  166. package/src/locales/no.ts +2 -4
  167. package/src/locales/np.ts +2 -4
  168. package/src/locales/pl.ts +1 -2
  169. package/src/locales/pt-BR.ts +1 -2
  170. package/src/locales/pt.ts +1 -2
  171. package/src/locales/ro.ts +1 -2
  172. package/src/locales/ru.ts +1 -2
  173. package/src/locales/sk.ts +2 -4
  174. package/src/locales/sr-Cyrl-RS.ts +1 -2
  175. package/src/locales/sr-Latn-RS.ts +1 -2
  176. package/src/locales/sv.ts +1 -2
  177. package/src/locales/tr.ts +1 -2
  178. package/src/locales/uk.ts +1 -2
  179. package/src/locales/vi.ts +1 -2
  180. package/src/types.ts +156 -349
  181. package/src/utils/cell.utils.ts +30 -68
  182. package/src/utils/column.utils.ts +61 -49
  183. package/src/utils/displayColumn.utils.ts +16 -38
  184. package/src/utils/highlight.utils.ts +7 -11
  185. package/src/utils/row.utils.ts +40 -65
  186. package/src/utils/slotProps.utils.ts +1 -4
  187. package/src/utils/style.utils.ts +18 -46
  188. package/src/utils/tanstack.helpers.ts +10 -17
  189. package/src/utils/utils.ts +6 -10
  190. package/src/utils/virtualization.utils.ts +5 -9
@@ -1,42 +1,34 @@
1
- import { Autocomplete, type AutocompleteInputChangeReason, type AutocompleteRenderInputParams } from '@mui/material';
2
- import { Box } from '@mui/material';
3
- import { Checkbox } from '@mui/material';
4
- import { Chip } from '@mui/material';
5
- import { IconButton } from '@mui/material';
6
- import { InputAdornment } from '@mui/material';
7
- import { MenuItem } from '@mui/material';
8
- import { TextField, type TextFieldProps } from '@mui/material';
9
- import { Tooltip } from '@mui/material';
1
+ import {
2
+ Autocomplete,
3
+ type AutocompleteInputChangeReason,
4
+ type AutocompleteRenderInputParams,
5
+ Box,
6
+ Checkbox,
7
+ Chip,
8
+ IconButton,
9
+ InputAdornment,
10
+ MenuItem,
11
+ TextField,
12
+ type TextFieldProps,
13
+ Tooltip,
14
+ } from '@mui/material';
15
+ import { type CSSObject } from '@mui/material/styles';
10
16
  import { debounce } from '@mui/material/utils';
11
17
  import { DatePicker } from '@mui/x-date-pickers/DatePicker';
12
18
  import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
19
+ import { type PickersTextFieldProps } from '@mui/x-date-pickers/PickersTextField';
13
20
  import { TimePicker } from '@mui/x-date-pickers/TimePicker';
14
- import {
15
- type ChangeEvent,
16
- type MouseEvent,
17
- type SyntheticEvent,
18
- useCallback,
19
- useEffect,
20
- useRef,
21
- useState,
22
- } from 'react';
21
+ import { type ChangeEvent, type MouseEvent, type SyntheticEvent, useEffect, useRef, useState } from 'react';
23
22
 
24
- import {
25
- type DropdownOption,
26
- type MRT_Header,
27
- type MRT_RowData,
28
- type MRT_TableInstance,
29
- } from '../../types';
30
- import {
31
- getColumnFilterInfo,
32
- useDropdownOptions,
33
- } from '../../utils/column.utils';
23
+ import { type DropdownOption, type MRT_Header, type MRT_RowData, type MRT_TableInstance } from '../../types';
24
+ import { getColumnFilterInfo, getFilterOptionLabel, useDropdownOptions } from '../../utils/column.utils';
34
25
  import { getTextFieldSlotProps } from '../../utils/slotProps.utils';
35
26
  import { getValueAndLabel, parseFromValuesOrFunc } from '../../utils/utils';
36
27
  import { MRT_FilterOptionMenu } from '../menus/MRT_FilterOptionMenu';
37
28
 
38
- export interface MRT_FilterTextFieldProps<TData extends MRT_RowData>
39
- extends TextFieldProps<'standard'> {
29
+ type MRT_FilterInputValue = (number | string)[] | Date | number | string | null;
30
+
31
+ export interface MRT_FilterTextFieldProps<TData extends MRT_RowData> extends TextFieldProps<'standard'> {
40
32
  header: MRT_Header<TData>;
41
33
  rangeFilterIndex?: number;
42
34
  table: MRT_TableInstance<TData>;
@@ -47,7 +39,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
47
39
  rangeFilterIndex,
48
40
  table,
49
41
  ...rest
50
- }: MRT_FilterTextFieldProps<TData>) => {
42
+ }: MRT_FilterTextFieldProps<TData>): JSX.Element => {
51
43
  const {
52
44
  options: {
53
45
  enableColumnFilterModes,
@@ -83,17 +75,17 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
83
75
  const datePickerProps = {
84
76
  ...parseFromValuesOrFunc(muiFilterDatePickerProps, args),
85
77
  ...parseFromValuesOrFunc(columnDef.muiFilterDatePickerProps, args),
86
- } as any;
78
+ };
87
79
 
88
80
  const dateTimePickerProps = {
89
81
  ...parseFromValuesOrFunc(muiFilterDateTimePickerProps, args),
90
82
  ...parseFromValuesOrFunc(columnDef.muiFilterDateTimePickerProps, args),
91
- } as any;
83
+ };
92
84
 
93
85
  const timePickerProps = {
94
86
  ...parseFromValuesOrFunc(muiFilterTimePickerProps, args),
95
87
  ...parseFromValuesOrFunc(columnDef.muiFilterTimePickerProps, args),
96
- } as any;
88
+ };
97
89
 
98
90
  const {
99
91
  allowedColumnFilterOptions,
@@ -110,20 +102,11 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
110
102
  const dropdownOptions = useDropdownOptions({ header, table });
111
103
 
112
104
  const filterChipLabel = ['empty', 'notEmpty'].includes(currentFilterOption)
113
- ? localization[
114
- `filter${
115
- currentFilterOption?.charAt?.(0)?.toUpperCase() +
116
- currentFilterOption?.slice(1)
117
- }` as keyof typeof localization
118
- ]
105
+ ? getFilterOptionLabel(localization, currentFilterOption)
119
106
  : '';
120
107
 
121
108
  const filterPlaceholder = !isRangeFilter
122
- ? (textFieldProps?.placeholder ??
123
- localization.filterByColumn?.replace(
124
- '{column}',
125
- String(columnDef.header),
126
- ))
109
+ ? (textFieldProps?.placeholder ?? localization.filterByColumn?.replace('{column}', String(columnDef.header)))
127
110
  : rangeFilterIndex === 0
128
111
  ? localization.min
129
112
  : rangeFilterIndex === 1
@@ -134,36 +117,30 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
134
117
  enableColumnFilterModes &&
135
118
  columnDef.enableColumnFilterModes !== false &&
136
119
  !rangeFilterIndex &&
137
- (allowedColumnFilterOptions === undefined ||
138
- !!allowedColumnFilterOptions?.length)
120
+ (allowedColumnFilterOptions === undefined || !!allowedColumnFilterOptions?.length)
139
121
  );
140
122
 
141
123
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
142
- const [filterValue, setFilterValue] = useState<string | string[]>(() =>
124
+ const [filterValue, setFilterValue] = useState<MRT_FilterInputValue>(() =>
143
125
  isMultiSelectFilter
144
126
  ? (column.getFilterValue() as string[]) || []
145
127
  : isRangeFilter
146
- ? (column.getFilterValue() as [string, string])?.[
147
- rangeFilterIndex as number
148
- ] || ''
128
+ ? (column.getFilterValue() as [string, string])?.[rangeFilterIndex as number] || ''
149
129
  : isAutocompleteFilter
150
130
  ? typeof column.getFilterValue() === 'string'
151
131
  ? (column.getFilterValue() as string)
152
132
  : ''
153
133
  : ((column.getFilterValue() as string) ?? ''),
154
134
  );
155
- const [autocompleteValue, setAutocompleteValue] =
156
- useState<DropdownOption | null>(() =>
157
- isAutocompleteFilter
158
- ? ((column.getFilterValue() || null) as DropdownOption | null)
159
- : null,
160
- );
161
-
162
- const handleChangeDebounced = useCallback(
135
+ const [autocompleteValue, setAutocompleteValue] = useState<DropdownOption | null>(() =>
136
+ isAutocompleteFilter ? ((column.getFilterValue() || null) as DropdownOption | null) : null,
137
+ );
138
+
139
+ const [handleChangeDebounced] = useState(() =>
163
140
  debounce(
164
- (newValue: any) => {
141
+ (newValue: unknown) => {
165
142
  if (isRangeFilter) {
166
- column.setFilterValue((old: Array<Date | null | number | string>) => {
143
+ column.setFilterValue((old: unknown[]) => {
167
144
  const newFilterValues = old ?? ['', ''];
168
145
  newFilterValues[rangeFilterIndex as number] = newValue ?? undefined;
169
146
  return newFilterValues;
@@ -174,10 +151,9 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
174
151
  },
175
152
  isTextboxFilter ? (manualFiltering ? 400 : 200) : 1,
176
153
  ),
177
- [],
178
154
  );
179
155
 
180
- const handleChange = (newValue: any) => {
156
+ const handleChange = (newValue: MRT_FilterInputValue) => {
181
157
  setFilterValue(newValue ?? '');
182
158
  handleChangeDebounced(newValue);
183
159
  };
@@ -243,12 +219,18 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
243
219
  };
244
220
 
245
221
  const isMounted = useRef(false);
222
+ const handleClearRef = useRef(handleClear);
223
+ const columnFilterValue = column.getFilterValue();
224
+
225
+ useEffect(() => {
226
+ handleClearRef.current = handleClear;
227
+ });
246
228
 
247
229
  useEffect(() => {
248
230
  if (isMounted.current) {
249
- const filterValue = column.getFilterValue();
231
+ const filterValue = columnFilterValue;
250
232
  if (filterValue === undefined) {
251
- handleClear();
233
+ handleClearRef.current();
252
234
  } else if (isRangeFilter && rangeFilterIndex !== undefined) {
253
235
  setFilterValue((filterValue as [string, string])[rangeFilterIndex]);
254
236
  } else {
@@ -256,12 +238,10 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
256
238
  }
257
239
  }
258
240
  isMounted.current = true;
259
- }, [column.getFilterValue()]);
241
+ }, [columnFilterValue, isRangeFilter, rangeFilterIndex]);
260
242
 
261
243
  if (columnDef.Filter) {
262
- return (
263
- <>{columnDef.Filter?.({ column, header, rangeFilterIndex, table })}</>
264
- );
244
+ return <>{columnDef.Filter?.({ column, header, rangeFilterIndex, table })}</>;
265
245
  }
266
246
 
267
247
  const endAdornment =
@@ -270,7 +250,10 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
270
250
  position="end"
271
251
  sx={{
272
252
  mr: isSelectFilter || isMultiSelectFilter ? '20px' : undefined,
273
- visibility: (filterValue?.length ?? 0) > 0 ? 'visible' : 'hidden',
253
+ visibility:
254
+ (typeof filterValue === 'string' || Array.isArray(filterValue)) && filterValue.length > 0
255
+ ? 'visible'
256
+ : 'hidden',
274
257
  }}
275
258
  >
276
259
  <Tooltip placement="right" title={localization.clearFilter ?? ''}>
@@ -307,39 +290,25 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
307
290
  </IconButton>
308
291
  </span>
309
292
  </Tooltip>
310
- {filterChipLabel && (
311
- <Chip label={filterChipLabel} onDelete={handleClearEmptyFilterChip} />
312
- )}
293
+ {filterChipLabel && <Chip label={filterChipLabel} onDelete={handleClearEmptyFilterChip} />}
313
294
  </InputAdornment>
314
295
  ) : null;
315
296
 
316
- const commonTextFieldProps: TextFieldProps<any> = {
297
+ const commonTextFieldProps: TextFieldProps = {
317
298
  fullWidth: true,
318
299
  helperText: showChangeModeButton ? (
319
300
  <label>
320
- {localization.filterMode.replace(
321
- '{filterType}',
322
- localization[
323
- `filter${
324
- currentFilterOption?.charAt(0)?.toUpperCase() +
325
- currentFilterOption?.slice(1)
326
- }` as keyof typeof localization
327
- ],
328
- )}
301
+ {localization.filterMode.replace('{filterType}', getFilterOptionLabel(localization, currentFilterOption))}
329
302
  </label>
330
303
  ) : null,
331
304
  inputRef: (inputRef) => {
332
- filterInputRefs.current![`${column.id}-${rangeFilterIndex ?? 0}`] =
333
- inputRef;
305
+ filterInputRefs.current![`${column.id}-${rangeFilterIndex ?? 0}`] = inputRef;
334
306
  if (textFieldProps.inputRef) {
335
307
  textFieldProps.inputRef = inputRef;
336
308
  }
337
309
  },
338
310
  margin: 'none',
339
- placeholder:
340
- filterChipLabel || isSelectFilter || isMultiSelectFilter
341
- ? undefined
342
- : filterPlaceholder,
311
+ placeholder: filterChipLabel || isSelectFilter || isMultiSelectFilter ? undefined : filterPlaceholder,
343
312
  variant: 'standard',
344
313
  ...textFieldProps,
345
314
  onKeyDown: (e) => {
@@ -384,12 +353,12 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
384
353
  mx: '-2px',
385
354
  p: 0,
386
355
  width: 'calc(100% + 4px)',
387
- ...(parseFromValuesOrFunc(textFieldProps?.sx, theme) as any),
356
+ ...(parseFromValuesOrFunc(textFieldProps?.sx, theme) as CSSObject),
388
357
  }),
389
358
  };
390
359
 
391
360
  const commonDatePickerProps = {
392
- onChange: (newDate: any) => {
361
+ onChange: (newDate: Date | null) => {
393
362
  handleChange(newDate);
394
363
  },
395
364
  value: filterValue || null,
@@ -409,7 +378,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
409
378
  ...timePickerProps?.slotProps?.field,
410
379
  },
411
380
  textField: {
412
- ...commonTextFieldProps,
381
+ ...(commonTextFieldProps as PickersTextFieldProps),
413
382
  ...timePickerProps?.slotProps?.textField,
414
383
  },
415
384
  }}
@@ -426,7 +395,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
426
395
  ...dateTimePickerProps?.slotProps?.field,
427
396
  },
428
397
  textField: {
429
- ...commonTextFieldProps,
398
+ ...(commonTextFieldProps as PickersTextFieldProps),
430
399
  ...dateTimePickerProps?.slotProps?.textField,
431
400
  },
432
401
  }}
@@ -443,7 +412,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
443
412
  ...datePickerProps?.slotProps?.field,
444
413
  },
445
414
  textField: {
446
- ...commonTextFieldProps,
415
+ ...(commonTextFieldProps as PickersTextFieldProps),
447
416
  ...datePickerProps?.slotProps?.textField,
448
417
  },
449
418
  }}
@@ -451,34 +420,22 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
451
420
  ) : isAutocompleteFilter ? (
452
421
  <Autocomplete
453
422
  freeSolo
454
- getOptionLabel={(option: DropdownOption) =>
455
- getValueAndLabel(option).label
456
- }
423
+ getOptionLabel={(option: DropdownOption) => getValueAndLabel(option).label}
457
424
  inputValue={filterValue as string}
458
- onChange={(_e, newValue) =>
459
- handleAutocompleteChange(newValue as DropdownOption | null)
460
- }
425
+ onChange={(_e, newValue) => handleAutocompleteChange(newValue as DropdownOption | null)}
461
426
  onInputChange={handleAutocompleteInputChange}
462
- options={
463
- dropdownOptions?.map((option) => getValueAndLabel(option)) ?? []
464
- }
427
+ options={dropdownOptions?.map((option) => getValueAndLabel(option)) ?? []}
465
428
  {...autocompleteProps}
466
429
  renderInput={(params: AutocompleteRenderInputParams) => {
467
- const commonInput = getTextFieldSlotProps(
468
- commonTextFieldProps.slotProps,
469
- ).input;
470
- const commonHtmlInput = getTextFieldSlotProps(
471
- commonTextFieldProps.slotProps,
472
- ).htmlInput;
430
+ const commonInput = getTextFieldSlotProps(commonTextFieldProps.slotProps).input;
431
+ const commonHtmlInput = getTextFieldSlotProps(commonTextFieldProps.slotProps).htmlInput;
473
432
  return (
474
433
  <TextField
475
434
  {...commonTextFieldProps}
476
435
  disabled={params.disabled}
477
436
  fullWidth={params.fullWidth}
478
437
  id={params.id}
479
- onClick={(e: MouseEvent<HTMLInputElement>) =>
480
- e.stopPropagation()
481
- }
438
+ onClick={(e: MouseEvent<HTMLInputElement>) => e.stopPropagation()}
482
439
  size={params.size}
483
440
  slotProps={{
484
441
  ...commonTextFieldProps.slotProps,
@@ -507,31 +464,23 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
507
464
  ...commonTextFieldProps.slotProps,
508
465
  inputLabel: {
509
466
  shrink: isSelectFilter || isMultiSelectFilter,
510
- ...(commonTextFieldProps.slotProps?.inputLabel as any),
467
+ ...commonTextFieldProps.slotProps?.inputLabel,
511
468
  },
512
469
  select: {
513
470
  displayEmpty: true,
514
471
  MenuProps: { disableScrollLock: true },
515
472
  multiple: isMultiSelectFilter,
516
473
  renderValue: isMultiSelectFilter
517
- ? (selected: any) =>
474
+ ? (selected: unknown) =>
518
475
  !Array.isArray(selected) || selected?.length === 0 ? (
519
476
  <Box sx={{ opacity: 0.5 }}>{filterPlaceholder}</Box>
520
477
  ) : (
521
- <Box
522
- sx={{ display: 'flex', flexWrap: 'wrap', gap: '2px' }}
523
- >
478
+ <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: '2px' }}>
524
479
  {selected.map((value: string) => {
525
480
  const selectedValue = dropdownOptions?.find(
526
- (option) =>
527
- getValueAndLabel(option).value === value,
528
- );
529
- return (
530
- <Chip
531
- key={value}
532
- label={getValueAndLabel(selectedValue).label}
533
- />
481
+ (option) => getValueAndLabel(option).value === value,
534
482
  );
483
+ return <Chip key={value} label={getValueAndLabel(selectedValue).label} />;
535
484
  })}
536
485
  </Box>
537
486
  )
@@ -539,13 +488,7 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
539
488
  ...commonTextFieldProps.slotProps?.select,
540
489
  },
541
490
  }}
542
- value={
543
- isMultiSelectFilter
544
- ? Array.isArray(filterValue)
545
- ? filterValue
546
- : []
547
- : filterValue
548
- }
491
+ value={isMultiSelectFilter ? (Array.isArray(filterValue) ? filterValue : []) : filterValue}
549
492
  >
550
493
  {(isSelectFilter || isMultiSelectFilter) && [
551
494
  <MenuItem disabled divider hidden key="p" value="">
@@ -568,15 +511,11 @@ export const MRT_FilterTextField = <TData extends MRT_RowData>({
568
511
  >
569
512
  {isMultiSelectFilter && (
570
513
  <Checkbox
571
- checked={(
572
- (column.getFilterValue() ?? []) as string[]
573
- ).includes(value)}
514
+ checked={((column.getFilterValue() ?? []) as (number | string)[]).includes(value)}
574
515
  sx={{ mr: '0.5rem' }}
575
516
  />
576
517
  )}
577
- {label}{' '}
578
- {!columnDef.filterSelectOptions &&
579
- `(${facetedUniqueValues.get(value)})`}
518
+ {label} {!columnDef.filterSelectOptions && `(${facetedUniqueValues.get(value)})`}
580
519
  </MenuItem>
581
520
  );
582
521
  }),
@@ -1,32 +1,20 @@
1
- import { Collapse } from '@mui/material';
2
- import { IconButton } from '@mui/material';
3
- import { InputAdornment } from '@mui/material';
4
- import { TextField, type TextFieldProps } from '@mui/material';
5
- import { Tooltip } from '@mui/material';
1
+ import { Collapse, IconButton, InputAdornment, TextField, type TextFieldProps, Tooltip } from '@mui/material';
6
2
  import { debounce } from '@mui/material/utils';
7
- import {
8
- type ChangeEvent,
9
- type MouseEvent,
10
- useCallback,
11
- useEffect,
12
- useRef,
13
- useState,
14
- } from 'react';
3
+ import { type ChangeEvent, type MouseEvent, useEffect, useRef, useState } from 'react';
15
4
 
16
5
  import { type MRT_RowData, type MRT_TableInstance } from '../../types';
17
6
  import { getTextFieldSlotProps } from '../../utils/slotProps.utils';
18
7
  import { parseFromValuesOrFunc } from '../../utils/utils';
19
8
  import { MRT_FilterOptionMenu } from '../menus/MRT_FilterOptionMenu';
20
9
 
21
- export interface MRT_GlobalFilterTextFieldProps<TData extends MRT_RowData>
22
- extends TextFieldProps<'standard'> {
10
+ export interface MRT_GlobalFilterTextFieldProps<TData extends MRT_RowData> extends TextFieldProps<'standard'> {
23
11
  table: MRT_TableInstance<TData>;
24
12
  }
25
13
 
26
14
  export const MRT_GlobalFilterTextField = <TData extends MRT_RowData>({
27
15
  table,
28
16
  ...rest
29
- }: MRT_GlobalFilterTextFieldProps<TData>) => {
17
+ }: MRT_GlobalFilterTextFieldProps<TData>): JSX.Element => {
30
18
  const {
31
19
  options: {
32
20
  enableGlobalFilterModes,
@@ -51,14 +39,13 @@ export const MRT_GlobalFilterTextField = <TData extends MRT_RowData>({
51
39
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
52
40
  const [searchValue, setSearchValue] = useState(globalFilter ?? '');
53
41
 
54
- const handleChangeDebounced = useCallback(
42
+ const [handleChangeDebounced] = useState(() =>
55
43
  debounce(
56
44
  (event: ChangeEvent<HTMLInputElement>) => {
57
45
  setGlobalFilter(event.target.value ?? undefined);
58
46
  },
59
47
  manualFiltering ? 500 : 250,
60
48
  ),
61
- [],
62
49
  );
63
50
 
64
51
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
@@ -78,23 +65,19 @@ export const MRT_GlobalFilterTextField = <TData extends MRT_RowData>({
78
65
  useEffect(() => {
79
66
  if (isMounted.current) {
80
67
  if (globalFilter === undefined) {
81
- handleClear();
68
+ setSearchValue('');
69
+ setGlobalFilter(undefined);
82
70
  } else {
83
71
  setSearchValue(globalFilter);
84
72
  }
85
73
  }
86
74
  isMounted.current = true;
87
- }, [globalFilter]);
75
+ }, [globalFilter, setGlobalFilter]);
88
76
 
89
77
  const consumerSlots = getTextFieldSlotProps(textFieldProps.slotProps);
90
78
 
91
79
  return (
92
- <Collapse
93
- in={showGlobalFilter}
94
- mountOnEnter
95
- orientation="horizontal"
96
- unmountOnExit
97
- >
80
+ <Collapse in={showGlobalFilter} mountOnEnter orientation="horizontal" unmountOnExit>
98
81
  <TextField
99
82
  onChange={handleChange}
100
83
  placeholder={localization.search}
@@ -148,12 +131,7 @@ export const MRT_GlobalFilterTextField = <TData extends MRT_RowData>({
148
131
  },
149
132
  }}
150
133
  />
151
- <MRT_FilterOptionMenu
152
- anchorEl={anchorEl}
153
- onSelect={handleClear}
154
- setAnchorEl={setAnchorEl}
155
- table={table}
156
- />
134
+ <MRT_FilterOptionMenu anchorEl={anchorEl} onSelect={handleClear} setAnchorEl={setAnchorEl} table={table} />
157
135
  </Collapse>
158
136
  );
159
137
  };
@@ -11,22 +11,15 @@ interface Person {
11
11
 
12
12
  const data: Person[] = [{ name: 'Alice' }, { name: 'Bob' }];
13
13
 
14
- const columns = (): MRT_ColumnDef<Person>[] => [
15
- { accessorKey: 'name', header: 'Name' },
16
- ];
14
+ const columns = (): MRT_ColumnDef<Person>[] => [{ accessorKey: 'name', header: 'Name' }];
17
15
 
18
16
  const selectAll = (container: HTMLElement) =>
19
17
  container.querySelector('thead input[type="checkbox"]') as HTMLInputElement;
20
18
 
21
19
  const rowBoxes = (container: HTMLElement) =>
22
- Array.from(
23
- container.querySelectorAll<HTMLInputElement>(
24
- 'tbody input[type="checkbox"]',
25
- ),
26
- );
27
-
28
- const renderTable = () =>
29
- render(<MaterialReactTable columns={columns()} data={data} enableRowSelection />);
20
+ Array.from(container.querySelectorAll<HTMLInputElement>('tbody input[type="checkbox"]'));
21
+
22
+ const renderTable = () => render(<MaterialReactTable columns={columns()} data={data} enableRowSelection />);
30
23
 
31
24
  describe('row selection checkboxes', () => {
32
25
  test('select all checks every row', async () => {
@@ -1,24 +1,13 @@
1
- import { Checkbox, type CheckboxProps } from '@mui/material';
2
- import { Radio, type RadioProps } from '@mui/material';
3
- import { Tooltip } from '@mui/material';
1
+ import { Checkbox, type CheckboxProps, Radio, type RadioProps, Tooltip } from '@mui/material';
4
2
  import { type Theme } from '@mui/material/styles';
5
3
  import { type MouseEvent } from 'react';
6
4
 
7
- import {
8
- type MRT_Row,
9
- type MRT_RowData,
10
- type MRT_TableInstance,
11
- } from '../../types';
12
- import {
13
- getIsRowSelected,
14
- getMRT_RowSelectionHandler,
15
- getMRT_SelectAllHandler,
16
- } from '../../utils/row.utils';
5
+ import { type MRT_Row, type MRT_RowData, type MRT_TableInstance } from '../../types';
6
+ import { getIsRowSelected, getMRT_RowSelectionHandler, getMRT_SelectAllHandler } from '../../utils/row.utils';
17
7
  import { getCommonTooltipProps } from '../../utils/style.utils';
18
8
  import { parseFromValuesOrFunc } from '../../utils/utils';
19
9
 
20
- export interface MRT_SelectCheckboxProps<TData extends MRT_RowData>
21
- extends CheckboxProps {
10
+ export interface MRT_SelectCheckboxProps<TData extends MRT_RowData> extends CheckboxProps {
22
11
  row?: MRT_Row<TData>;
23
12
  staticRowIndex?: number;
24
13
  table: MRT_TableInstance<TData>;
@@ -29,7 +18,7 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
29
18
  staticRowIndex,
30
19
  table,
31
20
  ...rest
32
- }: MRT_SelectCheckboxProps<TData>) => {
21
+ }: MRT_SelectCheckboxProps<TData>): JSX.Element => {
33
22
  const {
34
23
  options: {
35
24
  enableMultiRowSelection,
@@ -49,9 +38,7 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
49
38
  : table.getIsAllRowsSelected()
50
39
  : undefined;
51
40
 
52
- const isChecked = selectAll
53
- ? allRowsSelected
54
- : getIsRowSelected({ row, table });
41
+ const isChecked = selectAll ? allRowsSelected : getIsRowSelected({ row, table });
55
42
 
56
43
  const checkboxProps = {
57
44
  ...(selectAll
@@ -75,22 +62,21 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
75
62
  const onSelectAllChange = getMRT_SelectAllHandler({ table });
76
63
 
77
64
  const commonProps = {
78
- 'aria-label': selectAll
79
- ? localization.toggleSelectAll
80
- : localization.toggleSelectRow,
65
+ 'aria-label': selectAll ? localization.toggleSelectAll : localization.toggleSelectRow,
81
66
  checked: isChecked,
82
- disabled:
83
- isLoading || (row && !row.getCanSelect()) || row?.id === 'mrt-row-create',
67
+ disabled: isLoading || (row && !row.getCanSelect()) || row?.id === 'mrt-row-create',
84
68
  onChange: (event) => {
85
69
  event.stopPropagation();
86
- selectAll ? onSelectAllChange(event) : onSelectionChange!(event);
70
+ if (selectAll) {
71
+ onSelectAllChange(event);
72
+ } else {
73
+ onSelectionChange!(event);
74
+ }
87
75
  },
88
76
  size: (density === 'compact' ? 'small' : 'medium') as 'medium' | 'small',
89
77
  slotProps: {
90
78
  input: {
91
- 'aria-label': selectAll
92
- ? localization.toggleSelectAll
93
- : localization.toggleSelectRow,
79
+ 'aria-label': selectAll ? localization.toggleSelectAll : localization.toggleSelectRow,
94
80
  },
95
81
  },
96
82
  ...checkboxProps,
@@ -106,20 +92,15 @@ export const MRT_SelectCheckbox = <TData extends MRT_RowData>({
106
92
  ...parseFromValuesOrFunc(checkboxProps?.sx, theme),
107
93
  }),
108
94
  title: undefined,
109
- } as CheckboxProps | RadioProps;
95
+ } as CheckboxProps;
110
96
 
111
97
  return (
112
98
  <Tooltip
113
99
  {...getCommonTooltipProps()}
114
- title={
115
- checkboxProps?.title ??
116
- (selectAll
117
- ? localization.toggleSelectAll
118
- : localization.toggleSelectRow)
119
- }
100
+ title={checkboxProps?.title ?? (selectAll ? localization.toggleSelectAll : localization.toggleSelectRow)}
120
101
  >
121
102
  {enableMultiRowSelection === false ? (
122
- <Radio {...(commonProps as any)} />
103
+ <Radio {...(commonProps as RadioProps)} />
123
104
  ) : (
124
105
  <Checkbox
125
106
  indeterminate={