Skip to content

Commit ee5c60e

Browse files
citizensasSassoun Derderian
andauthored
fix: row grouping algorithm (#999)
fix: typings for RowGroupingMapperResult Co-authored-by: Sassoun Derderian <[email protected]>
1 parent 242df27 commit ee5c60e

File tree

3 files changed

+88
-10
lines changed

3 files changed

+88
-10
lines changed

packages/core/src/data-editor/row-grouping-api.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React from "react";
22
import type { Item } from "../internal/data-grid/data-grid-types.js";
3-
import { flattenRowGroups, mapRowIndexToPath, type RowGroup, type RowGroupingOptions } from "./row-grouping.js";
3+
import { flattenRowGroups, mapRowIndexToPath, type RowGroup, type RowGroupingOptions, type MapResult } from "./row-grouping.js";
44

5-
export type RowGroupingMapperResult<T> = {
5+
export interface RowGroupingMapperResult<T> extends Omit<MapResult, 'originalIndex'> {
66
path: readonly number[];
77
originalIndex: T;
88
isGroupHeader: boolean;
99
groupRows: number;
10-
};
10+
}
1111

1212
export type RowGroupingMapper = {
1313
(itemOrRow: number): RowGroupingMapperResult<number>;

packages/core/src/data-editor/row-grouping.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number):
177177
});
178178
}
179179

180-
interface MapResult {
180+
export interface MapResult {
181181
readonly path: readonly number[];
182182
readonly isGroupHeader: boolean;
183183
readonly originalIndex: number;
@@ -209,18 +209,19 @@ export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly Fla
209209
contentIndex: -1,
210210
groupRows: group.rows,
211211
};
212-
toGo--;
213212
if (!group.isCollapsed) {
214-
if (toGo < group.rows)
213+
if (toGo <= group.rows)
215214
return {
216-
path: [...group.path, toGo],
215+
path: [...group.path, toGo - 1],
217216
originalIndex: group.headerIndex + toGo,
218217
isGroupHeader: false,
219-
groupIndex: toGo,
220-
contentIndex: group.contentIndex + toGo,
218+
groupIndex: toGo - 1,
219+
contentIndex: group.contentIndex + toGo - 1,
221220
groupRows: group.rows,
222221
};
223-
toGo -= group.rows;
222+
toGo = toGo - group.rows - 1;
223+
} else {
224+
toGo--;
224225
}
225226
}
226227
// this shouldn't happen
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { describe, it, expect, afterEach } from "vitest";
2+
import { renderHook, cleanup } from "@testing-library/react-hooks";
3+
import { useRowGrouping } from "../src/data-editor/row-grouping-api.js";
4+
import type { RowGroupingOptions } from "../src/data-editor/row-grouping.js";
5+
6+
describe("useRowGrouping - mapper", () => {
7+
afterEach(async () => {
8+
await cleanup();
9+
});
10+
11+
it("calculates rows correctly with no row grouping options", () => {
12+
const totalRows = 5;
13+
const { result } = renderHook(() => useRowGrouping(undefined, totalRows));
14+
15+
expect(result.current.mapper(0)).toEqual({
16+
path: [ 0 ],
17+
originalIndex: 0,
18+
isGroupHeader: false,
19+
groupIndex: 0,
20+
contentIndex: 0,
21+
groupRows: -1
22+
});
23+
expect(result.current.mapper(1)).toEqual({
24+
path: [ 1 ],
25+
originalIndex: 1,
26+
isGroupHeader: false,
27+
groupIndex: 1,
28+
contentIndex: 1,
29+
groupRows: -1
30+
});
31+
});
32+
33+
it("calculates rows correctly with uncollapsed groups - rowIndex is a group header", () => {
34+
const rowGroupingOptions: RowGroupingOptions = {
35+
groups: [
36+
{ headerIndex: 0, isCollapsed: false },
37+
{ headerIndex: 2, isCollapsed: false },
38+
],
39+
height: 30,
40+
};
41+
const totalRows = 5;
42+
43+
const { result } = renderHook(() => useRowGrouping(rowGroupingOptions, totalRows));
44+
45+
expect(result.current.mapper(0)).toEqual({
46+
path: [ 0, -1 ],
47+
originalIndex: 0,
48+
isGroupHeader: true,
49+
groupIndex: -1,
50+
contentIndex: -1,
51+
groupRows: 1
52+
});
53+
});
54+
55+
it("calculates rows correctly with uncollapsed groups - rowIndex is a regular row", () => {
56+
const rowGroupingOptions: RowGroupingOptions = {
57+
groups: [
58+
{ headerIndex: 0, isCollapsed: false },
59+
{ headerIndex: 2, isCollapsed: false },
60+
],
61+
height: 30,
62+
};
63+
const totalRows = 5;
64+
65+
const { result } = renderHook(() => useRowGrouping(rowGroupingOptions, totalRows));
66+
67+
expect(result.current.mapper(1)).toEqual({
68+
path: [ 0, 0 ],
69+
originalIndex: 1,
70+
isGroupHeader: false,
71+
groupIndex: 0,
72+
contentIndex: 0,
73+
groupRows: 1
74+
});
75+
});
76+
77+
});

0 commit comments

Comments
 (0)