Skip to content

NXT-9810: Added support for scrollend event#3389

Merged
alexandrumorariu merged 37 commits intodevelopfrom
feature/NXT-9810
Feb 25, 2026
Merged

NXT-9810: Added support for scrollend event#3389
alexandrumorariu merged 37 commits intodevelopfrom
feature/NXT-9810

Conversation

@daniel-stoian-lgp
Copy link
Contributor

@daniel-stoian-lgp daniel-stoian-lgp commented Feb 11, 2026

Checklist

  • I have read and understand the contribution guide
  • A CHANGELOG entry is included
  • At least one test case is included for this feature or bug fix
  • Documentation was added or is not needed
  • This is an API breaking change

Issue Resolved / Feature Added

scrollend event was launched https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollend_event

Resolution

Added scrollend event support, with fallback for older browsers

Scenario: User scrolls with mouse wheel

Before
User scrolls
onScroll fires (many times per second)
scrollStopJob.start() - Restarts 200ms timer on EVERY scroll event
onScroll fires again... timer resets
onScroll fires again... timer resets
User stops scrolling
No more onScroll events...
Wait 200ms...
Timer expires → scrollStopOnScroll() is called
Result - 200ms delay

After
User scrolls
The implementation now uses hybrid logic - different behavior for different scroll types:

  1. For Mouse/Touch Scrolling
    User scrolls with mouse wheel
    onScroll fires (many times)
    scrollStopJob.start() - Starts 200ms fallback timer
    onScroll fires again... fallback timer resets
    User stops scrolling
    Browser fires 'scrollend' event
    onScrollEnd() called
    → isScrollAnimationTargetAccumulated? NO (mouse/touch)
    → scrollStopOnScroll() called immediately
    → scrollStopJob.stop() - Cancel fallback timer
    Result: Instant scroll end detection (~0ms delay)

  2. For Keyboard Scrolling (Accumulating)
    User holds arrow key down
    onScroll fires (many times)
    scrollStopJob.start() - Starts 200ms fallback timer
    onScroll fires again... fallback timer resets
    scrollEndGraceTimer cleared (allows accumulation to continue)
    User releases arrow key
    Browser's smooth scroll continues briefly...
    Browser fires 'scrollend' event
    onScrollEnd() called
    → isScrollAnimationTargetAccumulated? YES (keyboard)
    → Start 100ms grace timer
    → scrollStopJob.stop() - Cancel fallback timer
    More 'scrollend' events might fire (smooth scroll continuing)...
    → Each one restarts the 100ms grace timer
    100ms passes with no new scrollend events
    Grace timer expires → scrollStopOnScroll() called
    Result: 100ms debounced scroll end (prevents callback spam)

Additional Considerations

No changelog because the component is private
JSDOM does not support scrollend event , so the unit tests cannot cover scrollend

Another issue that was solved: Vertical wheel scrolling triggered onScrollStop twice - once from the 200ms fallback timer, and again from the scrollend event arriving late.
Solution:

  • Added early return in onScrollEnd if scrolling is already false (prevents duplicate call when fallback timer fires first)
  • Set isScrollAnimationTargetAccumulated = true in onScroll for native mode (ensures scrollend uses grace period)
  • Don't restart fallback timer if already in grace period (prevents late onScroll from interfering)

Links

NXT-9810

Comments

Enact-DCO-1.0-Signed-off-by: Daniel Stoian (daniel.stoian@lgepartner.com)

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

❌ Patch coverage is 55.26316% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.85%. Comparing base (85353b5) to head (96f1355).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
packages/ui/useScroll/useScroll.js 42.85% 13 Missing and 3 partials ⚠️
packages/ui/useScroll/utilEvent.js 90.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3389      +/-   ##
===========================================
+ Coverage    83.18%   83.85%   +0.66%     
===========================================
  Files          154      154              
  Lines         7332     7388      +56     
  Branches      1927     1942      +15     
===========================================
+ Hits          6099     6195      +96     
+ Misses         969      941      -28     
+ Partials       264      252      -12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@alexandrumorariu alexandrumorariu left a comment

Choose a reason for hiding this comment

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

LGTM

@alexandrumorariu alexandrumorariu merged commit a2e050c into develop Feb 25, 2026
7 of 8 checks passed
@alexandrumorariu alexandrumorariu deleted the feature/NXT-9810 branch February 25, 2026 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants