@@ -5,6 +5,7 @@ import React, {
55 useLayoutEffect ,
66 useRef ,
77 useState ,
8+ useCallback ,
89} from 'react' ;
910import { TranslationsContext } from '../../providers/translations' ;
1011import { withGlobalProps } from '../../providers/globalProps' ;
@@ -58,20 +59,26 @@ export const ScrollView = React.forwardRef((props, ref) => {
5859 const blankRef = useRef ( null ) ;
5960 const scrollViewViewportEl = ref ?? blankRef ;
6061
61- const handleScrollViewState = ( currentPosition ) => {
62+ const handleScrollViewState = useCallback ( ( currentPosition ) => {
6263 const isScrolledAtStartActive = currentPosition [ scrollPositionStart ]
6364 <= - 1 * EDGE_DETECTION_INACCURACY_PX ;
6465 const isScrolledAtEndActive = currentPosition [ scrollPositionEnd ]
6566 >= EDGE_DETECTION_INACCURACY_PX ;
6667
67- if ( isScrolledAtStartActive !== isScrolledAtStart ) {
68- setIsScrolledAtStart ( isScrolledAtStartActive ) ;
69- }
68+ setIsScrolledAtStart ( ( prevIsScrolledAtStart ) => {
69+ if ( isScrolledAtStartActive !== prevIsScrolledAtStart ) {
70+ return isScrolledAtStartActive ;
71+ }
72+ return prevIsScrolledAtStart ;
73+ } ) ;
7074
71- if ( isScrolledAtEndActive !== isScrolledAtEnd ) {
72- setIsScrolledAtEnd ( isScrolledAtEndActive ) ;
73- }
74- } ;
75+ setIsScrolledAtEnd ( ( prevIsScrolledAtEnd ) => {
76+ if ( isScrolledAtEndActive !== prevIsScrolledAtEnd ) {
77+ return isScrolledAtEndActive ;
78+ }
79+ return prevIsScrolledAtEnd ;
80+ } ) ;
81+ } , [ scrollPositionStart , scrollPositionEnd ] ) ;
7582
7683 /**
7784 * It handles scroll event fired on `scrollViewViewportEl` element. If autoScroll is in progress,
@@ -146,7 +153,6 @@ export const ScrollView = React.forwardRef((props, ref) => {
146153
147154 useScrollPosition (
148155 ( currentPosition ) => ( handleScrollViewState ( currentPosition ) ) ,
149- [ isScrolledAtStart , isScrolledAtEnd ] ,
150156 scrollViewContentEl ,
151157 scrollViewViewportEl ,
152158 debounce ,
@@ -163,6 +169,30 @@ export const ScrollView = React.forwardRef((props, ref) => {
163169 [ autoScroll , autoScrollChildrenKeys , autoScrollChildrenLength ] ,
164170 ) ;
165171
172+ // ResizeObserver to detect when content or viewport dimensions change due to style changes
173+ useLayoutEffect ( ( ) => {
174+ const contentElement = scrollViewContentEl . current ;
175+ const viewportElement = scrollViewViewportEl . current ;
176+
177+ if ( ! contentElement || ! viewportElement ) {
178+ return ( ) => { } ;
179+ }
180+
181+ const resizeObserver = new ResizeObserver ( ( ) => {
182+ handleScrollViewState (
183+ getElementsPositionDifference ( scrollViewContentEl , scrollViewViewportEl ) ,
184+ ) ;
185+ } ) ;
186+
187+ // Observe both content and viewport for dimension changes
188+ resizeObserver . observe ( contentElement ) ;
189+ resizeObserver . observe ( viewportElement ) ;
190+
191+ return ( ) => {
192+ resizeObserver . disconnect ( ) ;
193+ } ;
194+ } , [ scrollViewContentEl , scrollViewViewportEl , handleScrollViewState ] ) ;
195+
166196 const arrowHandler = ( contentEl , viewportEl , scrollViewDirection , shiftDirection , step ) => {
167197 const offset = shiftDirection === 'next' ? step : - 1 * step ;
168198 const differenceX = scrollViewDirection === 'horizontal' ? offset : 0 ;
0 commit comments