@lminii/material-react-table 4.0.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 (349) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +234 -0
  3. package/dist/index.d.mts +2408 -0
  4. package/dist/index.d.ts +2408 -0
  5. package/dist/index.js +4825 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +4631 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/locales/ar/index.d.mts +3 -0
  10. package/locales/ar/index.d.ts +3 -0
  11. package/locales/ar/index.js +100 -0
  12. package/locales/ar/index.mjs +96 -0
  13. package/locales/ar/package.json +6 -0
  14. package/locales/az/index.d.mts +3 -0
  15. package/locales/az/index.d.ts +3 -0
  16. package/locales/az/index.js +100 -0
  17. package/locales/az/index.mjs +96 -0
  18. package/locales/az/package.json +6 -0
  19. package/locales/bg/index.d.mts +3 -0
  20. package/locales/bg/index.d.ts +3 -0
  21. package/locales/bg/index.js +100 -0
  22. package/locales/bg/index.mjs +96 -0
  23. package/locales/bg/package.json +6 -0
  24. package/locales/cs/index.d.mts +3 -0
  25. package/locales/cs/index.d.ts +3 -0
  26. package/locales/cs/index.js +100 -0
  27. package/locales/cs/index.mjs +96 -0
  28. package/locales/cs/package.json +6 -0
  29. package/locales/da/index.d.mts +3 -0
  30. package/locales/da/index.d.ts +3 -0
  31. package/locales/da/index.js +100 -0
  32. package/locales/da/index.mjs +96 -0
  33. package/locales/da/package.json +6 -0
  34. package/locales/de/index.d.mts +3 -0
  35. package/locales/de/index.d.ts +3 -0
  36. package/locales/de/index.js +100 -0
  37. package/locales/de/index.mjs +96 -0
  38. package/locales/de/package.json +6 -0
  39. package/locales/el/index.d.mts +3 -0
  40. package/locales/el/index.d.ts +3 -0
  41. package/locales/el/index.js +100 -0
  42. package/locales/el/index.mjs +96 -0
  43. package/locales/el/package.json +6 -0
  44. package/locales/en/index.d.mts +3 -0
  45. package/locales/en/index.d.ts +3 -0
  46. package/locales/en/index.js +100 -0
  47. package/locales/en/index.mjs +96 -0
  48. package/locales/en/package.json +6 -0
  49. package/locales/es/index.d.mts +3 -0
  50. package/locales/es/index.d.ts +3 -0
  51. package/locales/es/index.js +100 -0
  52. package/locales/es/index.mjs +96 -0
  53. package/locales/es/package.json +6 -0
  54. package/locales/et/index.d.mts +3 -0
  55. package/locales/et/index.d.ts +3 -0
  56. package/locales/et/index.js +100 -0
  57. package/locales/et/index.mjs +96 -0
  58. package/locales/et/package.json +6 -0
  59. package/locales/fa/index.d.mts +3 -0
  60. package/locales/fa/index.d.ts +3 -0
  61. package/locales/fa/index.js +100 -0
  62. package/locales/fa/index.mjs +96 -0
  63. package/locales/fa/package.json +6 -0
  64. package/locales/fi/index.d.mts +3 -0
  65. package/locales/fi/index.d.ts +3 -0
  66. package/locales/fi/index.js +100 -0
  67. package/locales/fi/index.mjs +96 -0
  68. package/locales/fi/package.json +6 -0
  69. package/locales/fr/index.d.mts +3 -0
  70. package/locales/fr/index.d.ts +3 -0
  71. package/locales/fr/index.js +100 -0
  72. package/locales/fr/index.mjs +96 -0
  73. package/locales/fr/package.json +6 -0
  74. package/locales/he/index.d.mts +3 -0
  75. package/locales/he/index.d.ts +3 -0
  76. package/locales/he/index.js +100 -0
  77. package/locales/he/index.mjs +96 -0
  78. package/locales/he/package.json +6 -0
  79. package/locales/hr/index.d.mts +3 -0
  80. package/locales/hr/index.d.ts +3 -0
  81. package/locales/hr/index.js +100 -0
  82. package/locales/hr/index.mjs +96 -0
  83. package/locales/hr/package.json +6 -0
  84. package/locales/hu/index.d.mts +3 -0
  85. package/locales/hu/index.d.ts +3 -0
  86. package/locales/hu/index.js +100 -0
  87. package/locales/hu/index.mjs +96 -0
  88. package/locales/hu/package.json +6 -0
  89. package/locales/hy/index.d.mts +3 -0
  90. package/locales/hy/index.d.ts +3 -0
  91. package/locales/hy/index.js +100 -0
  92. package/locales/hy/index.mjs +96 -0
  93. package/locales/hy/package.json +6 -0
  94. package/locales/id/index.d.mts +3 -0
  95. package/locales/id/index.d.ts +3 -0
  96. package/locales/id/index.js +100 -0
  97. package/locales/id/index.mjs +96 -0
  98. package/locales/id/package.json +6 -0
  99. package/locales/it/index.d.mts +3 -0
  100. package/locales/it/index.d.ts +3 -0
  101. package/locales/it/index.js +100 -0
  102. package/locales/it/index.mjs +96 -0
  103. package/locales/it/package.json +6 -0
  104. package/locales/ja/index.d.mts +3 -0
  105. package/locales/ja/index.d.ts +3 -0
  106. package/locales/ja/index.js +100 -0
  107. package/locales/ja/index.mjs +96 -0
  108. package/locales/ja/package.json +6 -0
  109. package/locales/ko/index.d.mts +3 -0
  110. package/locales/ko/index.d.ts +3 -0
  111. package/locales/ko/index.js +100 -0
  112. package/locales/ko/index.mjs +96 -0
  113. package/locales/ko/package.json +6 -0
  114. package/locales/nl/index.d.mts +3 -0
  115. package/locales/nl/index.d.ts +3 -0
  116. package/locales/nl/index.js +100 -0
  117. package/locales/nl/index.mjs +96 -0
  118. package/locales/nl/package.json +6 -0
  119. package/locales/no/index.d.mts +3 -0
  120. package/locales/no/index.d.ts +3 -0
  121. package/locales/no/index.js +100 -0
  122. package/locales/no/index.mjs +96 -0
  123. package/locales/no/package.json +6 -0
  124. package/locales/np/index.d.mts +3 -0
  125. package/locales/np/index.d.ts +3 -0
  126. package/locales/np/index.js +100 -0
  127. package/locales/np/index.mjs +96 -0
  128. package/locales/np/package.json +6 -0
  129. package/locales/pl/index.d.mts +3 -0
  130. package/locales/pl/index.d.ts +3 -0
  131. package/locales/pl/index.js +100 -0
  132. package/locales/pl/index.mjs +96 -0
  133. package/locales/pl/package.json +6 -0
  134. package/locales/pt/index.d.mts +3 -0
  135. package/locales/pt/index.d.ts +3 -0
  136. package/locales/pt/index.js +100 -0
  137. package/locales/pt/index.mjs +96 -0
  138. package/locales/pt/package.json +6 -0
  139. package/locales/pt-BR/index.d.mts +3 -0
  140. package/locales/pt-BR/index.d.ts +3 -0
  141. package/locales/pt-BR/index.js +100 -0
  142. package/locales/pt-BR/index.mjs +96 -0
  143. package/locales/pt-BR/package.json +6 -0
  144. package/locales/ro/index.d.mts +3 -0
  145. package/locales/ro/index.d.ts +3 -0
  146. package/locales/ro/index.js +100 -0
  147. package/locales/ro/index.mjs +96 -0
  148. package/locales/ro/package.json +6 -0
  149. package/locales/ru/index.d.mts +3 -0
  150. package/locales/ru/index.d.ts +3 -0
  151. package/locales/ru/index.js +100 -0
  152. package/locales/ru/index.mjs +96 -0
  153. package/locales/ru/package.json +6 -0
  154. package/locales/sk/index.d.mts +3 -0
  155. package/locales/sk/index.d.ts +3 -0
  156. package/locales/sk/index.js +100 -0
  157. package/locales/sk/index.mjs +96 -0
  158. package/locales/sk/package.json +6 -0
  159. package/locales/sr-Cyrl-RS/index.d.mts +3 -0
  160. package/locales/sr-Cyrl-RS/index.d.ts +3 -0
  161. package/locales/sr-Cyrl-RS/index.js +100 -0
  162. package/locales/sr-Cyrl-RS/index.mjs +96 -0
  163. package/locales/sr-Cyrl-RS/package.json +6 -0
  164. package/locales/sr-Latn-RS/index.d.mts +3 -0
  165. package/locales/sr-Latn-RS/index.d.ts +3 -0
  166. package/locales/sr-Latn-RS/index.js +100 -0
  167. package/locales/sr-Latn-RS/index.mjs +96 -0
  168. package/locales/sr-Latn-RS/package.json +6 -0
  169. package/locales/sv/index.d.mts +3 -0
  170. package/locales/sv/index.d.ts +3 -0
  171. package/locales/sv/index.js +100 -0
  172. package/locales/sv/index.mjs +96 -0
  173. package/locales/sv/package.json +6 -0
  174. package/locales/tr/index.d.mts +3 -0
  175. package/locales/tr/index.d.ts +3 -0
  176. package/locales/tr/index.js +100 -0
  177. package/locales/tr/index.mjs +96 -0
  178. package/locales/tr/package.json +6 -0
  179. package/locales/uk/index.d.mts +3 -0
  180. package/locales/uk/index.d.ts +3 -0
  181. package/locales/uk/index.js +100 -0
  182. package/locales/uk/index.mjs +96 -0
  183. package/locales/uk/package.json +6 -0
  184. package/locales/vi/index.d.mts +3 -0
  185. package/locales/vi/index.d.ts +3 -0
  186. package/locales/vi/index.js +100 -0
  187. package/locales/vi/index.mjs +96 -0
  188. package/locales/vi/package.json +6 -0
  189. package/locales/zh-Hans/index.d.mts +3 -0
  190. package/locales/zh-Hans/index.d.ts +3 -0
  191. package/locales/zh-Hans/index.js +100 -0
  192. package/locales/zh-Hans/index.mjs +96 -0
  193. package/locales/zh-Hans/package.json +6 -0
  194. package/locales/zh-Hant/index.d.mts +3 -0
  195. package/locales/zh-Hant/index.d.ts +3 -0
  196. package/locales/zh-Hant/index.js +100 -0
  197. package/locales/zh-Hant/index.mjs +96 -0
  198. package/locales/zh-Hant/package.json +6 -0
  199. package/package.json +147 -0
  200. package/skills/README.md +81 -0
  201. package/skills/composable-components/SKILL.md +189 -0
  202. package/skills/customization/SKILL.md +190 -0
  203. package/skills/drag-and-drop-ordering/SKILL.md +227 -0
  204. package/skills/editing/SKILL.md +243 -0
  205. package/skills/filtering/SKILL.md +213 -0
  206. package/skills/getting-started/SKILL.md +213 -0
  207. package/skills/localization/SKILL.md +182 -0
  208. package/skills/migrate-v3-to-v4/SKILL.md +161 -0
  209. package/skills/state-and-server-data/SKILL.md +200 -0
  210. package/skills/virtualization/SKILL.md +203 -0
  211. package/src/components/MaterialReactTable.tsx +36 -0
  212. package/src/components/body/MRT_TableBody.tsx +221 -0
  213. package/src/components/body/MRT_TableBodyCell.tsx +351 -0
  214. package/src/components/body/MRT_TableBodyCellValue.tsx +130 -0
  215. package/src/components/body/MRT_TableBodyRow.tsx +288 -0
  216. package/src/components/body/MRT_TableBodyRowGrabHandle.tsx +61 -0
  217. package/src/components/body/MRT_TableBodyRowPinButton.tsx +58 -0
  218. package/src/components/body/MRT_TableDetailPanel.tsx +110 -0
  219. package/src/components/buttons/MRT_ColumnPinningButtons.tsx +72 -0
  220. package/src/components/buttons/MRT_CopyButton.tsx +87 -0
  221. package/src/components/buttons/MRT_EditActionButtons.tsx +134 -0
  222. package/src/components/buttons/MRT_ExpandAllButton.tsx +78 -0
  223. package/src/components/buttons/MRT_ExpandButton.tsx +102 -0
  224. package/src/components/buttons/MRT_GrabHandleButton.tsx +65 -0
  225. package/src/components/buttons/MRT_RowPinButton.tsx +84 -0
  226. package/src/components/buttons/MRT_ShowHideColumnsButton.tsx +50 -0
  227. package/src/components/buttons/MRT_ToggleDensePaddingButton.tsx +52 -0
  228. package/src/components/buttons/MRT_ToggleFiltersButton.tsx +40 -0
  229. package/src/components/buttons/MRT_ToggleFullScreenButton.tsx +51 -0
  230. package/src/components/buttons/MRT_ToggleGlobalFilterButton.tsx +46 -0
  231. package/src/components/buttons/MRT_ToggleRowActionMenuButton.tsx +126 -0
  232. package/src/components/footer/MRT_TableFooter.tsx +88 -0
  233. package/src/components/footer/MRT_TableFooterCell.tsx +107 -0
  234. package/src/components/footer/MRT_TableFooterRow.tsx +95 -0
  235. package/src/components/head/MRT_TableHead.tsx +91 -0
  236. package/src/components/head/MRT_TableHeadCell.tsx +351 -0
  237. package/src/components/head/MRT_TableHeadCellColumnActionsButton.tsx +96 -0
  238. package/src/components/head/MRT_TableHeadCellFilterContainer.tsx +52 -0
  239. package/src/components/head/MRT_TableHeadCellFilterLabel.tsx +178 -0
  240. package/src/components/head/MRT_TableHeadCellGrabHandle.tsx +91 -0
  241. package/src/components/head/MRT_TableHeadCellResizeHandle.tsx +96 -0
  242. package/src/components/head/MRT_TableHeadCellSortLabel.tsx +101 -0
  243. package/src/components/head/MRT_TableHeadRow.tsx +90 -0
  244. package/src/components/inputs/MRT_EditCellTextField.tsx +202 -0
  245. package/src/components/inputs/MRT_FilterCheckbox.tsx +90 -0
  246. package/src/components/inputs/MRT_FilterRangeFields.tsx +41 -0
  247. package/src/components/inputs/MRT_FilterRangeSlider.tsx +143 -0
  248. package/src/components/inputs/MRT_FilterTextField.tsx +592 -0
  249. package/src/components/inputs/MRT_GlobalFilterTextField.tsx +167 -0
  250. package/src/components/inputs/MRT_SelectCheckbox.tsx +135 -0
  251. package/src/components/menus/MRT_ActionMenuItem.tsx +62 -0
  252. package/src/components/menus/MRT_CellActionMenu.tsx +107 -0
  253. package/src/components/menus/MRT_ColumnActionMenu.tsx +352 -0
  254. package/src/components/menus/MRT_FilterOptionMenu.tsx +292 -0
  255. package/src/components/menus/MRT_RowActionMenu.tsx +88 -0
  256. package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +181 -0
  257. package/src/components/menus/MRT_ShowHideColumnsMenuItems.tsx +203 -0
  258. package/src/components/modals/MRT_EditRowModal.tsx +114 -0
  259. package/src/components/table/MRT_Table.tsx +84 -0
  260. package/src/components/table/MRT_TableContainer.tsx +111 -0
  261. package/src/components/table/MRT_TableLoadingOverlay.tsx +58 -0
  262. package/src/components/table/MRT_TablePaper.tsx +89 -0
  263. package/src/components/toolbar/MRT_BottomToolbar.tsx +111 -0
  264. package/src/components/toolbar/MRT_LinearProgressBar.tsx +53 -0
  265. package/src/components/toolbar/MRT_TablePagination.tsx +241 -0
  266. package/src/components/toolbar/MRT_ToolbarAlertBanner.tsx +184 -0
  267. package/src/components/toolbar/MRT_ToolbarDropZone.tsx +83 -0
  268. package/src/components/toolbar/MRT_ToolbarInternalButtons.tsx +72 -0
  269. package/src/components/toolbar/MRT_TopToolbar.tsx +130 -0
  270. package/src/features/mrtCellActionsFeature.ts +67 -0
  271. package/src/features/mrtColumnDraggingFeature.ts +83 -0
  272. package/src/features/mrtDensityFeature.ts +64 -0
  273. package/src/features/mrtEditingFeature.ts +102 -0
  274. package/src/features/mrtFeatures.ts +103 -0
  275. package/src/features/mrtFilterModesFeature.ts +99 -0
  276. package/src/features/mrtFnsFeature.ts +46 -0
  277. package/src/features/mrtFullScreenFeature.ts +63 -0
  278. package/src/features/mrtLoadingFeature.ts +35 -0
  279. package/src/features/mrtRefsFeature.ts +60 -0
  280. package/src/features/mrtRowDraggingFeature.ts +81 -0
  281. package/src/features/mrtStateCompatFeature.ts +43 -0
  282. package/src/features/mrtToolbarsFeature.ts +76 -0
  283. package/src/fns/aggregationFns.ts +3 -0
  284. package/src/fns/filterFns.ts +196 -0
  285. package/src/fns/sortingFns.ts +31 -0
  286. package/src/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +28 -0
  287. package/src/hooks/display-columns/getMRT_RowDragColumnDef.tsx +29 -0
  288. package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +97 -0
  289. package/src/hooks/display-columns/getMRT_RowNumbersColumnDef.tsx +30 -0
  290. package/src/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +24 -0
  291. package/src/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +34 -0
  292. package/src/hooks/display-columns/getMRT_RowSpacerColumnDef.tsx +33 -0
  293. package/src/hooks/useMRT_ColumnVirtualizer.ts +124 -0
  294. package/src/hooks/useMRT_Effects.ts +108 -0
  295. package/src/hooks/useMRT_RowVirtualizer.ts +88 -0
  296. package/src/hooks/useMRT_Rows.ts +44 -0
  297. package/src/hooks/useMRT_TableInstance.ts +181 -0
  298. package/src/hooks/useMRT_TableOptions.ts +241 -0
  299. package/src/hooks/useMaterialReactTable.ts +12 -0
  300. package/src/icons.ts +73 -0
  301. package/src/index.ts +91 -0
  302. package/src/locales/ar.ts +97 -0
  303. package/src/locales/az.ts +97 -0
  304. package/src/locales/bg.ts +97 -0
  305. package/src/locales/cs.ts +98 -0
  306. package/src/locales/da.ts +97 -0
  307. package/src/locales/de.ts +97 -0
  308. package/src/locales/el.ts +97 -0
  309. package/src/locales/en.ts +97 -0
  310. package/src/locales/es.ts +97 -0
  311. package/src/locales/et.ts +98 -0
  312. package/src/locales/fa.ts +97 -0
  313. package/src/locales/fi.ts +98 -0
  314. package/src/locales/fr.ts +97 -0
  315. package/src/locales/he.ts +97 -0
  316. package/src/locales/hr.ts +97 -0
  317. package/src/locales/hu.ts +97 -0
  318. package/src/locales/hy.ts +97 -0
  319. package/src/locales/id.ts +98 -0
  320. package/src/locales/it.ts +97 -0
  321. package/src/locales/ja.ts +97 -0
  322. package/src/locales/ko.ts +97 -0
  323. package/src/locales/mk.ts +96 -0
  324. package/src/locales/nl.ts +97 -0
  325. package/src/locales/no.ts +99 -0
  326. package/src/locales/np.ts +98 -0
  327. package/src/locales/pl.ts +97 -0
  328. package/src/locales/pt-BR.ts +97 -0
  329. package/src/locales/pt.ts +97 -0
  330. package/src/locales/ro.ts +97 -0
  331. package/src/locales/ru.ts +97 -0
  332. package/src/locales/sk.ts +98 -0
  333. package/src/locales/sr-Cyrl-RS.ts +97 -0
  334. package/src/locales/sr-Latn-RS.ts +97 -0
  335. package/src/locales/sv.ts +97 -0
  336. package/src/locales/tr.ts +97 -0
  337. package/src/locales/uk.ts +97 -0
  338. package/src/locales/vi.ts +97 -0
  339. package/src/locales/zh-Hans.ts +96 -0
  340. package/src/locales/zh-Hant.ts +96 -0
  341. package/src/types.ts +1314 -0
  342. package/src/utils/cell.utils.ts +234 -0
  343. package/src/utils/column.utils.ts +204 -0
  344. package/src/utils/displayColumn.utils.ts +152 -0
  345. package/src/utils/row.utils.ts +258 -0
  346. package/src/utils/style.utils.ts +211 -0
  347. package/src/utils/tanstack.helpers.ts +64 -0
  348. package/src/utils/utils.ts +34 -0
  349. package/src/utils/virtualization.utils.ts +24 -0
@@ -0,0 +1,203 @@
1
+ ---
2
+ name: virtualization
3
+ description: >
4
+ Render thousands of rows or hundreds of columns in Material React Table V4 with enableRowVirtualization and enableColumnVirtualization, tune rowVirtualizerOptions and columnVirtualizerOptions (overscan, estimateSize), reach the TanStack Virtual instance through rowVirtualizerInstanceRef for scrollToIndex, and understand the automatic layoutMode grid and sticky header. Load for large unpaginated tables, infinite scroll, scroll-to-row, jumpy scrolling, or headless virtualization with useMRT_RowVirtualizer.
5
+ metadata:
6
+ type: framework
7
+ library: '@lminii/material-react-table'
8
+ library_version: '4.0.0'
9
+ framework: react
10
+ requires:
11
+ - getting-started
12
+ sources:
13
+ - 'lminii/material-react-table:apps/material-react-table-docs/pages/docs/guides/virtualization.mdx'
14
+ - 'lminii/material-react-table:apps/material-react-table-docs/examples/enable-row-virtualization/sandbox/src/TS.tsx'
15
+ - 'lminii/material-react-table:packages/material-react-table/src/hooks/useMRT_RowVirtualizer.ts'
16
+ - 'lminii/material-react-table:packages/material-react-table/src/hooks/useMRT_TableOptions.ts'
17
+ - 'lminii/material-react-table:packages/material-react-table/src/types.ts'
18
+ ---
19
+
20
+ This skill builds on `getting-started`. MRT wraps `@tanstack/react-virtual` so only the rows and columns inside the scroll container render. Enable it when a table shows more than about 50 rows without pagination or more than about a dozen columns; below that it adds overhead without benefit.
21
+
22
+ ## Setup
23
+
24
+ ```tsx
25
+ const table = useMaterialReactTable({
26
+ columns,
27
+ data, // 10,000 rows
28
+ enablePagination: false,
29
+ enableRowVirtualization: true,
30
+ enableColumnVirtualization: true, // only with many columns
31
+ muiTableContainerProps: { sx: { maxHeight: '600px' } },
32
+ rowVirtualizerOptions: { overscan: 5 },
33
+ columnVirtualizerOptions: { overscan: 2 },
34
+ })
35
+ ```
36
+
37
+ Row virtualization sets `enableStickyHeader` to true and, unless `layoutMode` was given, switches `layoutMode` to `'grid'`, so the table renders with CSS grid and flexbox instead of semantic table layout. The container needs a bounded height for scrolling; the sticky header default caps it at 100vh, and `muiTableContainerProps.sx.maxHeight` sets a tighter one.
38
+
39
+ ## Core Patterns
40
+
41
+ ### Tune the virtualizer
42
+
43
+ ```tsx
44
+ rowVirtualizerOptions: ({ table }) => ({
45
+ overscan: 10,
46
+ estimateSize: () => (table.getState().density === 'compact' ? 37 : 73),
47
+ }),
48
+ columnVirtualizerOptions: { overscan: 3, estimateSize: () => 200 },
49
+ ```
50
+
51
+ Both options accept an object or a callback receiving `table`, and both are `Partial<VirtualizerOptions>` from TanStack Virtual. MRT already estimates row height from the density (37, 58, or 73 px) and measures rendered rows, sets `overscan: 4`, and keeps a dragging row mounted; anything you pass merges over those defaults. Raise `overscan` if fast scrolling shows blank rows, and set `estimateSize` when rows or columns are far from the defaults so the scrollbar length is accurate.
52
+
53
+ ### Reach the virtualizer instance
54
+
55
+ ```tsx
56
+ const rowVirtualizerInstanceRef = useRef<MRT_RowVirtualizer>(null)
57
+ const [sorting, setSorting] = useState<MRT_SortingState>([])
58
+
59
+ useEffect(() => {
60
+ rowVirtualizerInstanceRef.current?.scrollToIndex?.(0) // back to top when sorting changes
61
+ }, [sorting])
62
+
63
+ const table = useMaterialReactTable({
64
+ columns,
65
+ data,
66
+ enablePagination: false,
67
+ enableRowVirtualization: true,
68
+ rowVirtualizerInstanceRef,
69
+ state: { sorting },
70
+ onSortingChange: setSorting,
71
+ })
72
+ ```
73
+
74
+ `MRT_RowVirtualizer` and `MRT_ColumnVirtualizer` are the TanStack `Virtualizer` plus `virtualRows` or `virtualColumns`, so `scrollToIndex`, `scrollToOffset`, `measure`, and `getVirtualItems` are available. `columnVirtualizerInstanceRef` is the column counterpart.
75
+
76
+ ### Infinite scroll on the container
77
+
78
+ ```tsx
79
+ const tableContainerRef = useRef<HTMLDivElement>(null)
80
+
81
+ const table = useMaterialReactTable({
82
+ columns,
83
+ data: flatRows,
84
+ enablePagination: false,
85
+ enableRowVirtualization: true,
86
+ manualFiltering: true,
87
+ manualSorting: true,
88
+ muiTableContainerProps: {
89
+ ref: tableContainerRef,
90
+ sx: { maxHeight: '600px' },
91
+ onScroll: (event) => {
92
+ const { scrollHeight, scrollTop, clientHeight } = event.currentTarget
93
+ if (scrollHeight - scrollTop - clientHeight < 400 && !isFetching && hasNextPage) fetchNextPage()
94
+ },
95
+ },
96
+ renderBottomToolbarCustomActions: () => <Typography>Fetched {flatRows.length} of {totalRowCount} rows</Typography>,
97
+ state: { isLoading, showProgressBars: isFetching },
98
+ })
99
+ ```
100
+
101
+ Virtualization keeps the DOM small while the fetched array grows. Server-side sorting and filtering options are covered in `state-and-server-data`.
102
+
103
+ ### Headless virtualization
104
+
105
+ ```tsx
106
+ import { useMRT_Rows, useMRT_RowVirtualizer, useMRT_ColumnVirtualizer } from '@lminii/material-react-table'
107
+
108
+ const rows = useMRT_Rows(table)
109
+ const rowVirtualizer = useMRT_RowVirtualizer(table)
110
+ const columnVirtualizer = useMRT_ColumnVirtualizer(table)
111
+
112
+ rowVirtualizer?.virtualRows.map((virtualRow) => {
113
+ const row = rows[virtualRow.index]
114
+ return <MyRow key={row.id} row={row} style={{ transform: `translateY(${virtualRow.start}px)` }} />
115
+ })
116
+ ```
117
+
118
+ The hooks return `undefined` when the matching `enable*Virtualization` option is off. They read the scroll element from `table.refs.tableContainerRef`, so a custom layout must attach that ref to its scroll container.
119
+
120
+ ## Common Mistakes
121
+
122
+ ### HIGH Enabling virtualization conditionally
123
+
124
+ Wrong:
125
+
126
+ ```tsx
127
+ enableRowVirtualization: data.length > 100,
128
+ ```
129
+
130
+ Correct:
131
+
132
+ ```tsx
133
+ enableRowVirtualization: true, // decide once per table, not per render
134
+ ```
135
+
136
+ The virtualizer hooks run only when enabled, so toggling the option at runtime changes the hook order and breaks React's rules of hooks; it also flips `layoutMode`, which re-lays out every cell.
137
+
138
+ Source: `docs/guides/virtualization.mdx`
139
+
140
+ ### HIGH Leaving pagination on
141
+
142
+ Wrong:
143
+
144
+ ```tsx
145
+ enableRowVirtualization: true,
146
+ ```
147
+
148
+ Correct:
149
+
150
+ ```tsx
151
+ enableRowVirtualization: true,
152
+ enablePagination: false,
153
+ ```
154
+
155
+ With pagination on, only one page of rows exists to virtualize, so the table still renders 10 rows and the user pages through 10,000.
156
+
157
+ Source: `docs/guides/virtualization.mdx`
158
+
159
+ ### MEDIUM Expecting semantic table CSS to keep working
160
+
161
+ Wrong:
162
+
163
+ ```tsx
164
+ enableRowVirtualization: true,
165
+ muiTableBodyCellProps: { sx: { width: '20%' } }, // percentage widths ignored in grid layout
166
+ ```
167
+
168
+ Correct:
169
+
170
+ ```tsx
171
+ enableRowVirtualization: true,
172
+ columns: [{ accessorKey: 'email', header: 'Email', size: 300, grow: false }],
173
+ ```
174
+
175
+ Virtualization forces `layoutMode: 'grid'`, where column widths come from `size`, `minSize`, `maxSize`, and `grow`, not from table-layout CSS.
176
+
177
+ Source: `packages/material-react-table/src/hooks/useMRT_TableOptions.ts`
178
+
179
+ ### MEDIUM Detail panels with a fixed row estimate
180
+
181
+ Wrong:
182
+
183
+ ```tsx
184
+ enableRowVirtualization: true,
185
+ renderDetailPanel: ({ row }) => <Details row={row} />,
186
+ rowVirtualizerOptions: { estimateSize: () => 50 },
187
+ ```
188
+
189
+ Correct:
190
+
191
+ ```tsx
192
+ enableRowVirtualization: true,
193
+ renderDetailPanel: ({ row }) => <Details row={row} />,
194
+ // keep MRT's estimate: it counts two virtual items per row and sizes the panel item from the expanded state
195
+ ```
196
+
197
+ With a detail panel MRT virtualizes two items per row (row and panel) and estimates the panel at 0 or 100 px depending on expansion. A flat `estimateSize` breaks the scrollbar and item positions.
198
+
199
+ Source: `packages/material-react-table/src/hooks/useMRT_RowVirtualizer.ts`
200
+
201
+ ## API Discovery
202
+
203
+ Search `node_modules/@lminii/material-react-table/dist/index.d.ts` for `Virtualizer` to find `MRT_RowVirtualizer`, `MRT_ColumnVirtualizer`, `MRT_VirtualizerOptions`, and `MRT_VirtualItem`. The TanStack Virtual docs at `https://tanstack.com/virtual/v3/docs/api/virtualizer` list every option and instance method. The Virtualization guide at `/docs/guides/virtualization` and the examples `/docs/examples/virtualized`, `enable-row-virtualization`, `enable-column-virtualization`, `enable-detail-panel-virtualized`, and `infinite-scrolling` show the patterns above.
@@ -0,0 +1,36 @@
1
+ import { MRT_TablePaper } from './table/MRT_TablePaper';
2
+ import { useMaterialReactTable } from '../hooks/useMaterialReactTable';
3
+ import {
4
+ type MRT_RowData,
5
+ type MRT_TableInstance,
6
+ type MRT_TableOptions,
7
+ type Xor,
8
+ } from '../types';
9
+
10
+ export type MaterialReactTableProps<TData extends MRT_RowData> = Xor<
11
+ TableInstanceProp<TData>,
12
+ MRT_TableOptions<TData>
13
+ >;
14
+
15
+ type TableInstanceProp<TData extends MRT_RowData> = {
16
+ table: MRT_TableInstance<TData>;
17
+ };
18
+
19
+ const isTableInstanceProp = <TData extends MRT_RowData>(
20
+ props: MaterialReactTableProps<TData>,
21
+ ): props is TableInstanceProp<TData> =>
22
+ (props as TableInstanceProp<TData>).table !== undefined;
23
+
24
+ export const MaterialReactTable = <TData extends MRT_RowData>(
25
+ props: MaterialReactTableProps<TData>,
26
+ ) => {
27
+ let table: MRT_TableInstance<TData>;
28
+
29
+ if (isTableInstanceProp(props)) {
30
+ table = props.table;
31
+ } else {
32
+ table = useMaterialReactTable(props);
33
+ }
34
+
35
+ return <MRT_TablePaper table={table} />;
36
+ };
@@ -0,0 +1,221 @@
1
+ import { memo, useMemo } from 'react';
2
+ import { type VirtualItem } from '@tanstack/react-virtual';
3
+ import TableBody, { type TableBodyProps } from '@mui/material/TableBody';
4
+ import Typography from '@mui/material/Typography';
5
+ import { useMRT_Rows } from '../../hooks/useMRT_Rows';
6
+ import { useMRT_RowVirtualizer } from '../../hooks/useMRT_RowVirtualizer';
7
+ import { Memo_MRT_TableBodyRow, MRT_TableBodyRow } from './MRT_TableBodyRow';
8
+ import {
9
+ type MRT_ColumnVirtualizer,
10
+ type MRT_Row,
11
+ type MRT_RowData,
12
+ type MRT_TableInstance,
13
+ } from '../../types';
14
+ import { parseFromValuesOrFunc } from '../../utils/utils';
15
+
16
+ export interface MRT_TableBodyProps<TData extends MRT_RowData>
17
+ extends TableBodyProps {
18
+ columnVirtualizer?: MRT_ColumnVirtualizer;
19
+ table: MRT_TableInstance<TData>;
20
+ }
21
+
22
+ export const MRT_TableBody = <TData extends MRT_RowData>({
23
+ columnVirtualizer,
24
+ table,
25
+ ...rest
26
+ }: MRT_TableBodyProps<TData>) => {
27
+ const {
28
+ getBottomRows,
29
+ getIsSomeRowsPinned,
30
+ getRowModel,
31
+ getTopRows,
32
+ options: {
33
+ enableStickyFooter,
34
+ enableStickyHeader,
35
+ layoutMode,
36
+ localization,
37
+ memoMode,
38
+ muiTableBodyProps,
39
+ renderDetailPanel,
40
+ renderEmptyRowsFallback,
41
+ rowPinningDisplayMode,
42
+ },
43
+ refs: { tableFooterRef, tableHeadRef, tablePaperRef },
44
+ state,
45
+ } = table;
46
+ const { columnFilters, globalFilter, isFullScreen, rowPinning } = state;
47
+
48
+ const tableBodyProps = {
49
+ ...parseFromValuesOrFunc(muiTableBodyProps, { table }),
50
+ ...rest,
51
+ };
52
+
53
+ const tableHeadHeight =
54
+ ((enableStickyHeader || isFullScreen) &&
55
+ tableHeadRef.current?.clientHeight) ||
56
+ 0;
57
+ const tableFooterHeight =
58
+ (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
59
+
60
+ const pinnedRowIds = useMemo(() => {
61
+ if (!rowPinning.bottom?.length && !rowPinning.top?.length) return [];
62
+ return getRowModel()
63
+ .rows.filter((row) => row.getIsPinned())
64
+ .map((r) => r.id);
65
+ }, [rowPinning, getRowModel().rows]);
66
+
67
+ const rows = useMRT_Rows(table);
68
+
69
+ const rowVirtualizer = useMRT_RowVirtualizer(table, rows);
70
+
71
+ const { virtualRows } = rowVirtualizer ?? {};
72
+
73
+ const commonRowProps = {
74
+ columnVirtualizer,
75
+ numRows: rows.length,
76
+ table,
77
+ };
78
+
79
+ return (
80
+ <>
81
+ {!rowPinningDisplayMode?.includes('sticky') &&
82
+ getIsSomeRowsPinned('top') && (
83
+ <TableBody
84
+ {...tableBodyProps}
85
+ sx={(theme) => ({
86
+ display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
87
+ position: 'sticky',
88
+ top: tableHeadHeight - 1,
89
+ zIndex: 1,
90
+ ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
91
+ })}
92
+ >
93
+ {getTopRows().map((row, staticRowIndex) => {
94
+ const props = {
95
+ ...commonRowProps,
96
+ row,
97
+ staticRowIndex,
98
+ };
99
+ return memoMode === 'rows' ? (
100
+ <Memo_MRT_TableBodyRow key={row.id} {...props} />
101
+ ) : (
102
+ <MRT_TableBodyRow key={row.id} {...props} />
103
+ );
104
+ })}
105
+ </TableBody>
106
+ )}
107
+ <TableBody
108
+ {...tableBodyProps}
109
+ sx={(theme) => ({
110
+ display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
111
+ height: rowVirtualizer
112
+ ? `${rowVirtualizer.getTotalSize()}px`
113
+ : undefined,
114
+ minHeight: !rows.length ? '100px' : undefined,
115
+ position: 'relative',
116
+ ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
117
+ })}
118
+ >
119
+ {tableBodyProps?.children ??
120
+ (!rows.length ? (
121
+ <tr
122
+ style={{
123
+ display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
124
+ }}
125
+ >
126
+ <td
127
+ colSpan={table.getVisibleLeafColumns().length}
128
+ style={{
129
+ display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
130
+ }}
131
+ >
132
+ {renderEmptyRowsFallback?.({ table }) ?? (
133
+ <Typography
134
+ sx={{
135
+ color: 'text.secondary',
136
+ fontStyle: 'italic',
137
+ maxWidth: `min(100vw, ${
138
+ tablePaperRef.current?.clientWidth ? tablePaperRef.current?.clientWidth + "px" : "100%"
139
+ })`,
140
+ py: '2rem',
141
+ textAlign: 'center',
142
+ width: '100%',
143
+ }}
144
+ >
145
+ {globalFilter || columnFilters.length
146
+ ? localization.noResultsFound
147
+ : localization.noRecordsToDisplay}
148
+ </Typography>
149
+ )}
150
+ </td>
151
+ </tr>
152
+ ) : (
153
+ <>
154
+ {(virtualRows ?? rows).map((rowOrVirtualRow, staticRowIndex) => {
155
+ let row = rowOrVirtualRow as MRT_Row<TData>;
156
+ if (rowVirtualizer) {
157
+ if (renderDetailPanel) {
158
+ if (rowOrVirtualRow.index % 2 === 1) {
159
+ return null;
160
+ } else {
161
+ staticRowIndex = rowOrVirtualRow.index / 2;
162
+ }
163
+ } else {
164
+ staticRowIndex = rowOrVirtualRow.index;
165
+ }
166
+ row = rows[staticRowIndex];
167
+ }
168
+ const props = {
169
+ ...commonRowProps,
170
+ pinnedRowIds,
171
+ row,
172
+ rowVirtualizer,
173
+ staticRowIndex,
174
+ virtualRow: rowVirtualizer
175
+ ? (rowOrVirtualRow as VirtualItem)
176
+ : undefined,
177
+ };
178
+ const key = `${row.id}-${row.index}`;
179
+ return memoMode === 'rows' ? (
180
+ <Memo_MRT_TableBodyRow key={key} {...props} />
181
+ ) : (
182
+ <MRT_TableBodyRow key={key} {...props} />
183
+ );
184
+ })}
185
+ </>
186
+ ))}
187
+ </TableBody>
188
+ {!rowPinningDisplayMode?.includes('sticky') &&
189
+ getIsSomeRowsPinned('bottom') && (
190
+ <TableBody
191
+ {...tableBodyProps}
192
+ sx={(theme) => ({
193
+ bottom: tableFooterHeight - 1,
194
+ display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
195
+ position: 'sticky',
196
+ zIndex: 1,
197
+ ...(parseFromValuesOrFunc(tableBodyProps?.sx, theme) as any),
198
+ })}
199
+ >
200
+ {getBottomRows().map((row, staticRowIndex) => {
201
+ const props = {
202
+ ...commonRowProps,
203
+ row,
204
+ staticRowIndex,
205
+ };
206
+ return memoMode === 'rows' ? (
207
+ <Memo_MRT_TableBodyRow key={row.id} {...props} />
208
+ ) : (
209
+ <MRT_TableBodyRow key={row.id} {...props} />
210
+ );
211
+ })}
212
+ </TableBody>
213
+ )}
214
+ </>
215
+ );
216
+ };
217
+
218
+ export const Memo_MRT_TableBody = memo(
219
+ MRT_TableBody,
220
+ (prev, next) => prev.table.options.data === next.table.options.data,
221
+ ) as typeof MRT_TableBody;