Skip to content

Commit 4aefa15

Browse files
YongThePsibor章勇
and
章勇
authored
fixes #1041 fixes #1217: row dragging when filtering fixes (#1361)
* fix: #1041, #1217, wrong draggingRowIndex in virtual when filtered. * docs: add docs of wyh should do a extra index of rangeExtractor * chore: add vscode launch.json for debug storybook * Delete .vscode/launch.json * fix: draggingRowIndex should depend on realRows --------- Co-authored-by: 章勇 <[email protected]>
1 parent 3dbab32 commit 4aefa15

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

packages/material-react-table/src/hooks/useMRT_RowVirtualizer.ts

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback } from 'react';
1+
import { useCallback, useMemo } from 'react';
22
import { type Range, useVirtualizer } from '@tanstack/react-virtual';
33
import {
44
type MRT_Row,
@@ -36,7 +36,19 @@ export const useMRT_RowVirtualizer = <
3636
table,
3737
});
3838

39-
const rowCount = rows?.length ?? getRowModel().rows.length;
39+
const realRows = rows ?? getRowModel().rows;
40+
/**
41+
* when filtering, should find the correct index in filtered rows
42+
*/
43+
const draggingRowIndex = useMemo(
44+
() =>
45+
draggingRow?.id
46+
? realRows.findIndex((r) => r.id === draggingRow?.id)
47+
: undefined,
48+
[realRows, draggingRow?.id],
49+
);
50+
51+
const rowCount = realRows.length;
4052

4153
const normalRowHeight =
4254
density === 'compact' ? 37 : density === 'comfortable' ? 58 : 73;
@@ -58,9 +70,9 @@ export const useMRT_RowVirtualizer = <
5870
overscan: 4,
5971
rangeExtractor: useCallback(
6072
(range: Range) => {
61-
return extraIndexRangeExtractor(range, draggingRow?.index ?? 0);
73+
return extraIndexRangeExtractor(range, draggingRowIndex);
6274
},
63-
[draggingRow],
75+
[draggingRowIndex],
6476
),
6577
...rowVirtualizerProps,
6678
}) as unknown as MRT_RowVirtualizer<TScrollElement, TItemElement>;

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

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { type Range, defaultRangeExtractor } from '@tanstack/react-virtual';
22

3+
/**
4+
* When scroll, the `draggingRow` or `draggingColumn` can be removed from document because of virtualization,
5+
* then, the `dragEnd` event on `MRT_TableBodyRowGrabHandle` or `MRT_TableHeadCellGrabHandle` will not fire.
6+
* We should keep the `draggingRow` or `draggingColumn` in `getVirtualItems()` to avoid this thing.
7+
*/
38
export const extraIndexRangeExtractor = (
49
range: Range,
510
draggingIndex?: number,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { faker } from '@faker-js/faker';
2+
import { type Meta } from '@storybook/react';
3+
import { useState } from 'react';
4+
import {
5+
MaterialReactTable,
6+
useMaterialReactTable,
7+
type MRT_ColumnDef,
8+
} from '../../src';
9+
const meta: Meta = {
10+
title: 'Fixed Bugs/dragging virtual when filtered',
11+
};
12+
export default meta;
13+
const initData = [...Array(25)].map(() => ({
14+
age: faker.number.int(20) + 18,
15+
email: faker.internet.email(),
16+
firstName: faker.person.firstName(),
17+
id: faker.string.alphanumeric(6),
18+
lastName: faker.person.lastName(),
19+
}));
20+
initData.push({
21+
age: 18,
22+
23+
firstName: 'Foobar',
24+
lastName: 'Baz',
25+
id: '1',
26+
});
27+
const columns: MRT_ColumnDef<(typeof initData)[0]>[] = [
28+
{
29+
accessorKey: 'id',
30+
header: 'ID',
31+
},
32+
{
33+
accessorKey: 'firstName',
34+
header: 'First Name',
35+
},
36+
{
37+
accessorKey: 'lastName',
38+
header: 'Last Name',
39+
},
40+
{
41+
accessorKey: 'email',
42+
header: 'Email Address',
43+
},
44+
{
45+
accessorKey: 'age',
46+
header: 'Age',
47+
},
48+
{
49+
accessorKey: 'state',
50+
header: 'State',
51+
},
52+
];
53+
export const DraggingRowWhenFiltered = () => {
54+
const [data, _setData] = useState(() => initData);
55+
const t = useMaterialReactTable({
56+
enableRowVirtualization: true,
57+
enableRowNumbers: true,
58+
columns: columns,
59+
data: data,
60+
enableRowDragging: true,
61+
initialState: {
62+
density: 'compact',
63+
columnFilters: [{ id: 'firstName', value: 'foo' }],
64+
showColumnFilters: true,
65+
},
66+
});
67+
return <MaterialReactTable table={t} />;
68+
};

0 commit comments

Comments
 (0)