material-react-table 0.23.5 → 0.24.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.
- package/dist/MaterialReactTable.d.ts +46 -15
- package/dist/body/MRT_TableBodyCell.d.ts +2 -1
- package/dist/body/MRT_TableBodyRowGrabHandle.d.ts +9 -0
- package/dist/buttons/MRT_GrabHandleButton.d.ts +4 -2
- package/dist/head/MRT_TableHeadCellGrabHandle.d.ts +9 -0
- package/dist/localization.d.ts +1 -0
- package/dist/material-react-table.cjs.development.js +287 -167
- package/dist/material-react-table.cjs.development.js.map +1 -1
- package/dist/material-react-table.cjs.production.min.js +1 -1
- package/dist/material-react-table.cjs.production.min.js.map +1 -1
- package/dist/material-react-table.esm.js +288 -168
- package/dist/material-react-table.esm.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/package.json +1 -1
- package/src/MaterialReactTable.tsx +69 -14
- package/src/body/MRT_TableBodyCell.tsx +17 -3
- package/src/body/MRT_TableBodyRow.tsx +37 -3
- package/src/body/MRT_TableBodyRowGrabHandle.tsx +48 -0
- package/src/buttons/MRT_GrabHandleButton.tsx +12 -8
- package/src/head/MRT_TableHeadCell.tsx +14 -31
- package/src/head/MRT_TableHeadCellGrabHandle.tsx +77 -0
- package/src/localization.ts +2 -0
- package/src/menus/MRT_ColumnActionMenu.tsx +1 -1
- package/src/menus/MRT_ShowHideColumnsMenuItems.tsx +3 -3
- package/src/table/MRT_TableRoot.tsx +25 -6
- package/src/utils.ts +9 -8
package/dist/utils.d.ts
CHANGED
@@ -4,7 +4,7 @@ export declare const getAllLeafColumnDefs: <TData extends Record<string, any> =
|
|
4
4
|
export declare const prepareColumns: <TData extends Record<string, any> = {}>(columnDefs: MRT_ColumnDef<TData>[], currentFilterFns: {
|
5
5
|
[key: string]: "between" | "contains" | "empty" | "endsWith" | "equals" | "fuzzy" | "greaterThan" | "lessThan" | "notEmpty" | "notEquals" | "startsWith" | "includesString" | "includesStringSensitive" | "equalsString" | "arrIncludes" | "arrIncludesAll" | "arrIncludesSome" | "weakEquals" | "inNumberRange";
|
6
6
|
}) => MRT_DefinedColumnDef<TData>[];
|
7
|
-
export declare const reorderColumn: <TData extends Record<string, any> = {}>(
|
7
|
+
export declare const reorderColumn: <TData extends Record<string, any> = {}>(draggedColumn: MRT_Column<TData>, targetColumn: MRT_Column<TData>, columnOrder: ColumnOrderState) => ColumnOrderState;
|
8
8
|
export declare const getLeadingDisplayColumnIds: <TData extends Record<string, any> = {}>(props: MaterialReactTableProps<TData>) => string[];
|
9
9
|
export declare const getTrailingDisplayColumnIds: <TData extends Record<string, any> = {}>(props: MaterialReactTableProps<TData>) => (string | false | undefined)[];
|
10
10
|
export declare const getDefaultColumnOrderIds: <TData extends Record<string, any> = {}>(props: MaterialReactTableProps<TData>) => string[];
|
package/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"version": "0.
|
2
|
+
"version": "0.24.0",
|
3
3
|
"license": "MIT",
|
4
4
|
"name": "material-react-table",
|
5
5
|
"description": "A fully featured Material UI implementation of TanStack React Table, inspired by material-table and the MUI X DataGrid, written from the ground up in TypeScript.",
|
@@ -1,12 +1,13 @@
|
|
1
1
|
import React, {
|
2
2
|
ChangeEvent,
|
3
3
|
Dispatch,
|
4
|
+
DragEvent,
|
4
5
|
FC,
|
5
6
|
FocusEvent,
|
6
7
|
ReactNode,
|
7
8
|
SetStateAction,
|
8
9
|
} from 'react';
|
9
|
-
import {
|
10
|
+
import type {
|
10
11
|
AlertProps,
|
11
12
|
ButtonProps,
|
12
13
|
CheckboxProps,
|
@@ -25,7 +26,7 @@ import {
|
|
25
26
|
TextFieldProps,
|
26
27
|
ToolbarProps,
|
27
28
|
} from '@mui/material';
|
28
|
-
import {
|
29
|
+
import type {
|
29
30
|
Cell,
|
30
31
|
Column,
|
31
32
|
ColumnDef,
|
@@ -39,7 +40,7 @@ import {
|
|
39
40
|
TableOptions,
|
40
41
|
TableState,
|
41
42
|
} from '@tanstack/react-table';
|
42
|
-
import { Options as VirtualizerOptions } from 'react-virtual';
|
43
|
+
import type { Options as VirtualizerOptions } from 'react-virtual';
|
43
44
|
import { MRT_Localization, MRT_DefaultLocalization_EN } from './localization';
|
44
45
|
import { MRT_Default_Icons, MRT_Icons } from './icons';
|
45
46
|
import { MRT_TableRoot } from './table/MRT_TableRoot';
|
@@ -107,6 +108,7 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
|
|
107
108
|
localization: MRT_Localization;
|
108
109
|
};
|
109
110
|
setCurrentDraggingColumn: Dispatch<SetStateAction<MRT_Column<TData> | null>>;
|
111
|
+
setCurrentDraggingRow: Dispatch<SetStateAction<MRT_Row<TData> | null>>;
|
110
112
|
setCurrentEditingCell: Dispatch<SetStateAction<MRT_Cell | null>>;
|
111
113
|
setCurrentEditingRow: Dispatch<SetStateAction<MRT_Row | null>>;
|
112
114
|
setCurrentFilterFns: Dispatch<
|
@@ -116,6 +118,7 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
|
|
116
118
|
>;
|
117
119
|
setCurrentGlobalFilterFn: Dispatch<SetStateAction<MRT_FilterOption>>;
|
118
120
|
setCurrentHoveredColumn: Dispatch<SetStateAction<MRT_Column<TData> | null>>;
|
121
|
+
setCurrentHoveredRow: Dispatch<SetStateAction<MRT_Row | null>>;
|
119
122
|
setDensity: Dispatch<SetStateAction<'comfortable' | 'compact' | 'spacious'>>;
|
120
123
|
setIsFullScreen: Dispatch<SetStateAction<boolean>>;
|
121
124
|
setShowAlertBanner: Dispatch<SetStateAction<boolean>>;
|
@@ -126,11 +129,13 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
|
|
126
129
|
export type MRT_TableState<TData extends Record<string, any> = {}> =
|
127
130
|
TableState & {
|
128
131
|
currentDraggingColumn: MRT_Column<TData> | null;
|
132
|
+
currentDraggingRow: MRT_Row<TData> | null;
|
129
133
|
currentEditingCell: MRT_Cell<TData> | null;
|
130
134
|
currentEditingRow: MRT_Row<TData> | null;
|
131
135
|
currentFilterFns: Record<string, MRT_FilterOption>;
|
132
136
|
currentGlobalFilterFn: Record<string, MRT_FilterOption>;
|
133
137
|
currentHoveredColumn: MRT_Column<TData> | null;
|
138
|
+
currentHoveredRow: MRT_Row<TData> | null;
|
134
139
|
density: 'comfortable' | 'compact' | 'spacious';
|
135
140
|
isFullScreen: boolean;
|
136
141
|
isLoading: boolean;
|
@@ -226,6 +231,7 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
|
|
226
231
|
columns?: MRT_ColumnDef<TData>[];
|
227
232
|
enableClickToCopy?: boolean;
|
228
233
|
enableColumnActions?: boolean;
|
234
|
+
enableColumnDragging?: boolean;
|
229
235
|
enableColumnFilterChangeMode?: boolean;
|
230
236
|
enableColumnOrdering?: boolean;
|
231
237
|
enableEditing?: boolean;
|
@@ -295,6 +301,15 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
|
|
295
301
|
table: MRT_TableInstance<TData>;
|
296
302
|
column: MRT_Column<TData>;
|
297
303
|
}) => IconButtonProps);
|
304
|
+
muiTableHeadCellDragHandleProps?:
|
305
|
+
| IconButtonProps
|
306
|
+
| (({
|
307
|
+
table,
|
308
|
+
column,
|
309
|
+
}: {
|
310
|
+
table: MRT_TableInstance<TData>;
|
311
|
+
column: MRT_Column<TData>;
|
312
|
+
}) => IconButtonProps);
|
298
313
|
muiTableHeadCellFilterTextFieldProps?:
|
299
314
|
| TextFieldProps
|
300
315
|
| (({
|
@@ -368,12 +383,11 @@ export type MRT_HeaderGroup<TData extends Record<string, any> = {}> = Omit<
|
|
368
383
|
|
369
384
|
export type MRT_Row<TData extends Record<string, any> = {}> = Omit<
|
370
385
|
Row<TData>,
|
371
|
-
'getVisibleCells' | 'getAllCells' | 'subRows' | '
|
386
|
+
'getVisibleCells' | 'getAllCells' | 'subRows' | '_valuesCache'
|
372
387
|
> & {
|
373
388
|
getAllCells: () => MRT_Cell<TData>[];
|
374
389
|
getVisibleCells: () => MRT_Cell<TData>[];
|
375
390
|
subRows?: MRT_Row<TData>[];
|
376
|
-
original: TData;
|
377
391
|
_valuesCache?: TData;
|
378
392
|
};
|
379
393
|
|
@@ -397,11 +411,21 @@ export type MRT_FilterFn<TData extends Record<string, any> = {}> =
|
|
397
411
|
| FilterFn<TData>
|
398
412
|
| MRT_FilterOption;
|
399
413
|
|
414
|
+
/**
|
415
|
+
* `columns` and `data` props are the only required props, but there are over 150 other optional props.
|
416
|
+
*
|
417
|
+
* See more info on creating columns and data on the official docs site:
|
418
|
+
* @link https://www.material-react-table.com/docs/usage
|
419
|
+
*
|
420
|
+
* See the full props list on the official docs site:
|
421
|
+
* @link https://www.material-react-table.com/docs/api/props
|
422
|
+
*/
|
400
423
|
export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
401
424
|
MRT_TableOptions<TData> & {
|
402
425
|
editingMode?: 'table' | 'row' | 'cell';
|
403
426
|
enableClickToCopy?: boolean;
|
404
427
|
enableColumnActions?: boolean;
|
428
|
+
enableColumnDragging?: boolean;
|
405
429
|
enableColumnFilterChangeMode?: boolean;
|
406
430
|
enableColumnOrdering?: boolean;
|
407
431
|
enableDensityToggle?: boolean;
|
@@ -412,7 +436,9 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
412
436
|
enableGlobalFilterRankedResults?: boolean;
|
413
437
|
enablePagination?: boolean;
|
414
438
|
enableRowActions?: boolean;
|
439
|
+
enableRowDragging?: boolean;
|
415
440
|
enableRowNumbers?: boolean;
|
441
|
+
enableRowOrdering?: boolean;
|
416
442
|
enableRowVirtualization?: boolean;
|
417
443
|
enableSelectAll?: boolean;
|
418
444
|
enableStickyHeader?: boolean;
|
@@ -496,6 +522,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
496
522
|
table: MRT_TableInstance<TData>;
|
497
523
|
cell: MRT_Cell<TData>;
|
498
524
|
}) => SkeletonProps);
|
525
|
+
muiTableBodyRowDragHandleProps?:
|
526
|
+
| IconButtonProps
|
527
|
+
| (({
|
528
|
+
table,
|
529
|
+
row,
|
530
|
+
}: {
|
531
|
+
table: MRT_TableInstance<TData>;
|
532
|
+
row: MRT_Row<TData>;
|
533
|
+
}) => IconButtonProps);
|
499
534
|
muiTableBodyProps?:
|
500
535
|
| TableBodyProps
|
501
536
|
| (({ table }: { table: MRT_TableInstance<TData> }) => TableBodyProps);
|
@@ -554,6 +589,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
554
589
|
table: MRT_TableInstance<TData>;
|
555
590
|
column: MRT_Column<TData>;
|
556
591
|
}) => IconButtonProps);
|
592
|
+
muiTableHeadCellDragHandleProps?:
|
593
|
+
| IconButtonProps
|
594
|
+
| (({
|
595
|
+
table,
|
596
|
+
column,
|
597
|
+
}: {
|
598
|
+
table: MRT_TableInstance<TData>;
|
599
|
+
column: MRT_Column<TData>;
|
600
|
+
}) => IconButtonProps);
|
557
601
|
muiTableHeadCellFilterTextFieldProps?:
|
558
602
|
| TextFieldProps
|
559
603
|
| (({
|
@@ -624,12 +668,23 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
624
668
|
cell: MRT_Cell<TData>;
|
625
669
|
table: MRT_TableInstance<TData>;
|
626
670
|
}) => void;
|
671
|
+
onColumnDrop?: ({
|
672
|
+
event,
|
673
|
+
draggedColumn,
|
674
|
+
targetColumn,
|
675
|
+
}: {
|
676
|
+
event: DragEvent<HTMLButtonElement>;
|
677
|
+
draggedColumn: MRT_Column<TData>;
|
678
|
+
targetColumn: MRT_Column<TData> | null;
|
679
|
+
}) => void;
|
627
680
|
onCurrentDraggingColumnChange?: OnChangeFn<MRT_Column<TData> | null>;
|
681
|
+
onCurrentDraggingRowChange?: OnChangeFn<MRT_Row<TData> | null>;
|
628
682
|
onCurrentEditingCellChange?: OnChangeFn<MRT_Cell<TData> | null>;
|
629
683
|
onCurrentEditingRowChange?: OnChangeFn<MRT_Row<TData> | null>;
|
630
684
|
onCurrentFilterFnsChange?: OnChangeFn<{ [key: string]: MRT_FilterOption }>;
|
631
685
|
onCurrentGlobalFilterFnChange?: OnChangeFn<MRT_FilterOption>;
|
632
686
|
onCurrentHoveredColumnChange?: OnChangeFn<MRT_Column<TData> | null>;
|
687
|
+
onCurrentHoveredRowChange?: OnChangeFn<MRT_Row<TData> | null>;
|
633
688
|
onEditRowSubmit?: ({
|
634
689
|
row,
|
635
690
|
table,
|
@@ -639,6 +694,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
639
694
|
}) => Promise<void> | void;
|
640
695
|
onDensityChange?: OnChangeFn<boolean>;
|
641
696
|
onIsFullScreenChange?: OnChangeFn<boolean>;
|
697
|
+
onRowDrop?: ({
|
698
|
+
event,
|
699
|
+
draggedRow,
|
700
|
+
targetRow,
|
701
|
+
}: {
|
702
|
+
event: DragEvent<HTMLButtonElement>;
|
703
|
+
draggedRow: MRT_Row<TData>;
|
704
|
+
targetRow: MRT_Row<TData> | null;
|
705
|
+
}) => void;
|
642
706
|
onShowAlertBannerChange?: OnChangeFn<boolean>;
|
643
707
|
onShowFiltersChange?: OnChangeFn<boolean>;
|
644
708
|
onShowGlobalFilterChange?: OnChangeFn<boolean>;
|
@@ -711,15 +775,6 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
|
|
711
775
|
virtualizerProps?: Partial<VirtualizerOptions<HTMLDivElement>>;
|
712
776
|
};
|
713
777
|
|
714
|
-
/**
|
715
|
-
* `columns` and `data` props are the only required props, but there are over 150 other optional props.
|
716
|
-
*
|
717
|
-
* See more info on creating columns and data on the official docs site:
|
718
|
-
* @link https://www.material-react-table.com/docs/usage
|
719
|
-
*
|
720
|
-
* See the full props list on the official docs site:
|
721
|
-
* @link https://www.material-react-table.com/docs/api/props
|
722
|
-
*/
|
723
778
|
export default <TData extends Record<string, any> = {}>({
|
724
779
|
autoResetExpanded = false,
|
725
780
|
columnResizeMode = 'onEnd',
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { DragEvent, FC, MouseEvent, useMemo } from 'react';
|
1
|
+
import React, { DragEvent, FC, MouseEvent, RefObject, useMemo } from 'react';
|
2
2
|
import {
|
3
3
|
alpha,
|
4
4
|
darken,
|
@@ -10,11 +10,13 @@ import {
|
|
10
10
|
import { MRT_EditCellTextField } from '../inputs/MRT_EditCellTextField';
|
11
11
|
import { MRT_CopyButton } from '../buttons/MRT_CopyButton';
|
12
12
|
import type { MRT_Cell, MRT_TableInstance } from '..';
|
13
|
+
import { MRT_TableBodyRowGrabHandle } from './MRT_TableBodyRowGrabHandle';
|
13
14
|
|
14
15
|
interface Props {
|
15
16
|
cell: MRT_Cell;
|
16
17
|
enableHover?: boolean;
|
17
18
|
rowIndex: number;
|
19
|
+
rowRef: RefObject<HTMLTableRowElement>;
|
18
20
|
table: MRT_TableInstance;
|
19
21
|
}
|
20
22
|
|
@@ -22,6 +24,7 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
22
24
|
cell,
|
23
25
|
enableHover,
|
24
26
|
rowIndex,
|
27
|
+
rowRef,
|
25
28
|
table,
|
26
29
|
}) => {
|
27
30
|
const theme = useTheme();
|
@@ -30,6 +33,7 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
30
33
|
options: {
|
31
34
|
editingMode,
|
32
35
|
enableClickToCopy,
|
36
|
+
enableColumnOrdering,
|
33
37
|
enableEditing,
|
34
38
|
enableRowNumbers,
|
35
39
|
muiTableBodyCellProps,
|
@@ -124,7 +128,7 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
124
128
|
};
|
125
129
|
|
126
130
|
const handleDragEnter = (_e: DragEvent) => {
|
127
|
-
if (currentDraggingColumn) {
|
131
|
+
if (enableColumnOrdering && currentDraggingColumn) {
|
128
132
|
setCurrentHoveredColumn(columnDefType === 'data' ? column : null);
|
129
133
|
}
|
130
134
|
};
|
@@ -140,6 +144,10 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
140
144
|
? {
|
141
145
|
borderLeft: draggingBorder,
|
142
146
|
borderRight: draggingBorder,
|
147
|
+
borderBottom:
|
148
|
+
row.index === table.getRowModel().rows.length - 1
|
149
|
+
? draggingBorder
|
150
|
+
: undefined,
|
143
151
|
}
|
144
152
|
: undefined;
|
145
153
|
|
@@ -181,7 +189,7 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
181
189
|
? '1rem 1.25rem'
|
182
190
|
: '1.5rem',
|
183
191
|
pl:
|
184
|
-
column.id === 'mrt-expand'
|
192
|
+
column.id === 'mrt-row-expand'
|
185
193
|
? `${
|
186
194
|
row.depth +
|
187
195
|
(density === 'compact'
|
@@ -233,6 +241,12 @@ export const MRT_TableBodyCell: FC<Props> = ({
|
|
233
241
|
rowNumberMode === 'static' &&
|
234
242
|
column.id === 'mrt-row-numbers' ? (
|
235
243
|
rowIndex + 1
|
244
|
+
) : column.id === 'mrt-row-drag' ? (
|
245
|
+
<MRT_TableBodyRowGrabHandle
|
246
|
+
cell={cell}
|
247
|
+
rowRef={rowRef}
|
248
|
+
table={table}
|
249
|
+
/>
|
236
250
|
) : columnDefType === 'display' ? (
|
237
251
|
columnDef.Cell?.({ cell, table })
|
238
252
|
) : isEditing ? (
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import React, { FC } from 'react';
|
2
|
-
import { darken, lighten, TableRow } from '@mui/material';
|
1
|
+
import React, { DragEvent, FC, useRef } from 'react';
|
2
|
+
import { darken, lighten, TableRow, useTheme } from '@mui/material';
|
3
3
|
import { MRT_TableBodyCell } from './MRT_TableBodyCell';
|
4
4
|
import { MRT_TableDetailPanel } from './MRT_TableDetailPanel';
|
5
5
|
import type { MRT_Row, MRT_TableInstance } from '..';
|
@@ -11,24 +11,56 @@ interface Props {
|
|
11
11
|
}
|
12
12
|
|
13
13
|
export const MRT_TableBodyRow: FC<Props> = ({ row, rowIndex, table }) => {
|
14
|
+
const theme = useTheme();
|
14
15
|
const {
|
15
16
|
getIsSomeColumnsPinned,
|
16
|
-
|
17
|
+
getState,
|
18
|
+
options: { enableRowOrdering, muiTableBodyRowProps, renderDetailPanel },
|
19
|
+
setCurrentHoveredRow,
|
17
20
|
} = table;
|
21
|
+
const { currentDraggingRow, currentHoveredRow } = getState();
|
18
22
|
|
19
23
|
const tableRowProps =
|
20
24
|
muiTableBodyRowProps instanceof Function
|
21
25
|
? muiTableBodyRowProps({ row, table })
|
22
26
|
: muiTableBodyRowProps;
|
23
27
|
|
28
|
+
const handleDragEnter = (_e: DragEvent) => {
|
29
|
+
if (enableRowOrdering && currentDraggingRow) {
|
30
|
+
setCurrentHoveredRow(row);
|
31
|
+
}
|
32
|
+
};
|
33
|
+
|
34
|
+
const rowRef = useRef<HTMLTableRowElement>(null);
|
35
|
+
|
36
|
+
const draggingBorder =
|
37
|
+
currentDraggingRow?.id === row.id
|
38
|
+
? `1px dashed ${theme.palette.divider}`
|
39
|
+
: currentHoveredRow?.id === row.id
|
40
|
+
? `2px dashed ${theme.palette.primary.main}`
|
41
|
+
: undefined;
|
42
|
+
|
43
|
+
const draggingBorders = draggingBorder
|
44
|
+
? {
|
45
|
+
border: draggingBorder,
|
46
|
+
}
|
47
|
+
: undefined;
|
48
|
+
|
24
49
|
return (
|
25
50
|
<>
|
26
51
|
<TableRow
|
52
|
+
onDragEnter={handleDragEnter}
|
27
53
|
hover
|
28
54
|
selected={row.getIsSelected()}
|
55
|
+
ref={rowRef}
|
29
56
|
{...tableRowProps}
|
30
57
|
sx={(theme) => ({
|
31
58
|
backgroundColor: lighten(theme.palette.background.default, 0.06),
|
59
|
+
opacity:
|
60
|
+
currentDraggingRow?.id === row.id ||
|
61
|
+
currentHoveredRow?.id === row.id
|
62
|
+
? 0.5
|
63
|
+
: 1,
|
32
64
|
transition: 'all 0.2s ease-in-out',
|
33
65
|
'&:hover td': {
|
34
66
|
backgroundColor:
|
@@ -39,6 +71,7 @@ export const MRT_TableBodyRow: FC<Props> = ({ row, rowIndex, table }) => {
|
|
39
71
|
: undefined,
|
40
72
|
},
|
41
73
|
...(tableRowProps?.sx as any),
|
74
|
+
...draggingBorders,
|
42
75
|
})}
|
43
76
|
>
|
44
77
|
{row?.getVisibleCells()?.map?.((cell) => (
|
@@ -47,6 +80,7 @@ export const MRT_TableBodyRow: FC<Props> = ({ row, rowIndex, table }) => {
|
|
47
80
|
key={cell.id}
|
48
81
|
enableHover={tableRowProps?.hover !== false}
|
49
82
|
rowIndex={rowIndex}
|
83
|
+
rowRef={rowRef}
|
50
84
|
table={table}
|
51
85
|
/>
|
52
86
|
))}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import React, { DragEvent, FC, RefObject } from 'react';
|
2
|
+
import { MRT_Cell, MRT_TableInstance } from '..';
|
3
|
+
import { MRT_GrabHandleButton } from '../buttons/MRT_GrabHandleButton';
|
4
|
+
|
5
|
+
interface Props {
|
6
|
+
cell: MRT_Cell;
|
7
|
+
rowRef: RefObject<HTMLTableRowElement>;
|
8
|
+
table: MRT_TableInstance;
|
9
|
+
}
|
10
|
+
|
11
|
+
export const MRT_TableBodyRowGrabHandle: FC<Props> = ({
|
12
|
+
cell,
|
13
|
+
rowRef,
|
14
|
+
table,
|
15
|
+
}) => {
|
16
|
+
const {
|
17
|
+
options: { muiTableBodyRowDragHandleProps, onRowDrop },
|
18
|
+
} = table;
|
19
|
+
|
20
|
+
const iconButtonProps =
|
21
|
+
muiTableBodyRowDragHandleProps instanceof Function
|
22
|
+
? muiTableBodyRowDragHandleProps({ row: cell.row, table })
|
23
|
+
: muiTableBodyRowDragHandleProps;
|
24
|
+
|
25
|
+
const handleDragStart = (e: DragEvent<HTMLButtonElement>) => {
|
26
|
+
e.dataTransfer.setDragImage(rowRef.current as HTMLElement, 0, 0);
|
27
|
+
table.setCurrentDraggingRow(cell.row as any);
|
28
|
+
};
|
29
|
+
|
30
|
+
const handleDragEnd = (event: DragEvent<HTMLButtonElement>) => {
|
31
|
+
onRowDrop?.({
|
32
|
+
event,
|
33
|
+
draggedRow: table.getState().currentDraggingRow as any,
|
34
|
+
targetRow: table.getState().currentHoveredRow as any,
|
35
|
+
});
|
36
|
+
table.setCurrentDraggingRow(null);
|
37
|
+
table.setCurrentHoveredRow(null);
|
38
|
+
};
|
39
|
+
|
40
|
+
return (
|
41
|
+
<MRT_GrabHandleButton
|
42
|
+
iconButtonProps={iconButtonProps}
|
43
|
+
onDragStart={handleDragStart}
|
44
|
+
onDragEnd={handleDragEnd}
|
45
|
+
table={table}
|
46
|
+
/>
|
47
|
+
);
|
48
|
+
};
|
@@ -1,16 +1,18 @@
|
|
1
|
-
import { IconButton, Tooltip } from '@mui/material';
|
1
|
+
import { IconButton, IconButtonProps, Tooltip } from '@mui/material';
|
2
2
|
import React, { DragEventHandler, FC } from 'react';
|
3
3
|
import { MRT_TableInstance } from '..';
|
4
4
|
|
5
5
|
interface Props {
|
6
|
-
|
7
|
-
|
6
|
+
iconButtonProps?: IconButtonProps;
|
7
|
+
onDragStart: DragEventHandler<HTMLButtonElement>;
|
8
|
+
onDragEnd: DragEventHandler<HTMLButtonElement>;
|
8
9
|
table: MRT_TableInstance;
|
9
10
|
}
|
10
11
|
|
11
12
|
export const MRT_GrabHandleButton: FC<Props> = ({
|
12
|
-
|
13
|
-
|
13
|
+
iconButtonProps,
|
14
|
+
onDragEnd,
|
15
|
+
onDragStart,
|
14
16
|
table,
|
15
17
|
}) => {
|
16
18
|
const {
|
@@ -26,14 +28,15 @@ export const MRT_GrabHandleButton: FC<Props> = ({
|
|
26
28
|
enterDelay={1000}
|
27
29
|
enterNextDelay={1000}
|
28
30
|
placement="top"
|
29
|
-
title={localization.
|
31
|
+
title={localization.move}
|
30
32
|
>
|
31
33
|
<IconButton
|
32
34
|
disableRipple
|
33
35
|
draggable="true"
|
34
|
-
onDragStart={
|
35
|
-
onDragEnd={
|
36
|
+
onDragStart={onDragStart}
|
37
|
+
onDragEnd={onDragEnd}
|
36
38
|
size="small"
|
39
|
+
{...iconButtonProps}
|
37
40
|
sx={{
|
38
41
|
cursor: 'grab',
|
39
42
|
m: 0,
|
@@ -47,6 +50,7 @@ export const MRT_GrabHandleButton: FC<Props> = ({
|
|
47
50
|
'&:active': {
|
48
51
|
cursor: 'grabbing',
|
49
52
|
},
|
53
|
+
...iconButtonProps?.sx,
|
50
54
|
}}
|
51
55
|
>
|
52
56
|
<DragHandleIcon />
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import React, { DragEvent, FC, ReactNode } from 'react';
|
2
2
|
import { Box, TableCell, Theme, alpha, lighten, useTheme } from '@mui/material';
|
3
|
+
import { MRT_TableHeadCellColumnActionsButton } from './MRT_TableHeadCellColumnActionsButton';
|
3
4
|
import { MRT_TableHeadCellFilterContainer } from './MRT_TableHeadCellFilterContainer';
|
4
5
|
import { MRT_TableHeadCellFilterLabel } from './MRT_TableHeadCellFilterLabel';
|
5
|
-
import {
|
6
|
+
import { MRT_TableHeadCellGrabHandle } from './MRT_TableHeadCellGrabHandle';
|
6
7
|
import { MRT_TableHeadCellResizeHandle } from './MRT_TableHeadCellResizeHandle';
|
7
8
|
import { MRT_TableHeadCellSortLabel } from './MRT_TableHeadCellSortLabel';
|
8
|
-
import { MRT_TableHeadCellColumnActionsButton } from './MRT_TableHeadCellColumnActionsButton';
|
9
|
-
import { reorderColumn } from '../utils';
|
10
9
|
import type { MRT_Header, MRT_TableInstance } from '..';
|
11
10
|
|
12
11
|
interface Props {
|
@@ -20,18 +19,16 @@ export const MRT_TableHeadCell: FC<Props> = ({ header, table }) => {
|
|
20
19
|
getState,
|
21
20
|
options: {
|
22
21
|
enableColumnActions,
|
22
|
+
enableColumnDragging,
|
23
23
|
enableColumnOrdering,
|
24
24
|
enableColumnResizing,
|
25
25
|
enableGrouping,
|
26
26
|
enableMultiSort,
|
27
27
|
muiTableHeadCellProps,
|
28
28
|
},
|
29
|
-
setColumnOrder,
|
30
|
-
setCurrentDraggingColumn,
|
31
29
|
setCurrentHoveredColumn,
|
32
30
|
} = table;
|
33
|
-
const {
|
34
|
-
getState();
|
31
|
+
const { density, currentDraggingColumn, currentHoveredColumn } = getState();
|
35
32
|
const { column } = header;
|
36
33
|
const { columnDef } = column;
|
37
34
|
const { columnDefType } = columnDef;
|
@@ -75,30 +72,14 @@ export const MRT_TableHeadCell: FC<Props> = ({ header, table }) => {
|
|
75
72
|
);
|
76
73
|
};
|
77
74
|
|
78
|
-
const tableHeadCellRef = React.useRef<HTMLElement>(null);
|
79
|
-
|
80
|
-
const handleDragStart = (e: DragEvent<HTMLButtonElement>) => {
|
81
|
-
setCurrentDraggingColumn(column);
|
82
|
-
e.dataTransfer.setDragImage(tableHeadCellRef.current as HTMLElement, 0, 0);
|
83
|
-
};
|
84
|
-
|
85
|
-
const handleDragEnd = (_e: DragEvent<HTMLButtonElement>) => {
|
86
|
-
setCurrentDraggingColumn(null);
|
87
|
-
setCurrentHoveredColumn(null);
|
88
|
-
if (
|
89
|
-
currentHoveredColumn &&
|
90
|
-
currentHoveredColumn?.id !== currentDraggingColumn?.id
|
91
|
-
) {
|
92
|
-
setColumnOrder(reorderColumn(column, currentHoveredColumn, columnOrder));
|
93
|
-
}
|
94
|
-
};
|
95
|
-
|
96
75
|
const handleDragEnter = (_e: DragEvent) => {
|
97
|
-
if (currentDraggingColumn) {
|
76
|
+
if (enableColumnOrdering && currentDraggingColumn) {
|
98
77
|
setCurrentHoveredColumn(columnDefType === 'data' ? column : null);
|
99
78
|
}
|
100
79
|
};
|
101
80
|
|
81
|
+
const tableHeadCellRef = React.useRef<HTMLTableCellElement>(null);
|
82
|
+
|
102
83
|
const draggingBorder =
|
103
84
|
currentDraggingColumn?.id === column.id
|
104
85
|
? `1px dashed ${theme.palette.divider}`
|
@@ -223,13 +204,15 @@ export const MRT_TableHeadCell: FC<Props> = ({ header, table }) => {
|
|
223
204
|
</Box>
|
224
205
|
<Box sx={{ whiteSpace: 'nowrap' }}>
|
225
206
|
{columnDefType === 'data' &&
|
226
|
-
((
|
227
|
-
columnDef.
|
207
|
+
((enableColumnDragging &&
|
208
|
+
columnDef.enableColumnDragging !== false) ||
|
209
|
+
(enableColumnOrdering &&
|
210
|
+
columnDef.enableColumnOrdering !== false) ||
|
228
211
|
(enableGrouping && columnDef.enableGrouping !== false)) && (
|
229
|
-
<
|
230
|
-
|
231
|
-
handleDragEnd={handleDragEnd}
|
212
|
+
<MRT_TableHeadCellGrabHandle
|
213
|
+
column={column}
|
232
214
|
table={table}
|
215
|
+
tableHeadCellRef={tableHeadCellRef}
|
233
216
|
/>
|
234
217
|
)}
|
235
218
|
{(enableColumnActions || columnDef.enableColumnActions) &&
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import React, { DragEvent, FC, RefObject } from 'react';
|
2
|
+
import { MRT_GrabHandleButton } from '../buttons/MRT_GrabHandleButton';
|
3
|
+
import { reorderColumn } from '../utils';
|
4
|
+
import type { MRT_Column, MRT_TableInstance } from '..';
|
5
|
+
|
6
|
+
interface Props {
|
7
|
+
column: MRT_Column;
|
8
|
+
table: MRT_TableInstance;
|
9
|
+
tableHeadCellRef: RefObject<HTMLTableCellElement>;
|
10
|
+
}
|
11
|
+
|
12
|
+
export const MRT_TableHeadCellGrabHandle: FC<Props> = ({
|
13
|
+
column,
|
14
|
+
table,
|
15
|
+
tableHeadCellRef,
|
16
|
+
}) => {
|
17
|
+
const {
|
18
|
+
getState,
|
19
|
+
options: {
|
20
|
+
enableColumnOrdering,
|
21
|
+
muiTableHeadCellDragHandleProps,
|
22
|
+
onColumnDrop,
|
23
|
+
},
|
24
|
+
setColumnOrder,
|
25
|
+
setCurrentDraggingColumn,
|
26
|
+
setCurrentHoveredColumn,
|
27
|
+
} = table;
|
28
|
+
const { columnDef } = column;
|
29
|
+
const { currentHoveredColumn, currentDraggingColumn, columnOrder } =
|
30
|
+
getState();
|
31
|
+
|
32
|
+
const mIconButtonProps =
|
33
|
+
muiTableHeadCellDragHandleProps instanceof Function
|
34
|
+
? muiTableHeadCellDragHandleProps({ column, table })
|
35
|
+
: muiTableHeadCellDragHandleProps;
|
36
|
+
|
37
|
+
const mcIconButtonProps =
|
38
|
+
columnDef.muiTableHeadCellDragHandleProps instanceof Function
|
39
|
+
? columnDef.muiTableHeadCellDragHandleProps({ column, table })
|
40
|
+
: columnDef.muiTableHeadCellDragHandleProps;
|
41
|
+
|
42
|
+
const iconButtonProps = {
|
43
|
+
...mIconButtonProps,
|
44
|
+
...mcIconButtonProps,
|
45
|
+
};
|
46
|
+
|
47
|
+
const handleDragStart = (e: DragEvent<HTMLButtonElement>) => {
|
48
|
+
setCurrentDraggingColumn(column);
|
49
|
+
e.dataTransfer.setDragImage(tableHeadCellRef.current as HTMLElement, 0, 0);
|
50
|
+
};
|
51
|
+
|
52
|
+
const handleDragEnd = (event: DragEvent<HTMLButtonElement>) => {
|
53
|
+
onColumnDrop?.({
|
54
|
+
event,
|
55
|
+
draggedColumn: column,
|
56
|
+
targetColumn: currentHoveredColumn,
|
57
|
+
});
|
58
|
+
if (
|
59
|
+
enableColumnOrdering &&
|
60
|
+
currentHoveredColumn &&
|
61
|
+
currentHoveredColumn?.id !== currentDraggingColumn?.id
|
62
|
+
) {
|
63
|
+
setColumnOrder(reorderColumn(column, currentHoveredColumn, columnOrder));
|
64
|
+
}
|
65
|
+
setCurrentDraggingColumn(null);
|
66
|
+
setCurrentHoveredColumn(null);
|
67
|
+
};
|
68
|
+
|
69
|
+
return (
|
70
|
+
<MRT_GrabHandleButton
|
71
|
+
iconButtonProps={iconButtonProps}
|
72
|
+
onDragStart={handleDragStart}
|
73
|
+
onDragEnd={handleDragEnd}
|
74
|
+
table={table}
|
75
|
+
/>
|
76
|
+
);
|
77
|
+
};
|
package/src/localization.ts
CHANGED
@@ -34,6 +34,7 @@ export interface MRT_Localization {
|
|
34
34
|
hideColumn: string;
|
35
35
|
max: string;
|
36
36
|
min: string;
|
37
|
+
move: string;
|
37
38
|
pinToLeft: string;
|
38
39
|
pinToRight: string;
|
39
40
|
resetColumnSize: string;
|
@@ -102,6 +103,7 @@ export const MRT_DefaultLocalization_EN: MRT_Localization = {
|
|
102
103
|
hideColumn: 'Hide {column} column',
|
103
104
|
max: 'Max',
|
104
105
|
min: 'Min',
|
106
|
+
move: 'Move',
|
105
107
|
pinToLeft: 'Pin to left',
|
106
108
|
pinToRight: 'Pin to right',
|
107
109
|
resetColumnSize: 'Reset column size',
|
@@ -100,7 +100,7 @@ export const MRT_ColumnActionMenu: FC<Props> = ({
|
|
100
100
|
|
101
101
|
const handleGroupByColumn = () => {
|
102
102
|
column.toggleGrouping();
|
103
|
-
setColumnOrder((old) => ['mrt-expand', ...old]);
|
103
|
+
setColumnOrder((old) => ['mrt-row-expand', ...old]);
|
104
104
|
setAnchorEl(null);
|
105
105
|
};
|
106
106
|
|