Skip to content

Commit d75e1f7

Browse files
devongovettalunyov
authored andcommitted
Add support for onScrollEnd event (facebook#26789)
## 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.
1 parent 50340b2 commit d75e1f7

File tree

8 files changed

+186
-37
lines changed

8 files changed

+186
-37
lines changed

packages/react-dom-bindings/src/client/ReactDOMComponent.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,15 @@ function setProp(
588588
}
589589
break;
590590
}
591+
case 'onScrollEnd': {
592+
if (value != null) {
593+
if (__DEV__ && typeof value !== 'function') {
594+
warnForInvalidEventListener(key, value);
595+
}
596+
listenToNonDelegatedEvent('scrollend', domElement);
597+
}
598+
break;
599+
}
591600
case 'dangerouslySetInnerHTML': {
592601
if (value != null) {
593602
if (typeof value !== 'object' || !('__html' in value)) {
@@ -956,6 +965,15 @@ function setPropOnCustomElement(
956965
}
957966
break;
958967
}
968+
case 'onScrollEnd': {
969+
if (value != null) {
970+
if (__DEV__ && typeof value !== 'function') {
971+
warnForInvalidEventListener(key, value);
972+
}
973+
listenToNonDelegatedEvent('scrollend', domElement);
974+
}
975+
break;
976+
}
959977
case 'onClick': {
960978
// TODO: This cast may not be sound for SVG, MathML or custom elements.
961979
if (value != null) {
@@ -2815,6 +2833,10 @@ export function diffHydratedProperties(
28152833
listenToNonDelegatedEvent('scroll', domElement);
28162834
}
28172835

2836+
if (props.onScrollEnd != null) {
2837+
listenToNonDelegatedEvent('scrollend', domElement);
2838+
}
2839+
28182840
if (props.onClick != null) {
28192841
// TODO: This cast may not be sound for SVG, MathML or custom elements.
28202842
trapClickOnNonInteractiveElement(((domElement: any): HTMLElement));

packages/react-dom-bindings/src/events/DOMEventNames.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export type DOMEventName =
8888
| 'reset'
8989
| 'resize'
9090
| 'scroll'
91+
| 'scrollend'
9192
| 'seeked'
9293
| 'seeking'
9394
| 'select'

packages/react-dom-bindings/src/events/DOMEventProperties.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const simpleEventPluginEvents = [
9696
'touchStart',
9797
'volumeChange',
9898
'scroll',
99+
'scrollEnd',
99100
'toggle',
100101
'touchMove',
101102
'waiting',

packages/react-dom-bindings/src/events/DOMPluginEventSystem.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ export const nonDelegatedEvents: Set<DOMEventName> = new Set([
226226
'invalid',
227227
'load',
228228
'scroll',
229+
'scrollend',
229230
'toggle',
230231
// In order to reduce bytes, we insert the above array of media events
231232
// into this Set. Note: the "error" event isn't an exclusive media event,

packages/react-dom-bindings/src/events/TopLevelEventTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export type TopLevelType =
7373
| 'reset'
7474
| 'resize'
7575
| 'scroll'
76+
| 'scrollend'
7677
| 'seeked'
7778
| 'seeking'
7879
| 'selectionchange'

packages/react-dom-bindings/src/events/plugins/SimpleEventPlugin.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ function extractEvents(
140140
SyntheticEventCtor = SyntheticTransitionEvent;
141141
break;
142142
case 'scroll':
143+
case 'scrollend':
143144
SyntheticEventCtor = SyntheticUIEvent;
144145
break;
145146
case 'wheel':
@@ -199,7 +200,7 @@ function extractEvents(
199200
// nonDelegatedEvents list in DOMPluginEventSystem.
200201
// Then we can remove this special list.
201202
// This is a breaking change that can wait until React 18.
202-
domEventName === 'scroll';
203+
(domEventName === 'scroll' || domEventName === 'scrollend');
203204

204205
const listeners = accumulateSinglePhaseListeners(
205206
targetInst,

0 commit comments

Comments
 (0)