material-react-table 3.0.0-alpha.0 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -246,6 +246,7 @@ export interface MRT_Localization {
246
246
 
247
247
  export interface MRT_Theme {
248
248
  baseBackgroundColor: string;
249
+ cellNavigationOutlineColor: string;
249
250
  draggingBorderColor: string;
250
251
  matchHighlightColor: string;
251
252
  menuBackgroundColor: string;
@@ -270,6 +271,7 @@ export type MRT_TableInstance<TData extends MRT_RowData> = Omit<
270
271
  | 'getColumn'
271
272
  | 'getExpandedRowModel'
272
273
  | 'getFlatHeaders'
274
+ | 'getFooterGroups'
273
275
  | 'getHeaderGroups'
274
276
  | 'getLeafHeaders'
275
277
  | 'getLeftLeafColumns'
@@ -292,6 +294,7 @@ export type MRT_TableInstance<TData extends MRT_RowData> = Omit<
292
294
  getColumn: (columnId: string) => MRT_Column<TData>;
293
295
  getExpandedRowModel: () => MRT_RowModel<TData>;
294
296
  getFlatHeaders: () => MRT_Header<TData>[];
297
+ getFooterGroups: () => MRT_HeaderGroup<TData>[];
295
298
  getHeaderGroups: () => MRT_HeaderGroup<TData>[];
296
299
  getLeafHeaders: () => MRT_Header<TData>[];
297
300
  getLeftLeafColumns: () => MRT_Column<TData>[];
@@ -810,9 +813,7 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
810
813
  columnFilterModeOptions?: Array<
811
814
  LiteralUnion<string & MRT_FilterOption>
812
815
  > | null;
813
- columnVirtualizerInstanceRef?: MutableRefObject<
814
- MRT_ColumnVirtualizer | null
815
- >;
816
+ columnVirtualizerInstanceRef?: MutableRefObject<MRT_ColumnVirtualizer | null>;
816
817
  columnVirtualizerOptions?:
817
818
  | ((props: {
818
819
  table: MRT_TableInstance<TData>;
@@ -869,6 +870,7 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
869
870
  enableFullScreenToggle?: boolean;
870
871
  enableGlobalFilterModes?: boolean;
871
872
  enableGlobalFilterRankedResults?: boolean;
873
+ enableCellNavigation?: boolean;
872
874
  enablePagination?: boolean;
873
875
  enableRowActions?: boolean;
874
876
  enableRowDragging?: boolean;
@@ -920,18 +922,27 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
920
922
  table: MRT_TableInstance<TData>;
921
923
  }) => CircularProgressProps & { Component?: ReactNode })
922
924
  | (CircularProgressProps & { Component?: ReactNode });
925
+ /**
926
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
927
+ */
923
928
  muiColumnActionsButtonProps?:
924
929
  | ((props: {
925
930
  column: MRT_Column<TData>;
926
931
  table: MRT_TableInstance<TData>;
927
932
  }) => IconButtonProps)
928
933
  | IconButtonProps;
934
+ /**
935
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
936
+ */
929
937
  muiColumnDragHandleProps?:
930
938
  | ((props: {
931
939
  column: MRT_Column<TData>;
932
940
  table: MRT_TableInstance<TData>;
933
941
  }) => IconButtonProps)
934
942
  | IconButtonProps;
943
+ /**
944
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
945
+ */
935
946
  muiCopyButtonProps?:
936
947
  | ((props: {
937
948
  cell: MRT_Cell<TData>;
@@ -958,6 +969,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
958
969
  table: MRT_TableInstance<TData>;
959
970
  }) => DialogProps)
960
971
  | DialogProps;
972
+ /**
973
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
974
+ */
961
975
  muiEditTextFieldProps?:
962
976
  | ((props: {
963
977
  cell: MRT_Cell<TData>;
@@ -976,18 +990,27 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
976
990
  table: MRT_TableInstance<TData>;
977
991
  }) => IconButtonProps)
978
992
  | IconButtonProps;
993
+ /**
994
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
995
+ */
979
996
  muiFilterAutocompleteProps?:
980
997
  | ((props: {
981
998
  column: MRT_Column<TData>;
982
999
  table: MRT_TableInstance<TData>;
983
1000
  }) => AutocompleteProps<any, any, any, any>)
984
1001
  | AutocompleteProps<any, any, any, any>;
1002
+ /**
1003
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1004
+ */
985
1005
  muiFilterCheckboxProps?:
986
1006
  | ((props: {
987
1007
  column: MRT_Column<TData>;
988
1008
  table: MRT_TableInstance<TData>;
989
1009
  }) => CheckboxProps)
990
1010
  | CheckboxProps;
1011
+ /**
1012
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1013
+ */
991
1014
  muiFilterDatePickerProps?:
992
1015
  | ((props: {
993
1016
  column: MRT_Column<TData>;
@@ -995,6 +1018,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
995
1018
  table: MRT_TableInstance<TData>;
996
1019
  }) => DatePickerProps<never>)
997
1020
  | DatePickerProps<never>;
1021
+ /**
1022
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1023
+ */
998
1024
  muiFilterDateTimePickerProps?:
999
1025
  | ((props: {
1000
1026
  column: MRT_Column<TData>;
@@ -1002,12 +1028,18 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1002
1028
  table: MRT_TableInstance<TData>;
1003
1029
  }) => DateTimePickerProps<never>)
1004
1030
  | DateTimePickerProps<never>;
1031
+ /**
1032
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1033
+ */
1005
1034
  muiFilterSliderProps?:
1006
1035
  | ((props: {
1007
1036
  column: MRT_Column<TData>;
1008
1037
  table: MRT_TableInstance<TData>;
1009
1038
  }) => SliderProps)
1010
1039
  | SliderProps;
1040
+ /**
1041
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1042
+ */
1011
1043
  muiFilterTextFieldProps?:
1012
1044
  | ((props: {
1013
1045
  column: MRT_Column<TData>;
@@ -1015,6 +1047,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1015
1047
  table: MRT_TableInstance<TData>;
1016
1048
  }) => TextFieldProps)
1017
1049
  | TextFieldProps;
1050
+ /**
1051
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1052
+ */
1018
1053
  muiFilterTimePickerProps?:
1019
1054
  | ((props: {
1020
1055
  column: MRT_Column<TData>;
@@ -1072,6 +1107,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1072
1107
  table: MRT_TableInstance<TData>;
1073
1108
  }) => SkeletonProps)
1074
1109
  | SkeletonProps;
1110
+ /**
1111
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1112
+ */
1075
1113
  muiTableBodyCellProps?:
1076
1114
  | ((props: {
1077
1115
  cell: MRT_Cell<TData>;
@@ -1109,6 +1147,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1109
1147
  table: MRT_TableInstance<TData>;
1110
1148
  }) => TableRowProps)
1111
1149
  | TableRowProps;
1150
+ /**
1151
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1152
+ */
1112
1153
  muiTableHeadCellProps?:
1113
1154
  | ((props: {
1114
1155
  column: MRT_Column<TData>;
@@ -1192,6 +1233,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1192
1233
  renderCaption?:
1193
1234
  | ((props: { table: MRT_TableInstance<TData> }) => ReactNode)
1194
1235
  | ReactNode;
1236
+ /**
1237
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1238
+ */
1195
1239
  renderCellActionMenuItems?: (props: {
1196
1240
  cell: MRT_Cell<TData>;
1197
1241
  closeMenu: () => void;
@@ -1202,12 +1246,18 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1202
1246
  staticRowIndex?: number;
1203
1247
  table: MRT_TableInstance<TData>;
1204
1248
  }) => ReactNode[];
1249
+ /**
1250
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1251
+ */
1205
1252
  renderColumnActionsMenuItems?: (props: {
1206
1253
  closeMenu: () => void;
1207
1254
  column: MRT_Column<TData>;
1208
1255
  internalColumnMenuItems: ReactNode[];
1209
1256
  table: MRT_TableInstance<TData>;
1210
1257
  }) => ReactNode[];
1258
+ /**
1259
+ * @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1260
+ */
1211
1261
  renderColumnFilterModeMenuItems?: (props: {
1212
1262
  column: MRT_Column<TData>;
1213
1263
  internalFilterOptions: MRT_InternalFilterOption[];
@@ -1241,7 +1291,7 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1241
1291
  row: MRT_Row<TData>;
1242
1292
  staticRowIndex?: number;
1243
1293
  table: MRT_TableInstance<TData>;
1244
- }) => ReactNode[];
1294
+ }) => ReactNode[] | undefined;
1245
1295
  renderRowActions?: (props: {
1246
1296
  cell: MRT_Cell<TData>;
1247
1297
  row: MRT_Row<TData>;
@@ -1271,9 +1321,7 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
1271
1321
  | 'sticky'
1272
1322
  | 'top'
1273
1323
  | 'top-and-bottom';
1274
- rowVirtualizerInstanceRef?: MutableRefObject<
1275
- MRT_RowVirtualizer | null
1276
- >;
1324
+ rowVirtualizerInstanceRef?: MutableRefObject<MRT_RowVirtualizer | null>;
1277
1325
  rowVirtualizerOptions?:
1278
1326
  | ((props: {
1279
1327
  table: MRT_TableInstance<TData>;
@@ -1,8 +1,13 @@
1
1
  import {
2
+ MRT_Header,
2
3
  type MRT_Cell,
3
4
  type MRT_RowData,
4
5
  type MRT_TableInstance,
5
6
  } from '../types';
7
+ import {
8
+ getMRT_RowSelectionHandler,
9
+ getMRT_SelectAllHandler,
10
+ } from './row.utils';
6
11
  import { parseFromValuesOrFunc } from './utils';
7
12
 
8
13
  export const isCellEditable = <TData extends MRT_RowData>({
@@ -48,3 +53,135 @@ export const openEditingCell = <TData extends MRT_RowData>({
48
53
  });
49
54
  }
50
55
  };
56
+
57
+ export const cellNavigation = <TData extends MRT_RowData = MRT_RowData>({
58
+ cell,
59
+ cellElements,
60
+ cellValue,
61
+ containerElement,
62
+ event,
63
+ header,
64
+ parentElement,
65
+ table,
66
+ }: {
67
+ cell?: MRT_Cell<TData>;
68
+ header?: MRT_Header<TData>;
69
+ cellElements?: Array<HTMLTableCellElement>;
70
+ cellValue?: string;
71
+ containerElement?: HTMLTableElement;
72
+ event: React.KeyboardEvent<HTMLTableCellElement>;
73
+ parentElement?: HTMLTableRowElement;
74
+ table: MRT_TableInstance<TData>;
75
+ }) => {
76
+ if (cellValue && (event.ctrlKey || event.metaKey) && event.key === 'c') {
77
+ navigator.clipboard.writeText(cellValue);
78
+ } else if (['Enter', ' '].includes(event.key)) {
79
+ if (cell?.column?.id === 'mrt-row-select') {
80
+ getMRT_RowSelectionHandler({
81
+ row: cell.row,
82
+ table,
83
+ //@ts-ignore
84
+ staticRowIndex: +event.target.getAttribute('data-index'),
85
+ })(event as any);
86
+ } else if (
87
+ header?.column?.id === 'mrt-row-select' &&
88
+ table.options.enableSelectAll
89
+ ) {
90
+ getMRT_SelectAllHandler({
91
+ table,
92
+ })(event as any);
93
+ } else if (
94
+ cell?.column?.id === 'mrt-row-expand' &&
95
+ (cell.row.getCanExpand() ||
96
+ table.options.renderDetailPanel?.({ row: cell.row, table }))
97
+ ) {
98
+ cell.row.toggleExpanded();
99
+ } else if (
100
+ header?.column?.id === 'mrt-row-expand' &&
101
+ table.options.enableExpandAll
102
+ ) {
103
+ table.toggleAllRowsExpanded();
104
+ } else if (header?.column?.getCanSort()) {
105
+ header.column.toggleSorting();
106
+ } else if (cell?.column.id === 'mrt-row-pin') {
107
+ cell.row.getIsPinned()
108
+ ? cell.row.pin(false)
109
+ : cell.row.pin(
110
+ table.options.rowPinningDisplayMode?.includes('bottom')
111
+ ? 'bottom'
112
+ : 'top',
113
+ );
114
+ }
115
+ } else if (
116
+ ['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(
117
+ event.key,
118
+ )
119
+ ) {
120
+ event.preventDefault();
121
+ const currentCell = event.currentTarget;
122
+ const currentRow = parentElement || currentCell.closest('tr');
123
+
124
+ const tableElement = containerElement || currentCell.closest('table');
125
+ const allCells =
126
+ cellElements ||
127
+ Array.from(tableElement?.querySelectorAll('th, td') || []);
128
+ const currentCellIndex = allCells.indexOf(currentCell);
129
+
130
+ const currentIndex = parseInt(
131
+ currentCell.getAttribute('data-index') || '0',
132
+ );
133
+ let nextCell: HTMLElement | undefined = undefined;
134
+
135
+ //home/end first or last cell in row
136
+ const findEdgeCell = (rowIndex: 'c' | 'f' | 'l', edge: 'f' | 'l') => {
137
+ const row =
138
+ rowIndex === 'c'
139
+ ? currentRow
140
+ : rowIndex === 'f'
141
+ ? tableElement?.querySelector('tr')
142
+ : tableElement?.lastElementChild?.lastElementChild;
143
+ const rowCells = Array.from(row?.children || []);
144
+ const targetCell =
145
+ edge === 'f' ? rowCells[0] : rowCells[rowCells.length - 1];
146
+ return targetCell as HTMLElement;
147
+ };
148
+
149
+ const findAdjacentCell = (
150
+ columnIndex: number,
151
+ searchDirection: 'f' | 'b',
152
+ ) => {
153
+ const searchArray =
154
+ searchDirection === 'f'
155
+ ? allCells.slice(currentCellIndex + 1)
156
+ : allCells.slice(0, currentCellIndex).reverse();
157
+ return searchArray.find((cell) =>
158
+ cell.matches(`[data-index="${columnIndex}"]`),
159
+ ) as HTMLElement | undefined;
160
+ };
161
+
162
+ switch (event.key) {
163
+ case 'ArrowRight':
164
+ nextCell = findAdjacentCell(currentIndex + 1, 'f');
165
+ break;
166
+ case 'ArrowLeft':
167
+ nextCell = findAdjacentCell(currentIndex - 1, 'b');
168
+ break;
169
+ case 'ArrowUp':
170
+ nextCell = findAdjacentCell(currentIndex, 'b');
171
+ break;
172
+ case 'ArrowDown':
173
+ nextCell = findAdjacentCell(currentIndex, 'f');
174
+ break;
175
+ case 'Home':
176
+ nextCell = findEdgeCell(event.ctrlKey ? 'f' : 'c', 'f');
177
+ break;
178
+ case 'End':
179
+ nextCell = findEdgeCell(event.ctrlKey ? 'l' : 'c', 'l');
180
+ break;
181
+ }
182
+
183
+ if (nextCell) {
184
+ nextCell.focus();
185
+ }
186
+ }
187
+ };
@@ -27,6 +27,7 @@ export const getMRTTheme = <TData extends MRT_RowData>(
27
27
  : muiTheme.palette.background.default);
28
28
  return {
29
29
  baseBackgroundColor,
30
+ cellNavigationOutlineColor: muiTheme.palette.primary.main,
30
31
  draggingBorderColor: muiTheme.palette.primary.main,
31
32
  matchHighlightColor:
32
33
  muiTheme.palette.mode === 'dark'
@@ -170,6 +171,10 @@ export const getCommonMRTCellStyles = <TData extends MRT_RowData>({
170
171
  : columnDefType !== 'group' && isColumnPinned
171
172
  ? 1
172
173
  : 0,
174
+ '&:focus-visible': {
175
+ outline: `2px solid ${table.options.mrtTheme.cellNavigationOutlineColor}`,
176
+ outlineOffset: '-2px',
177
+ },
173
178
  ...pinnedStyles,
174
179
  ...widthStyles,
175
180
  ...(parseFromValuesOrFunc(tableCellProps?.sx, theme) as any),