diff --git a/packages/bento-design-system/src/Table/Table.tsx b/packages/bento-design-system/src/Table/Table.tsx index dfa8c38e7..1724269d2 100644 --- a/packages/bento-design-system/src/Table/Table.tsx +++ b/packages/bento-design-system/src/Table/Table.tsx @@ -94,6 +94,11 @@ type Props< > = { columns: C; data: ReadonlyArray>; + groupBy?: C extends ReadonlyArray> + ? C[number]["accessor"] + : C extends ReadonlyArray> + ? C[number]["columns"][number]["accessor"] + : never; noResultsTitle?: LocalizedString; noResultsDescription?: LocalizedString; noResultsFeedbackSize?: FeedbackProps["size"]; @@ -101,18 +106,8 @@ type Props< stickyHeaders?: boolean; height?: { custom: string | number }; onRowPress?: (row: Row>) => void; -} & ( - | { - groupBy?: C extends ReadonlyArray> - ? C[number]["accessor"] - : C extends ReadonlyArray> - ? C[number]["columns"][number]["accessor"] - : never; - virtualizeRows?: never; - } - | { groupBy?: never; virtualizeRows?: boolean | { estimateRowHeight: (index: number) => number } } -) & - SortingProps; + virtualizeRows?: boolean | { estimateRowHeight: (index: number) => number }; +} & SortingProps; /** * A component that renders a Table, with sorting capabilities @@ -360,8 +355,9 @@ export function Table< .exhaustive(); } - const gridTemplateColumns = flatColumns - .filter(({ accessor }) => accessor !== groupBy) + const nonGroupedColumns = flatColumns.filter(({ accessor }) => accessor !== groupBy); + + const gridTemplateColumns = nonGroupedColumns .map(({ gridWidth = "fit-content" }) => gridWidthStyle(gridWidth)) .join(" "); @@ -385,50 +381,43 @@ export function Table< )); } - const renderedRows = virtualizeRows - ? columns - .map((_, index) => ( -
- )) - .concat( - virtualRows.map((virtualRow) => { - const index = virtualRow.index; - const row = rows[index]; - prepareRow(row); - return ( - - {renderCells(row.cells, index, onRowPress !== undefined)} - - ); - }) - ) - .concat( - columns.map((_, index) => ( -
- )) - ) - : rows.flatMap((row, index) => { - if (row.isGrouped) { - return [ - , - ...row.leafRows.map((row, index) => { - prepareRow(row); - return renderCells(row.cells, index, false); - }), - ]; - } else { + const rowsToRender = virtualizeRows + ? virtualRows.map((virtualRow) => [rows[virtualRow.index], virtualRow.index] as const) + : rows.map((row, index) => [row, index] as const); + + const paddingTopRow = virtualizeRows + ? nonGroupedColumns.map((_, index) => ( +
+ )) + : []; + const paddingBottomRow = virtualizeRows + ? nonGroupedColumns.map((_, index) => ( +
+ )) + : []; + + const renderedRows = rowsToRender.flatMap(([row, index]) => { + if (row.isGrouped) { + return [ + , + ...row.leafRows.map((row, index) => { prepareRow(row); - return ( - - {renderCells(row.cells, index, onRowPress !== undefined)} - - ); - } - }); + return renderCells(row.cells, index, false); + }), + ]; + } else { + prepareRow(row); + return ( + + {renderCells(row.cells, index, onRowPress !== undefined)} + + ); + } + }); return ( )) )} + {paddingTopRow} {renderedRows} + {paddingBottomRow} ); } diff --git a/packages/bento-design-system/stories/Components/Table.stories.tsx b/packages/bento-design-system/stories/Components/Table.stories.tsx index 7ac70ebda..6d92a4a56 100644 --- a/packages/bento-design-system/stories/Components/Table.stories.tsx +++ b/packages/bento-design-system/stories/Components/Table.stories.tsx @@ -577,3 +577,20 @@ export const VirtualizedRows = { data: repeatToLength(exampleData, 1_000), }, } satisfies Story; + +export const VirtualizedRowsGrouped = { + args: { + columns: [ + ...exampleColumns, + tableColumn.text({ + headerLabel: "Group", + accessor: "group", + }), + ] as const, + groupBy: "group", + stickyHeaders: true, + height: { custom: 340 }, + virtualizeRows: true, + data: repeatToLength(exampleData, 1_000), + }, +} satisfies Story;