Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/VirtualTable/VirtualCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ export interface VirtualCellProps<RecordType> {
* Return the width of the column by `colSpan`.
* When `colSpan` is `0` will be trade as `1`.
*/
export function getColumnWidth(colIndex: number, colSpan: number, columnsOffset: number[]) {
export function getColumnWidth(colIndex: number, colSpan: number, columnsOffset: number[]): number {
const mergedColSpan = colSpan || 1;
return columnsOffset[colIndex + mergedColSpan] - (columnsOffset[colIndex] || 0);

const startIndex = Math.max(colIndex, 0);
const endIndex = Math.min(startIndex + mergedColSpan, columnsOffset.length - 1);

const startOffset = columnsOffset[startIndex] || 0;
const endOffset = columnsOffset[endIndex] || startOffset;
return Math.max(endOffset - startOffset, 0);
Comment on lines +37 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

While this change fixes the out-of-bounds access when colSpan is large, it introduces a new issue. When calculating the width for a span starting at the first column (i.e., when colIndex is -1), the startIndex becomes 0, and startOffset is incorrectly calculated as columnsOffset[0] instead of 0. This results in an incorrect width calculation.

I suggest a more robust implementation that correctly handles all edge cases, including negative colIndex, large colSpan, and out-of-bounds colIndex values, while being more readable.

  const len = columnsOffset.length;
  const lastOffset = len > 0 ? columnsOffset[len - 1] : 0;

  const startIdx = colIndex;
  const endIdx = colIndex + mergedColSpan;

  const startOffset = startIdx < 0 ? 0 : (startIdx >= len ? lastOffset : columnsOffset[startIdx]);
  const endOffset = endIdx < 0 ? 0 : (endIdx >= len ? lastOffset : columnsOffset[endIdx]);

  return Math.max(endOffset - startOffset, 0);

}

const VirtualCell = <RecordType,>(props: VirtualCellProps<RecordType>) => {
Expand Down