@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,124 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { type Range, useVirtualizer } from '@tanstack/react-virtual';
3
+ import {
4
+ type MRT_ColumnVirtualizer,
5
+ type MRT_RowData,
6
+ type MRT_TableInstance,
7
+ } from '../types';
8
+ import { parseFromValuesOrFunc } from '../utils/utils';
9
+ import { extraIndexRangeExtractor } from '../utils/virtualization.utils';
10
+
11
+ export const useMRT_ColumnVirtualizer = <
12
+ TData extends MRT_RowData,
13
+ TScrollElement extends Element | Window = HTMLDivElement,
14
+ TItemElement extends Element = HTMLTableCellElement,
15
+ >(
16
+ table: MRT_TableInstance<TData>,
17
+ ): MRT_ColumnVirtualizer | undefined => {
18
+ const {
19
+ options: {
20
+ columnVirtualizerInstanceRef,
21
+ columnVirtualizerOptions,
22
+ enableColumnPinning,
23
+ enableColumnVirtualization,
24
+ },
25
+ refs: { tableContainerRef },
26
+ state,
27
+ } = table;
28
+ const { columnPinning, columnVisibility, draggingColumn } = state;
29
+
30
+ if (!enableColumnVirtualization) return undefined;
31
+
32
+ const columnVirtualizerProps = parseFromValuesOrFunc(
33
+ columnVirtualizerOptions,
34
+ {
35
+ table,
36
+ },
37
+ );
38
+
39
+ const visibleColumns = table.getVisibleLeafColumns();
40
+
41
+ const [leftPinnedIndexes, rightPinnedIndexes] = useMemo(
42
+ () =>
43
+ enableColumnPinning
44
+ ? [
45
+ table.getStartVisibleLeafColumns().map((c) => c.getPinnedIndex()),
46
+ table
47
+ .getEndVisibleLeafColumns()
48
+ .map(
49
+ (column) => visibleColumns.length - column.getPinnedIndex() - 1,
50
+ )
51
+ .sort((a, b) => a - b),
52
+ ]
53
+ : [[], []],
54
+ [columnPinning, columnVisibility, enableColumnPinning],
55
+ );
56
+
57
+ const numPinnedLeft = leftPinnedIndexes.length;
58
+ const numPinnedRight = rightPinnedIndexes.length;
59
+
60
+ const draggingColumnIndex = useMemo(
61
+ () =>
62
+ draggingColumn?.id
63
+ ? visibleColumns.findIndex((c) => c.id === draggingColumn?.id)
64
+ : undefined,
65
+ [draggingColumn?.id],
66
+ );
67
+
68
+ const columnVirtualizer = useVirtualizer({
69
+ count: visibleColumns.length,
70
+ estimateSize: (index) => visibleColumns[index].getSize(),
71
+ getScrollElement: () => tableContainerRef.current,
72
+ horizontal: true,
73
+ overscan: 3,
74
+ rangeExtractor: useCallback(
75
+ (range: Range) => {
76
+ const newIndexes = extraIndexRangeExtractor(range, draggingColumnIndex);
77
+ if (!numPinnedLeft && !numPinnedRight) {
78
+ return newIndexes;
79
+ }
80
+ return [
81
+ ...new Set([
82
+ ...leftPinnedIndexes,
83
+ ...newIndexes,
84
+ ...rightPinnedIndexes,
85
+ ]),
86
+ ];
87
+ },
88
+ [leftPinnedIndexes, rightPinnedIndexes, draggingColumnIndex],
89
+ ),
90
+ ...columnVirtualizerProps,
91
+ }) as unknown as MRT_ColumnVirtualizer<TScrollElement, TItemElement>;
92
+
93
+ const virtualColumns = columnVirtualizer.getVirtualItems();
94
+ columnVirtualizer.virtualColumns = virtualColumns as any;
95
+ const numColumns = virtualColumns.length;
96
+
97
+ if (numColumns) {
98
+ const totalSize = columnVirtualizer.getTotalSize();
99
+
100
+ const leftNonPinnedStart = virtualColumns[numPinnedLeft]?.start || 0;
101
+ const leftNonPinnedEnd =
102
+ virtualColumns[leftPinnedIndexes.length - 1]?.end || 0;
103
+
104
+ const rightNonPinnedStart =
105
+ virtualColumns[numColumns - numPinnedRight]?.start || 0;
106
+ const rightNonPinnedEnd =
107
+ virtualColumns[numColumns - numPinnedRight - 1]?.end || 0;
108
+
109
+ columnVirtualizer.virtualPaddingLeft =
110
+ leftNonPinnedStart - leftNonPinnedEnd;
111
+
112
+ columnVirtualizer.virtualPaddingRight =
113
+ totalSize -
114
+ rightNonPinnedEnd -
115
+ (numPinnedRight ? totalSize - rightNonPinnedStart : 0);
116
+ }
117
+
118
+ if (columnVirtualizerInstanceRef) {
119
+ //@ts-expect-error
120
+ columnVirtualizerInstanceRef.current = columnVirtualizer;
121
+ }
122
+
123
+ return columnVirtualizer as any;
124
+ };
@@ -0,0 +1,108 @@
1
+ import { useEffect, useReducer, useRef } from 'react';
2
+ import {
3
+ type MRT_RowData,
4
+ type MRT_SortingState,
5
+ type MRT_TableInstance,
6
+ } from '../types';
7
+ import { getDefaultColumnOrderIds } from '../utils/displayColumn.utils';
8
+ import { getCanRankRows } from '../utils/row.utils';
9
+
10
+ export const useMRT_Effects = <TData extends MRT_RowData>(
11
+ table: MRT_TableInstance<TData>,
12
+ ) => {
13
+ const {
14
+ getIsSomeRowsPinned,
15
+ getPrePaginatedRowModel,
16
+ options: { enablePagination, enableRowPinning, rowCount },
17
+ state,
18
+ } = table;
19
+ const {
20
+ columnOrder,
21
+ density,
22
+ globalFilter,
23
+ isFullScreen,
24
+ isLoading,
25
+ pagination,
26
+ showSkeletons,
27
+ sorting,
28
+ } = state;
29
+
30
+ const totalColumnCount = table.options.columns.length;
31
+ const totalRowCount = rowCount ?? getPrePaginatedRowModel().rows.length;
32
+
33
+ const rerender = useReducer(() => ({}), {})[1];
34
+ const initialBodyHeight = useRef<string>(null);
35
+ const previousTop = useRef<number>(null);
36
+
37
+ useEffect(() => {
38
+ if (typeof window !== 'undefined') {
39
+ initialBodyHeight.current = document.body.style.height;
40
+ }
41
+ }, []);
42
+
43
+ //hide scrollbars when table is in full screen mode, preserve body scroll position after full screen exit
44
+ useEffect(() => {
45
+ if (typeof window !== 'undefined') {
46
+ if (isFullScreen) {
47
+ previousTop.current = document.body.getBoundingClientRect().top; //save scroll position
48
+ document.body.style.height = '100dvh'; //hide page scrollbars when table is in full screen mode
49
+ } else {
50
+ document.body.style.height = initialBodyHeight.current as string;
51
+ if (!previousTop.current) return;
52
+ //restore scroll position
53
+ window.scrollTo({
54
+ behavior: 'instant',
55
+ top: -1 * (previousTop.current as number),
56
+ });
57
+ }
58
+ }
59
+ }, [isFullScreen]);
60
+
61
+ //recalculate column order when columns change or features are toggled on/off
62
+ useEffect(() => {
63
+ if (totalColumnCount !== columnOrder.length) {
64
+ table.setColumnOrder(
65
+ getDefaultColumnOrderIds({ ...table.options, state: table.state }),
66
+ );
67
+ }
68
+ }, [totalColumnCount]);
69
+
70
+ //if page index is out of bounds, set it to the last page
71
+ useEffect(() => {
72
+ if (!enablePagination || isLoading || showSkeletons) return;
73
+ const { pageIndex, pageSize } = pagination;
74
+ const totalPages: number =
75
+ totalRowCount > 0 ? Math.ceil(totalRowCount / pageSize) : 1;
76
+ const isOutOfBounds: boolean = pageIndex < 0 || pageIndex >= totalPages;
77
+
78
+ if (isOutOfBounds) {
79
+ table.setPageIndex(totalPages - 1);
80
+ }
81
+ }, [totalRowCount, enablePagination, isLoading, showSkeletons]);
82
+
83
+ //turn off sort when global filter is looking for ranked results
84
+ const appliedSort = useRef<MRT_SortingState>(sorting);
85
+ useEffect(() => {
86
+ if (sorting.length) {
87
+ appliedSort.current = sorting;
88
+ }
89
+ }, [sorting]);
90
+
91
+ useEffect(() => {
92
+ if (!getCanRankRows(table)) return;
93
+ if (globalFilter) {
94
+ table.setSorting([]);
95
+ } else {
96
+ table.setSorting(() => appliedSort.current || []);
97
+ }
98
+ }, [globalFilter]);
99
+
100
+ //fix pinned row top style when density changes
101
+ useEffect(() => {
102
+ if (enableRowPinning && getIsSomeRowsPinned()) {
103
+ setTimeout(() => {
104
+ rerender();
105
+ }, 150);
106
+ }
107
+ }, [density]);
108
+ };
@@ -0,0 +1,88 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { type Range, useVirtualizer } from '@tanstack/react-virtual';
3
+ import {
4
+ type MRT_Row,
5
+ type MRT_RowData,
6
+ type MRT_RowVirtualizer,
7
+ type MRT_TableInstance,
8
+ } from '../types';
9
+ import { parseFromValuesOrFunc } from '../utils/utils';
10
+ import { extraIndexRangeExtractor } from '../utils/virtualization.utils';
11
+
12
+ export const useMRT_RowVirtualizer = <
13
+ TData extends MRT_RowData,
14
+ TScrollElement extends Element | Window = HTMLDivElement,
15
+ TItemElement extends Element = HTMLTableRowElement,
16
+ >(
17
+ table: MRT_TableInstance<TData>,
18
+ rows?: MRT_Row<TData>[],
19
+ ): MRT_RowVirtualizer<TScrollElement, TItemElement> | undefined => {
20
+ const {
21
+ getRowModel,
22
+ options: {
23
+ enableRowVirtualization,
24
+ renderDetailPanel,
25
+ rowVirtualizerInstanceRef,
26
+ rowVirtualizerOptions,
27
+ },
28
+ refs: { tableContainerRef },
29
+ state,
30
+ } = table;
31
+ const { density, draggingRow, expanded } = state;
32
+
33
+ if (!enableRowVirtualization) return undefined;
34
+
35
+ const rowVirtualizerProps = parseFromValuesOrFunc(rowVirtualizerOptions, {
36
+ table,
37
+ });
38
+
39
+ const realRows = rows ?? getRowModel().rows;
40
+ /**
41
+ * when filtering, should find the correct index in filtered rows
42
+ */
43
+ const draggingRowIndex = useMemo(
44
+ () =>
45
+ draggingRow?.id
46
+ ? realRows.findIndex((r) => r.id === draggingRow?.id)
47
+ : undefined,
48
+ [realRows, draggingRow?.id],
49
+ );
50
+
51
+ const rowCount = realRows.length;
52
+
53
+ const normalRowHeight =
54
+ density === 'compact' ? 37 : density === 'comfortable' ? 58 : 73;
55
+
56
+ const rowVirtualizer = useVirtualizer({
57
+ count: renderDetailPanel ? rowCount * 2 : rowCount,
58
+ estimateSize: (index) =>
59
+ renderDetailPanel && index % 2 === 1
60
+ ? expanded === true
61
+ ? 100
62
+ : 0
63
+ : normalRowHeight,
64
+ getScrollElement: () => tableContainerRef.current,
65
+ measureElement:
66
+ typeof window !== 'undefined' &&
67
+ navigator.userAgent.indexOf('Firefox') === -1
68
+ ? (element) => element?.getBoundingClientRect().height
69
+ : undefined,
70
+ overscan: 4,
71
+ rangeExtractor: useCallback(
72
+ (range: Range) => {
73
+ return extraIndexRangeExtractor(range, draggingRowIndex);
74
+ },
75
+ [draggingRowIndex],
76
+ ),
77
+ ...rowVirtualizerProps,
78
+ }) as unknown as MRT_RowVirtualizer<TScrollElement, TItemElement>;
79
+
80
+ rowVirtualizer.virtualRows = rowVirtualizer.getVirtualItems() as any;
81
+
82
+ if (rowVirtualizerInstanceRef) {
83
+ //@ts-expect-error
84
+ rowVirtualizerInstanceRef.current = rowVirtualizer;
85
+ }
86
+
87
+ return rowVirtualizer;
88
+ };
@@ -0,0 +1,44 @@
1
+ import { useMemo } from 'react';
2
+ import {
3
+ type MRT_Row,
4
+ type MRT_RowData,
5
+ type MRT_TableInstance,
6
+ } from '../types';
7
+ import { getMRT_Rows } from '../utils/row.utils';
8
+
9
+ export const useMRT_Rows = <TData extends MRT_RowData>(
10
+ table: MRT_TableInstance<TData>,
11
+ ): MRT_Row<TData>[] => {
12
+ const {
13
+ getRowModel,
14
+ options: { data, enableGlobalFilterRankedResults, positionCreatingRow },
15
+ state,
16
+ } = table;
17
+ const {
18
+ creatingRow,
19
+ expanded,
20
+ globalFilter,
21
+ pagination,
22
+ rowPinning,
23
+ sorting,
24
+ } = state;
25
+
26
+ const rows = useMemo(
27
+ () => getMRT_Rows(table),
28
+ [
29
+ creatingRow,
30
+ data,
31
+ enableGlobalFilterRankedResults,
32
+ expanded,
33
+ getRowModel().rows,
34
+ globalFilter,
35
+ pagination.pageIndex,
36
+ pagination.pageSize,
37
+ positionCreatingRow,
38
+ rowPinning,
39
+ sorting,
40
+ ],
41
+ );
42
+
43
+ return rows;
44
+ };
@@ -0,0 +1,181 @@
1
+ import { useMemo, useRef } from 'react';
2
+ import { useTable } from '@tanstack/react-table';
3
+ import { getMRT_RowActionsColumnDef } from './display-columns/getMRT_RowActionsColumnDef';
4
+ import { getMRT_RowDragColumnDef } from './display-columns/getMRT_RowDragColumnDef';
5
+ import { getMRT_RowExpandColumnDef } from './display-columns/getMRT_RowExpandColumnDef';
6
+ import { getMRT_RowNumbersColumnDef } from './display-columns/getMRT_RowNumbersColumnDef';
7
+ import { getMRT_RowPinningColumnDef } from './display-columns/getMRT_RowPinningColumnDef';
8
+ import { getMRT_RowSelectColumnDef } from './display-columns/getMRT_RowSelectColumnDef';
9
+ import { getMRT_RowSpacerColumnDef } from './display-columns/getMRT_RowSpacerColumnDef';
10
+ import { useMRT_Effects } from './useMRT_Effects';
11
+ import {
12
+ mrtFeatures,
13
+ mrtFeaturesWithoutFacetedValues,
14
+ } from '../features/mrtFeatures';
15
+ import {
16
+ type MRT_ColumnDef,
17
+ type MRT_ColumnResizingState,
18
+ type MRT_DefinedTableOptions,
19
+ type MRT_RowData,
20
+ type MRT_StatefulTableOptions,
21
+ type MRT_TableInstance,
22
+ type MRT_TableState,
23
+ } from '../types';
24
+ import {
25
+ getAllLeafColumnDefs,
26
+ getColumnId,
27
+ getDefaultColumnFilterFn,
28
+ prepareColumns,
29
+ } from '../utils/column.utils';
30
+ import {
31
+ getDefaultColumnOrderIds,
32
+ showRowActionsColumn,
33
+ showRowDragColumn,
34
+ showRowExpandColumn,
35
+ showRowNumbersColumn,
36
+ showRowPinningColumn,
37
+ showRowSelectionColumn,
38
+ showRowSpacerColumn,
39
+ } from '../utils/displayColumn.utils';
40
+
41
+ /**
42
+ * The MRT hook that wraps the TanStack useTable hook and adds additional functionality
43
+ * @param definedTableOptions - table options with proper defaults set
44
+ * @returns the MRT table instance
45
+ */
46
+ export const useMRT_TableInstance = <TData extends MRT_RowData>(
47
+ definedTableOptions: MRT_DefinedTableOptions<TData>,
48
+ ): MRT_TableInstance<TData> => {
49
+ const tableRef = useRef<MRT_TableInstance<TData> | null>(null);
50
+
51
+ //transform initial state with proper column order and filter fns
52
+ const initialState: Partial<MRT_TableState<TData>> = useMemo(() => {
53
+ const initState = definedTableOptions.initialState ?? {};
54
+ initState.columnOrder =
55
+ initState.columnOrder ??
56
+ getDefaultColumnOrderIds({
57
+ ...definedTableOptions,
58
+ state: {
59
+ ...definedTableOptions.initialState,
60
+ ...definedTableOptions.state,
61
+ },
62
+ } as MRT_StatefulTableOptions<TData>);
63
+ initState.columnFilterFns = Object.assign(
64
+ {},
65
+ ...getAllLeafColumnDefs(
66
+ definedTableOptions.columns as MRT_ColumnDef<TData>[],
67
+ ).map((col) => ({
68
+ [getColumnId(col)]:
69
+ col.filterFn instanceof Function
70
+ ? (col.filterFn.name ?? 'custom')
71
+ : (col.filterFn ??
72
+ initState.columnFilterFns?.[getColumnId(col)] ??
73
+ getDefaultColumnFilterFn(col)),
74
+ })),
75
+ );
76
+ initState.globalFilterFn = definedTableOptions.globalFilterFn ?? 'fuzzy';
77
+ return initState;
78
+ }, []);
79
+
80
+ definedTableOptions.initialState = initialState;
81
+
82
+ //MRT-owned state lives in the table store; the previous render's state feeds
83
+ //the option transforms below, falling back to the initial state on first render
84
+ const controlledState = definedTableOptions.state;
85
+ definedTableOptions.state = {
86
+ columnResizing: {} as MRT_ColumnResizingState,
87
+ creatingRow: null,
88
+ draggingColumn: null,
89
+ draggingRow: null,
90
+ grouping: [],
91
+ isLoading: false,
92
+ pagination: { pageIndex: 0, pageSize: 10 },
93
+ showSkeletons: false,
94
+ ...initialState,
95
+ ...tableRef.current?.state,
96
+ ...controlledState,
97
+ };
98
+
99
+ //The table options now include all state needed to help determine column visibility and order logic
100
+ const statefulTableOptions =
101
+ definedTableOptions as MRT_StatefulTableOptions<TData>;
102
+
103
+ //don't recompute columnDefs while resizing column or dragging column/row
104
+ const columnDefsRef = useRef<MRT_ColumnDef<TData>[]>([]);
105
+ statefulTableOptions.columns =
106
+ statefulTableOptions.state.columnResizing.isResizingColumn ||
107
+ statefulTableOptions.state.draggingColumn ||
108
+ statefulTableOptions.state.draggingRow
109
+ ? columnDefsRef.current
110
+ : prepareColumns({
111
+ columnDefs: [
112
+ ...([
113
+ showRowPinningColumn(statefulTableOptions) &&
114
+ getMRT_RowPinningColumnDef(statefulTableOptions),
115
+ showRowDragColumn(statefulTableOptions) &&
116
+ getMRT_RowDragColumnDef(statefulTableOptions),
117
+ showRowActionsColumn(statefulTableOptions) &&
118
+ getMRT_RowActionsColumnDef(statefulTableOptions),
119
+ showRowExpandColumn(statefulTableOptions) &&
120
+ getMRT_RowExpandColumnDef(statefulTableOptions),
121
+ showRowSelectionColumn(statefulTableOptions) &&
122
+ getMRT_RowSelectColumnDef(statefulTableOptions),
123
+ showRowNumbersColumn(statefulTableOptions) &&
124
+ getMRT_RowNumbersColumnDef(statefulTableOptions),
125
+ ].filter(Boolean) as MRT_ColumnDef<TData>[]),
126
+ ...statefulTableOptions.columns,
127
+ ...([
128
+ showRowSpacerColumn(statefulTableOptions) &&
129
+ getMRT_RowSpacerColumnDef(statefulTableOptions),
130
+ ].filter(Boolean) as MRT_ColumnDef<TData>[]),
131
+ ],
132
+ tableOptions: statefulTableOptions,
133
+ });
134
+ columnDefsRef.current = statefulTableOptions.columns;
135
+
136
+ //if loading, generate blank rows to show skeleton loaders
137
+ statefulTableOptions.data = useMemo(
138
+ () =>
139
+ (statefulTableOptions.state.isLoading ||
140
+ statefulTableOptions.state.showSkeletons) &&
141
+ !statefulTableOptions.data.length
142
+ ? [
143
+ ...Array(
144
+ Math.min(statefulTableOptions.state.pagination.pageSize, 20),
145
+ ).fill(null),
146
+ ].map(() =>
147
+ Object.assign(
148
+ {},
149
+ ...getAllLeafColumnDefs(statefulTableOptions.columns).map(
150
+ (col) => ({
151
+ [getColumnId(col)]: null,
152
+ }),
153
+ ),
154
+ ),
155
+ )
156
+ : statefulTableOptions.data,
157
+ [
158
+ statefulTableOptions.data,
159
+ statefulTableOptions.state.isLoading,
160
+ statefulTableOptions.state.showSkeletons,
161
+ ],
162
+ );
163
+
164
+ //only the user's own `state` option controls slices; the merged copy above
165
+ //is for the transforms and must not be passed to the table
166
+ const { state, ...tableOptions } = statefulTableOptions;
167
+ const table = useTable({
168
+ ...tableOptions,
169
+ features: tableOptions.enableFacetedValues
170
+ ? mrtFeatures
171
+ : mrtFeaturesWithoutFacetedValues,
172
+ globalFilterFn: state.globalFilterFn ?? 'fuzzy',
173
+ state: controlledState,
174
+ } as any) as unknown as MRT_TableInstance<TData>;
175
+
176
+ tableRef.current = table;
177
+
178
+ useMRT_Effects(table);
179
+
180
+ return table;
181
+ };