diff --git a/packages/@react-aria/collections/src/ScrollView.tsx b/packages/@react-aria/collections/src/ScrollView.tsx index baaebb17901..4dd6de515ee 100644 --- a/packages/@react-aria/collections/src/ScrollView.tsx +++ b/packages/@react-aria/collections/src/ScrollView.tsx @@ -48,8 +48,12 @@ function ScrollView(props: ScrollViewProps, ref: RefObject) { let [isScrolling, setScrolling] = useState(false); let onScroll = useCallback((e) => { flushSync(() => { - state.scrollTop = e.currentTarget.scrollTop; - state.scrollLeft = e.currentTarget.scrollLeft; + let {scrollTop, scrollLeft, scrollHeight, scrollWidth, clientHeight, clientWidth} = e.currentTarget; + + // Prevent rubber band scrolling from shaking when scrolling out of bounds + state.scrollTop = Math.max(0, Math.min(scrollTop, scrollHeight - clientHeight)); + state.scrollLeft = Math.max(0, Math.min(scrollLeft, scrollWidth - clientWidth)); + onVisibleRectChange(new Rect(state.scrollLeft, state.scrollTop, state.width, state.height)); if (!isScrolling) {