From 7324005e9f62982e75c2166db873f32203738b7b Mon Sep 17 00:00:00 2001 From: Luis Gustavo Date: Tue, 4 Jun 2024 07:25:27 -0300 Subject: [PATCH 1/3] Passing generateGroupId props --- src/TreeDataGrid.tsx | 16 +++++++++++++--- test/TreeDataGrid.test.tsx | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/TreeDataGrid.tsx b/src/TreeDataGrid.tsx index 2de102da6d..4b855b26c6 100644 --- a/src/TreeDataGrid.tsx +++ b/src/TreeDataGrid.tsx @@ -36,6 +36,7 @@ export interface TreeDataGridProps ) => Record[]>; expandedGroupIds: ReadonlySet; onExpandedGroupIdsChange: (expandedGroupIds: Set) => void; + generateGroupId: ((groupKey: string, parentId?: string) => string) | undefined; } type GroupByDictionary = Record< @@ -62,6 +63,7 @@ function TreeDataGrid( rowGrouper, expandedGroupIds, onExpandedGroupIdsChange, + generateGroupId, ...props }: TreeDataGridProps, ref: React.Ref @@ -144,6 +146,15 @@ function TreeDataGrid( if (!groupedRows) return [rawRows, isGroupRow]; const flattenedRows: Array> = []; + + const groupIdGenerator = (groupKey: string, parentId?: string) => { + if (generateGroupId !== undefined && typeof generateGroupId === 'function') { + return generateGroupId(groupKey, parentId); + } + + return `${parentId}__${groupKey}`; + }; + const expandGroup = ( rows: GroupByDictionary | readonly R[], parentId: string | undefined, @@ -154,8 +165,7 @@ function TreeDataGrid( return; } Object.keys(rows).forEach((groupKey, posInSet, keys) => { - // TODO: should users have control over the generated key? - const id = parentId !== undefined ? `${parentId}__${groupKey}` : groupKey; + const id = groupIdGenerator(groupKey, parentId); const isExpanded = expandedGroupIds.has(id); const { childRows, childGroups, startRowIndex } = rows[groupKey]; @@ -185,7 +195,7 @@ function TreeDataGrid( function isGroupRow(row: R | GroupRow): row is GroupRow { return allGroupRows.has(row); } - }, [expandedGroupIds, groupedRows, rawRows]); + }, [expandedGroupIds, groupedRows, rawRows, generateGroupId]); const rowHeight = useMemo(() => { if (typeof rawRowHeight === 'function') { diff --git a/test/TreeDataGrid.test.tsx b/test/TreeDataGrid.test.tsx index 1f252bf5db..a592511503 100644 --- a/test/TreeDataGrid.test.tsx +++ b/test/TreeDataGrid.test.tsx @@ -93,7 +93,12 @@ function rowKeyGetter(row: Row) { return row.id; } -function TestGrid({ groupBy }: { groupBy: string[] }) { +interface TestGridProps { + groupBy: string[]; + generateGroupId: ((groupKey: string, parentId?: string) => string) | undefined; +} + +function TestGrid({ groupBy, generateGroupId }: TestGridProps) { const [rows, setRows] = useState(initialRows); const [selectedRows, setSelectedRows] = useState((): ReadonlySet => new Set()); const [expandedGroupIds, setExpandedGroupIds] = useState( @@ -122,12 +127,16 @@ function TestGrid({ groupBy }: { groupBy: string[] }) { onExpandedGroupIdsChange={setExpandedGroupIds} onRowsChange={setRows} onPaste={onPaste} + generateGroupId={generateGroupId} /> ); } -function setup(groupBy: string[]) { - render(); +function setup( + groupBy: string[], + generateGroupId?: (groupKey: string, parentId?: string) => string +) { + render(); } function getHeaderCellsContent() { @@ -161,6 +170,15 @@ test('should group by multiple columns', () => { expect(getRows()).toHaveLength(4); }); +test('should group by multiple columns when passing generateGroupId', () => { + setup(['country', 'year'], (groupKey, parentId) => + parentId !== undefined ? `${groupKey}#${parentId}` : groupKey + ); + expect(getTreeGrid()).toHaveAttribute('aria-rowcount', '13'); + expect(getHeaderCellsContent()).toStrictEqual(['', 'Country', 'Year', 'Sport', 'Id']); + expect(getRows()).toHaveLength(4); +}); + test('should ignore duplicate groupBy columns', () => { setup(['year', 'year', 'year']); expect(getTreeGrid()).toHaveAttribute('aria-rowcount', '10'); @@ -184,6 +202,18 @@ test('should toggle group when group cell is clicked', async () => { expect(getRows()).toHaveLength(5); }); +test('should toggle group when group cell is clicked and is passing `generateGroupId` props', async () => { + setup(['country', 'year'], (groupKey, parentId) => + parentId !== undefined ? `${groupKey}#${parentId}` : groupKey + ); + expect(getTreeGrid()).toHaveAttribute('aria-rowcount', '13'); + expect(getHeaderCellsContent()).toStrictEqual(['', 'Country', 'Year', 'Sport', 'Id']); + await userEvent.click(screen.getByRole('gridcell', { name: 'USA' })); + expect(getRows()).toHaveLength(6); + await userEvent.click(screen.getByRole('gridcell', { name: 'Canada' })); + expect(getRows()).toHaveLength(8); +}); + test('should toggle group using keyboard', async () => { setup(['year']); expect(getRows()).toHaveLength(5); From c57c77ae92c36ebae484d8f5e40f8a1f55a73fda Mon Sep 17 00:00:00 2001 From: Luis Gustavo Date: Tue, 4 Jun 2024 07:42:54 -0300 Subject: [PATCH 2/3] expand all levels --- test/TreeDataGrid.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/TreeDataGrid.test.tsx b/test/TreeDataGrid.test.tsx index a592511503..5e7630e9fe 100644 --- a/test/TreeDataGrid.test.tsx +++ b/test/TreeDataGrid.test.tsx @@ -212,6 +212,8 @@ test('should toggle group when group cell is clicked and is passing `generateGro expect(getRows()).toHaveLength(6); await userEvent.click(screen.getByRole('gridcell', { name: 'Canada' })); expect(getRows()).toHaveLength(8); + await userEvent.click(screen.getByRole('gridcell', { name: '2020' })); + expect(getRows()).toHaveLength(9); }); test('should toggle group using keyboard', async () => { From d3ea22e8862dd52a0bccfc33c3ff0284e78c741f Mon Sep 17 00:00:00 2001 From: Luis Gustavo Date: Tue, 4 Jun 2024 07:44:18 -0300 Subject: [PATCH 3/3] conditional props in test --- src/TreeDataGrid.tsx | 2 +- test/TreeDataGrid.test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TreeDataGrid.tsx b/src/TreeDataGrid.tsx index 4b855b26c6..7aea6211aa 100644 --- a/src/TreeDataGrid.tsx +++ b/src/TreeDataGrid.tsx @@ -36,7 +36,7 @@ export interface TreeDataGridProps ) => Record[]>; expandedGroupIds: ReadonlySet; onExpandedGroupIdsChange: (expandedGroupIds: Set) => void; - generateGroupId: ((groupKey: string, parentId?: string) => string) | undefined; + generateGroupId?: (groupKey: string, parentId?: string) => string; } type GroupByDictionary = Record< diff --git a/test/TreeDataGrid.test.tsx b/test/TreeDataGrid.test.tsx index 5e7630e9fe..0f55399445 100644 --- a/test/TreeDataGrid.test.tsx +++ b/test/TreeDataGrid.test.tsx @@ -127,7 +127,7 @@ function TestGrid({ groupBy, generateGroupId }: TestGridProps) { onExpandedGroupIdsChange={setExpandedGroupIds} onRowsChange={setRows} onPaste={onPaste} - generateGroupId={generateGroupId} + {...(generateGroupId && { generateGroupId })} /> ); }