Skip to content
Open
Show file tree
Hide file tree
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
14 changes: 8 additions & 6 deletions src/FixedHolder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,31 +131,33 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
className: `${prefixCls}-cell-scrollbar`,
}),
};
const shouldAppendScrollBarColumn = combinationScrollBarSize && !noData;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

While this change correctly prevents the scrollbar column from being appended to the header when the table is empty, it is incomplete. The headerStickyOffsets calculation (around line 156) still uses combinationScrollBarSize directly, which means fixed columns will still have sticky offsets that account for a non-existent scrollbar. This leads to an incorrect layout gap in the empty state, as seen in the updated snapshots (e.g., inset-inline-end: 15px remaining despite the column removal). You should also update the headerStickyOffsets logic to use shouldAppendScrollBarColumn instead of combinationScrollBarSize.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch. This finding was valid.

I updated headerStickyOffsets to use the same shouldAppendScrollBarColumn condition, so the scrollbar width is only included when the scrollbar placeholder column is actually appended.

This was pushed in ca3af2e, and I re-ran pnpm test tests/FixedColumn.spec.tsx -u to verify the empty-state fixed-column layout stays in sync.


const columnsWithScrollbar = useMemo<ColumnsType<unknown>>(
() => (combinationScrollBarSize ? [...columns, ScrollBarColumn] : columns),
[combinationScrollBarSize, columns],
() => (shouldAppendScrollBarColumn ? [...columns, ScrollBarColumn] : columns),
[shouldAppendScrollBarColumn, columns],
);

const flattenColumnsWithScrollbar = useMemo(
() => (combinationScrollBarSize ? [...flattenColumns, ScrollBarColumn] : flattenColumns),
[combinationScrollBarSize, flattenColumns],
() => (shouldAppendScrollBarColumn ? [...flattenColumns, ScrollBarColumn] : flattenColumns),
[shouldAppendScrollBarColumn, flattenColumns],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
);

// Calculate the sticky offsets
const headerStickyOffsets = useMemo(() => {
const { start, end } = stickyOffsets;
const scrollbarOffset = shouldAppendScrollBarColumn ? combinationScrollBarSize : 0;
return {
...stickyOffsets,
// left:
// direction === 'rtl' ? [...left.map(width => width + combinationScrollBarSize), 0] : left,
// right:
// direction === 'rtl' ? right : [...right.map(width => width + combinationScrollBarSize), 0],
start: start,
end: [...end.map(width => width + combinationScrollBarSize), 0],
end: [...end.map(width => width + scrollbarOffset), 0],
isSticky,
};
}, [combinationScrollBarSize, stickyOffsets, isSticky]);
}, [shouldAppendScrollBarColumn, combinationScrollBarSize, stickyOffsets, isSticky]);

const mergedColumnWidth = useColumnWidth(colWidths, columCount);

Expand Down
24 changes: 24 additions & 0 deletions tests/FixedColumn.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,30 @@ describe('Table.FixedColumn', () => {

expect(container.querySelector('colgroup')?.outerHTML).toMatchSnapshot();
});

it('does not render scrollbar header cell when data is empty', async () => {
const { container } = render(
<Table columns={columns} data={[]} scroll={{ x: 1200, y: 100 }} />,
);

await triggerResize(container.querySelector<HTMLElement>('.rc-table'));

act(() => {
const coll = container.querySelector('.rc-table-resize-collection');
if (coll) {
triggerResize(coll as HTMLElement);
}
});

await act(async () => {
vi.runAllTimers();
await Promise.resolve();
});

expect(container.querySelectorAll('thead .rc-table-cell-scrollbar')).toHaveLength(0);
expect(container.querySelector('.rc-table-placeholder')).toBeTruthy();
vi.useRealTimers();
});
});

it('has correct scroll classNames when table resize', async () => {
Expand Down
10 changes: 3 additions & 7 deletions tests/__snapshots__/FixedColumn.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2723,14 +2723,14 @@ exports[`Table.FixedColumn > renders correctly > scrollXY - without data 1`] = `
<th
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-start"
scope="col"
style="inset-inline-start: 0px; --z-offset: 26; --z-offset-reverse: 13;"
style="inset-inline-start: 0px; --z-offset: 24; --z-offset-reverse: 12;"
>
title1
</th>
<th
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-start rc-table-cell-fix-start-shadow rc-table-cell-ellipsis"
scope="col"
style="inset-inline-start: 1000px; --z-offset: 25; --z-offset-reverse: 14;"
style="inset-inline-start: 1000px; --z-offset: 23; --z-offset-reverse: 13;"
title="title2"
>
<span
Expand Down Expand Up @@ -2796,14 +2796,10 @@ exports[`Table.FixedColumn > renders correctly > scrollXY - without data 1`] = `
<th
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-end rc-table-cell-fix-end-shadow"
scope="col"
style="inset-inline-end: 15px; --z-offset: 11; --z-offset-reverse: 2;"
style="inset-inline-end: 0px; --z-offset: 11; --z-offset-reverse: 1;"
>
title12
</th>
<th
class="rc-table-cell rc-table-cell-fix rc-table-cell-fix-end rc-table-cell-scrollbar"
style="inset-inline-end: 0px; --z-offset: 12; --z-offset-reverse: 1;"
/>
</tr>
</thead>
</table>
Expand Down