force row height on group rows

This commit is contained in:
jeffvli
2025-11-17 19:55:17 -08:00
parent 47e47e3cc3
commit a4a0a1d227
2 changed files with 18 additions and 84 deletions
@@ -12,7 +12,6 @@ export interface GroupRowInfo {
export const useStickyTableGroupRows = ({ export const useStickyTableGroupRows = ({
containerRef, containerRef,
enabled, enabled,
getGroupRowHeight,
getRowHeight, getRowHeight,
groups, groups,
headerHeight, headerHeight,
@@ -22,9 +21,8 @@ export const useStickyTableGroupRows = ({
}: { }: {
containerRef: React.RefObject<HTMLDivElement | null>; containerRef: React.RefObject<HTMLDivElement | null>;
enabled: boolean; enabled: boolean;
getGroupRowHeight?: (groupIndex: number) => number;
getRowHeight: (index: number) => number; getRowHeight: (index: number) => number;
groups?: Array<{ itemCount: number; rowHeight?: ((index: number) => number) | number }>; groups?: Array<{ itemCount: number }>;
headerHeight: number; headerHeight: number;
mainGridRef: React.RefObject<HTMLDivElement | null>; mainGridRef: React.RefObject<HTMLDivElement | null>;
shouldShowStickyHeader?: boolean; shouldShowStickyHeader?: boolean;
@@ -125,7 +123,8 @@ export const useStickyTableGroupRows = ({
const rowViewportTop = containerTop + rowTop - scrollTop; const rowViewportTop = containerTop + rowTop - scrollTop;
// Get the height of this group row to account for its own offset // Get the height of this group row to account for its own offset
const groupRowHeight = getGroupRowHeight ? getGroupRowHeight(groupIndex) : 40; // Default group row height // Use getRowHeight to get the actual row height for the group header row
const groupRowHeight = getRowHeight(rowIndex);
// Calculate the sticky position accounting for the sticky group row's own height // Calculate the sticky position accounting for the sticky group row's own height
// Similar to how stickyTop accounts for sticky header height, we add the group row height // Similar to how stickyTop accounts for sticky header height, we add the group row height
@@ -173,7 +172,6 @@ export const useStickyTableGroupRows = ({
groupRowIndexes, groupRowIndexes,
mainGridRef, mainGridRef,
containerRef, containerRef,
getGroupRowHeight,
getRowHeight, getRowHeight,
headerHeight, headerHeight,
stickyTop, stickyTop,
@@ -574,7 +574,6 @@ export interface TableGroupHeader {
internalState: ItemListStateActions; internalState: ItemListStateActions;
startDataIndex: number; startDataIndex: number;
}) => ReactElement; }) => ReactElement;
rowHeight?: ((index: number) => number) | number;
} }
export interface TableItemProps { export interface TableItemProps {
@@ -1393,33 +1392,6 @@ export const ItemTableList = ({
(index: number, cellProps: TableItemProps) => { (index: number, cellProps: TableItemProps) => {
const height = size === 'compact' ? 40 : size === 'large' ? 88 : 64; const height = size === 'compact' ? 40 : size === 'large' ? 88 : 64;
// Check if this row is a group header row and has a custom row height
if (groups && groups.length > 0) {
// Calculate which group this index belongs to
let cumulativeDataIndex = 0;
const headerOffset = enableHeader ? 1 : 0;
for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
const group = groups[groupIndex];
const groupHeaderIndex = headerOffset + cumulativeDataIndex + groupIndex;
if (index === groupHeaderIndex) {
if (group.rowHeight !== undefined) {
const groupRowHeight =
typeof group.rowHeight === 'number'
? group.rowHeight
: group.rowHeight(index);
if (groupRowHeight !== undefined) {
return groupRowHeight;
}
}
break;
}
cumulativeDataIndex += group.itemCount;
}
}
const baseHeight = const baseHeight =
typeof rowHeight === 'number' ? rowHeight : rowHeight?.(index, cellProps) || height; typeof rowHeight === 'number' ? rowHeight : rowHeight?.(index, cellProps) || height;
@@ -1430,7 +1402,7 @@ export const ItemTableList = ({
return baseHeight; return baseHeight;
}, },
[enableHeader, headerHeight, rowHeight, pinnedRowCount, size, groups], [enableHeader, headerHeight, rowHeight, pinnedRowCount, size],
); );
// Create a wrapper for getRowHeight that doesn't require cellProps (for sticky group rows hook) // Create a wrapper for getRowHeight that doesn't require cellProps (for sticky group rows hook)
@@ -1438,32 +1410,6 @@ export const ItemTableList = ({
(index: number) => { (index: number) => {
const height = size === 'compact' ? 40 : size === 'large' ? 88 : 64; const height = size === 'compact' ? 40 : size === 'large' ? 88 : 64;
// Check if this row is a group header row and has a custom row height
if (groups && groups.length > 0) {
let cumulativeDataIndex = 0;
const headerOffset = enableHeader ? 1 : 0;
for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
const group = groups[groupIndex];
const groupHeaderIndex = headerOffset + cumulativeDataIndex + groupIndex;
if (index === groupHeaderIndex) {
if (group.rowHeight !== undefined) {
const groupRowHeight =
typeof group.rowHeight === 'number'
? group.rowHeight
: group.rowHeight(index);
if (groupRowHeight !== undefined) {
return groupRowHeight;
}
}
break;
}
cumulativeDataIndex += group.itemCount;
}
}
const baseHeight = typeof rowHeight === 'number' ? rowHeight : height; const baseHeight = typeof rowHeight === 'number' ? rowHeight : height;
// If enableHeader is true and this is the first sticky row, use fixed header height // If enableHeader is true and this is the first sticky row, use fixed header height
@@ -1473,22 +1419,7 @@ export const ItemTableList = ({
return baseHeight; return baseHeight;
}, },
[enableHeader, headerHeight, rowHeight, pinnedRowCount, size, groups], [enableHeader, headerHeight, rowHeight, pinnedRowCount, size],
);
const getGroupRowHeightWrapper = useCallback(
(groupIndex: number) => {
if (!groups || groupIndex < 0 || groupIndex >= groups.length) {
return 40;
}
const group = groups[groupIndex];
if (group.rowHeight !== undefined) {
return typeof group.rowHeight === 'number' ? group.rowHeight : group.rowHeight(0);
}
return 40;
},
[groups],
); );
const { const {
@@ -1498,7 +1429,6 @@ export const ItemTableList = ({
} = useStickyTableGroupRows({ } = useStickyTableGroupRows({
containerRef: containerFocusRef, containerRef: containerFocusRef,
enabled: enableStickyGroupRows && !!groups && groups.length > 0, enabled: enableStickyGroupRows && !!groups && groups.length > 0,
getGroupRowHeight: getGroupRowHeightWrapper,
getRowHeight: getRowHeightWrapper, getRowHeight: getRowHeightWrapper,
groups, groups,
headerHeight, headerHeight,
@@ -1917,18 +1847,24 @@ export const ItemTableList = ({
stickyHeaderItemProps, stickyHeaderItemProps,
]); ]);
// Calculate group row height // Calculate group row height (use same as regular table row height)
const groupRowHeight = useMemo(() => { const groupRowHeight = useMemo(() => {
if (stickyGroupIndex === null || !groups) { if (stickyGroupIndex === null || !groups) {
return 40; // Default const height = size === 'compact' ? 40 : size === 'large' ? 88 : 64;
return typeof rowHeight === 'number' ? rowHeight : height;
} }
const group = groups[stickyGroupIndex]; // Calculate the row index for this group header
if (group.rowHeight !== undefined) { let cumulativeDataIndex = 0;
return typeof group.rowHeight === 'number' ? group.rowHeight : group.rowHeight(0); const headerOffset = enableHeader ? 1 : 0;
for (let i = 0; i < stickyGroupIndex; i++) {
cumulativeDataIndex += groups[i].itemCount;
} }
return 40; // Default group row height const groupHeaderIndex = headerOffset + cumulativeDataIndex + stickyGroupIndex;
}, [stickyGroupIndex, groups]);
// Use the regular row height for group rows
return getRowHeightWrapper(groupHeaderIndex);
}, [stickyGroupIndex, groups, getRowHeightWrapper, enableHeader, rowHeight, size]);
const StickyGroupRow = useMemo(() => { const StickyGroupRow = useMemo(() => {
if (!shouldRenderStickyGroupRow || stickyGroupIndex === null || !groups) { if (!shouldRenderStickyGroupRow || stickyGroupIndex === null || !groups) {