Skip to content

Commit e79c076

Browse files
authored
Feat: Add onscrollend event listener to ScrollView (#8573)
1 parent b205696 commit e79c076

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

packages/@react-aria/virtualizer/src/ScrollView.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ React.forwardRef(ScrollView);
5757
export {ScrollViewForwardRef as ScrollView};
5858

5959
interface ScrollViewAria {
60+
isScrolling: boolean,
6061
scrollViewProps: HTMLAttributes<HTMLElement>,
6162
contentProps: HTMLAttributes<HTMLElement>
6263
}
@@ -84,6 +85,16 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement
8485
let {direction} = useLocale();
8586

8687
let [isScrolling, setScrolling] = useState(false);
88+
89+
let onScrollTimeout = useCallback(() => {
90+
state.isScrolling = false;
91+
setScrolling(false);
92+
state.scrollTimeout = null;
93+
94+
window.dispatchEvent(new Event('tk.connect-observer'));
95+
onScrollEnd?.();
96+
}, [state, onScrollEnd]);
97+
8798
let onScroll = useCallback((e) => {
8899
if (e.target !== e.currentTarget) {
89100
return;
@@ -117,30 +128,21 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement
117128
// keep track of the current timeout time and only reschedule
118129
// the timer when it is getting close.
119130
let now = Date.now();
120-
if (state.scrollEndTime <= now + 50) {
131+
if (!('onscrollend' in window) && state.scrollEndTime <= now + 50) {
121132
state.scrollEndTime = now + 300;
122133

123134
if (state.scrollTimeout != null) {
124135
clearTimeout(state.scrollTimeout);
125136
}
126137

127-
state.scrollTimeout = setTimeout(() => {
128-
state.isScrolling = false;
129-
setScrolling(false);
130-
state.scrollTimeout = null;
131-
132-
window.dispatchEvent(new Event('tk.connect-observer'));
133-
if (onScrollEnd) {
134-
onScrollEnd();
135-
}
136-
}, 300);
138+
state.scrollTimeout = setTimeout(onScrollTimeout, 300);
137139
}
138140
});
139-
}, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollEnd]);
141+
}, [props, direction, state, contentSize, onVisibleRectChange, onScrollStart, onScrollTimeout]);
140142

141143
// Attach event directly to ref so RAC Virtualizer doesn't need to send props upward.
142144
useEvent(ref, 'scroll', onScroll);
143-
145+
useEvent(ref, 'scrollend', onScrollTimeout);
144146

145147
useEffect(() => {
146148
return () => {
@@ -265,6 +267,7 @@ export function useScrollView(props: ScrollViewProps, ref: RefObject<HTMLElement
265267
};
266268

267269
return {
270+
isScrolling,
268271
scrollViewProps: {
269272
...otherProps,
270273
style

0 commit comments

Comments
 (0)