From 84902b7523484559caccd3bdfef535d800aea8f8 Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sat, 9 Aug 2025 23:33:04 +0100 Subject: [PATCH 1/7] refactor: improve typing for useRowGrouping --- .../core/src/data-editor/row-grouping-api.ts | 22 ++++++++++--------- packages/core/src/data-editor/row-grouping.ts | 12 ++-------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping-api.ts b/packages/core/src/data-editor/row-grouping-api.ts index 988de9013..97d029ba4 100644 --- a/packages/core/src/data-editor/row-grouping-api.ts +++ b/packages/core/src/data-editor/row-grouping-api.ts @@ -1,18 +1,19 @@ import React from "react"; import type { Item } from "../internal/data-grid/data-grid-types.js"; -import { flattenRowGroups, mapRowIndexToPath, type RowGroup, type RowGroupingOptions, type MapResult } from "./row-grouping.js"; +import { flattenRowGroups, mapRowIndexToPath, type RowGroup, type RowGroupingOptions } from "./row-grouping.js"; -export interface RowGroupingMapperResult extends Omit { + +export interface RowGroupingMapperResult { path: readonly number[]; - originalIndex: T; isGroupHeader: boolean; groupRows: number; + originalIndex: T; + readonly groupIndex: number; + readonly contentIndex: number; } -export type RowGroupingMapper = { - (itemOrRow: number): RowGroupingMapperResult; - (itemOrRow: Item): RowGroupingMapperResult; -}; +export type RowGroupingMapper = (itemOrRow: number | Item) => RowGroupingMapperResult; + export interface UseRowGroupingResult { readonly mapper: RowGroupingMapper; @@ -33,8 +34,8 @@ export function useRowGrouping(options: RowGroupingOptions | undefined, rows: nu return { getRowGroupingForPath, updateRowGroupingByPath, - mapper: React.useCallback( - (itemOrRow: number | Item) => { + mapper: React.useCallback( + (itemOrRow) => { if (typeof itemOrRow === "number") { return mapRowIndexToPath(itemOrRow, flattenedRowGroups); } @@ -42,13 +43,14 @@ export function useRowGrouping(options: RowGroupingOptions | undefined, rows: nu return { ...r, originalIndex: [itemOrRow[0], r.originalIndex], - } as any; // FIXME + } as RowGroupingMapperResult; }, [flattenedRowGroups] ), }; } + export function updateRowGroupingByPath( rowGrouping: readonly RowGroup[], path: readonly number[], diff --git a/packages/core/src/data-editor/row-grouping.ts b/packages/core/src/data-editor/row-grouping.ts index f226dd93b..fc7be2ae5 100644 --- a/packages/core/src/data-editor/row-grouping.ts +++ b/packages/core/src/data-editor/row-grouping.ts @@ -3,6 +3,7 @@ import type { Theme } from "../common/styles.js"; import type { DataEditorProps } from "./data-editor.js"; import type { DataGridProps } from "../internal/data-grid/data-grid.js"; import { whenDefined } from "../common/utils.js"; +import type { RowGroupingMapperResult } from "./row-grouping-api.js"; type Mutable = { -readonly [K in keyof T]: T[K]; @@ -177,17 +178,8 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number): }); } -export interface MapResult { - readonly path: readonly number[]; - readonly isGroupHeader: boolean; - readonly originalIndex: number; - readonly groupIndex: number; - readonly groupRows: number; - readonly contentIndex: number; -} - // grid relative index to path and other details -export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): MapResult { +export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult { if (flattenedRowGroups === undefined || flattenRowGroups.length === 0) return { path: [row], From c8842d624fefc83ddb90f7c4d663d606b8f83057 Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:07:27 +0100 Subject: [PATCH 2/7] improve typing with type guard --- packages/core/src/data-editor/row-grouping-api.ts | 14 ++------------ packages/core/src/data-editor/row-grouping.ts | 13 +++++++++++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping-api.ts b/packages/core/src/data-editor/row-grouping-api.ts index 97d029ba4..a1b667f04 100644 --- a/packages/core/src/data-editor/row-grouping-api.ts +++ b/packages/core/src/data-editor/row-grouping-api.ts @@ -14,7 +14,6 @@ export interface RowGroupingMapperResult { export type RowGroupingMapper = (itemOrRow: number | Item) => RowGroupingMapperResult; - export interface UseRowGroupingResult { readonly mapper: RowGroupingMapper; readonly updateRowGroupingByPath: ( @@ -34,17 +33,8 @@ export function useRowGrouping(options: RowGroupingOptions | undefined, rows: nu return { getRowGroupingForPath, updateRowGroupingByPath, - mapper: React.useCallback( - (itemOrRow) => { - if (typeof itemOrRow === "number") { - return mapRowIndexToPath(itemOrRow, flattenedRowGroups); - } - const r = mapRowIndexToPath(itemOrRow[1], flattenedRowGroups); - return { - ...r, - originalIndex: [itemOrRow[0], r.originalIndex], - } as RowGroupingMapperResult; - }, + mapper: React.useCallback( + (itemOrRow) => mapRowIndexToPath(itemOrRow, flattenedRowGroups), [flattenedRowGroups] ), }; diff --git a/packages/core/src/data-editor/row-grouping.ts b/packages/core/src/data-editor/row-grouping.ts index fc7be2ae5..11c4f26e3 100644 --- a/packages/core/src/data-editor/row-grouping.ts +++ b/packages/core/src/data-editor/row-grouping.ts @@ -4,6 +4,7 @@ import type { DataEditorProps } from "./data-editor.js"; import type { DataGridProps } from "../internal/data-grid/data-grid.js"; import { whenDefined } from "../common/utils.js"; import type { RowGroupingMapperResult } from "./row-grouping-api.js"; +import type { Item } from "../internal/data-grid/data-grid-types.js"; type Mutable = { -readonly [K in keyof T]: T[K]; @@ -178,8 +179,14 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number): }); } + // grid relative index to path and other details -export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult { +function mapRowIndexToPathFn(itemRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +function mapRowIndexToPathFn(itemRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +function mapRowIndexToPathFn(itemRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { + const row = typeof itemRow === "number" ? itemRow : itemRow[1]; + const originalIndex = typeof itemRow === "number" ? row : itemRow[0]; + if (flattenedRowGroups === undefined || flattenRowGroups.length === 0) return { path: [row], @@ -221,7 +228,7 @@ export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly Fla // I suppose to eliminate this, you can treat this case as part of the overflow of the last group. return { path: [row], - originalIndex: row, + originalIndex, isGroupHeader: false, groupIndex: row, contentIndex: row, @@ -229,6 +236,8 @@ export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly Fla }; } +export const mapRowIndexToPath = (itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]) => typeof itemOrRow === "number" ? mapRowIndexToPathFn(itemOrRow, flattenedRowGroups) : mapRowIndexToPathFn(itemOrRow, flattenedRowGroups); + export interface UseRowGroupingInnerResult { readonly rows: number; readonly rowNumberMapper: (row: number) => number | undefined; From 6a517fffdd29d9904ddb507e866a69745483eb4d Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:08:31 +0100 Subject: [PATCH 3/7] Small renaming --- packages/core/src/data-editor/row-grouping.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping.ts b/packages/core/src/data-editor/row-grouping.ts index 11c4f26e3..378941a4c 100644 --- a/packages/core/src/data-editor/row-grouping.ts +++ b/packages/core/src/data-editor/row-grouping.ts @@ -181,11 +181,11 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number): // grid relative index to path and other details -function mapRowIndexToPathFn(itemRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -function mapRowIndexToPathFn(itemRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -function mapRowIndexToPathFn(itemRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { - const row = typeof itemRow === "number" ? itemRow : itemRow[1]; - const originalIndex = typeof itemRow === "number" ? row : itemRow[0]; +function mapRowIndexToPathFn(itemOrRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +function mapRowIndexToPathFn(itemOrRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +function mapRowIndexToPathFn(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { + const row = typeof itemOrRow === "number" ? itemOrRow : itemOrRow[1]; + const originalIndex = typeof itemOrRow === "number" ? row : itemOrRow[0]; if (flattenedRowGroups === undefined || flattenRowGroups.length === 0) return { From f751e7170b0e1b7b05cb770146dc065419c55d84 Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:13:52 +0100 Subject: [PATCH 4/7] fix lint error --- packages/core/src/data-editor/row-grouping.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping.ts b/packages/core/src/data-editor/row-grouping.ts index 378941a4c..eafc637dc 100644 --- a/packages/core/src/data-editor/row-grouping.ts +++ b/packages/core/src/data-editor/row-grouping.ts @@ -181,9 +181,10 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number): // grid relative index to path and other details -function mapRowIndexToPathFn(itemOrRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -function mapRowIndexToPathFn(itemOrRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -function mapRowIndexToPathFn(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { +export function mapRowIndexToPath(itemOrRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +export function mapRowIndexToPath(itemOrRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; +export function mapRowIndexToPath(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult; +export function mapRowIndexToPath(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { const row = typeof itemOrRow === "number" ? itemOrRow : itemOrRow[1]; const originalIndex = typeof itemOrRow === "number" ? row : itemOrRow[0]; @@ -236,8 +237,6 @@ function mapRowIndexToPathFn(itemOrRow: number | Item, flattenedRowGroups?: read }; } -export const mapRowIndexToPath = (itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]) => typeof itemOrRow === "number" ? mapRowIndexToPathFn(itemOrRow, flattenedRowGroups) : mapRowIndexToPathFn(itemOrRow, flattenedRowGroups); - export interface UseRowGroupingInnerResult { readonly rows: number; readonly rowNumberMapper: (row: number) => number | undefined; From 347bcd68db99b9b9ef94b15f64fa372a8e9794ed Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:19:55 +0100 Subject: [PATCH 5/7] use union type to avoid casing any --- packages/core/src/data-editor/row-grouping-api.ts | 11 ++++++++++- packages/core/src/data-editor/row-grouping.ts | 11 ++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping-api.ts b/packages/core/src/data-editor/row-grouping-api.ts index a1b667f04..35f433a30 100644 --- a/packages/core/src/data-editor/row-grouping-api.ts +++ b/packages/core/src/data-editor/row-grouping-api.ts @@ -34,7 +34,16 @@ export function useRowGrouping(options: RowGroupingOptions | undefined, rows: nu getRowGroupingForPath, updateRowGroupingByPath, mapper: React.useCallback( - (itemOrRow) => mapRowIndexToPath(itemOrRow, flattenedRowGroups), + (itemOrRow: number | Item) => { + if (typeof itemOrRow === "number") { + return mapRowIndexToPath(itemOrRow, flattenedRowGroups); + } + const r = mapRowIndexToPath(itemOrRow[1], flattenedRowGroups); + return { + ...r, + originalIndex: [itemOrRow[0], r.originalIndex], + } as RowGroupingMapperResult; + }, [flattenedRowGroups] ), }; diff --git a/packages/core/src/data-editor/row-grouping.ts b/packages/core/src/data-editor/row-grouping.ts index eafc637dc..d975fb7b5 100644 --- a/packages/core/src/data-editor/row-grouping.ts +++ b/packages/core/src/data-editor/row-grouping.ts @@ -4,7 +4,6 @@ import type { DataEditorProps } from "./data-editor.js"; import type { DataGridProps } from "../internal/data-grid/data-grid.js"; import { whenDefined } from "../common/utils.js"; import type { RowGroupingMapperResult } from "./row-grouping-api.js"; -import type { Item } from "../internal/data-grid/data-grid-types.js"; type Mutable = { -readonly [K in keyof T]: T[K]; @@ -181,13 +180,7 @@ export function flattenRowGroups(rowGrouping: RowGroupingOptions, rows: number): // grid relative index to path and other details -export function mapRowIndexToPath(itemOrRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -export function mapRowIndexToPath(itemOrRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult; -export function mapRowIndexToPath(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult; -export function mapRowIndexToPath(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult | RowGroupingMapperResult { - const row = typeof itemOrRow === "number" ? itemOrRow : itemOrRow[1]; - const originalIndex = typeof itemOrRow === "number" ? row : itemOrRow[0]; - +export function mapRowIndexToPath(row: number, flattenedRowGroups?: readonly FlattenedRowGroup[]): RowGroupingMapperResult { if (flattenedRowGroups === undefined || flattenRowGroups.length === 0) return { path: [row], @@ -229,7 +222,7 @@ export function mapRowIndexToPath(itemOrRow: number | Item, flattenedRowGroups?: // I suppose to eliminate this, you can treat this case as part of the overflow of the last group. return { path: [row], - originalIndex, + originalIndex: row, isGroupHeader: false, groupIndex: row, contentIndex: row, From 32af20f3099cf0ccf1db4a41355236b8d95abf5f Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:33:10 +0100 Subject: [PATCH 6/7] final version --- .../core/src/data-editor/row-grouping-api.ts | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/core/src/data-editor/row-grouping-api.ts b/packages/core/src/data-editor/row-grouping-api.ts index 35f433a30..4e8d1e899 100644 --- a/packages/core/src/data-editor/row-grouping-api.ts +++ b/packages/core/src/data-editor/row-grouping-api.ts @@ -1,7 +1,6 @@ import React from "react"; import type { Item } from "../internal/data-grid/data-grid-types.js"; -import { flattenRowGroups, mapRowIndexToPath, type RowGroup, type RowGroupingOptions } from "./row-grouping.js"; - +import { flattenRowGroups, mapRowIndexToPath, type FlattenedRowGroup, type RowGroup, type RowGroupingOptions } from "./row-grouping.js"; export interface RowGroupingMapperResult { path: readonly number[]; @@ -14,6 +13,20 @@ export interface RowGroupingMapperResult { export type RowGroupingMapper = (itemOrRow: number | Item) => RowGroupingMapperResult; +export function rowGroupingMapper(itemOrRow: number, flattenedRowGroups?: readonly FlattenedRowGroup[] | undefined): RowGroupingMapperResult; +export function rowGroupingMapper(itemOrRow: Item, flattenedRowGroups?: readonly FlattenedRowGroup[] | undefined): RowGroupingMapperResult; +export function rowGroupingMapper(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[] | undefined): RowGroupingMapperResult | RowGroupingMapperResult; +export function rowGroupingMapper(itemOrRow: number | Item, flattenedRowGroups?: readonly FlattenedRowGroup[] | undefined): RowGroupingMapperResult | RowGroupingMapperResult { + if (typeof itemOrRow === "number") { + return mapRowIndexToPath(itemOrRow, flattenedRowGroups); + } + const r = mapRowIndexToPath(itemOrRow[1], flattenedRowGroups); + return { + ...r, + originalIndex: [itemOrRow[0], r.originalIndex], + } as RowGroupingMapperResult; +}; + export interface UseRowGroupingResult { readonly mapper: RowGroupingMapper; readonly updateRowGroupingByPath: ( @@ -34,22 +47,12 @@ export function useRowGrouping(options: RowGroupingOptions | undefined, rows: nu getRowGroupingForPath, updateRowGroupingByPath, mapper: React.useCallback( - (itemOrRow: number | Item) => { - if (typeof itemOrRow === "number") { - return mapRowIndexToPath(itemOrRow, flattenedRowGroups); - } - const r = mapRowIndexToPath(itemOrRow[1], flattenedRowGroups); - return { - ...r, - originalIndex: [itemOrRow[0], r.originalIndex], - } as RowGroupingMapperResult; - }, + (itemOrRow: number | Item) => rowGroupingMapper(itemOrRow, flattenedRowGroups), [flattenedRowGroups] ), }; } - export function updateRowGroupingByPath( rowGrouping: readonly RowGroup[], path: readonly number[], From 5b0f4200bf26aefacfd48dc5965c7c8d45ef0207 Mon Sep 17 00:00:00 2001 From: ImmortalRabbit <29354535+ImmortalRabbit@users.noreply.github.com> Date: Sun, 10 Aug 2025 00:47:07 +0100 Subject: [PATCH 7/7] fix lint --- packages/core/src/data-editor/row-grouping-api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/data-editor/row-grouping-api.ts b/packages/core/src/data-editor/row-grouping-api.ts index 4e8d1e899..035fef94c 100644 --- a/packages/core/src/data-editor/row-grouping-api.ts +++ b/packages/core/src/data-editor/row-grouping-api.ts @@ -25,7 +25,7 @@ export function rowGroupingMapper(itemOrRow: number | Item, flattenedRowGroups?: ...r, originalIndex: [itemOrRow[0], r.originalIndex], } as RowGroupingMapperResult; -}; +} export interface UseRowGroupingResult { readonly mapper: RowGroupingMapper;