Account for sticky section header when scrolling a row into view

Arrow-key navigation scrolled the newly selected row flush with the top
of the view, leaving it hidden behind the pinned sticky section header.
Reserve a row's worth of space at the top so the row lands below the
pinned header.

Fixes #5959
This commit is contained in:
Dan Stillman 2026-06-19 14:26:49 -04:00
parent e71bd89e0d
commit bdf79336f9
2 changed files with 16 additions and 4 deletions

View file

@ -813,7 +813,16 @@ class VirtualizedTable extends React.Component {
* @param index {Number}
*/
scrollToRow(index) {
this._jsWindow && this._jsWindow.scrollToRow(index);
if (!this._jsWindow) return;
// When a sticky section header is pinned at the top of the view, it overlays the rows
// below it. Reserve a row's worth of space so a row scrolled up into view lands below the
// pinned header rather than behind it.
let topOffset = 0;
if (this.props.stickySectionHeaders && !this.props.isSectionHeader(index)
&& this._getSectionHeaderIndices().some(i => i < index)) {
topOffset = this._rowHeight;
}
this._jsWindow.scrollToRow(index, false, topOffset);
}
/**

View file

@ -205,8 +205,11 @@ module.exports = class {
* @param {Integer} index
* @param {Boolean} forceScrollToTop If true, the row will be scrolled to the top of the scrollbox
* even if it is below the current scroll window.
* @param {Integer} topOffset Amount of space reserved at the top of the scrollbox (e.g. for a
* sticky section header that overlays the rows). When scrolling a row into view from above, the
* row is positioned below this offset rather than flush with the top edge.
*/
scrollToRow(index, forceScrollToTop = false) {
scrollToRow(index, forceScrollToTop = false, topOffset = 0) {
const { scrollOffset } = this;
const itemCount = this._getItemCount();
const height = this.getWindowHeight();
@ -221,8 +224,8 @@ module.exports = class {
this.scrollTo(startPosition);
return;
}
if (startPosition < scrollOffset) {
this.scrollTo(startPosition);
if (startPosition - topOffset < scrollOffset) {
this.scrollTo(startPosition - topOffset);
}
else if (endPosition > scrollOffset + height) {
this.scrollTo(endPosition - height - 1);