Skip to content

Commit

Permalink
Add support for onScrollEnd event (#26789)
Browse files Browse the repository at this point in the history
## Summary

This adds support for the new
[scrollend](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollend_event)
event. It was recently added to the spec, and is currently supported in
Firefox 109 and Chrome Canary (shipping in Chrome 114). You can read
more about this event
[here](https://developer.chrome.com/blog/scrollend-a-new-javascript-event/).
This PR adds support for the `onScrollEnd` prop, following the
implementation for `onScroll`.

## How did you test this change?

Added unit tests.
  • Loading branch information
devongovett authored Oct 11, 2023
1 parent be67db4 commit 537228f
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 37 deletions.
22 changes: 22 additions & 0 deletions packages/react-dom-bindings/src/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,15 @@ function setProp(
}
break;
}
case 'onScrollEnd': {
if (value != null) {
if (__DEV__ && typeof value !== 'function') {
warnForInvalidEventListener(key, value);
}
listenToNonDelegatedEvent('scrollend', domElement);
}
break;
}
case 'dangerouslySetInnerHTML': {
if (value != null) {
if (typeof value !== 'object' || !('__html' in value)) {
Expand Down Expand Up @@ -956,6 +965,15 @@ function setPropOnCustomElement(
}
break;
}
case 'onScrollEnd': {
if (value != null) {
if (__DEV__ && typeof value !== 'function') {
warnForInvalidEventListener(key, value);
}
listenToNonDelegatedEvent('scrollend', domElement);
}
break;
}
case 'onClick': {
// TODO: This cast may not be sound for SVG, MathML or custom elements.
if (value != null) {
Expand Down Expand Up @@ -2815,6 +2833,10 @@ export function diffHydratedProperties(
listenToNonDelegatedEvent('scroll', domElement);
}

if (props.onScrollEnd != null) {
listenToNonDelegatedEvent('scrollend', domElement);
}

if (props.onClick != null) {
// TODO: This cast may not be sound for SVG, MathML or custom elements.
trapClickOnNonInteractiveElement(((domElement: any): HTMLElement));
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom-bindings/src/events/DOMEventNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export type DOMEventName =
| 'reset'
| 'resize'
| 'scroll'
| 'scrollend'
| 'seeked'
| 'seeking'
| 'select'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const simpleEventPluginEvents = [
'touchStart',
'volumeChange',
'scroll',
'scrollEnd',
'toggle',
'touchMove',
'waiting',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export const nonDelegatedEvents: Set<DOMEventName> = new Set([
'invalid',
'load',
'scroll',
'scrollend',
'toggle',
// In order to reduce bytes, we insert the above array of media events
// into this Set. Note: the "error" event isn't an exclusive media event,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export type TopLevelType =
| 'reset'
| 'resize'
| 'scroll'
| 'scrollend'
| 'seeked'
| 'seeking'
| 'selectionchange'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ function extractEvents(
SyntheticEventCtor = SyntheticTransitionEvent;
break;
case 'scroll':
case 'scrollend':
SyntheticEventCtor = SyntheticUIEvent;
break;
case 'wheel':
Expand Down Expand Up @@ -199,7 +200,7 @@ function extractEvents(
// nonDelegatedEvents list in DOMPluginEventSystem.
// Then we can remove this special list.
// This is a breaking change that can wait until React 18.
domEventName === 'scroll';
(domEventName === 'scroll' || domEventName === 'scrollend');

const listeners = accumulateSinglePhaseListeners(
targetInst,
Expand Down
Loading

0 comments on commit 537228f

Please sign in to comment.