MRT logoMaterial React Table

Row Dragging Example

Material React Table has built-in support row drag and drop features that can be used in a variety of ways. Learn more about column ordering in the Row Ordering/DnD Feature Guide.

More Examples

Demo

Open StackblitzOpen Code SandboxOpen on GitHub
Nice List
DylanMurrayEast Daphne
RaquelKohlerColumbus
ErvinReingerSouth Linda

1-3 of 3

Naughty List
BrittanyMcCulloughLincoln
BransonFramiCharleston

1-2 of 2

Source Code

1import { useMemo, useState } from 'react';
2import {
3 MaterialReactTable,
4 type MRT_TableOptions,
5 type MRT_ColumnDef,
6 type MRT_Row,
7} from 'material-react-table';
8import { Box, Typography } from '@mui/material';
9import { data, type Person } from './makeData';
10
11const Example = () => {
12 const columns = useMemo<MRT_ColumnDef<Person>[]>(
13 //column definitions...
30 );
31
32 const [data1, setData1] = useState<Person[]>(() => data.slice(0, 3));
33 const [data2, setData2] = useState<Person[]>(() => data.slice(3, 5));
34
35 const [draggingRow, setDraggingRow] = useState<MRT_Row<Person> | null>(null);
36 const [hoveredTable, setHoveredTable] = useState<string | null>(null);
37
38 const commonTableProps: Partial<MRT_TableOptions<Person>> & {
39 columns: MRT_ColumnDef<Person>[];
40 } = {
41 columns,
42 enableRowDragging: true,
43 enableFullScreenToggle: false,
44 muiTableContainerProps: {
45 sx: {
46 minHeight: '320px',
47 },
48 },
49 onDraggingRowChange: setDraggingRow,
50 state: { draggingRow },
51 };
52
53 return (
54 <Box
55 sx={{
56 display: 'grid',
57 gridTemplateColumns: { xs: 'auto', lg: '1fr 1fr' },
58 gap: '1rem',
59 overflow: 'auto',
60 p: '4px',
61 }}
62 >
63 <MaterialReactTable
64 {...commonTableProps}
65 data={data1}
66 getRowId={(originalRow) => `table-1-${originalRow.firstName}`}
67 muiRowDragHandleProps={{
68 onDragEnd: () => {
69 if (hoveredTable === 'table-2') {
70 setData2((data2) => [...data2, draggingRow!.original]);
71 setData1((data1) =>
72 data1.filter((d) => d !== draggingRow!.original),
73 );
74 }
75 setHoveredTable(null);
76 },
77 }}
78 muiTablePaperProps={{
79 onDragEnter: () => setHoveredTable('table-1'),
80 sx: {
81 outline: hoveredTable === 'table-1' ? '2px dashed pink' : undefined,
82 },
83 }}
84 renderTopToolbarCustomActions={() => (
85 <Typography color="success.main" component="span" variant="h4">
86 Nice List
87 </Typography>
88 )}
89 />
90 <MaterialReactTable
91 {...commonTableProps}
92 data={data2}
93 defaultColumn={{
94 size: 100,
95 }}
96 getRowId={(originalRow) => `table-2-${originalRow.firstName}`}
97 muiRowDragHandleProps={{
98 onDragEnd: () => {
99 if (hoveredTable === 'table-1') {
100 setData1((data1) => [...data1, draggingRow!.original]);
101 setData2((data2) =>
102 data2.filter((d) => d !== draggingRow!.original),
103 );
104 }
105 setHoveredTable(null);
106 },
107 }}
108 muiTablePaperProps={{
109 onDragEnter: () => setHoveredTable('table-2'),
110 sx: {
111 outline: hoveredTable === 'table-2' ? '2px dashed pink' : undefined,
112 },
113 }}
114 renderTopToolbarCustomActions={() => (
115 <Typography color="error.main" component="span" variant="h4">
116 Naughty List
117 </Typography>
118 )}
119 />
120 </Box>
121 );
122};
123
124export default Example;
125

View Extra Storybook Examples