material-react-table 0.23.5 → 0.25.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/utils.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { ColumnOrderState } from '@tanstack/react-table';
2
- import { MaterialReactTableProps, MRT_Column, MRT_ColumnDef, MRT_DefinedColumnDef, MRT_FilterOption } from '.';
2
+ import { MaterialReactTableProps, MRT_Column, MRT_ColumnDef, MRT_DefinedColumnDef, MRT_DisplayColumnIds, MRT_FilterOption } from '.';
3
3
  export declare const getAllLeafColumnDefs: <TData extends Record<string, any> = {}>(columns: MRT_ColumnDef<TData>[]) => MRT_ColumnDef<TData>[];
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> = {}>(movingColumn: MRT_Column<TData>, receivingColumn: MRT_Column<TData>, columnOrder: ColumnOrderState) => ColumnOrderState;
8
- export declare const getLeadingDisplayColumnIds: <TData extends Record<string, any> = {}>(props: MaterialReactTableProps<TData>) => string[];
7
+ export declare const reorderColumn: <TData extends Record<string, any> = {}>(draggedColumn: MRT_Column<TData>, targetColumn: MRT_Column<TData>, columnOrder: ColumnOrderState) => ColumnOrderState;
8
+ export declare const getLeadingDisplayColumnIds: <TData extends Record<string, any> = {}>(props: MaterialReactTableProps<TData>) => MRT_DisplayColumnIds[];
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.23.5",
2
+ "version": "0.25.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.",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "scripts": {
33
33
  "analyze": "size-limit --why",
34
- "build": "tsdx build && size-limit && rm -rf material-react-table-docs/node_modules/material-react-table/dist && cp -r dist material-react-table-docs/node_modules/material-react-table/ && cp -r src material-react-table-docs/node_modules/material-react-table/ && cp -r package.json material-react-table-docs/node_modules/material-react-table/package.json",
34
+ "build": "tsdx build && size-limit && rm -rf material-react-table-docs/node_modules/material-react-table/dist && cp -r dist material-react-table-docs/node_modules/material-react-table/",
35
35
  "build-storybook": "build-storybook",
36
36
  "format": "prettier -w .",
37
37
  "lint": "eslint .",
@@ -75,7 +75,7 @@
75
75
  "@types/react": "^18.0.15",
76
76
  "@types/react-dom": "^18.0.6",
77
77
  "babel-loader": "^8.2.5",
78
- "eslint": "^8.19.0",
78
+ "eslint": "^8.20.0",
79
79
  "eslint-plugin-react-hooks": "^4.6.0",
80
80
  "husky": "^8.0.1",
81
81
  "prettier": "^2.7.1",
@@ -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';
@@ -48,19 +49,6 @@ import { MRT_SortingFns } from './sortingFns';
48
49
 
49
50
  type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
50
51
 
51
- export type MRT_TableOptions<TData extends Record<string, any> = {}> = Partial<
52
- Omit<
53
- TableOptions<TData>,
54
- 'columns' | 'data' | 'initialState' | 'state' | 'expandRowsFn'
55
- >
56
- > & {
57
- columns: MRT_ColumnDef<TData>[];
58
- data: TData[];
59
- expandRowsFn?: (dataRow: TData) => TData[];
60
- initialState?: Partial<MRT_TableState<TData>>;
61
- state?: Partial<MRT_TableState<TData>>;
62
- };
63
-
64
52
  export interface MRT_RowModel<TData extends Record<string, any> = {}> {
65
53
  flatRows: MRT_Row<TData>[];
66
54
  rows: MRT_Row<TData>[];
@@ -107,6 +95,7 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
107
95
  localization: MRT_Localization;
108
96
  };
109
97
  setCurrentDraggingColumn: Dispatch<SetStateAction<MRT_Column<TData> | null>>;
98
+ setCurrentDraggingRow: Dispatch<SetStateAction<MRT_Row<TData> | null>>;
110
99
  setCurrentEditingCell: Dispatch<SetStateAction<MRT_Cell | null>>;
111
100
  setCurrentEditingRow: Dispatch<SetStateAction<MRT_Row | null>>;
112
101
  setCurrentFilterFns: Dispatch<
@@ -116,6 +105,7 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
116
105
  >;
117
106
  setCurrentGlobalFilterFn: Dispatch<SetStateAction<MRT_FilterOption>>;
118
107
  setCurrentHoveredColumn: Dispatch<SetStateAction<MRT_Column<TData> | null>>;
108
+ setCurrentHoveredRow: Dispatch<SetStateAction<MRT_Row | null>>;
119
109
  setDensity: Dispatch<SetStateAction<'comfortable' | 'compact' | 'spacious'>>;
120
110
  setIsFullScreen: Dispatch<SetStateAction<boolean>>;
121
111
  setShowAlertBanner: Dispatch<SetStateAction<boolean>>;
@@ -126,11 +116,13 @@ export type MRT_TableInstance<TData extends Record<string, any> = {}> = Omit<
126
116
  export type MRT_TableState<TData extends Record<string, any> = {}> =
127
117
  TableState & {
128
118
  currentDraggingColumn: MRT_Column<TData> | null;
119
+ currentDraggingRow: MRT_Row<TData> | null;
129
120
  currentEditingCell: MRT_Cell<TData> | null;
130
121
  currentEditingRow: MRT_Row<TData> | null;
131
122
  currentFilterFns: Record<string, MRT_FilterOption>;
132
123
  currentGlobalFilterFn: Record<string, MRT_FilterOption>;
133
124
  currentHoveredColumn: MRT_Column<TData> | null;
125
+ currentHoveredRow: MRT_Row<TData> | null;
134
126
  density: 'comfortable' | 'compact' | 'spacious';
135
127
  isFullScreen: boolean;
136
128
  isLoading: boolean;
@@ -213,7 +205,7 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
213
205
  *
214
206
  * @example accessorKey: 'username'
215
207
  */
216
- accessorKey?: LiteralUnion<string & keyof TData>;
208
+ accessorKey?: string & keyof TData;
217
209
  /**
218
210
  * Specify what type of column this is. Either `data`, `display`, or `group`. Defaults to `data`.
219
211
  * Leave this blank if you are just creating a normal data column.
@@ -226,6 +218,7 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
226
218
  columns?: MRT_ColumnDef<TData>[];
227
219
  enableClickToCopy?: boolean;
228
220
  enableColumnActions?: boolean;
221
+ enableColumnDragging?: boolean;
229
222
  enableColumnFilterChangeMode?: boolean;
230
223
  enableColumnOrdering?: boolean;
231
224
  enableEditing?: boolean;
@@ -295,6 +288,15 @@ export type MRT_ColumnDef<TData extends Record<string, any> = {}> = Omit<
295
288
  table: MRT_TableInstance<TData>;
296
289
  column: MRT_Column<TData>;
297
290
  }) => IconButtonProps);
291
+ muiTableHeadCellDragHandleProps?:
292
+ | IconButtonProps
293
+ | (({
294
+ table,
295
+ column,
296
+ }: {
297
+ table: MRT_TableInstance<TData>;
298
+ column: MRT_Column<TData>;
299
+ }) => IconButtonProps);
298
300
  muiTableHeadCellFilterTextFieldProps?:
299
301
  | TextFieldProps
300
302
  | (({
@@ -368,12 +370,11 @@ export type MRT_HeaderGroup<TData extends Record<string, any> = {}> = Omit<
368
370
 
369
371
  export type MRT_Row<TData extends Record<string, any> = {}> = Omit<
370
372
  Row<TData>,
371
- 'getVisibleCells' | 'getAllCells' | 'subRows' | 'original' | '_valuesCache'
373
+ 'getVisibleCells' | 'getAllCells' | 'subRows' | '_valuesCache'
372
374
  > & {
373
375
  getAllCells: () => MRT_Cell<TData>[];
374
376
  getVisibleCells: () => MRT_Cell<TData>[];
375
377
  subRows?: MRT_Row<TData>[];
376
- original: TData;
377
378
  _valuesCache?: TData;
378
379
  };
379
380
 
@@ -397,11 +398,36 @@ export type MRT_FilterFn<TData extends Record<string, any> = {}> =
397
398
  | FilterFn<TData>
398
399
  | MRT_FilterOption;
399
400
 
401
+ export type MRT_DisplayColumnIds =
402
+ | 'mrt-row-drag'
403
+ | 'mrt-row-actions'
404
+ | 'mrt-row-expand'
405
+ | 'mrt-row-select'
406
+ | 'mrt-row-numbers';
407
+
408
+ /**
409
+ * `columns` and `data` props are the only required props, but there are over 150 other optional props.
410
+ *
411
+ * See more info on creating columns and data on the official docs site:
412
+ * @link https://www.material-react-table.com/docs/usage
413
+ *
414
+ * See the full props list on the official docs site:
415
+ * @link https://www.material-react-table.com/docs/api/props
416
+ */
400
417
  export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
401
- MRT_TableOptions<TData> & {
418
+ Omit<
419
+ Partial<TableOptions<TData>>,
420
+ 'columns' | 'data' | 'initialState' | 'state' | 'expandRowsFn'
421
+ > & {
422
+ displayColumnDefOptions?: Partial<{
423
+ [key in MRT_DisplayColumnIds]: Partial<MRT_ColumnDef>;
424
+ }>;
425
+ columns: MRT_ColumnDef<TData>[];
426
+ data: TData[];
402
427
  editingMode?: 'table' | 'row' | 'cell';
403
428
  enableClickToCopy?: boolean;
404
429
  enableColumnActions?: boolean;
430
+ enableColumnDragging?: boolean;
405
431
  enableColumnFilterChangeMode?: boolean;
406
432
  enableColumnOrdering?: boolean;
407
433
  enableDensityToggle?: boolean;
@@ -412,7 +438,9 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
412
438
  enableGlobalFilterRankedResults?: boolean;
413
439
  enablePagination?: boolean;
414
440
  enableRowActions?: boolean;
441
+ enableRowDragging?: boolean;
415
442
  enableRowNumbers?: boolean;
443
+ enableRowOrdering?: boolean;
416
444
  enableRowVirtualization?: boolean;
417
445
  enableSelectAll?: boolean;
418
446
  enableStickyHeader?: boolean;
@@ -423,7 +451,9 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
423
451
  enableToolbarTop?: boolean;
424
452
  enabledColumnFilterOptions?: (MRT_FilterOption | string)[] | null;
425
453
  enabledGlobalFilterOptions?: (MRT_FilterOption | string)[] | null;
454
+ expandRowsFn?: (dataRow: TData) => TData[];
426
455
  icons?: Partial<MRT_Icons>;
456
+ initialState?: Partial<MRT_TableState<TData>>;
427
457
  localization?: Partial<MRT_Localization>;
428
458
  muiExpandAllButtonProps?:
429
459
  | IconButtonProps
@@ -499,6 +529,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
499
529
  muiTableBodyProps?:
500
530
  | TableBodyProps
501
531
  | (({ table }: { table: MRT_TableInstance<TData> }) => TableBodyProps);
532
+ muiTableBodyRowDragHandleProps?:
533
+ | IconButtonProps
534
+ | (({
535
+ table,
536
+ row,
537
+ }: {
538
+ table: MRT_TableInstance<TData>;
539
+ row: MRT_Row<TData>;
540
+ }) => IconButtonProps);
502
541
  muiTableBodyRowProps?:
503
542
  | TableRowProps
504
543
  | (({
@@ -554,6 +593,15 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
554
593
  table: MRT_TableInstance<TData>;
555
594
  column: MRT_Column<TData>;
556
595
  }) => IconButtonProps);
596
+ muiTableHeadCellDragHandleProps?:
597
+ | IconButtonProps
598
+ | (({
599
+ table,
600
+ column,
601
+ }: {
602
+ table: MRT_TableInstance<TData>;
603
+ column: MRT_Column<TData>;
604
+ }) => IconButtonProps);
557
605
  muiTableHeadCellFilterTextFieldProps?:
558
606
  | TextFieldProps
559
607
  | (({
@@ -624,12 +672,24 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
624
672
  cell: MRT_Cell<TData>;
625
673
  table: MRT_TableInstance<TData>;
626
674
  }) => void;
675
+ onColumnDrop?: ({
676
+ event,
677
+ draggedColumn,
678
+ targetColumn,
679
+ }: {
680
+ event: DragEvent<HTMLButtonElement>;
681
+ draggedColumn: MRT_Column<TData>;
682
+ targetColumn: MRT_Column<TData> | null;
683
+ }) => void;
627
684
  onCurrentDraggingColumnChange?: OnChangeFn<MRT_Column<TData> | null>;
685
+ onCurrentDraggingRowChange?: OnChangeFn<MRT_Row<TData> | null>;
628
686
  onCurrentEditingCellChange?: OnChangeFn<MRT_Cell<TData> | null>;
629
687
  onCurrentEditingRowChange?: OnChangeFn<MRT_Row<TData> | null>;
630
688
  onCurrentFilterFnsChange?: OnChangeFn<{ [key: string]: MRT_FilterOption }>;
631
689
  onCurrentGlobalFilterFnChange?: OnChangeFn<MRT_FilterOption>;
632
690
  onCurrentHoveredColumnChange?: OnChangeFn<MRT_Column<TData> | null>;
691
+ onCurrentHoveredRowChange?: OnChangeFn<MRT_Row<TData> | null>;
692
+ onDensityChange?: OnChangeFn<boolean>;
633
693
  onEditRowSubmit?: ({
634
694
  row,
635
695
  table,
@@ -637,8 +697,16 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
637
697
  row: MRT_Row<TData>;
638
698
  table: MRT_TableInstance<TData>;
639
699
  }) => Promise<void> | void;
640
- onDensityChange?: OnChangeFn<boolean>;
641
700
  onIsFullScreenChange?: OnChangeFn<boolean>;
701
+ onRowDrop?: ({
702
+ event,
703
+ draggedRow,
704
+ targetRow,
705
+ }: {
706
+ event: DragEvent<HTMLButtonElement>;
707
+ draggedRow: MRT_Row<TData>;
708
+ targetRow: MRT_Row<TData> | null;
709
+ }) => void;
642
710
  onShowAlertBannerChange?: OnChangeFn<boolean>;
643
711
  onShowFiltersChange?: OnChangeFn<boolean>;
644
712
  onShowGlobalFilterChange?: OnChangeFn<boolean>;
@@ -674,11 +742,6 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
674
742
  }: {
675
743
  table: MRT_TableInstance<TData>;
676
744
  }) => ReactNode;
677
- renderToolbarTopCustomActions?: ({
678
- table,
679
- }: {
680
- table: MRT_TableInstance<TData>;
681
- }) => ReactNode;
682
745
  renderToolbarInternalActions?: ({
683
746
  table,
684
747
  MRT_ToggleGlobalFilterButton,
@@ -704,22 +767,19 @@ export type MaterialReactTableProps<TData extends Record<string, any> = {}> =
704
767
  IconButtonProps & { table: MRT_TableInstance<TData> }
705
768
  >;
706
769
  }) => ReactNode;
770
+ renderToolbarTopCustomActions?: ({
771
+ table,
772
+ }: {
773
+ table: MRT_TableInstance<TData>;
774
+ }) => ReactNode;
707
775
  rowCount?: number;
708
776
  rowNumberMode?: 'original' | 'static';
709
777
  selectAllMode?: 'all' | 'page';
778
+ state?: Partial<MRT_TableState<TData>>;
710
779
  tableId?: string;
711
780
  virtualizerProps?: Partial<VirtualizerOptions<HTMLDivElement>>;
712
781
  };
713
782
 
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
783
  export default <TData extends Record<string, any> = {}>({
724
784
  autoResetExpanded = false,
725
785
  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,8 +128,10 @@ export const MRT_TableBodyCell: FC<Props> = ({
124
128
  };
125
129
 
126
130
  const handleDragEnter = (_e: DragEvent) => {
127
- if (currentDraggingColumn) {
128
- setCurrentHoveredColumn(columnDefType === 'data' ? column : null);
131
+ if (enableColumnOrdering && currentDraggingColumn) {
132
+ setCurrentHoveredColumn(
133
+ columnDef.enableColumnOrdering !== false ? column : null,
134
+ );
129
135
  }
130
136
  };
131
137
 
@@ -140,6 +146,10 @@ export const MRT_TableBodyCell: FC<Props> = ({
140
146
  ? {
141
147
  borderLeft: draggingBorder,
142
148
  borderRight: draggingBorder,
149
+ borderBottom:
150
+ row.index === table.getRowModel().rows.length - 1
151
+ ? draggingBorder
152
+ : undefined,
143
153
  }
144
154
  : undefined;
145
155
 
@@ -181,7 +191,7 @@ export const MRT_TableBodyCell: FC<Props> = ({
181
191
  ? '1rem 1.25rem'
182
192
  : '1.5rem',
183
193
  pl:
184
- column.id === 'mrt-expand'
194
+ column.id === 'mrt-row-expand'
185
195
  ? `${
186
196
  row.depth +
187
197
  (density === 'compact'
@@ -233,6 +243,12 @@ export const MRT_TableBodyCell: FC<Props> = ({
233
243
  rowNumberMode === 'static' &&
234
244
  column.id === 'mrt-row-numbers' ? (
235
245
  rowIndex + 1
246
+ ) : column.id === 'mrt-row-drag' ? (
247
+ <MRT_TableBodyRowGrabHandle
248
+ cell={cell}
249
+ rowRef={rowRef}
250
+ table={table}
251
+ />
236
252
  ) : columnDefType === 'display' ? (
237
253
  columnDef.Cell?.({ cell, table })
238
254
  ) : 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
- options: { muiTableBodyRowProps, renderDetailPanel },
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
- handleDragStart: DragEventHandler<HTMLButtonElement>;
7
- handleDragEnd: DragEventHandler<HTMLButtonElement>;
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
- handleDragStart,
13
- handleDragEnd,
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.grab}
31
+ title={localization.move}
30
32
  >
31
33
  <IconButton
32
34
  disableRipple
33
35
  draggable="true"
34
- onDragStart={handleDragStart}
35
- onDragEnd={handleDragEnd}
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 />