handle table row indexing with group rows

This commit is contained in:
jeffvli
2025-11-17 21:57:01 -08:00
parent 8433ce7f3e
commit fd85f1f51a
2 changed files with 69 additions and 7 deletions
@@ -29,7 +29,19 @@ export const RowIndexColumn = (props: ItemTableListInnerColumn) => {
};
const DefaultRowIndexColumn = (props: ItemTableListInnerColumn) => {
const { controls, enableExpansion } = props;
const {
adjustedRowIndexMap,
controls,
data,
enableExpansion,
enableHeader,
internalState,
itemType,
rowIndex,
} = props;
const adjustedRowIndex =
adjustedRowIndexMap?.get(rowIndex) ?? (enableHeader ? rowIndex : rowIndex + 1);
if (enableExpansion) {
return (
@@ -41,28 +53,32 @@ const DefaultRowIndexColumn = (props: ItemTableListInnerColumn) => {
onClick={(e) =>
controls.onExpand?.({
event: e,
internalState: props.internalState,
item: props.data[props.rowIndex] as ItemListItem,
itemType: props.itemType,
internalState,
item: data[rowIndex] as ItemListItem,
itemType,
})
}
size="xs"
variant="subtle"
/>
<Text className="hide-on-hover" isMuted isNoSelect>
{props.rowIndex}
{adjustedRowIndex}
</Text>
</TableColumnContainer>
);
}
return <TableColumnTextContainer {...props}>{props.rowIndex}</TableColumnTextContainer>;
return <TableColumnTextContainer {...props}>{adjustedRowIndex}</TableColumnTextContainer>;
};
const QueueSongRowIndexColumn = (props: ItemTableListInnerColumn) => {
const status = usePlayerStatus();
const { isActive } = useIsCurrentSong(props.data[props.rowIndex] as QueueSong);
const adjustedRowIndex =
props.adjustedRowIndexMap?.get(props.rowIndex) ??
(props.enableHeader ? props.rowIndex : props.rowIndex + 1);
return (
<TableColumnTextContainer {...props}>
{isActive ? (
@@ -76,7 +92,7 @@ const QueueSongRowIndexColumn = (props: ItemTableListInnerColumn) => {
</Flex>
)
) : (
props.rowIndex
adjustedRowIndex
)}
</TableColumnTextContainer>
);
@@ -226,8 +226,52 @@ const VirtualizedTableGrid = React.memo(
return result;
}, [data, enableHeader, groups]);
const adjustedRowIndexMap = useMemo(() => {
const map = new Map<number, number>();
if (!groups || groups.length === 0) {
const startIndex = enableHeader ? 1 : 0;
const endIndex = enableHeader ? dataWithGroups.length : dataWithGroups.length;
for (let rowIndex = startIndex; rowIndex < endIndex; rowIndex++) {
map.set(rowIndex, enableHeader ? rowIndex : rowIndex + 1);
}
return map;
}
const groupIndexes: number[] = [];
let cumulativeDataIndex = 0;
const headerOffset = enableHeader ? 1 : 0;
groups.forEach((group, groupIndex) => {
const groupHeaderIndex = headerOffset + cumulativeDataIndex + groupIndex;
groupIndexes.push(groupHeaderIndex);
cumulativeDataIndex += group.itemCount;
});
let adjustedIndex = 1;
const startIndex = enableHeader ? 0 : 0;
const endIndex = dataWithGroups.length;
for (let rowIndex = startIndex; rowIndex < endIndex; rowIndex++) {
if (enableHeader && rowIndex === 0) {
// Header row
map.set(rowIndex, 0);
} else if (groupIndexes.includes(rowIndex)) {
// Group header row - don't increment adjustedIndex
map.set(rowIndex, 0);
} else {
// Data row
map.set(rowIndex, adjustedIndex);
adjustedIndex++;
}
}
return map;
}, [dataWithGroups, enableHeader, groups]);
const itemProps: TableItemProps = useMemo(
() => ({
adjustedRowIndexMap,
calculatedColumnWidths,
cellPadding,
columns: parsedColumns,
@@ -256,6 +300,7 @@ const VirtualizedTableGrid = React.memo(
tableId,
}),
[
adjustedRowIndexMap,
calculatedColumnWidths,
cellPadding,
controls,
@@ -577,6 +622,7 @@ export interface TableGroupHeader {
}
export interface TableItemProps {
adjustedRowIndexMap?: Map<number, number>; // Maps rowIndex to adjustedRowIndex (1-indexed, excluding group rows)
calculatedColumnWidths?: number[];
cellPadding?: ItemTableListProps['cellPadding'];
columns: ItemTableListColumnConfig[];