Skip to content

fix(grid): restore trailing scroll emission so top rows aren't lost after fast scroll - 22.0.x#17459

Open
Zneeky wants to merge 3 commits into
22.0.xfrom
aahmedov/fix-grid-scroll-trailing-22.0.x
Open

fix(grid): restore trailing scroll emission so top rows aren't lost after fast scroll - 22.0.x#17459
Zneeky wants to merge 3 commits into
22.0.xfrom
aahmedov/fix-grid-scroll-trailing-22.0.x

Conversation

@Zneeky

@Zneeky Zneeky commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Closes #17287

Description

Fixes a regression where the top rows of igx-grid / igx-tree-grid /
igx-hierarchical-grid could become invisible after a fast momentum/inertia
scroll back to the top. The scrollbar reports scrollTop ≈ 0, but the
virtualized rows stay frozen at an intermediate startIndex (~row 10–15).

The vertical-scroll throttle on scrollNotify was passing no config, so it
used RxJS's default { leading: true, trailing: false }. The trailing edge
is what guarantees the final settle position of a scroll gets processed, so
without it the last events of a momentum flick (including the scrollTop ≈ 0
settle) were dropped. Restoring { leading: true, trailing: true } fixes this
while keeping the immediate leading-edge response.

Motivation / Context

The throttle originally used
throttleTime(THROTTLE_TIME, animationFrameScheduler, { leading: false, trailing: true }).
When it was changed to a data-size–dependent throttle(durationSelector) (in
"feat(grids): Apply different throttle based on the amount of data in display"),
the config object was dropped and the operator fell back to the RxJS default
{ leading: true, trailing: false }.

Without the trailing edge, the last scroll events of a momentum flick fall inside
a throttle window (up to 60 ms for large grids) and are discarded.
verticalScrollContainer.onScroll never runs for the final position, so
virtualization stays at the last leading startIndex while the DOM scrollbar
settles at the top → the top rows appear missing.

The fix keeps leading: true (matching current master, so timing-sensitive
scroll/navigation tests are unaffected) and adds trailing: true to restore the
guarantee that the final resting scroll position is always handled — a strict
superset of the current behavior. Independent of zone/zoneless change detection.

Backported to 21.2.x and 22.0.x.

Copilot AI review requested due to automatic review settings July 24, 2026 08:51

Copilot AI left a comment

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.

Pull request overview

Restores correct vertical scroll handling in the shared grid base directive by ensuring throttled scroll notifications emit on the trailing edge, preventing virtualization from getting “stuck” at an intermediate startIndex after fast momentum scrolling back to the top.

Changes:

  • Adds { leading: true, trailing: true } throttle configuration to scrollNotify handling so the final “settle” scroll position is processed.
  • Adds inline rationale explaining why trailing-edge emission is required for correctness in momentum/inertia scrolling scenarios.

Comment thread projects/igniteui-angular/grids/grid/src/grid-base.directive.ts
Zneeky and others added 2 commits July 24, 2026 12:57
Drives the vertical scrollNotify stream with an intermediate (leading-edge)
position followed by a scrollTop=0 settle in the same throttle window, so the
settle can only be delivered on the trailing edge. Asserts the grid resets to
startIndex 0 / renders row 0, guarding against the dropped-trailing throttle
config that left the top rows frozen out of view.
@Zneeky
Zneeky requested a review from ChronosSF July 24, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants