@novastera-oss/material-react-table 4.0.0-beta.7

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 (324) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/dist/index.cjs +5190 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +1871 -0
  6. package/dist/index.js +5084 -0
  7. package/dist/index.js.map +1 -0
  8. package/locales/ar/index.d.ts +3 -0
  9. package/locales/ar/index.esm.d.ts +3 -0
  10. package/locales/ar/index.esm.js +96 -0
  11. package/locales/ar/index.js +98 -0
  12. package/locales/ar/package.json +6 -0
  13. package/locales/az/index.d.ts +3 -0
  14. package/locales/az/index.esm.d.ts +3 -0
  15. package/locales/az/index.esm.js +96 -0
  16. package/locales/az/index.js +98 -0
  17. package/locales/az/package.json +6 -0
  18. package/locales/bg/index.d.ts +3 -0
  19. package/locales/bg/index.esm.d.ts +3 -0
  20. package/locales/bg/index.esm.js +96 -0
  21. package/locales/bg/index.js +98 -0
  22. package/locales/bg/package.json +6 -0
  23. package/locales/cs/index.d.ts +3 -0
  24. package/locales/cs/index.esm.d.ts +3 -0
  25. package/locales/cs/index.esm.js +96 -0
  26. package/locales/cs/index.js +98 -0
  27. package/locales/cs/package.json +6 -0
  28. package/locales/da/index.d.ts +3 -0
  29. package/locales/da/index.esm.d.ts +3 -0
  30. package/locales/da/index.esm.js +96 -0
  31. package/locales/da/index.js +98 -0
  32. package/locales/da/package.json +6 -0
  33. package/locales/de/index.d.ts +3 -0
  34. package/locales/de/index.esm.d.ts +3 -0
  35. package/locales/de/index.esm.js +96 -0
  36. package/locales/de/index.js +98 -0
  37. package/locales/de/package.json +6 -0
  38. package/locales/el/index.d.ts +3 -0
  39. package/locales/el/index.esm.d.ts +3 -0
  40. package/locales/el/index.esm.js +96 -0
  41. package/locales/el/index.js +98 -0
  42. package/locales/el/package.json +6 -0
  43. package/locales/en/index.d.ts +3 -0
  44. package/locales/en/index.esm.d.ts +3 -0
  45. package/locales/en/index.esm.js +96 -0
  46. package/locales/en/index.js +98 -0
  47. package/locales/en/package.json +6 -0
  48. package/locales/es/index.d.ts +3 -0
  49. package/locales/es/index.esm.d.ts +3 -0
  50. package/locales/es/index.esm.js +96 -0
  51. package/locales/es/index.js +98 -0
  52. package/locales/es/package.json +6 -0
  53. package/locales/et/index.d.ts +3 -0
  54. package/locales/et/index.esm.d.ts +3 -0
  55. package/locales/et/index.esm.js +96 -0
  56. package/locales/et/index.js +98 -0
  57. package/locales/et/package.json +6 -0
  58. package/locales/fa/index.d.ts +3 -0
  59. package/locales/fa/index.esm.d.ts +3 -0
  60. package/locales/fa/index.esm.js +96 -0
  61. package/locales/fa/index.js +98 -0
  62. package/locales/fa/package.json +6 -0
  63. package/locales/fi/index.d.ts +3 -0
  64. package/locales/fi/index.esm.d.ts +3 -0
  65. package/locales/fi/index.esm.js +96 -0
  66. package/locales/fi/index.js +98 -0
  67. package/locales/fi/package.json +6 -0
  68. package/locales/fr/index.d.ts +3 -0
  69. package/locales/fr/index.esm.d.ts +3 -0
  70. package/locales/fr/index.esm.js +96 -0
  71. package/locales/fr/index.js +98 -0
  72. package/locales/fr/package.json +6 -0
  73. package/locales/he/index.d.ts +3 -0
  74. package/locales/he/index.esm.d.ts +3 -0
  75. package/locales/he/index.esm.js +96 -0
  76. package/locales/he/index.js +98 -0
  77. package/locales/he/package.json +6 -0
  78. package/locales/hr/index.d.ts +3 -0
  79. package/locales/hr/index.esm.d.ts +3 -0
  80. package/locales/hr/index.esm.js +96 -0
  81. package/locales/hr/index.js +98 -0
  82. package/locales/hr/package.json +6 -0
  83. package/locales/hu/index.d.ts +3 -0
  84. package/locales/hu/index.esm.d.ts +3 -0
  85. package/locales/hu/index.esm.js +96 -0
  86. package/locales/hu/index.js +98 -0
  87. package/locales/hu/package.json +6 -0
  88. package/locales/hy/index.d.ts +3 -0
  89. package/locales/hy/index.esm.d.ts +3 -0
  90. package/locales/hy/index.esm.js +96 -0
  91. package/locales/hy/index.js +98 -0
  92. package/locales/hy/package.json +6 -0
  93. package/locales/id/index.d.ts +3 -0
  94. package/locales/id/index.esm.d.ts +3 -0
  95. package/locales/id/index.esm.js +96 -0
  96. package/locales/id/index.js +98 -0
  97. package/locales/id/package.json +6 -0
  98. package/locales/it/index.d.ts +3 -0
  99. package/locales/it/index.esm.d.ts +3 -0
  100. package/locales/it/index.esm.js +96 -0
  101. package/locales/it/index.js +98 -0
  102. package/locales/it/package.json +6 -0
  103. package/locales/ja/index.d.ts +3 -0
  104. package/locales/ja/index.esm.d.ts +3 -0
  105. package/locales/ja/index.esm.js +96 -0
  106. package/locales/ja/index.js +98 -0
  107. package/locales/ja/package.json +6 -0
  108. package/locales/ko/index.d.ts +3 -0
  109. package/locales/ko/index.esm.d.ts +3 -0
  110. package/locales/ko/index.esm.js +96 -0
  111. package/locales/ko/index.js +98 -0
  112. package/locales/ko/package.json +6 -0
  113. package/locales/nl/index.d.ts +3 -0
  114. package/locales/nl/index.esm.d.ts +3 -0
  115. package/locales/nl/index.esm.js +96 -0
  116. package/locales/nl/index.js +98 -0
  117. package/locales/nl/package.json +6 -0
  118. package/locales/no/index.d.ts +3 -0
  119. package/locales/no/index.esm.d.ts +3 -0
  120. package/locales/no/index.esm.js +96 -0
  121. package/locales/no/index.js +98 -0
  122. package/locales/no/package.json +6 -0
  123. package/locales/np/index.d.ts +3 -0
  124. package/locales/np/index.esm.d.ts +3 -0
  125. package/locales/np/index.esm.js +96 -0
  126. package/locales/np/index.js +98 -0
  127. package/locales/np/package.json +6 -0
  128. package/locales/pl/index.d.ts +3 -0
  129. package/locales/pl/index.esm.d.ts +3 -0
  130. package/locales/pl/index.esm.js +96 -0
  131. package/locales/pl/index.js +98 -0
  132. package/locales/pl/package.json +6 -0
  133. package/locales/pt/index.d.ts +3 -0
  134. package/locales/pt/index.esm.d.ts +3 -0
  135. package/locales/pt/index.esm.js +96 -0
  136. package/locales/pt/index.js +98 -0
  137. package/locales/pt/package.json +6 -0
  138. package/locales/pt-BR/index.d.ts +3 -0
  139. package/locales/pt-BR/index.esm.d.ts +3 -0
  140. package/locales/pt-BR/index.esm.js +96 -0
  141. package/locales/pt-BR/index.js +98 -0
  142. package/locales/pt-BR/package.json +6 -0
  143. package/locales/ro/index.d.ts +3 -0
  144. package/locales/ro/index.esm.d.ts +3 -0
  145. package/locales/ro/index.esm.js +96 -0
  146. package/locales/ro/index.js +98 -0
  147. package/locales/ro/package.json +6 -0
  148. package/locales/ru/index.d.ts +3 -0
  149. package/locales/ru/index.esm.d.ts +3 -0
  150. package/locales/ru/index.esm.js +96 -0
  151. package/locales/ru/index.js +98 -0
  152. package/locales/ru/package.json +6 -0
  153. package/locales/sk/index.d.ts +3 -0
  154. package/locales/sk/index.esm.d.ts +3 -0
  155. package/locales/sk/index.esm.js +96 -0
  156. package/locales/sk/index.js +98 -0
  157. package/locales/sk/package.json +6 -0
  158. package/locales/sr-Cyrl-RS/index.d.ts +3 -0
  159. package/locales/sr-Cyrl-RS/index.esm.d.ts +3 -0
  160. package/locales/sr-Cyrl-RS/index.esm.js +96 -0
  161. package/locales/sr-Cyrl-RS/index.js +98 -0
  162. package/locales/sr-Cyrl-RS/package.json +6 -0
  163. package/locales/sr-Latn-RS/index.d.ts +3 -0
  164. package/locales/sr-Latn-RS/index.esm.d.ts +3 -0
  165. package/locales/sr-Latn-RS/index.esm.js +96 -0
  166. package/locales/sr-Latn-RS/index.js +98 -0
  167. package/locales/sr-Latn-RS/package.json +6 -0
  168. package/locales/sv/index.d.ts +3 -0
  169. package/locales/sv/index.esm.d.ts +3 -0
  170. package/locales/sv/index.esm.js +96 -0
  171. package/locales/sv/index.js +98 -0
  172. package/locales/sv/package.json +6 -0
  173. package/locales/tr/index.d.ts +3 -0
  174. package/locales/tr/index.esm.d.ts +3 -0
  175. package/locales/tr/index.esm.js +96 -0
  176. package/locales/tr/index.js +98 -0
  177. package/locales/tr/package.json +6 -0
  178. package/locales/uk/index.d.ts +3 -0
  179. package/locales/uk/index.esm.d.ts +3 -0
  180. package/locales/uk/index.esm.js +96 -0
  181. package/locales/uk/index.js +98 -0
  182. package/locales/uk/package.json +6 -0
  183. package/locales/vi/index.d.ts +3 -0
  184. package/locales/vi/index.esm.d.ts +3 -0
  185. package/locales/vi/index.esm.js +96 -0
  186. package/locales/vi/index.js +98 -0
  187. package/locales/vi/package.json +6 -0
  188. package/locales/zh-Hans/index.d.ts +3 -0
  189. package/locales/zh-Hans/index.esm.d.ts +3 -0
  190. package/locales/zh-Hans/index.esm.js +96 -0
  191. package/locales/zh-Hans/index.js +98 -0
  192. package/locales/zh-Hans/package.json +6 -0
  193. package/locales/zh-Hant/index.d.ts +3 -0
  194. package/locales/zh-Hant/index.esm.d.ts +3 -0
  195. package/locales/zh-Hant/index.esm.js +96 -0
  196. package/locales/zh-Hant/index.js +98 -0
  197. package/locales/zh-Hant/package.json +6 -0
  198. package/package.json +103 -0
  199. package/src/components/MaterialReactTable.tsx +36 -0
  200. package/src/components/body/MRT_TableBody.tsx +233 -0
  201. package/src/components/body/MRT_TableBodyCell.tsx +356 -0
  202. package/src/components/body/MRT_TableBodyCellValue.tsx +130 -0
  203. package/src/components/body/MRT_TableBodyRow.tsx +306 -0
  204. package/src/components/body/MRT_TableBodyRowGrabHandle.tsx +61 -0
  205. package/src/components/body/MRT_TableBodyRowPinButton.tsx +58 -0
  206. package/src/components/body/MRT_TableDetailPanel.tsx +118 -0
  207. package/src/components/buttons/MRT_ColumnPinningButtons.tsx +73 -0
  208. package/src/components/buttons/MRT_CopyButton.tsx +91 -0
  209. package/src/components/buttons/MRT_EditActionButtons.tsx +135 -0
  210. package/src/components/buttons/MRT_ExpandAllButton.tsx +82 -0
  211. package/src/components/buttons/MRT_ExpandButton.tsx +106 -0
  212. package/src/components/buttons/MRT_GrabHandleButton.tsx +66 -0
  213. package/src/components/buttons/MRT_RowPinButton.tsx +84 -0
  214. package/src/components/buttons/MRT_ShowHideColumnsButton.tsx +50 -0
  215. package/src/components/buttons/MRT_ToggleDensePaddingButton.tsx +52 -0
  216. package/src/components/buttons/MRT_ToggleFiltersButton.tsx +40 -0
  217. package/src/components/buttons/MRT_ToggleFullScreenButton.tsx +51 -0
  218. package/src/components/buttons/MRT_ToggleGlobalFilterButton.tsx +46 -0
  219. package/src/components/buttons/MRT_ToggleRowActionMenuButton.tsx +126 -0
  220. package/src/components/footer/MRT_TableFooter.tsx +92 -0
  221. package/src/components/footer/MRT_TableFooterCell.tsx +111 -0
  222. package/src/components/footer/MRT_TableFooterRow.tsx +99 -0
  223. package/src/components/head/MRT_TableHead.tsx +95 -0
  224. package/src/components/head/MRT_TableHeadCell.tsx +357 -0
  225. package/src/components/head/MRT_TableHeadCellColumnActionsButton.tsx +100 -0
  226. package/src/components/head/MRT_TableHeadCellFilterContainer.tsx +52 -0
  227. package/src/components/head/MRT_TableHeadCellFilterLabel.tsx +180 -0
  228. package/src/components/head/MRT_TableHeadCellGrabHandle.tsx +91 -0
  229. package/src/components/head/MRT_TableHeadCellResizeHandle.tsx +96 -0
  230. package/src/components/head/MRT_TableHeadCellSortLabel.tsx +102 -0
  231. package/src/components/head/MRT_TableHeadRow.tsx +94 -0
  232. package/src/components/inputs/MRT_EditCellTextField.tsx +195 -0
  233. package/src/components/inputs/MRT_FilterCheckbox.tsx +94 -0
  234. package/src/components/inputs/MRT_FilterRangeFields.tsx +42 -0
  235. package/src/components/inputs/MRT_FilterRangeSlider.tsx +145 -0
  236. package/src/components/inputs/MRT_FilterTextField.tsx +610 -0
  237. package/src/components/inputs/MRT_GlobalFilterTextField.tsx +166 -0
  238. package/src/components/inputs/MRT_SelectCheckbox.tsx +133 -0
  239. package/src/components/menus/MRT_ActionMenuItem.tsx +62 -0
  240. package/src/components/menus/MRT_CellActionMenu.tsx +109 -0
  241. package/src/components/menus/MRT_ColumnActionMenu.tsx +354 -0
  242. package/src/components/menus/MRT_FilterOptionMenu.tsx +294 -0
  243. package/src/components/menus/MRT_RowActionMenu.tsx +90 -0
  244. package/src/components/menus/MRT_ShowHideColumnsMenu.tsx +181 -0
  245. package/src/components/menus/MRT_ShowHideColumnsMenuItems.tsx +204 -0
  246. package/src/components/modals/MRT_EditRowModal.tsx +114 -0
  247. package/src/components/table/MRT_Table.tsx +86 -0
  248. package/src/components/table/MRT_TableContainer.tsx +115 -0
  249. package/src/components/table/MRT_TableLoadingOverlay.tsx +58 -0
  250. package/src/components/table/MRT_TablePaper.tsx +91 -0
  251. package/src/components/toolbar/MRT_BottomToolbar.tsx +112 -0
  252. package/src/components/toolbar/MRT_LinearProgressBar.tsx +53 -0
  253. package/src/components/toolbar/MRT_TablePagination.tsx +241 -0
  254. package/src/components/toolbar/MRT_ToolbarAlertBanner.tsx +182 -0
  255. package/src/components/toolbar/MRT_ToolbarDropZone.tsx +82 -0
  256. package/src/components/toolbar/MRT_ToolbarInternalButtons.tsx +73 -0
  257. package/src/components/toolbar/MRT_TopToolbar.tsx +134 -0
  258. package/src/fns/aggregationFns.ts +3 -0
  259. package/src/fns/filterFns.ts +196 -0
  260. package/src/fns/sortingFns.ts +33 -0
  261. package/src/hooks/display-columns/getMRT_RowActionsColumnDef.tsx +28 -0
  262. package/src/hooks/display-columns/getMRT_RowDragColumnDef.tsx +29 -0
  263. package/src/hooks/display-columns/getMRT_RowExpandColumnDef.tsx +91 -0
  264. package/src/hooks/display-columns/getMRT_RowNumbersColumnDef.tsx +30 -0
  265. package/src/hooks/display-columns/getMRT_RowPinningColumnDef.tsx +24 -0
  266. package/src/hooks/display-columns/getMRT_RowSelectColumnDef.tsx +34 -0
  267. package/src/hooks/display-columns/getMRT_RowSpacerColumnDef.tsx +33 -0
  268. package/src/hooks/useMRT_ColumnVirtualizer.ts +124 -0
  269. package/src/hooks/useMRT_Effects.ts +106 -0
  270. package/src/hooks/useMRT_RowVirtualizer.ts +88 -0
  271. package/src/hooks/useMRT_Rows.ts +44 -0
  272. package/src/hooks/useMRT_TableInstance.ts +317 -0
  273. package/src/hooks/useMRT_TableOptions.ts +270 -0
  274. package/src/hooks/useMaterialReactTable.ts +12 -0
  275. package/src/icons.ts +73 -0
  276. package/src/index.ts +91 -0
  277. package/src/locales/ar.ts +97 -0
  278. package/src/locales/az.ts +97 -0
  279. package/src/locales/bg.ts +97 -0
  280. package/src/locales/cs.ts +98 -0
  281. package/src/locales/da.ts +97 -0
  282. package/src/locales/de.ts +97 -0
  283. package/src/locales/el.ts +97 -0
  284. package/src/locales/en.ts +97 -0
  285. package/src/locales/es.ts +97 -0
  286. package/src/locales/et.ts +98 -0
  287. package/src/locales/fa.ts +97 -0
  288. package/src/locales/fi.ts +98 -0
  289. package/src/locales/fr.ts +97 -0
  290. package/src/locales/he.ts +97 -0
  291. package/src/locales/hr.ts +97 -0
  292. package/src/locales/hu.ts +97 -0
  293. package/src/locales/hy.ts +97 -0
  294. package/src/locales/id.ts +98 -0
  295. package/src/locales/it.ts +97 -0
  296. package/src/locales/ja.ts +97 -0
  297. package/src/locales/ko.ts +97 -0
  298. package/src/locales/mk.ts +96 -0
  299. package/src/locales/nl.ts +97 -0
  300. package/src/locales/no.ts +99 -0
  301. package/src/locales/np.ts +98 -0
  302. package/src/locales/pl.ts +97 -0
  303. package/src/locales/pt-BR.ts +97 -0
  304. package/src/locales/pt.ts +97 -0
  305. package/src/locales/ro.ts +97 -0
  306. package/src/locales/ru.ts +97 -0
  307. package/src/locales/sk.ts +98 -0
  308. package/src/locales/sr-Cyrl-RS.ts +97 -0
  309. package/src/locales/sr-Latn-RS.ts +97 -0
  310. package/src/locales/sv.ts +97 -0
  311. package/src/locales/tr.ts +97 -0
  312. package/src/locales/uk.ts +97 -0
  313. package/src/locales/vi.ts +97 -0
  314. package/src/locales/zh-Hans.ts +96 -0
  315. package/src/locales/zh-Hant.ts +96 -0
  316. package/src/types.ts +1298 -0
  317. package/src/utils/cell.utils.ts +234 -0
  318. package/src/utils/column.utils.ts +209 -0
  319. package/src/utils/displayColumn.utils.ts +152 -0
  320. package/src/utils/row.utils.ts +260 -0
  321. package/src/utils/style.utils.ts +221 -0
  322. package/src/utils/tanstack.helpers.ts +64 -0
  323. package/src/utils/utils.ts +56 -0
  324. package/src/utils/virtualization.utils.ts +24 -0
@@ -0,0 +1,234 @@
1
+ import {
2
+ MRT_Header,
3
+ type MRT_Cell,
4
+ type MRT_RowData,
5
+ type MRT_TableInstance,
6
+ } from '../types';
7
+ import {
8
+ getMRT_RowSelectionHandler,
9
+ getMRT_SelectAllHandler,
10
+ } from './row.utils';
11
+ import { parseFromValuesOrFunc } from './utils';
12
+
13
+ const isWinCtrlMacMeta = (event: React.KeyboardEvent<HTMLTableCellElement>) => {
14
+ return (
15
+ (event.ctrlKey && navigator.platform.toLowerCase().includes('win')) ||
16
+ (event.metaKey && navigator.platform.toLowerCase().includes('mac'))
17
+ );
18
+ };
19
+
20
+ export const isCellEditable = <TData extends MRT_RowData>({
21
+ cell,
22
+ table,
23
+ }: {
24
+ cell: MRT_Cell<TData>;
25
+ table: MRT_TableInstance<TData>;
26
+ }) => {
27
+ const { enableEditing } = table.options;
28
+ const {
29
+ column: { columnDef },
30
+ row,
31
+ } = cell;
32
+ return (
33
+ !cell.getIsPlaceholder() &&
34
+ parseFromValuesOrFunc(enableEditing, row) &&
35
+ parseFromValuesOrFunc(columnDef.enableEditing, row) !== false
36
+ );
37
+ };
38
+
39
+ export const openEditingCell = <TData extends MRT_RowData>({
40
+ cell,
41
+ table,
42
+ }: {
43
+ cell: MRT_Cell<TData>;
44
+ table: MRT_TableInstance<TData>;
45
+ }) => {
46
+ const {
47
+ options: { editDisplayMode },
48
+ refs: { editInputRefs },
49
+ } = table;
50
+ const { column } = cell;
51
+
52
+ if (isCellEditable({ cell, table }) && editDisplayMode === 'cell') {
53
+ table.setEditingCell(cell);
54
+ queueMicrotask(() => {
55
+ const textField = editInputRefs.current?.[column.id];
56
+ if (textField) {
57
+ textField.focus();
58
+ textField.select?.();
59
+ }
60
+ });
61
+ }
62
+ };
63
+
64
+ export const cellKeyboardShortcuts = <TData extends MRT_RowData = MRT_RowData>({
65
+ cell,
66
+ cellElements,
67
+ cellValue,
68
+ containerElement,
69
+ event,
70
+ header,
71
+ parentElement,
72
+ table,
73
+ }: {
74
+ cell?: MRT_Cell<TData>;
75
+ header?: MRT_Header<TData>;
76
+ cellElements?: Array<HTMLTableCellElement>;
77
+ cellValue?: string;
78
+ containerElement?: HTMLTableElement;
79
+ event: React.KeyboardEvent<HTMLTableCellElement>;
80
+ parentElement?: HTMLTableRowElement;
81
+ table: MRT_TableInstance<TData>;
82
+ }) => {
83
+ if (!table.options.enableKeyboardShortcuts) return;
84
+ if (event.isPropagationStopped()) return;
85
+ const currentCell = event.currentTarget;
86
+
87
+ if (cellValue && isWinCtrlMacMeta(event) && event.key === 'c') {
88
+ navigator.clipboard.writeText(cellValue);
89
+ } else if (['Enter', ' '].includes(event.key)) {
90
+ if (cell?.column?.id === 'mrt-row-select') {
91
+ event.preventDefault();
92
+ getMRT_RowSelectionHandler({
93
+ row: cell.row,
94
+ table,
95
+ //@ts-expect-error
96
+ staticRowIndex: +event.target.getAttribute('data-index'),
97
+ })(event as any);
98
+ } else if (
99
+ header?.column?.id === 'mrt-row-select' &&
100
+ table.options.enableSelectAll
101
+ ) {
102
+ event.preventDefault();
103
+ getMRT_SelectAllHandler({
104
+ table,
105
+ })(event as any);
106
+ } else if (
107
+ cell?.column?.id === 'mrt-row-expand' &&
108
+ (cell.row.getCanExpand() ||
109
+ table.options.renderDetailPanel?.({ row: cell.row, table }))
110
+ ) {
111
+ event.preventDefault();
112
+ cell.row.toggleExpanded();
113
+ } else if (
114
+ header?.column?.id === 'mrt-row-expand' &&
115
+ table.options.enableExpandAll
116
+ ) {
117
+ event.preventDefault();
118
+ table.toggleAllRowsExpanded();
119
+ } else if (cell?.column.id === 'mrt-row-pin') {
120
+ event.preventDefault();
121
+ cell.row.getIsPinned()
122
+ ? cell.row.pin(false)
123
+ : cell.row.pin(
124
+ table.options.rowPinningDisplayMode?.includes('bottom')
125
+ ? 'bottom'
126
+ : 'top',
127
+ );
128
+ } else if (header && isWinCtrlMacMeta(event)) {
129
+ const actionsButton = currentCell.querySelector(
130
+ `button[aria-label="${table.options.localization.columnActions}"]`,
131
+ );
132
+ if (actionsButton) {
133
+ (actionsButton as HTMLButtonElement).click();
134
+ }
135
+ } else if (header?.column?.getCanSort()) {
136
+ event.preventDefault();
137
+ header.column.toggleSorting();
138
+ }
139
+ } else if (
140
+ [
141
+ 'ArrowRight',
142
+ 'ArrowLeft',
143
+ 'ArrowUp',
144
+ 'ArrowDown',
145
+ 'Home',
146
+ 'End',
147
+ 'PageUp',
148
+ 'PageDown',
149
+ ].includes(event.key)
150
+ ) {
151
+ event.preventDefault();
152
+
153
+ const currentRow = parentElement || currentCell.closest('tr');
154
+ const tableElement = containerElement || currentCell.closest('table');
155
+ const allCells =
156
+ cellElements ||
157
+ Array.from(tableElement?.querySelectorAll('th, td') || []);
158
+ const currentCellIndex = allCells.indexOf(currentCell);
159
+
160
+ const currentIndex = parseInt(
161
+ currentCell.getAttribute('data-index') || '0',
162
+ );
163
+ let nextCell: HTMLElement | undefined = undefined;
164
+
165
+ //home/end first or last cell in row
166
+ const findEdgeCell = (rowIndex: 'c' | 'f' | 'l', edge: 'f' | 'l') => {
167
+ const row =
168
+ rowIndex === 'c'
169
+ ? currentRow
170
+ : rowIndex === 'f'
171
+ ? tableElement?.querySelector('tr')
172
+ : tableElement?.lastElementChild?.lastElementChild;
173
+ const rowCells = Array.from(row?.children || []);
174
+ const targetCell =
175
+ edge === 'f' ? rowCells[0] : rowCells[rowCells.length - 1];
176
+ return targetCell as HTMLElement;
177
+ };
178
+
179
+ //page up/down first or last cell in column
180
+ const findBottomTopCell = (columnIndex: number, edge: 'b' | 't') => {
181
+ const row =
182
+ edge === 't'
183
+ ? tableElement?.querySelector('tr')
184
+ : tableElement?.lastElementChild?.lastElementChild;
185
+ const rowCells = Array.from(row?.children || []);
186
+ const targetCell = rowCells[columnIndex];
187
+ return targetCell as HTMLElement;
188
+ };
189
+
190
+ const findAdjacentCell = (
191
+ columnIndex: number,
192
+ searchDirection: 'f' | 'b',
193
+ ) => {
194
+ const searchArray =
195
+ searchDirection === 'f'
196
+ ? allCells.slice(currentCellIndex + 1)
197
+ : allCells.slice(0, currentCellIndex).reverse();
198
+ return searchArray.find((cell) =>
199
+ cell.matches(`[data-index="${columnIndex}"]`),
200
+ ) as HTMLElement | undefined;
201
+ };
202
+
203
+ switch (event.key) {
204
+ case 'ArrowRight':
205
+ nextCell = findAdjacentCell(currentIndex + 1, 'f');
206
+ break;
207
+ case 'ArrowLeft':
208
+ nextCell = findAdjacentCell(currentIndex - 1, 'b');
209
+ break;
210
+ case 'ArrowUp':
211
+ nextCell = findAdjacentCell(currentIndex, 'b');
212
+ break;
213
+ case 'ArrowDown':
214
+ nextCell = findAdjacentCell(currentIndex, 'f');
215
+ break;
216
+ case 'Home':
217
+ nextCell = findEdgeCell(isWinCtrlMacMeta(event) ? 'f' : 'c', 'f');
218
+ break;
219
+ case 'End':
220
+ nextCell = findEdgeCell(isWinCtrlMacMeta(event) ? 'l' : 'c', 'l');
221
+ break;
222
+ case 'PageUp':
223
+ nextCell = findBottomTopCell(currentIndex, 't');
224
+ break;
225
+ case 'PageDown':
226
+ nextCell = findBottomTopCell(currentIndex, 'b');
227
+ break;
228
+ }
229
+
230
+ if (nextCell) {
231
+ nextCell.focus();
232
+ }
233
+ }
234
+ };
@@ -0,0 +1,209 @@
1
+ import { useMemo } from 'react';
2
+ import { type Row } from '@tanstack/react-table';
3
+ import {
4
+ type DropdownOption,
5
+ type MRT_Column,
6
+ type MRT_ColumnDef,
7
+ type MRT_ColumnOrderState,
8
+ type MRT_DefinedColumnDef,
9
+ type MRT_DefinedTableOptions,
10
+ type MRT_FilterOption,
11
+ type MRT_Header,
12
+ type MRT_RowData,
13
+ type MRT_TableInstance,
14
+ } from '../types';
15
+
16
+ export const getColumnId = <TData extends MRT_RowData>(
17
+ columnDef: MRT_ColumnDef<TData>,
18
+ ): string =>
19
+ columnDef.id ?? columnDef.accessorKey?.toString?.() ?? columnDef.header;
20
+
21
+ export const getAllLeafColumnDefs = <TData extends MRT_RowData>(
22
+ columns: MRT_ColumnDef<TData>[],
23
+ ): MRT_ColumnDef<TData>[] => {
24
+ const allLeafColumnDefs: MRT_ColumnDef<TData>[] = [];
25
+ const getLeafColumns = (cols: MRT_ColumnDef<TData>[]) => {
26
+ cols.forEach((col) => {
27
+ if (col.columns) {
28
+ getLeafColumns(col.columns);
29
+ } else {
30
+ allLeafColumnDefs.push(col);
31
+ }
32
+ });
33
+ };
34
+ getLeafColumns(columns);
35
+ return allLeafColumnDefs;
36
+ };
37
+
38
+ export const prepareColumns = <TData extends MRT_RowData>({
39
+ columnDefs,
40
+ tableOptions,
41
+ }: {
42
+ columnDefs: MRT_ColumnDef<TData>[];
43
+ tableOptions: MRT_DefinedTableOptions<TData>;
44
+ }): MRT_DefinedColumnDef<TData>[] => {
45
+ const {
46
+ aggregationFns = {},
47
+ defaultDisplayColumn,
48
+ filterFns = {},
49
+ sortingFns = {},
50
+ state: { columnFilterFns = {} } = {},
51
+ } = tableOptions;
52
+ return columnDefs.map((columnDef) => {
53
+ //assign columnId
54
+ if (!columnDef.id) columnDef.id = getColumnId(columnDef);
55
+ //assign columnDefType
56
+ if (!columnDef.columnDefType) columnDef.columnDefType = 'data';
57
+ if (columnDef.columns?.length) {
58
+ columnDef.columnDefType = 'group';
59
+ //recursively prepare columns if this is a group column
60
+ columnDef.columns = prepareColumns({
61
+ columnDefs: columnDef.columns,
62
+ tableOptions,
63
+ });
64
+ } else if (columnDef.columnDefType === 'data') {
65
+ //assign aggregationFns if multiple aggregationFns are provided
66
+ if (Array.isArray(columnDef.aggregationFn)) {
67
+ const aggFns = columnDef.aggregationFn as string[];
68
+ columnDef.aggregationFn = (
69
+ columnId: string,
70
+ leafRows: Row<TData>[],
71
+ childRows: Row<TData>[],
72
+ ) =>
73
+ aggFns.map((fn) =>
74
+ aggregationFns[fn]?.(columnId, leafRows, childRows),
75
+ );
76
+ }
77
+
78
+ //assign filterFns
79
+ if (Object.keys(filterFns).includes(columnFilterFns[columnDef.id])) {
80
+ columnDef.filterFn =
81
+ filterFns[columnFilterFns[columnDef.id]] ?? filterFns.fuzzy;
82
+ (columnDef as MRT_DefinedColumnDef<TData>)._filterFn =
83
+ columnFilterFns[columnDef.id];
84
+ }
85
+
86
+ //assign sortingFns
87
+ if (Object.keys(sortingFns).includes(columnDef.sortingFn as string)) {
88
+ // @ts-expect-error
89
+ columnDef.sortingFn = sortingFns[columnDef.sortingFn];
90
+ }
91
+ } else if (columnDef.columnDefType === 'display') {
92
+ columnDef = {
93
+ ...(defaultDisplayColumn as MRT_ColumnDef<TData>),
94
+ ...columnDef,
95
+ };
96
+ }
97
+ return columnDef;
98
+ }) as MRT_DefinedColumnDef<TData>[];
99
+ };
100
+
101
+ export const reorderColumn = <TData extends MRT_RowData>(
102
+ draggedColumn: MRT_Column<TData>,
103
+ targetColumn: MRT_Column<TData>,
104
+ columnOrder: MRT_ColumnOrderState,
105
+ ): MRT_ColumnOrderState => {
106
+ if (draggedColumn.getCanPin()) {
107
+ draggedColumn.pin(targetColumn.getIsPinned());
108
+ }
109
+ const newColumnOrder = [...columnOrder];
110
+ newColumnOrder.splice(
111
+ newColumnOrder.indexOf(targetColumn.id),
112
+ 0,
113
+ newColumnOrder.splice(newColumnOrder.indexOf(draggedColumn.id), 1)[0],
114
+ );
115
+ return newColumnOrder;
116
+ };
117
+
118
+ export const getDefaultColumnFilterFn = <TData extends MRT_RowData>(
119
+ columnDef: MRT_ColumnDef<TData>,
120
+ ): MRT_FilterOption => {
121
+ const { filterVariant } = columnDef;
122
+ if (filterVariant === 'multi-select') return 'arrIncludesSome';
123
+ if (filterVariant?.includes('range')) return 'betweenInclusive';
124
+ if (filterVariant === 'select' || filterVariant === 'checkbox')
125
+ return 'equals';
126
+ return 'fuzzy';
127
+ };
128
+
129
+ export const getColumnFilterInfo = <TData extends MRT_RowData>({
130
+ header,
131
+ table,
132
+ }: {
133
+ header: MRT_Header<TData>;
134
+ table: MRT_TableInstance<TData>;
135
+ }) => {
136
+ const {
137
+ options: { columnFilterModeOptions },
138
+ } = table;
139
+ const { column } = header;
140
+ const { columnDef } = column;
141
+ const { filterVariant } = columnDef;
142
+
143
+ const isDateFilter = !!(
144
+ filterVariant?.startsWith('date') || filterVariant?.startsWith('time')
145
+ );
146
+ const isAutocompleteFilter = filterVariant === 'autocomplete';
147
+ const isRangeFilter =
148
+ filterVariant?.includes('range') ||
149
+ ['between', 'betweenInclusive', 'inNumberRange'].includes(
150
+ columnDef._filterFn,
151
+ );
152
+ const isSelectFilter = filterVariant === 'select';
153
+ const isMultiSelectFilter = filterVariant === 'multi-select';
154
+ const isTextboxFilter =
155
+ ['autocomplete', 'text'].includes(filterVariant!) ||
156
+ (!isSelectFilter && !isMultiSelectFilter);
157
+ const currentFilterOption = columnDef._filterFn;
158
+
159
+ const allowedColumnFilterOptions =
160
+ columnDef?.columnFilterModeOptions ?? columnFilterModeOptions;
161
+
162
+ const facetedUniqueValues = column.getFacetedUniqueValues();
163
+
164
+ return {
165
+ allowedColumnFilterOptions,
166
+ currentFilterOption,
167
+ facetedUniqueValues,
168
+ isAutocompleteFilter,
169
+ isDateFilter,
170
+ isMultiSelectFilter,
171
+ isRangeFilter,
172
+ isSelectFilter,
173
+ isTextboxFilter,
174
+ } as const;
175
+ };
176
+
177
+ export const useDropdownOptions = <TData extends MRT_RowData>({
178
+ header,
179
+ table,
180
+ }: {
181
+ header: MRT_Header<TData>;
182
+ table: MRT_TableInstance<TData>;
183
+ }): DropdownOption[] | undefined => {
184
+ const { column } = header;
185
+ const { columnDef } = column;
186
+ const {
187
+ facetedUniqueValues,
188
+ isAutocompleteFilter,
189
+ isMultiSelectFilter,
190
+ isSelectFilter,
191
+ } = getColumnFilterInfo({ header, table });
192
+
193
+ return useMemo<DropdownOption[] | undefined>(
194
+ () =>
195
+ columnDef.filterSelectOptions ??
196
+ ((isSelectFilter || isMultiSelectFilter || isAutocompleteFilter) &&
197
+ facetedUniqueValues
198
+ ? Array.from(facetedUniqueValues.keys())
199
+ .filter((value) => value !== null && value !== undefined)
200
+ .sort((a, b) => a.localeCompare(b))
201
+ : undefined),
202
+ [
203
+ columnDef.filterSelectOptions,
204
+ facetedUniqueValues,
205
+ isMultiSelectFilter,
206
+ isSelectFilter,
207
+ ],
208
+ );
209
+ };
@@ -0,0 +1,152 @@
1
+ import {
2
+ type MRT_DefinedTableOptions,
3
+ type MRT_DisplayColumnIds,
4
+ type MRT_Localization,
5
+ type MRT_RowData,
6
+ type MRT_StatefulTableOptions,
7
+ } from '../types';
8
+ import { getAllLeafColumnDefs, getColumnId } from './column.utils';
9
+
10
+ export function defaultDisplayColumnProps<TData extends MRT_RowData>({
11
+ header,
12
+ id,
13
+ size,
14
+ tableOptions,
15
+ }: {
16
+ header?: keyof MRT_Localization;
17
+ id: MRT_DisplayColumnIds;
18
+ size: number;
19
+ tableOptions: MRT_DefinedTableOptions<TData>;
20
+ }) {
21
+ const { defaultDisplayColumn, displayColumnDefOptions, localization } =
22
+ tableOptions;
23
+ return {
24
+ ...defaultDisplayColumn,
25
+ header: header ? localization[header]! : '',
26
+ size,
27
+ ...displayColumnDefOptions?.[id],
28
+ id,
29
+ } as const;
30
+ }
31
+
32
+ export const showRowPinningColumn = <TData extends MRT_RowData>(
33
+ tableOptions: MRT_StatefulTableOptions<TData>,
34
+ ): boolean => {
35
+ const { enableRowPinning, rowPinningDisplayMode } = tableOptions;
36
+ return !!(enableRowPinning && !rowPinningDisplayMode?.startsWith('select'));
37
+ };
38
+
39
+ export const showRowDragColumn = <TData extends MRT_RowData>(
40
+ tableOptions: MRT_StatefulTableOptions<TData>,
41
+ ): boolean => {
42
+ const { enableRowDragging, enableRowOrdering } = tableOptions;
43
+ return !!(enableRowDragging || enableRowOrdering);
44
+ };
45
+
46
+ export const showRowExpandColumn = <TData extends MRT_RowData>(
47
+ tableOptions: MRT_StatefulTableOptions<TData>,
48
+ ): boolean => {
49
+ const {
50
+ enableExpanding,
51
+ enableGrouping,
52
+ renderDetailPanel,
53
+ state: { grouping },
54
+ } = tableOptions;
55
+ return !!(
56
+ enableExpanding ||
57
+ (enableGrouping && grouping?.length) ||
58
+ renderDetailPanel
59
+ );
60
+ };
61
+
62
+ export const showRowActionsColumn = <TData extends MRT_RowData>(
63
+ tableOptions: MRT_StatefulTableOptions<TData>,
64
+ ): boolean => {
65
+ const {
66
+ createDisplayMode,
67
+ editDisplayMode,
68
+ enableEditing,
69
+ enableRowActions,
70
+ state: { creatingRow },
71
+ } = tableOptions;
72
+ return !!(
73
+ enableRowActions ||
74
+ (creatingRow && createDisplayMode === 'row') ||
75
+ (enableEditing && ['modal', 'row'].includes(editDisplayMode ?? ''))
76
+ );
77
+ };
78
+
79
+ export const showRowSelectionColumn = <TData extends MRT_RowData>(
80
+ tableOptions: MRT_StatefulTableOptions<TData>,
81
+ ): boolean => !!tableOptions.enableRowSelection;
82
+
83
+ export const showRowNumbersColumn = <TData extends MRT_RowData>(
84
+ tableOptions: MRT_StatefulTableOptions<TData>,
85
+ ): boolean => !!tableOptions.enableRowNumbers;
86
+
87
+ export const showRowSpacerColumn = <TData extends MRT_RowData>(
88
+ tableOptions: MRT_StatefulTableOptions<TData>,
89
+ ): boolean => tableOptions.layoutMode === 'grid-no-grow';
90
+
91
+ export const getLeadingDisplayColumnIds = <TData extends MRT_RowData>(
92
+ tableOptions: MRT_StatefulTableOptions<TData>,
93
+ ) =>
94
+ [
95
+ showRowPinningColumn(tableOptions) && 'mrt-row-pin',
96
+ showRowDragColumn(tableOptions) && 'mrt-row-drag',
97
+ tableOptions.positionActionsColumn === 'first' &&
98
+ showRowActionsColumn(tableOptions) &&
99
+ 'mrt-row-actions',
100
+ tableOptions.positionExpandColumn === 'first' &&
101
+ showRowExpandColumn(tableOptions) &&
102
+ 'mrt-row-expand',
103
+ showRowSelectionColumn(tableOptions) && 'mrt-row-select',
104
+ showRowNumbersColumn(tableOptions) && 'mrt-row-numbers',
105
+ ].filter(Boolean) as MRT_DisplayColumnIds[];
106
+
107
+ export const getTrailingDisplayColumnIds = <TData extends MRT_RowData>(
108
+ tableOptions: MRT_StatefulTableOptions<TData>,
109
+ ) =>
110
+ [
111
+ tableOptions.positionActionsColumn === 'last' &&
112
+ showRowActionsColumn(tableOptions) &&
113
+ 'mrt-row-actions',
114
+ tableOptions.positionExpandColumn === 'last' &&
115
+ showRowExpandColumn(tableOptions) &&
116
+ 'mrt-row-expand',
117
+ showRowSpacerColumn(tableOptions) && 'mrt-row-spacer',
118
+ ].filter(Boolean) as MRT_DisplayColumnIds[];
119
+
120
+ export const getDefaultColumnOrderIds = <TData extends MRT_RowData>(
121
+ tableOptions: MRT_StatefulTableOptions<TData>,
122
+ reset = false,
123
+ ) => {
124
+ const {
125
+ state: { columnOrder: currentColumnOrderIds = [] },
126
+ } = tableOptions;
127
+
128
+ const leadingDisplayColIds: string[] =
129
+ getLeadingDisplayColumnIds(tableOptions);
130
+ const trailingDisplayColIds: string[] =
131
+ getTrailingDisplayColumnIds(tableOptions);
132
+
133
+ const defaultColumnDefIds = getAllLeafColumnDefs(tableOptions.columns).map(
134
+ (columnDef) => getColumnId(columnDef),
135
+ );
136
+
137
+ let allLeafColumnDefIds = reset
138
+ ? defaultColumnDefIds
139
+ : Array.from(new Set([...currentColumnOrderIds, ...defaultColumnDefIds]));
140
+
141
+ allLeafColumnDefIds = allLeafColumnDefIds.filter(
142
+ (colId) =>
143
+ !leadingDisplayColIds.includes(colId) &&
144
+ !trailingDisplayColIds.includes(colId),
145
+ );
146
+
147
+ return [
148
+ ...leadingDisplayColIds,
149
+ ...allLeafColumnDefIds,
150
+ ...trailingDisplayColIds,
151
+ ];
152
+ };