material-react-table 1.4.3 → 1.5.0-beta.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 (41) hide show
  1. package/dist/cjs/index.js +167 -61
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/MaterialReactTable.d.ts +18 -5
  4. package/dist/cjs/types/body/MRT_TableBody.d.ts +5 -0
  5. package/dist/cjs/types/body/MRT_TableBodyCell.d.ts +3 -0
  6. package/dist/cjs/types/body/MRT_TableBodyRow.d.ts +5 -1
  7. package/dist/cjs/types/footer/MRT_TableFooter.d.ts +4 -0
  8. package/dist/cjs/types/footer/MRT_TableFooterRow.d.ts +4 -0
  9. package/dist/cjs/types/head/MRT_TableHead.d.ts +4 -0
  10. package/dist/cjs/types/head/MRT_TableHeadRow.d.ts +4 -0
  11. package/dist/cjs/types/table/MRT_TableRoot.d.ts +12 -5
  12. package/dist/cjs/types/toolbar/MRT_TablePagination.d.ts +1 -1
  13. package/dist/esm/material-react-table.esm.js +163 -57
  14. package/dist/esm/material-react-table.esm.js.map +1 -1
  15. package/dist/esm/types/MaterialReactTable.d.ts +18 -5
  16. package/dist/esm/types/body/MRT_TableBody.d.ts +5 -0
  17. package/dist/esm/types/body/MRT_TableBodyCell.d.ts +3 -0
  18. package/dist/esm/types/body/MRT_TableBodyRow.d.ts +5 -1
  19. package/dist/esm/types/footer/MRT_TableFooter.d.ts +4 -0
  20. package/dist/esm/types/footer/MRT_TableFooterRow.d.ts +4 -0
  21. package/dist/esm/types/head/MRT_TableHead.d.ts +4 -0
  22. package/dist/esm/types/head/MRT_TableHeadRow.d.ts +4 -0
  23. package/dist/esm/types/table/MRT_TableRoot.d.ts +12 -5
  24. package/dist/esm/types/toolbar/MRT_TablePagination.d.ts +1 -1
  25. package/dist/index.d.ts +20 -7
  26. package/locales/ru.esm.js +1 -1
  27. package/locales/ru.js +1 -1
  28. package/package.json +1 -1
  29. package/src/MaterialReactTable.tsx +30 -8
  30. package/src/_locales/ru.ts +1 -1
  31. package/src/body/MRT_TableBody.tsx +42 -13
  32. package/src/body/MRT_TableBodyCell.tsx +17 -1
  33. package/src/body/MRT_TableBodyRow.tsx +24 -3
  34. package/src/footer/MRT_TableFooter.tsx +13 -1
  35. package/src/footer/MRT_TableFooterCell.tsx +10 -2
  36. package/src/footer/MRT_TableFooterRow.tsx +31 -4
  37. package/src/head/MRT_TableHead.tsx +13 -1
  38. package/src/head/MRT_TableHeadCell.tsx +6 -3
  39. package/src/head/MRT_TableHeadRow.tsx +30 -4
  40. package/src/table/MRT_Table.tsx +105 -7
  41. package/src/toolbar/MRT_TablePagination.tsx +2 -2
@@ -2,13 +2,22 @@ import React, { FC } from 'react';
2
2
  import TableFooter from '@mui/material/TableFooter';
3
3
  import { lighten } from '@mui/material/styles';
4
4
  import { MRT_TableFooterRow } from './MRT_TableFooterRow';
5
+ import type { VirtualItem } from '@tanstack/react-virtual';
5
6
  import type { MRT_TableInstance } from '..';
6
7
 
7
8
  interface Props {
8
9
  table: MRT_TableInstance;
10
+ virtualColumns?: VirtualItem[];
11
+ virtualPaddingLeft?: number;
12
+ virtualPaddingRight?: number;
9
13
  }
10
14
 
11
- export const MRT_TableFooter: FC<Props> = ({ table }) => {
15
+ export const MRT_TableFooter: FC<Props> = ({
16
+ table,
17
+ virtualColumns,
18
+ virtualPaddingLeft,
19
+ virtualPaddingRight,
20
+ }) => {
12
21
  const {
13
22
  getFooterGroups,
14
23
  getState,
@@ -48,6 +57,9 @@ export const MRT_TableFooter: FC<Props> = ({ table }) => {
48
57
  footerGroup={footerGroup as any}
49
58
  key={footerGroup.id}
50
59
  table={table}
60
+ virtualColumns={virtualColumns}
61
+ virtualPaddingLeft={virtualPaddingLeft}
62
+ virtualPaddingRight={virtualPaddingRight}
51
63
  />
52
64
  ))}
53
65
  </TableFooter>
@@ -8,7 +8,10 @@ interface Props {
8
8
  table: MRT_TableInstance;
9
9
  }
10
10
 
11
- export const MRT_TableFooterCell: FC<Props> = ({ footer, table }) => {
11
+ export const MRT_TableFooterCell: FC<Props> = ({
12
+ footer,
13
+ table,
14
+ }) => {
12
15
  const {
13
16
  getState,
14
17
  options: { layoutMode, muiTableFooterCellProps },
@@ -51,7 +54,12 @@ export const MRT_TableFooterCell: FC<Props> = ({ footer, table }) => {
51
54
  : '1.5rem',
52
55
  verticalAlign: 'top',
53
56
  zIndex: column.getIsPinned() && columnDefType !== 'group' ? 2 : 1,
54
- ...getCommonCellStyles({ column, table, theme, tableCellProps }),
57
+ ...getCommonCellStyles({
58
+ column,
59
+ table,
60
+ theme,
61
+ tableCellProps,
62
+ }),
55
63
  })}
56
64
  >
57
65
  <>
@@ -1,14 +1,24 @@
1
1
  import React, { FC } from 'react';
2
2
  import TableRow from '@mui/material/TableRow';
3
3
  import { MRT_TableFooterCell } from './MRT_TableFooterCell';
4
+ import { VirtualItem } from '@tanstack/react-virtual';
4
5
  import type { MRT_Header, MRT_HeaderGroup, MRT_TableInstance } from '..';
5
6
 
6
7
  interface Props {
7
8
  footerGroup: MRT_HeaderGroup;
8
9
  table: MRT_TableInstance;
10
+ virtualColumns?: VirtualItem[];
11
+ virtualPaddingLeft?: number;
12
+ virtualPaddingRight?: number;
9
13
  }
10
14
 
11
- export const MRT_TableFooterRow: FC<Props> = ({ footerGroup, table }) => {
15
+ export const MRT_TableFooterRow: FC<Props> = ({
16
+ footerGroup,
17
+ table,
18
+ virtualColumns,
19
+ virtualPaddingLeft,
20
+ virtualPaddingRight,
21
+ }) => {
12
22
  const {
13
23
  options: { layoutMode, muiTableFooterRowProps },
14
24
  } = table;
@@ -34,14 +44,31 @@ export const MRT_TableFooterRow: FC<Props> = ({ footerGroup, table }) => {
34
44
  {...tableRowProps}
35
45
  sx={(theme) => ({
36
46
  display: layoutMode === 'grid' ? 'flex' : 'table-row',
47
+ width: '100%',
37
48
  ...(tableRowProps?.sx instanceof Function
38
49
  ? tableRowProps?.sx(theme)
39
50
  : (tableRowProps?.sx as any)),
40
51
  })}
41
52
  >
42
- {footerGroup.headers.map((footer: MRT_Header) => (
43
- <MRT_TableFooterCell footer={footer} key={footer.id} table={table} />
44
- ))}
53
+ {virtualPaddingLeft ? (
54
+ <th style={{ display: 'flex', width: virtualPaddingLeft }} />
55
+ ) : null}
56
+ {(virtualColumns ?? footerGroup.headers).map((footerOrVirtualFooter) => {
57
+ const footer = virtualColumns
58
+ ? footerGroup.headers[footerOrVirtualFooter.index]
59
+ : (footerOrVirtualFooter as MRT_Header);
60
+
61
+ return (
62
+ <MRT_TableFooterCell
63
+ footer={footer}
64
+ key={footer.id}
65
+ table={table}
66
+ />
67
+ );
68
+ })}
69
+ {virtualPaddingRight ? (
70
+ <th style={{ display: 'flex', width: virtualPaddingRight }} />
71
+ ) : null}
45
72
  </TableRow>
46
73
  );
47
74
  };
@@ -1,13 +1,22 @@
1
1
  import React, { FC } from 'react';
2
2
  import TableHead from '@mui/material/TableHead';
3
3
  import { MRT_TableHeadRow } from './MRT_TableHeadRow';
4
+ import type { VirtualItem } from '@tanstack/react-virtual';
4
5
  import type { MRT_TableInstance } from '..';
5
6
 
6
7
  interface Props {
7
8
  table: MRT_TableInstance;
9
+ virtualColumns?: VirtualItem[];
10
+ virtualPaddingLeft?: number;
11
+ virtualPaddingRight?: number;
8
12
  }
9
13
 
10
- export const MRT_TableHead: FC<Props> = ({ table }) => {
14
+ export const MRT_TableHead: FC<Props> = ({
15
+ table,
16
+ virtualColumns,
17
+ virtualPaddingLeft,
18
+ virtualPaddingRight,
19
+ }) => {
11
20
  const {
12
21
  getHeaderGroups,
13
22
  getState,
@@ -41,6 +50,9 @@ export const MRT_TableHead: FC<Props> = ({ table }) => {
41
50
  headerGroup={headerGroup as any}
42
51
  key={headerGroup.id}
43
52
  table={table}
53
+ virtualColumns={virtualColumns}
54
+ virtualPaddingLeft={virtualPaddingLeft}
55
+ virtualPaddingRight={virtualPaddingRight}
44
56
  />
45
57
  ))}
46
58
  </TableHead>
@@ -17,7 +17,10 @@ interface Props {
17
17
  table: MRT_TableInstance;
18
18
  }
19
19
 
20
- export const MRT_TableHeadCell: FC<Props> = ({ header, table }) => {
20
+ export const MRT_TableHeadCell: FC<Props> = ({
21
+ header,
22
+ table,
23
+ }) => {
21
24
  const theme = useTheme();
22
25
  const {
23
26
  getState,
@@ -123,9 +126,9 @@ export const MRT_TableHeadCell: FC<Props> = ({ header, table }) => {
123
126
  align={columnDefType === 'group' ? 'center' : 'left'}
124
127
  colSpan={header.colSpan}
125
128
  onDragEnter={handleDragEnter}
126
- ref={(node) => {
129
+ ref={(node: HTMLTableCellElement) => {
127
130
  if (node) {
128
- tableHeadCellRefs.current[column.id] = node as HTMLTableCellElement;
131
+ tableHeadCellRefs.current[column.id] = node;
129
132
  }
130
133
  }}
131
134
  {...tableCellProps}
@@ -2,14 +2,24 @@ import React, { FC } from 'react';
2
2
  import TableRow from '@mui/material/TableRow';
3
3
  import { alpha, lighten } from '@mui/material/styles';
4
4
  import { MRT_TableHeadCell } from './MRT_TableHeadCell';
5
+ import type { VirtualItem } from '@tanstack/react-virtual';
5
6
  import type { MRT_Header, MRT_HeaderGroup, MRT_TableInstance } from '..';
6
7
 
7
8
  interface Props {
8
9
  headerGroup: MRT_HeaderGroup;
9
10
  table: MRT_TableInstance;
11
+ virtualColumns?: VirtualItem[];
12
+ virtualPaddingLeft?: number;
13
+ virtualPaddingRight?: number;
10
14
  }
11
15
 
12
- export const MRT_TableHeadRow: FC<Props> = ({ headerGroup, table }) => {
16
+ export const MRT_TableHeadRow: FC<Props> = ({
17
+ headerGroup,
18
+ table,
19
+ virtualColumns,
20
+ virtualPaddingLeft,
21
+ virtualPaddingRight,
22
+ }) => {
13
23
  const {
14
24
  options: { layoutMode, muiTableHeadRowProps },
15
25
  } = table;
@@ -32,9 +42,25 @@ export const MRT_TableHeadRow: FC<Props> = ({ headerGroup, table }) => {
32
42
  : (tableRowProps?.sx as any)),
33
43
  })}
34
44
  >
35
- {headerGroup.headers.map((header: MRT_Header) => (
36
- <MRT_TableHeadCell header={header} key={header.id} table={table} />
37
- ))}
45
+ {virtualPaddingLeft ? (
46
+ <th style={{ display: 'flex', width: virtualPaddingLeft }} />
47
+ ) : null}
48
+ {(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader) => {
49
+ const header = virtualColumns
50
+ ? headerGroup.headers[headerOrVirtualHeader.index]
51
+ : (headerOrVirtualHeader as MRT_Header);
52
+
53
+ return (
54
+ <MRT_TableHeadCell
55
+ header={header}
56
+ key={header.id}
57
+ table={table}
58
+ />
59
+ );
60
+ })}
61
+ {virtualPaddingRight ? (
62
+ <th style={{ display: 'flex', width: virtualPaddingRight }} />
63
+ ) : null}
38
64
  </TableRow>
39
65
  );
40
66
  };
@@ -1,4 +1,10 @@
1
- import React, { FC } from 'react';
1
+ import React, { FC, useCallback, useMemo } from 'react';
2
+ import {
3
+ defaultRangeExtractor,
4
+ Range,
5
+ useVirtualizer,
6
+ Virtualizer,
7
+ } from '@tanstack/react-virtual';
2
8
  import Table from '@mui/material/Table';
3
9
  import { MRT_TableHead } from '../head/MRT_TableHead';
4
10
  import { Memo_MRT_TableBody, MRT_TableBody } from '../body/MRT_TableBody';
@@ -13,7 +19,11 @@ export const MRT_Table: FC<Props> = ({ table }) => {
13
19
  const {
14
20
  getState,
15
21
  options: {
22
+ columnVirtualizerInstanceRef,
23
+ columnVirtualizerProps,
16
24
  enableColumnResizing,
25
+ enableColumnVirtualization,
26
+ enablePinning,
17
27
  enableStickyHeader,
18
28
  enableTableFooter,
19
29
  enableTableHead,
@@ -21,33 +31,121 @@ export const MRT_Table: FC<Props> = ({ table }) => {
21
31
  memoMode,
22
32
  muiTableProps,
23
33
  },
34
+ refs: { tableContainerRef },
24
35
  } = table;
25
- const { isFullScreen } = getState();
36
+ const { isFullScreen, columnPinning, columnVisibility } = getState();
26
37
 
27
38
  const tableProps =
28
39
  muiTableProps instanceof Function
29
40
  ? muiTableProps({ table })
30
41
  : muiTableProps;
31
42
 
43
+ const vProps =
44
+ columnVirtualizerProps instanceof Function
45
+ ? columnVirtualizerProps({ table })
46
+ : columnVirtualizerProps;
47
+
48
+ //get first 16 column widths and average them
49
+ const averageColumnWidth = useMemo(() => {
50
+ const columnsWidths =
51
+ table
52
+ .getRowModel()
53
+ .rows[0]?.getCenterVisibleCells()
54
+ ?.slice(0, 16)
55
+ ?.map((cell) => cell.column.getSize() * 1.25) ?? [];
56
+ return columnsWidths.reduce((a, b) => a + b, 0) / columnsWidths.length;
57
+ }, [table.getRowModel().rows, columnPinning, columnVisibility]);
58
+
59
+ const pinnedColumnIndexes = useMemo(
60
+ () =>
61
+ enableColumnVirtualization && enablePinning
62
+ ? [
63
+ ...table.getLeftFlatHeaders().map((h) => h.column.getPinnedIndex()),
64
+ ...table
65
+ .getRightFlatHeaders()
66
+ .map(
67
+ (h) =>
68
+ table.getVisibleFlatColumns().length -
69
+ h.column.getPinnedIndex() -
70
+ 1,
71
+ ),
72
+ ]
73
+ : [],
74
+ [columnPinning, enableColumnVirtualization, enablePinning],
75
+ );
76
+
77
+ const columnVirtualizer:
78
+ | Virtualizer<HTMLDivElement, HTMLTableCellElement>
79
+ | undefined = enableColumnVirtualization
80
+ ? useVirtualizer({
81
+ count: table.getRowModel().rows[0].getVisibleCells().length,
82
+ estimateSize: () => averageColumnWidth,
83
+ getScrollElement: () => tableContainerRef.current,
84
+ horizontal: true,
85
+ measureElement: (element) => element?.getBoundingClientRect().width,
86
+ overscan: 3,
87
+ rangeExtractor: useCallback(
88
+ (range: Range) =>
89
+ [
90
+ ...new Set([
91
+ ...pinnedColumnIndexes,
92
+ ...defaultRangeExtractor(range),
93
+ ]),
94
+ ].sort((a, b) => a - b),
95
+ [pinnedColumnIndexes],
96
+ ),
97
+ ...vProps,
98
+ })
99
+ : undefined;
100
+
101
+ if (columnVirtualizerInstanceRef && columnVirtualizer) {
102
+ columnVirtualizerInstanceRef.current = columnVirtualizer;
103
+ }
104
+
105
+ const virtualColumns = columnVirtualizer
106
+ ? columnVirtualizer.getVirtualItems()
107
+ : undefined;
108
+
109
+ let virtualPaddingLeft: number | undefined;
110
+ let virtualPaddingRight: number | undefined;
111
+
112
+ if (columnVirtualizer && virtualColumns?.length) {
113
+ virtualPaddingLeft = virtualColumns?.length
114
+ ? virtualColumns[0]?.start || 0
115
+ : 0;
116
+ virtualPaddingRight = virtualColumns?.length
117
+ ? columnVirtualizer.getTotalSize() -
118
+ (virtualColumns[virtualColumns.length - 1]?.end || 0)
119
+ : 0;
120
+ }
121
+
122
+ const props = {
123
+ table,
124
+ virtualColumns,
125
+ virtualPaddingLeft,
126
+ virtualPaddingRight,
127
+ };
128
+
32
129
  return (
33
130
  <Table
34
131
  stickyHeader={enableStickyHeader || isFullScreen}
35
132
  {...tableProps}
36
133
  sx={(theme) => ({
37
134
  display: layoutMode === 'grid' ? 'grid' : 'table',
38
- tableLayout: enableColumnResizing ? 'fixed' : 'auto',
135
+ tableLayout:
136
+ layoutMode !== 'grid' && enableColumnResizing ? 'fixed' : undefined,
39
137
  ...(tableProps?.sx instanceof Function
40
138
  ? tableProps.sx(theme)
41
139
  : (tableProps?.sx as any)),
42
140
  })}
43
141
  >
44
- {enableTableHead && <MRT_TableHead table={table} />}
142
+ {enableTableHead && <MRT_TableHead {...props} />}
45
143
  {memoMode === 'table-body' ? (
46
- <Memo_MRT_TableBody table={table} />
144
+ <Memo_MRT_TableBody columnVirtualizer={columnVirtualizer} {...props} />
47
145
  ) : (
48
- <MRT_TableBody table={table} />
146
+ <MRT_TableBody columnVirtualizer={columnVirtualizer} {...props} />
49
147
  )}
50
- {enableTableFooter && <MRT_TableFooter table={table} />}
148
+ {enableTableFooter && <MRT_TableFooter {...props} />}
51
149
  </Table>
52
150
  );
53
151
  };
@@ -3,13 +3,13 @@ import TablePagination from '@mui/material/TablePagination';
3
3
  import { MRT_TableInstance } from '..';
4
4
 
5
5
  interface Props<TData extends Record<string, any> = {}> {
6
- position: 'top' | 'bottom';
6
+ position?: 'top' | 'bottom';
7
7
  table: MRT_TableInstance<TData>;
8
8
  }
9
9
 
10
10
  export const MRT_TablePagination = <TData extends Record<string, any> = {}>({
11
11
  table,
12
- position,
12
+ position = 'bottom',
13
13
  }: Props<TData>) => {
14
14
  const {
15
15
  getPrePaginationRowModel,