Skip to content

Commit d49a09c

Browse files
committed
more progress on v3 migration and keyboard navigation
1 parent 70df7b3 commit d49a09c

File tree

7 files changed

+96
-29
lines changed

7 files changed

+96
-29
lines changed

apps/material-react-table-docs/pages/docs/getting-started/migrating-to-v3.mdx

+48-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ This will be the easiest MRT upgrade ever! Material React Table V3 is mostly jus
1717

1818
### New Feature Highlights
1919

20-
1. Compatible with Material UI V6
21-
2. **Almost no other changes**. MRT is not taking advantage of the new optional features in Material UI V6 yet. MRT V3 will serve as an easy upgrade target for those who are just looking to upgrade their Material UI package versions.
20+
1. Compatible with Material UI V6 with generally better performance across the board
21+
2. Keyboard navigation improvements that are now included by default
22+
3. **Almost no other changes**. MRT is not taking advantage of the new optional features in Material UI V6 yet. MRT V3 will serve as an easy upgrade target for those who are just looking to upgrade their Material UI package versions.
2223

2324
### Upgrade Dependencies
2425

@@ -46,18 +47,59 @@ npx npm-check-updates -u material-react-table
4647

4748
And then perform the actual install (downloading the new version):
4849

49-
<InstallCommand packagesString="material-react-table" />
50+
<InstallCommand packagesString="" />
5051

5152
You should now be on Material React Table V3! Look for any code or type errors in your project and fix them as needed.
5253

5354
### Breaking Changes
5455

55-
- `@mui/material` and `@mui/icons-material` v6.0.0 are now minimum required versions of Material UI packages
56+
- `@mui/material` and `@mui/icons-material` v6.0.0 are now minimum required versions of Material UI packages (you might be able to get away with lower MUI versions for a while, but eventually MUI V6 APIs will be used internally by MRT and your project will break)
5657
- `@mui/x-date-pickers` v7.15.0 is now a minimum required dependency
57-
5858
- Removed deprecated `MRT_Virtualizer` type in favor of separate `MRT_RowVirtualizer` and `MRT_ColumnVirtualizer` types
59-
6059
- Removed deprecated `text` in favor of the more consistent `label` type in dropdown/autocomplete/select option types.
60+
- Deprecated several `mui*Props` table options that were column-specific. These table options should either be specified in column defs or in the `defaultColumn` table option.
61+
- `muiColumnActionsButtonProps`
62+
- `muiColumnDragHandleProps`
63+
- `muiCopyButtonProps`
64+
- `muiEditTextFieldProps`
65+
- `muiFilterAutocompleteProps`
66+
- `muiFilterCheckboxProps`
67+
- `muiFilterDatePickerProps`
68+
- `muiFilterDateTimePickerProps`
69+
- `muiFilterSliderProps`
70+
- `muiFilterTextFieldProps`
71+
- `muiFilterTimePickerProps`
72+
- `muiSkeletonProps`
73+
- `muiTableBodyCellProps`
74+
- `muiTableHeadCellProps`
75+
- `renderCellActionMenuItems`
76+
- `renderColumnActionsMenuItems`
77+
- `renderColumnFilterModeMenuItems`
78+
79+
```diff
80+
const table = useTable({
81+
columns,
82+
data,
83+
// Recommended to specify these table options in the defaultColumn instead
84+
+ defaultColumn: { // applies to all columns
85+
+ muiTableBodyCellProps: {
86+
+ align: 'center',
87+
+ },
88+
+ muiFilterAutocompleteProps: {
89+
+ sx: { my: 2 },
90+
+ },
91+
+ },
92+
// these table options will be removed in MRT V4
93+
- muiTableBodyCellProps: {
94+
- align: 'center',
95+
- },
96+
- muiFilterAutocompleteProps: {
97+
- sx: { my: 2 },
98+
- },
99+
)};
100+
```
101+
102+
You can be lazy with these changes. These table options are just marked as deprecated, but they will still work until MRT V4.
61103

62104
> Can I uninstall Emotion Yet? No, Emotion is still required for Material React Table V3, but it won't be for long. MRT V4 will remove the Emotion dependency in favor of [Pigment CSS](https://mui.com/blog/introducing-pigment-css/).
63105

packages/material-react-table/src/components/body/MRT_TableBodyCell.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,11 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
232232
}
233233
};
234234

235-
const handleKeyDown = (e: React.KeyboardEvent<HTMLTableCellElement>) => {
235+
const handleKeyDown = (event: React.KeyboardEvent<HTMLTableCellElement>) => {
236236
if (enableCellNavigation) {
237-
cellNavigation(e);
237+
cellNavigation({ event, cellValue: cell.getValue<string>() });
238238
}
239-
tableCellProps?.onKeyDown?.(e);
239+
tableCellProps?.onKeyDown?.(event);
240240
};
241241

242242
return (

packages/material-react-table/src/components/footer/MRT_TableFooterCell.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ export const MRT_TableFooterCell = <TData extends MRT_RowData>({
4848
...rest,
4949
};
5050

51-
const handleKeyDown = (e: React.KeyboardEvent<HTMLTableCellElement>) => {
51+
const handleKeyDown = (event: React.KeyboardEvent<HTMLTableCellElement>) => {
5252
if (enableCellNavigation) {
53-
cellNavigation(e);
53+
cellNavigation({ event, cellValue: footer.column.footer });
5454
}
55-
tableCellProps?.onKeyDown?.(e);
55+
tableCellProps?.onKeyDown?.(event);
5656
};
5757

5858
return (

packages/material-react-table/src/components/head/MRT_TableHeadCell.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ export const MRT_TableHeadCell = <TData extends MRT_RowData>({
149149
}
150150
};
151151

152-
const handleKeyDown = (e: React.KeyboardEvent<HTMLTableCellElement>) => {
152+
const handleKeyDown = (event: React.KeyboardEvent<HTMLTableCellElement>) => {
153153
if (enableCellNavigation) {
154-
cellNavigation(e);
154+
cellNavigation({ event, cellValue: header.column.header });
155155
}
156-
tableCellProps?.onKeyDown?.(e);
156+
tableCellProps?.onKeyDown?.(event);
157157
};
158158

159159
const HeaderElement =

packages/material-react-table/src/components/menus/MRT_ActionMenuItem.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const MRT_ActionMenuItem = <TData extends MRT_RowData>({
3535
my: 0,
3636
py: '6px',
3737
}}
38+
tabIndex={0}
3839
{...rest}
3940
>
4041
<Box

packages/material-react-table/src/types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
12361236
renderCaption?:
12371237
| ((props: { table: MRT_TableInstance<TData> }) => ReactNode)
12381238
| ReactNode;
1239+
/**
1240+
* @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1241+
*/
12391242
renderCellActionMenuItems?: (props: {
12401243
cell: MRT_Cell<TData>;
12411244
closeMenu: () => void;
@@ -1246,12 +1249,18 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
12461249
staticRowIndex?: number;
12471250
table: MRT_TableInstance<TData>;
12481251
}) => ReactNode[];
1252+
/**
1253+
* @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1254+
*/
12491255
renderColumnActionsMenuItems?: (props: {
12501256
closeMenu: () => void;
12511257
column: MRT_Column<TData>;
12521258
internalColumnMenuItems: ReactNode[];
12531259
table: MRT_TableInstance<TData>;
12541260
}) => ReactNode[];
1261+
/**
1262+
* @deprecated Specify this in the `defaultColumn` table option instead if you want to apply to all columns.
1263+
*/
12551264
renderColumnFilterModeMenuItems?: (props: {
12561265
column: MRT_Column<TData>;
12571266
internalFilterOptions: MRT_InternalFilterOption[];

packages/material-react-table/src/utils/cell.utils.ts

+29-14
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,35 @@ export const openEditingCell = <TData extends MRT_RowData>({
4949
}
5050
};
5151

52-
export const cellNavigation = (
53-
e: React.KeyboardEvent<HTMLTableCellElement>,
54-
) => {
52+
export const cellNavigation = ({
53+
cellElements,
54+
cellValue,
55+
containerElement,
56+
event,
57+
parentElement,
58+
}: {
59+
cellElements?: Array<HTMLTableCellElement | HTMLDivElement>;
60+
cellValue?: string;
61+
containerElement?: HTMLDivElement | HTMLTableElement;
62+
event: React.KeyboardEvent<HTMLTableCellElement | HTMLDivElement>;
63+
parentElement?: HTMLTableRowElement | HTMLDivElement;
64+
}) => {
65+
if (cellValue && (event.ctrlKey || event.metaKey) && event.key === 'c') {
66+
navigator.clipboard.writeText(cellValue);
67+
}
5568
if (
5669
['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(
57-
e.key,
70+
event.key,
5871
)
5972
) {
60-
e.preventDefault();
61-
const currentCell = e.currentTarget;
62-
const currentRow = currentCell.closest('tr');
73+
event.preventDefault();
74+
const currentCell = event.currentTarget;
75+
const currentRow = parentElement || currentCell.closest('tr');
6376

64-
const tableElement = currentCell.closest('table');
65-
const allCells = Array.from(tableElement?.querySelectorAll('th, td') || []);
77+
const tableElement = containerElement || currentCell.closest('table');
78+
const allCells =
79+
cellElements ||
80+
Array.from(tableElement?.querySelectorAll('th, td') || []);
6681
const currentCellIndex = allCells.indexOf(currentCell);
6782

6883
const currentIndex = parseInt(
@@ -76,8 +91,8 @@ export const cellNavigation = (
7691
rowIndex === 'c'
7792
? currentRow
7893
: rowIndex === 'f'
79-
? currentCell.closest('table')?.querySelector('tr')
80-
: currentCell.closest('table')?.lastElementChild?.lastElementChild;
94+
? tableElement?.querySelector('tr')
95+
: tableElement?.lastElementChild?.lastElementChild;
8196
const rowCells = Array.from(row?.children || []);
8297
const targetCell =
8398
edge === 'f' ? rowCells[0] : rowCells[rowCells.length - 1];
@@ -97,7 +112,7 @@ export const cellNavigation = (
97112
) as HTMLElement | undefined;
98113
};
99114

100-
switch (e.key) {
115+
switch (event.key) {
101116
case 'ArrowRight':
102117
nextCell = findAdjacentCell(currentIndex + 1, 'f');
103118
break;
@@ -111,10 +126,10 @@ export const cellNavigation = (
111126
nextCell = findAdjacentCell(currentIndex, 'f');
112127
break;
113128
case 'Home':
114-
nextCell = findEdgeCell(e.ctrlKey ? 'f' : 'c', 'f');
129+
nextCell = findEdgeCell(event.ctrlKey ? 'f' : 'c', 'f');
115130
break;
116131
case 'End':
117-
nextCell = findEdgeCell(e.ctrlKey ? 'l' : 'c', 'l');
132+
nextCell = findEdgeCell(event.ctrlKey ? 'l' : 'c', 'l');
118133
break;
119134
}
120135

0 commit comments

Comments
 (0)