@cutting/material-react-table 4.0.5 → 5.0.0-beta.1

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 (311) hide show
  1. package/dist/index.d.ts +1825 -1737
  2. package/dist/index.js +5332 -4317
  3. package/dist/index.js.map +1 -1
  4. package/locales/ar/index.mjs +97 -0
  5. package/locales/ar/package.json +3 -3
  6. package/locales/az/index.mjs +97 -0
  7. package/locales/az/package.json +3 -3
  8. package/locales/bg/index.mjs +97 -0
  9. package/locales/bg/package.json +3 -3
  10. package/locales/cs/index.mjs +97 -0
  11. package/locales/cs/package.json +3 -3
  12. package/locales/da/index.mjs +97 -0
  13. package/locales/da/package.json +3 -3
  14. package/locales/de/index.mjs +97 -0
  15. package/locales/de/package.json +3 -3
  16. package/locales/el/index.mjs +97 -0
  17. package/locales/el/package.json +3 -3
  18. package/locales/en/index.mjs +97 -0
  19. package/locales/en/package.json +3 -3
  20. package/locales/es/index.mjs +97 -0
  21. package/locales/es/package.json +3 -3
  22. package/locales/et/index.mjs +97 -0
  23. package/locales/et/package.json +3 -3
  24. package/locales/fa/index.mjs +97 -0
  25. package/locales/fa/package.json +3 -3
  26. package/locales/fi/index.mjs +97 -0
  27. package/locales/fi/package.json +3 -3
  28. package/locales/fr/index.mjs +97 -0
  29. package/locales/fr/package.json +3 -3
  30. package/locales/he/index.mjs +97 -0
  31. package/locales/he/package.json +3 -3
  32. package/locales/hr/index.mjs +97 -0
  33. package/locales/hr/package.json +3 -3
  34. package/locales/hu/index.mjs +97 -0
  35. package/locales/hu/package.json +3 -3
  36. package/locales/hy/index.mjs +97 -0
  37. package/locales/hy/package.json +3 -3
  38. package/locales/id/index.mjs +97 -0
  39. package/locales/id/package.json +3 -3
  40. package/locales/it/index.mjs +97 -0
  41. package/locales/it/package.json +3 -3
  42. package/locales/ja/index.mjs +97 -0
  43. package/locales/ja/package.json +3 -3
  44. package/locales/ko/index.mjs +97 -0
  45. package/locales/ko/package.json +3 -3
  46. package/locales/nl/index.mjs +97 -0
  47. package/locales/nl/package.json +3 -3
  48. package/locales/no/index.mjs +97 -0
  49. package/locales/no/package.json +3 -3
  50. package/locales/np/index.mjs +97 -0
  51. package/locales/np/package.json +3 -3
  52. package/locales/pl/index.mjs +97 -0
  53. package/locales/pl/package.json +3 -3
  54. package/locales/pt/index.mjs +97 -0
  55. package/locales/pt/package.json +3 -3
  56. package/locales/pt-BR/index.mjs +97 -0
  57. package/locales/pt-BR/package.json +3 -3
  58. package/locales/ro/index.mjs +97 -0
  59. package/locales/ro/package.json +3 -3
  60. package/locales/ru/index.mjs +97 -0
  61. package/locales/ru/package.json +3 -3
  62. package/locales/sk/index.mjs +97 -0
  63. package/locales/sk/package.json +3 -3
  64. package/locales/sr-Cyrl-RS/index.mjs +97 -0
  65. package/locales/sr-Cyrl-RS/package.json +3 -3
  66. package/locales/sr-Latn-RS/index.mjs +97 -0
  67. package/locales/sr-Latn-RS/package.json +3 -3
  68. package/locales/sv/index.mjs +97 -0
  69. package/locales/sv/package.json +3 -3
  70. package/locales/tr/index.mjs +97 -0
  71. package/locales/tr/package.json +3 -3
  72. package/locales/uk/index.mjs +97 -0
  73. package/locales/uk/package.json +3 -3
  74. package/locales/vi/index.mjs +97 -0
  75. package/locales/vi/package.json +3 -3
  76. package/locales/zh-Hans/index.mjs +97 -0
  77. package/locales/zh-Hans/package.json +3 -3
  78. package/locales/zh-Hant/index.mjs +97 -0
  79. package/locales/zh-Hant/package.json +3 -3
  80. package/package.json +57 -53
  81. package/src/components/body/MRT_TableBody.tsx +1 -2
  82. package/src/components/body/MRT_TableBodyCell.tsx +4 -5
  83. package/src/components/body/MRT_TableBodyCellValue.tsx +1 -2
  84. package/src/components/body/MRT_TableBodyRow.tsx +1 -2
  85. package/src/components/body/MRT_TableBodyRowGrabHandle.test.tsx +42 -0
  86. package/src/components/body/MRT_TableBodyRowPinButton.tsx +1 -2
  87. package/src/components/body/MRT_TableDetailPanel.test.tsx +40 -0
  88. package/src/components/body/MRT_TableDetailPanel.tsx +1 -2
  89. package/src/components/buttons/MRT_ColumnPinningButtons.test.tsx +69 -0
  90. package/src/components/buttons/MRT_ColumnPinningButtons.tsx +3 -3
  91. package/src/components/buttons/MRT_EditActionButtons.test.tsx +50 -0
  92. package/src/components/buttons/MRT_EditActionButtons.tsx +1 -3
  93. package/src/components/buttons/MRT_ExpandAllButton.tsx +1 -2
  94. package/src/components/buttons/MRT_ExpandButton.tsx +1 -2
  95. package/src/components/buttons/MRT_ToggleDensePaddingButton.test.tsx +38 -0
  96. package/src/components/buttons/MRT_ToggleDensePaddingButton.tsx +1 -2
  97. package/src/components/buttons/MRT_ToggleFiltersButton.test.tsx +38 -0
  98. package/src/components/buttons/MRT_ToggleFiltersButton.tsx +1 -2
  99. package/src/components/buttons/MRT_ToggleFullScreenButton.test.tsx +36 -0
  100. package/src/components/buttons/MRT_ToggleFullScreenButton.tsx +1 -2
  101. package/src/components/buttons/MRT_ToggleGlobalFilterButton.tsx +1 -2
  102. package/src/components/buttons/MRT_ToggleRowActionMenuButton.tsx +2 -3
  103. package/src/components/footer/MRT_TableFooter.tsx +1 -2
  104. package/src/components/footer/MRT_TableFooterCell.tsx +1 -2
  105. package/src/components/head/MRT_TableHead.tsx +1 -2
  106. package/src/components/head/MRT_TableHeadCell.tsx +9 -9
  107. package/src/components/head/MRT_TableHeadCellFilterContainer.tsx +1 -2
  108. package/src/components/head/MRT_TableHeadCellGrabHandle.test.tsx +61 -0
  109. package/src/components/head/MRT_TableHeadCellGrabHandle.tsx +4 -5
  110. package/src/components/head/MRT_TableHeadCellResizeHandle.test.tsx +45 -0
  111. package/src/components/head/MRT_TableHeadCellResizeHandle.tsx +4 -5
  112. package/src/components/head/MRT_TableHeadCellSortLabel.tsx +1 -2
  113. package/src/components/inputs/MRT_EditCellTextField.test.tsx +36 -0
  114. package/src/components/inputs/MRT_EditCellTextField.tsx +1 -3
  115. package/src/components/inputs/MRT_FilterCheckbox.tsx +1 -2
  116. package/src/components/inputs/MRT_FilterRangeSlider.tsx +2 -1
  117. package/src/components/inputs/MRT_FilterTextField.test.tsx +75 -0
  118. package/src/components/inputs/MRT_GlobalFilterTextField.tsx +1 -2
  119. package/src/components/inputs/MRT_SelectCheckbox.test.tsx +69 -0
  120. package/src/components/inputs/MRT_SelectCheckbox.tsx +1 -2
  121. package/src/components/menus/MRT_CellActionMenu.tsx +1 -2
  122. package/src/components/menus/MRT_ColumnActionMenu.tsx +12 -13
  123. package/src/components/menus/MRT_FilterOptionMenu.tsx +1 -2
  124. package/src/components/menus/MRT_RowActionMenu.tsx +1 -2
  125. package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +1 -2
  126. package/src/components/menus/MRT_ShowHideColumnsMenuItems.tsx +4 -5
  127. package/src/components/modals/MRT_EditRowModal.test.tsx +54 -0
  128. package/src/components/modals/MRT_EditRowModal.tsx +1 -2
  129. package/src/components/table/MRT_Table.tsx +4 -5
  130. package/src/components/table/MRT_TableContainer.tsx +1 -2
  131. package/src/components/table/MRT_TablePaper.tsx +1 -2
  132. package/src/components/toolbar/MRT_BottomToolbar.tsx +2 -3
  133. package/src/components/toolbar/MRT_LinearProgressBar.tsx +1 -2
  134. package/src/components/toolbar/MRT_TablePagination.tsx +1 -2
  135. package/src/components/toolbar/MRT_ToolbarAlertBanner.tsx +3 -4
  136. package/src/components/toolbar/MRT_ToolbarDropZone.test.tsx +42 -0
  137. package/src/components/toolbar/MRT_ToolbarDropZone.tsx +1 -2
  138. package/src/components/toolbar/MRT_TopToolbar.tsx +1 -2
  139. package/src/fns/aggregationFns.test.tsx +57 -0
  140. package/src/fns/filterFns.test.tsx +156 -0
  141. package/src/fns/filterFns.ts +36 -22
  142. package/src/fns/sortingFns.ts +14 -5
  143. package/src/fns/tableFeatures.test.tsx +106 -0
  144. package/src/fns/tableFeatures.ts +103 -0
  145. package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +2 -2
  146. package/src/hooks/useMRT_ColumnVirtualizer.ts +6 -5
  147. package/src/hooks/useMRT_Effects.ts +3 -4
  148. package/src/hooks/useMRT_RowVirtualizer.ts +1 -2
  149. package/src/hooks/useMRT_Rows.ts +1 -2
  150. package/src/hooks/useMRT_TableInstance.ts +82 -63
  151. package/src/hooks/useMRT_TableOptions.ts +5 -37
  152. package/src/icons.ts +1 -1
  153. package/src/types.ts +162 -134
  154. package/src/utils/column.utils.ts +31 -24
  155. package/src/utils/row.utils.ts +7 -10
  156. package/src/utils/style.utils.ts +9 -10
  157. package/src/utils/tanstack.helpers.ts +2 -2
  158. package/dist/index.esm.js +0 -4384
  159. package/dist/index.esm.js.map +0 -1
  160. package/locales/ar/index.esm.d.ts +0 -3
  161. package/locales/ar/index.esm.js +0 -96
  162. package/locales/ar/index.js +0 -98
  163. package/locales/az/index.esm.d.ts +0 -3
  164. package/locales/az/index.esm.js +0 -96
  165. package/locales/az/index.js +0 -98
  166. package/locales/bg/index.esm.d.ts +0 -3
  167. package/locales/bg/index.esm.js +0 -96
  168. package/locales/bg/index.js +0 -98
  169. package/locales/cs/index.esm.d.ts +0 -3
  170. package/locales/cs/index.esm.js +0 -96
  171. package/locales/cs/index.js +0 -98
  172. package/locales/da/index.esm.d.ts +0 -3
  173. package/locales/da/index.esm.js +0 -96
  174. package/locales/da/index.js +0 -98
  175. package/locales/de/index.esm.d.ts +0 -3
  176. package/locales/de/index.esm.js +0 -96
  177. package/locales/de/index.js +0 -98
  178. package/locales/el/index.esm.d.ts +0 -3
  179. package/locales/el/index.esm.js +0 -96
  180. package/locales/el/index.js +0 -98
  181. package/locales/en/index.esm.d.ts +0 -3
  182. package/locales/en/index.esm.js +0 -96
  183. package/locales/en/index.js +0 -98
  184. package/locales/es/index.esm.d.ts +0 -3
  185. package/locales/es/index.esm.js +0 -96
  186. package/locales/es/index.js +0 -98
  187. package/locales/et/index.esm.d.ts +0 -3
  188. package/locales/et/index.esm.js +0 -96
  189. package/locales/et/index.js +0 -98
  190. package/locales/fa/index.esm.d.ts +0 -3
  191. package/locales/fa/index.esm.js +0 -96
  192. package/locales/fa/index.js +0 -98
  193. package/locales/fi/index.esm.d.ts +0 -3
  194. package/locales/fi/index.esm.js +0 -96
  195. package/locales/fi/index.js +0 -98
  196. package/locales/fr/index.esm.d.ts +0 -3
  197. package/locales/fr/index.esm.js +0 -96
  198. package/locales/fr/index.js +0 -98
  199. package/locales/he/index.esm.d.ts +0 -3
  200. package/locales/he/index.esm.js +0 -96
  201. package/locales/he/index.js +0 -98
  202. package/locales/hr/index.esm.d.ts +0 -3
  203. package/locales/hr/index.esm.js +0 -96
  204. package/locales/hr/index.js +0 -98
  205. package/locales/hu/index.esm.d.ts +0 -3
  206. package/locales/hu/index.esm.js +0 -96
  207. package/locales/hu/index.js +0 -98
  208. package/locales/hy/index.esm.d.ts +0 -3
  209. package/locales/hy/index.esm.js +0 -96
  210. package/locales/hy/index.js +0 -98
  211. package/locales/id/index.esm.d.ts +0 -3
  212. package/locales/id/index.esm.js +0 -96
  213. package/locales/id/index.js +0 -98
  214. package/locales/it/index.esm.d.ts +0 -3
  215. package/locales/it/index.esm.js +0 -96
  216. package/locales/it/index.js +0 -98
  217. package/locales/ja/index.esm.d.ts +0 -3
  218. package/locales/ja/index.esm.js +0 -96
  219. package/locales/ja/index.js +0 -98
  220. package/locales/ko/index.esm.d.ts +0 -3
  221. package/locales/ko/index.esm.js +0 -96
  222. package/locales/ko/index.js +0 -98
  223. package/locales/nl/index.esm.d.ts +0 -3
  224. package/locales/nl/index.esm.js +0 -96
  225. package/locales/nl/index.js +0 -98
  226. package/locales/no/index.esm.d.ts +0 -3
  227. package/locales/no/index.esm.js +0 -96
  228. package/locales/no/index.js +0 -98
  229. package/locales/np/index.esm.d.ts +0 -3
  230. package/locales/np/index.esm.js +0 -96
  231. package/locales/np/index.js +0 -98
  232. package/locales/pl/index.esm.d.ts +0 -3
  233. package/locales/pl/index.esm.js +0 -96
  234. package/locales/pl/index.js +0 -98
  235. package/locales/pt/index.esm.d.ts +0 -3
  236. package/locales/pt/index.esm.js +0 -96
  237. package/locales/pt/index.js +0 -98
  238. package/locales/pt-BR/index.esm.d.ts +0 -3
  239. package/locales/pt-BR/index.esm.js +0 -96
  240. package/locales/pt-BR/index.js +0 -98
  241. package/locales/ro/index.esm.d.ts +0 -3
  242. package/locales/ro/index.esm.js +0 -96
  243. package/locales/ro/index.js +0 -98
  244. package/locales/ru/index.esm.d.ts +0 -3
  245. package/locales/ru/index.esm.js +0 -96
  246. package/locales/ru/index.js +0 -98
  247. package/locales/sk/index.esm.d.ts +0 -3
  248. package/locales/sk/index.esm.js +0 -96
  249. package/locales/sk/index.js +0 -98
  250. package/locales/sr-Cyrl-RS/index.esm.d.ts +0 -3
  251. package/locales/sr-Cyrl-RS/index.esm.js +0 -96
  252. package/locales/sr-Cyrl-RS/index.js +0 -98
  253. package/locales/sr-Latn-RS/index.esm.d.ts +0 -3
  254. package/locales/sr-Latn-RS/index.esm.js +0 -96
  255. package/locales/sr-Latn-RS/index.js +0 -98
  256. package/locales/sv/index.esm.d.ts +0 -3
  257. package/locales/sv/index.esm.js +0 -96
  258. package/locales/sv/index.js +0 -98
  259. package/locales/tr/index.esm.d.ts +0 -3
  260. package/locales/tr/index.esm.js +0 -96
  261. package/locales/tr/index.js +0 -98
  262. package/locales/uk/index.esm.d.ts +0 -3
  263. package/locales/uk/index.esm.js +0 -96
  264. package/locales/uk/index.js +0 -98
  265. package/locales/vi/index.esm.d.ts +0 -3
  266. package/locales/vi/index.esm.js +0 -96
  267. package/locales/vi/index.js +0 -98
  268. package/locales/zh-Hans/index.esm.d.ts +0 -3
  269. package/locales/zh-Hans/index.esm.js +0 -96
  270. package/locales/zh-Hans/index.js +0 -98
  271. package/locales/zh-Hant/index.esm.d.ts +0 -3
  272. package/locales/zh-Hant/index.esm.js +0 -96
  273. package/locales/zh-Hant/index.js +0 -98
  274. /package/locales/ar/{index.d.ts → index.d.mts} +0 -0
  275. /package/locales/az/{index.d.ts → index.d.mts} +0 -0
  276. /package/locales/bg/{index.d.ts → index.d.mts} +0 -0
  277. /package/locales/cs/{index.d.ts → index.d.mts} +0 -0
  278. /package/locales/da/{index.d.ts → index.d.mts} +0 -0
  279. /package/locales/de/{index.d.ts → index.d.mts} +0 -0
  280. /package/locales/el/{index.d.ts → index.d.mts} +0 -0
  281. /package/locales/en/{index.d.ts → index.d.mts} +0 -0
  282. /package/locales/es/{index.d.ts → index.d.mts} +0 -0
  283. /package/locales/et/{index.d.ts → index.d.mts} +0 -0
  284. /package/locales/fa/{index.d.ts → index.d.mts} +0 -0
  285. /package/locales/fi/{index.d.ts → index.d.mts} +0 -0
  286. /package/locales/fr/{index.d.ts → index.d.mts} +0 -0
  287. /package/locales/he/{index.d.ts → index.d.mts} +0 -0
  288. /package/locales/hr/{index.d.ts → index.d.mts} +0 -0
  289. /package/locales/hu/{index.d.ts → index.d.mts} +0 -0
  290. /package/locales/hy/{index.d.ts → index.d.mts} +0 -0
  291. /package/locales/id/{index.d.ts → index.d.mts} +0 -0
  292. /package/locales/it/{index.d.ts → index.d.mts} +0 -0
  293. /package/locales/ja/{index.d.ts → index.d.mts} +0 -0
  294. /package/locales/ko/{index.d.ts → index.d.mts} +0 -0
  295. /package/locales/nl/{index.d.ts → index.d.mts} +0 -0
  296. /package/locales/no/{index.d.ts → index.d.mts} +0 -0
  297. /package/locales/np/{index.d.ts → index.d.mts} +0 -0
  298. /package/locales/pl/{index.d.ts → index.d.mts} +0 -0
  299. /package/locales/pt/{index.d.ts → index.d.mts} +0 -0
  300. /package/locales/pt-BR/{index.d.ts → index.d.mts} +0 -0
  301. /package/locales/ro/{index.d.ts → index.d.mts} +0 -0
  302. /package/locales/ru/{index.d.ts → index.d.mts} +0 -0
  303. /package/locales/sk/{index.d.ts → index.d.mts} +0 -0
  304. /package/locales/sr-Cyrl-RS/{index.d.ts → index.d.mts} +0 -0
  305. /package/locales/sr-Latn-RS/{index.d.ts → index.d.mts} +0 -0
  306. /package/locales/sv/{index.d.ts → index.d.mts} +0 -0
  307. /package/locales/tr/{index.d.ts → index.d.mts} +0 -0
  308. /package/locales/uk/{index.d.ts → index.d.mts} +0 -0
  309. /package/locales/vi/{index.d.ts → index.d.mts} +0 -0
  310. /package/locales/zh-Hans/{index.d.ts → index.d.mts} +0 -0
  311. /package/locales/zh-Hant/{index.d.ts → index.d.mts} +0 -0
@@ -27,7 +27,7 @@ export const MRT_ColumnPinningButtons = <TData extends MRT_RowData>({
27
27
  },
28
28
  } = table;
29
29
 
30
- const handlePinColumn = (pinDirection: 'left' | 'right' | false) => {
30
+ const handlePinColumn = (pinDirection: 'end' | 'start' | false) => {
31
31
  column.pin(pinDirection);
32
32
  };
33
33
 
@@ -49,7 +49,7 @@ export const MRT_ColumnPinningButtons = <TData extends MRT_RowData>({
49
49
  ) : (
50
50
  <>
51
51
  <Tooltip title={localization.pinToLeft}>
52
- <IconButton onClick={() => handlePinColumn('left')} size="small">
52
+ <IconButton onClick={() => handlePinColumn('start')} size="small">
53
53
  <PushPinIcon
54
54
  style={{
55
55
  transform: 'rotate(90deg)',
@@ -58,7 +58,7 @@ export const MRT_ColumnPinningButtons = <TData extends MRT_RowData>({
58
58
  </IconButton>
59
59
  </Tooltip>
60
60
  <Tooltip title={localization.pinToRight}>
61
- <IconButton onClick={() => handlePinColumn('right')} size="small">
61
+ <IconButton onClick={() => handlePinColumn('end')} size="small">
62
62
  <PushPinIcon
63
63
  style={{
64
64
  transform: 'rotate(-90deg)',
@@ -0,0 +1,50 @@
1
+ import { act, render } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test, vi } from 'vitest';
4
+
5
+ import { type MRT_ColumnDef, type MRT_TableInstance } from '../../types';
6
+ import { MaterialReactTable } from '../MaterialReactTable';
7
+
8
+ interface Person {
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ ];
17
+
18
+ describe('creating a row', () => {
19
+ test('calls onCreatingRowSave when save is clicked', async () => {
20
+ const user = userEvent.setup();
21
+ const onCreatingRowSave = vi.fn();
22
+ let table: MRT_TableInstance<Person> | undefined;
23
+
24
+ const { container } = render(
25
+ <MaterialReactTable
26
+ columns={columns()}
27
+ createDisplayMode="row"
28
+ data={data}
29
+ enableEditing
30
+ onCreatingRowSave={onCreatingRowSave}
31
+ renderTopToolbarCustomActions={({ table: t }) => {
32
+ table = t;
33
+ return null;
34
+ }}
35
+ />,
36
+ );
37
+
38
+ act(() => {
39
+ table?.setCreatingRow(true);
40
+ });
41
+
42
+ expect(container.querySelectorAll('tbody input').length).toBeGreaterThan(0);
43
+
44
+ await user.click(
45
+ container.querySelector('[aria-label="Save"]') as HTMLElement,
46
+ );
47
+
48
+ expect(onCreatingRowSave).toHaveBeenCalled();
49
+ });
50
+ });
@@ -25,7 +25,6 @@ export const MRT_EditActionButtons = <TData extends MRT_RowData>({
25
25
  ...rest
26
26
  }: MRT_EditActionButtonsProps<TData>) => {
27
27
  const {
28
- getState,
29
28
  options: {
30
29
  icons: { CancelIcon, SaveIcon },
31
30
  localization,
@@ -38,7 +37,7 @@ export const MRT_EditActionButtons = <TData extends MRT_RowData>({
38
37
  setCreatingRow,
39
38
  setEditingRow,
40
39
  } = table;
41
- const { creatingRow, editingRow, isSaving } = getState();
40
+ const { creatingRow, editingRow, isSaving } = table.state;
42
41
 
43
42
  const isCreating = creatingRow?.id === row.id;
44
43
  const isEditing = editingRow?.id === row.id;
@@ -63,7 +62,6 @@ export const MRT_EditActionButtons = <TData extends MRT_RowData>({
63
62
  input.value !== undefined &&
64
63
  Object.hasOwn(row?._valuesCache as object, input.name)
65
64
  ) {
66
- // @ts-expect-error
67
65
  row._valuesCache[input.name] = input.value;
68
66
  }
69
67
  });
@@ -18,7 +18,6 @@ export const MRT_ExpandAllButton = <TData extends MRT_RowData>({
18
18
  getCanSomeRowsExpand,
19
19
  getIsAllRowsExpanded,
20
20
  getIsSomeRowsExpanded,
21
- getState,
22
21
  options: {
23
22
  icons: { KeyboardDoubleArrowDownIcon },
24
23
  localization,
@@ -27,7 +26,7 @@ export const MRT_ExpandAllButton = <TData extends MRT_RowData>({
27
26
  },
28
27
  toggleAllRowsExpanded,
29
28
  } = table;
30
- const { density, isLoading } = getState();
29
+ const { density, isLoading } = table.state;
31
30
 
32
31
  const iconButtonProps = {
33
32
  ...parseFromValuesOrFunc(muiExpandAllButtonProps, {
@@ -25,7 +25,6 @@ export const MRT_ExpandButton = <TData extends MRT_RowData>({
25
25
  }: MRT_ExpandButtonProps<TData>) => {
26
26
  const theme = useTheme();
27
27
  const {
28
- getState,
29
28
  options: {
30
29
  icons: { ExpandMoreIcon },
31
30
  localization,
@@ -34,7 +33,7 @@ export const MRT_ExpandButton = <TData extends MRT_RowData>({
34
33
  renderDetailPanel,
35
34
  },
36
35
  } = table;
37
- const { density } = getState();
36
+ const { density } = table.state;
38
37
 
39
38
  const iconButtonProps = parseFromValuesOrFunc(muiExpandButtonProps, {
40
39
  row,
@@ -0,0 +1,38 @@
1
+ import { render } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test } from 'vitest';
4
+
5
+ import { type MRT_ColumnDef } from '../../types';
6
+ import { MaterialReactTable } from '../MaterialReactTable';
7
+
8
+ interface Person {
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ ];
17
+
18
+ const bodyCellPadding = (container: HTMLElement) =>
19
+ getComputedStyle(
20
+ container.querySelector('tbody td') as HTMLElement,
21
+ ).getPropertyValue('padding');
22
+
23
+ describe('density toggle', () => {
24
+ test('changes body cell padding when clicked', async () => {
25
+ const user = userEvent.setup();
26
+ const { container } = render(
27
+ <MaterialReactTable columns={columns()} data={data} />,
28
+ );
29
+
30
+ const before = bodyCellPadding(container);
31
+
32
+ await user.click(
33
+ container.querySelector('[aria-label="Toggle density"]') as HTMLElement,
34
+ );
35
+
36
+ expect(bodyCellPadding(container)).not.toBe(before);
37
+ });
38
+ });
@@ -13,14 +13,13 @@ export const MRT_ToggleDensePaddingButton = <TData extends MRT_RowData>({
13
13
  ...rest
14
14
  }: MRT_ToggleDensePaddingButtonProps<TData>) => {
15
15
  const {
16
- getState,
17
16
  options: {
18
17
  icons: { DensityLargeIcon, DensityMediumIcon, DensitySmallIcon },
19
18
  localization,
20
19
  },
21
20
  setDensity,
22
21
  } = table;
23
- const { density } = getState();
22
+ const { density } = table.state;
24
23
 
25
24
  const handleToggleDensePadding = () => {
26
25
  const nextDensity =
@@ -0,0 +1,38 @@
1
+ import { render } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test } from 'vitest';
4
+
5
+ import { type MRT_ColumnDef } from '../../types';
6
+ import { MaterialReactTable } from '../MaterialReactTable';
7
+
8
+ interface Person {
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ ];
17
+
18
+ const filterInputCount = (container: HTMLElement) =>
19
+ container.querySelectorAll('thead input').length;
20
+
21
+ describe('filters toggle', () => {
22
+ test('reveals the column filter inputs when clicked', async () => {
23
+ const user = userEvent.setup();
24
+ const { container } = render(
25
+ <MaterialReactTable columns={columns()} data={data} />,
26
+ );
27
+
28
+ expect(filterInputCount(container)).toBe(0);
29
+
30
+ await user.click(
31
+ container.querySelector(
32
+ '[aria-label="Show/Hide filters"]',
33
+ ) as HTMLElement,
34
+ );
35
+
36
+ expect(filterInputCount(container)).toBeGreaterThan(0);
37
+ });
38
+ });
@@ -13,14 +13,13 @@ export const MRT_ToggleFiltersButton = <TData extends MRT_RowData>({
13
13
  ...rest
14
14
  }: MRT_ToggleFiltersButtonProps<TData>) => {
15
15
  const {
16
- getState,
17
16
  options: {
18
17
  icons: { FilterListIcon, FilterListOffIcon },
19
18
  localization,
20
19
  },
21
20
  setShowColumnFilters,
22
21
  } = table;
23
- const { showColumnFilters } = getState();
22
+ const { showColumnFilters } = table.state;
24
23
 
25
24
  const handleToggleShowFilters = () => {
26
25
  setShowColumnFilters(!showColumnFilters);
@@ -0,0 +1,36 @@
1
+ import { render } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { describe, expect, test } from 'vitest';
4
+
5
+ import { type MRT_ColumnDef } from '../../types';
6
+ import { MaterialReactTable } from '../MaterialReactTable';
7
+
8
+ interface Person {
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ ];
17
+
18
+ describe('full screen toggle', () => {
19
+ test('fixes the table paper to the viewport when clicked', async () => {
20
+ const user = userEvent.setup();
21
+ const { container } = render(
22
+ <MaterialReactTable columns={columns()} data={data} />,
23
+ );
24
+
25
+ const paper = container.firstElementChild as HTMLElement;
26
+ expect(getComputedStyle(paper).position).not.toBe('fixed');
27
+
28
+ await user.click(
29
+ container.querySelector(
30
+ '[aria-label="Toggle full screen"]',
31
+ ) as HTMLElement,
32
+ );
33
+
34
+ expect(getComputedStyle(paper).position).toBe('fixed');
35
+ });
36
+ });
@@ -14,14 +14,13 @@ export const MRT_ToggleFullScreenButton = <TData extends MRT_RowData>({
14
14
  ...rest
15
15
  }: MRT_ToggleFullScreenButtonProps<TData>) => {
16
16
  const {
17
- getState,
18
17
  options: {
19
18
  icons: { FullscreenExitIcon, FullscreenIcon },
20
19
  localization,
21
20
  },
22
21
  setIsFullScreen,
23
22
  } = table;
24
- const { isFullScreen } = getState();
23
+ const { isFullScreen } = table.state;
25
24
 
26
25
  const [tooltipOpened, setTooltipOpened] = useState(false);
27
26
 
@@ -13,7 +13,6 @@ export const MRT_ToggleGlobalFilterButton = <TData extends MRT_RowData>({
13
13
  ...rest
14
14
  }: MRT_ToggleGlobalFilterButtonProps<TData>) => {
15
15
  const {
16
- getState,
17
16
  options: {
18
17
  icons: { SearchIcon, SearchOffIcon },
19
18
 
@@ -22,7 +21,7 @@ export const MRT_ToggleGlobalFilterButton = <TData extends MRT_RowData>({
22
21
  refs: { searchInputRef },
23
22
  setShowGlobalFilter,
24
23
  } = table;
25
- const { globalFilter, showGlobalFilter } = getState();
24
+ const { globalFilter, showGlobalFilter } = table.state;
26
25
 
27
26
  const handleToggleSearch = () => {
28
27
  setShowGlobalFilter(!showGlobalFilter);
@@ -40,7 +40,6 @@ export const MRT_ToggleRowActionMenuButton = <TData extends MRT_RowData>({
40
40
  ...rest
41
41
  }: MRT_ToggleRowActionMenuButtonProps<TData>) => {
42
42
  const {
43
- getState,
44
43
  options: {
45
44
  createDisplayMode,
46
45
  editDisplayMode,
@@ -53,7 +52,7 @@ export const MRT_ToggleRowActionMenuButton = <TData extends MRT_RowData>({
53
52
  setEditingRow,
54
53
  } = table;
55
54
 
56
- const { creatingRow, editingRow } = getState();
55
+ const { creatingRow, editingRow } = table.state;
57
56
 
58
57
  const isCreating = creatingRow?.id === row.id;
59
58
  const isEditing = editingRow?.id === row.id;
@@ -72,7 +71,7 @@ export const MRT_ToggleRowActionMenuButton = <TData extends MRT_RowData>({
72
71
 
73
72
  const handleStartEditMode = (event: MouseEvent) => {
74
73
  event.stopPropagation();
75
- setEditingRow({ ...row });
74
+ setEditingRow(row);
76
75
  setAnchorEl(null);
77
76
  };
78
77
 
@@ -20,11 +20,10 @@ export const MRT_TableFooter = <TData extends MRT_RowData>({
20
20
  ...rest
21
21
  }: MRT_TableFooterProps<TData>) => {
22
22
  const {
23
- getState,
24
23
  options: { enableStickyFooter, layoutMode, muiTableFooterProps },
25
24
  refs: { tableFooterRef },
26
25
  } = table;
27
- const { isFullScreen } = getState();
26
+ const { isFullScreen } = table.state;
28
27
 
29
28
  const tableFooterProps = {
30
29
  ...parseFromValuesOrFunc(muiTableFooterProps, {
@@ -25,14 +25,13 @@ export const MRT_TableFooterCell = <TData extends MRT_RowData>({
25
25
  }: MRT_TableFooterCellProps<TData>) => {
26
26
  const theme = useTheme();
27
27
  const {
28
- getState,
29
28
  options: {
30
29
  enableColumnPinning,
31
30
  enableKeyboardShortcuts,
32
31
  muiTableFooterCellProps,
33
32
  },
34
33
  } = table;
35
- const { density } = getState();
34
+ const { density } = table.state;
36
35
  const { column } = footer;
37
36
  const { columnDef } = column;
38
37
  const { columnDefType } = columnDef;
@@ -21,7 +21,6 @@ export const MRT_TableHead = <TData extends MRT_RowData>({
21
21
  ...rest
22
22
  }: MRT_TableHeadProps<TData>) => {
23
23
  const {
24
- getState,
25
24
  options: {
26
25
  enableStickyHeader,
27
26
  layoutMode,
@@ -30,7 +29,7 @@ export const MRT_TableHead = <TData extends MRT_RowData>({
30
29
  },
31
30
  refs: { tableHeadRef },
32
31
  } = table;
33
- const { isFullScreen, showAlertBanner } = getState();
32
+ const { isFullScreen, showAlertBanner } = table.state;
34
33
 
35
34
  const tableHeadProps = {
36
35
  ...parseFromValuesOrFunc(muiTableHeadProps, { table }),
@@ -2,7 +2,7 @@ import { Box } from '@mui/material';
2
2
  import { TableCell, type TableCellProps } from '@mui/material';
3
3
  import { useTheme } from '@mui/material/styles';
4
4
  import { type Theme } from '@mui/material/styles';
5
- import { type DragEvent, useCallback, useMemo } from 'react';
5
+ import { type DragEvent, useCallback, useMemo, useRef } from 'react';
6
6
 
7
7
  import {
8
8
  type MRT_ColumnVirtualizer,
@@ -37,7 +37,6 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
37
37
  }: MRT_TableHeadCellProps<TData>) => {
38
38
  const theme = useTheme();
39
39
  const {
40
- getState,
41
40
  options: {
42
41
  columnFilterDisplayMode,
43
42
  columnResizeDirection,
@@ -57,13 +56,13 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
57
56
  setHoveredColumn,
58
57
  } = table;
59
58
  const {
60
- columnSizingInfo,
59
+ columnResizing,
61
60
  density,
62
61
  draggingColumn,
63
62
  grouping,
64
63
  hoveredColumn,
65
64
  showColumnFilters,
66
- } = getState();
65
+ } = table.state;
67
66
  const { column } = header;
68
67
  const { columnDef } = column;
69
68
  const { columnDefType } = columnDef;
@@ -105,7 +104,7 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
105
104
 
106
105
  const draggingBorders = useMemo(() => {
107
106
  const showResizeBorder =
108
- columnSizingInfo.isResizingColumn === column.id &&
107
+ columnResizing.isResizingColumn === column.id &&
109
108
  columnResizeMode === 'onChange' &&
110
109
  !header.subHeaders.length;
111
110
 
@@ -131,7 +130,7 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
131
130
  : undefined;
132
131
 
133
132
  return draggingBorders;
134
- }, [draggingColumn, hoveredColumn, columnSizingInfo.isResizingColumn]);
133
+ }, [draggingColumn, hoveredColumn, columnResizing.isResizingColumn]);
135
134
 
136
135
  const handleDragEnter = (_e: DragEvent) => {
137
136
  if (enableGrouping && hoveredColumn?.id === 'drop-zone') {
@@ -160,8 +159,11 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
160
159
  });
161
160
  };
162
161
 
162
+ const tableHeadCellRef = useRef<HTMLTableCellElement | null>(null);
163
+
163
164
  const handleRef = useCallback(
164
165
  (node: HTMLTableCellElement) => {
166
+ tableHeadCellRef.current = node;
165
167
  if (node) {
166
168
  if (tableHeadCellRefs.current) {
167
169
  tableHeadCellRefs.current[column.id] = node;
@@ -326,9 +328,7 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
326
328
  <MRT_TableHeadCellGrabHandle
327
329
  column={column}
328
330
  table={table}
329
- tableHeadCellRef={{
330
- current: tableHeadCellRefs.current?.[column.id]!,
331
- }}
331
+ tableHeadCellRef={tableHeadCellRef}
332
332
  />
333
333
  )}
334
334
  {showColumnActions && (
@@ -24,10 +24,9 @@ export const MRT_TableHeadCellFilterContainer = <TData extends MRT_RowData>({
24
24
  ...rest
25
25
  }: MRT_TableHeadCellFilterContainerProps<TData>) => {
26
26
  const {
27
- getState,
28
27
  options: { columnFilterDisplayMode },
29
28
  } = table;
30
- const { showColumnFilters } = getState();
29
+ const { showColumnFilters } = table.state;
31
30
  const { column } = header;
32
31
  const { columnDef } = column;
33
32
  const { isRangeFilter } = getColumnFilterInfo({ header, table });
@@ -0,0 +1,61 @@
1
+ import { fireEvent, render } from '@testing-library/react';
2
+ import { describe, expect, test } from 'vitest';
3
+
4
+ import { type MRT_ColumnDef } from '../../types';
5
+ import { MaterialReactTable } from '../MaterialReactTable';
6
+
7
+ interface Person {
8
+ city: string;
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ city: 'Glasgow', name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ { accessorKey: 'city', header: 'City' },
17
+ ];
18
+
19
+ const headerOrder = (container: HTMLElement) =>
20
+ Array.from(container.querySelectorAll('thead th')).map((th) =>
21
+ th.textContent?.replace(/[^A-Za-z]/g, ''),
22
+ );
23
+
24
+ const dragColumnOnto = (container: HTMLElement, from: string, to: string) => {
25
+ const handles = Array.from(
26
+ container.querySelectorAll<HTMLElement>('thead [aria-label="Move"]'),
27
+ );
28
+ const headerCells = Array.from(
29
+ container.querySelectorAll<HTMLElement>('thead th'),
30
+ );
31
+ const fromIndex = headerCells.findIndex((th) =>
32
+ th.textContent?.includes(from),
33
+ );
34
+ const toIndex = headerCells.findIndex((th) => th.textContent?.includes(to));
35
+
36
+ fireEvent.dragStart(handles[fromIndex], {
37
+ dataTransfer: { setDragImage: () => {} },
38
+ });
39
+ fireEvent.dragEnter(headerCells[toIndex]);
40
+ fireEvent.dragOver(headerCells[toIndex]);
41
+ fireEvent.drop(headerCells[toIndex]);
42
+ fireEvent.dragEnd(handles[fromIndex]);
43
+ };
44
+
45
+ describe('column dragging', () => {
46
+ test('reorders columns when one is dragged onto another', () => {
47
+ const { container } = render(
48
+ <MaterialReactTable
49
+ columns={columns()}
50
+ data={data}
51
+ enableColumnOrdering
52
+ />,
53
+ );
54
+
55
+ expect(headerOrder(container)).toEqual(['Name', 'City']);
56
+
57
+ dragColumnOnto(container, 'Name', 'City');
58
+
59
+ expect(headerOrder(container)).toEqual(['City', 'Name']);
60
+ });
61
+ });
@@ -24,7 +24,6 @@ export const MRT_TableHeadCellGrabHandle = <TData extends MRT_RowData>({
24
24
  ...rest
25
25
  }: MRT_TableHeadCellGrabHandleProps<TData>) => {
26
26
  const {
27
- getState,
28
27
  options: { enableColumnOrdering, muiColumnDragHandleProps },
29
28
  setColumnOrder,
30
29
  setColumnPinning,
@@ -32,7 +31,7 @@ export const MRT_TableHeadCellGrabHandle = <TData extends MRT_RowData>({
32
31
  setHoveredColumn,
33
32
  } = table;
34
33
  const { columnDef } = column;
35
- const { columnOrder, draggingColumn, hoveredColumn } = getState();
34
+ const { columnOrder, draggingColumn, hoveredColumn } = table.state;
36
35
 
37
36
  const iconButtonProps = {
38
37
  ...parseFromValuesOrFunc(muiColumnDragHandleProps, { column, table }),
@@ -72,9 +71,9 @@ export const MRT_TableHeadCellGrabHandle = <TData extends MRT_RowData>({
72
71
  columnOrder,
73
72
  );
74
73
  setColumnOrder(reorderedColumns);
75
- setColumnPinning(({ left = [], right = [] }) => ({
76
- left: reorderedColumns.filter((header) => left.includes(header)),
77
- right: reorderedColumns.filter((header) => right.includes(header)),
74
+ setColumnPinning(({ end = [], start = [] }) => ({
75
+ end: reorderedColumns.filter((header) => end.includes(header)),
76
+ start: reorderedColumns.filter((header) => start.includes(header)),
78
77
  }));
79
78
  }
80
79
  setDraggingColumn(null);
@@ -0,0 +1,45 @@
1
+ import { fireEvent, render } from '@testing-library/react';
2
+ import { describe, expect, test } from 'vitest';
3
+
4
+ import { type MRT_ColumnDef } from '../../types';
5
+ import { MaterialReactTable } from '../MaterialReactTable';
6
+
7
+ interface Person {
8
+ city: string;
9
+ name: string;
10
+ }
11
+
12
+ const data: Person[] = [{ city: 'Glasgow', name: 'Alice' }];
13
+
14
+ const columns = (): MRT_ColumnDef<Person>[] => [
15
+ { accessorKey: 'name', header: 'Name' },
16
+ { accessorKey: 'city', header: 'City' },
17
+ ];
18
+
19
+ const nameColumnSize = (container: HTMLElement) =>
20
+ (container.querySelector('table') as HTMLElement).style.getPropertyValue(
21
+ '--header-name-size',
22
+ );
23
+
24
+ describe('column resizing', () => {
25
+ test('dragging the resize handle widens the column', () => {
26
+ const { container } = render(
27
+ <MaterialReactTable
28
+ columns={columns()}
29
+ data={data}
30
+ enableColumnResizing
31
+ />,
32
+ );
33
+
34
+ const before = nameColumnSize(container);
35
+ const handle = container.querySelector(
36
+ 'thead .Mui-TableHeadCell-ResizeHandle-Wrapper',
37
+ ) as HTMLElement;
38
+
39
+ fireEvent.mouseDown(handle, { clientX: 0 });
40
+ fireEvent.mouseMove(document, { clientX: 120 });
41
+ fireEvent.mouseUp(document, { clientX: 120 });
42
+
43
+ expect(nameColumnSize(container)).not.toBe(before);
44
+ });
45
+ });
@@ -20,11 +20,10 @@ export const MRT_TableHeadCellResizeHandle = <TData extends MRT_RowData>({
20
20
  ...rest
21
21
  }: MRT_TableHeadCellResizeHandleProps<TData>) => {
22
22
  const {
23
- getState,
24
23
  options: { columnResizeDirection, columnResizeMode },
25
- setColumnSizingInfo,
24
+ setColumnResizing,
26
25
  } = table;
27
- const { density } = getState();
26
+ const { density } = table.state;
28
27
  const { column } = header;
29
28
 
30
29
  const handler = header.getResizeHandler();
@@ -42,7 +41,7 @@ export const MRT_TableHeadCellResizeHandle = <TData extends MRT_RowData>({
42
41
  <Box
43
42
  className="Mui-TableHeadCell-ResizeHandle-Wrapper"
44
43
  onDoubleClick={() => {
45
- setColumnSizingInfo((old) => ({
44
+ setColumnResizing((old) => ({
46
45
  ...old,
47
46
  isResizingColumn: false,
48
47
  }));
@@ -55,7 +54,7 @@ export const MRT_TableHeadCellResizeHandle = <TData extends MRT_RowData>({
55
54
  column.getIsResizing() && columnResizeMode === 'onEnd'
56
55
  ? `translateX(${
57
56
  (columnResizeDirection === 'rtl' ? -1 : 1) *
58
- (getState().columnSizingInfo.deltaOffset ?? 0)
57
+ (table.state.columnResizing.deltaOffset ?? 0)
59
58
  }px)`
60
59
  : undefined,
61
60
  }}
@@ -21,7 +21,6 @@ export const MRT_TableHeadCellSortLabel = <TData extends MRT_RowData>({
21
21
  ...rest
22
22
  }: MRT_TableHeadCellSortLabelProps<TData>) => {
23
23
  const {
24
- getState,
25
24
  options: {
26
25
  icons: { ArrowDownwardIcon, SyncAltIcon },
27
26
  localization,
@@ -29,7 +28,7 @@ export const MRT_TableHeadCellSortLabel = <TData extends MRT_RowData>({
29
28
  } = table;
30
29
  const { column } = header;
31
30
  const { columnDef } = column;
32
- const { isLoading, showSkeletons, sorting } = getState();
31
+ const { isLoading, showSkeletons, sorting } = table.state;
33
32
 
34
33
  const isSorted = !!column.getIsSorted();
35
34