@@ -5,6 +5,7 @@ import React, {
5
5
useLayoutEffect ,
6
6
useRef ,
7
7
useState ,
8
+ useCallback ,
8
9
} from 'react' ;
9
10
import { TranslationsContext } from '../../providers/translations' ;
10
11
import { withGlobalProps } from '../../providers/globalProps' ;
@@ -58,20 +59,26 @@ export const ScrollView = React.forwardRef((props, ref) => {
58
59
const blankRef = useRef ( null ) ;
59
60
const scrollViewViewportEl = ref ?? blankRef ;
60
61
61
- const handleScrollViewState = ( currentPosition ) => {
62
+ const handleScrollViewState = useCallback ( ( currentPosition ) => {
62
63
const isScrolledAtStartActive = currentPosition [ scrollPositionStart ]
63
64
<= - 1 * EDGE_DETECTION_INACCURACY_PX ;
64
65
const isScrolledAtEndActive = currentPosition [ scrollPositionEnd ]
65
66
>= EDGE_DETECTION_INACCURACY_PX ;
66
67
67
- if ( isScrolledAtStartActive !== isScrolledAtStart ) {
68
- setIsScrolledAtStart ( isScrolledAtStartActive ) ;
69
- }
68
+ setIsScrolledAtStart ( ( prevIsScrolledAtStart ) => {
69
+ if ( isScrolledAtStartActive !== prevIsScrolledAtStart ) {
70
+ return isScrolledAtStartActive ;
71
+ }
72
+ return prevIsScrolledAtStart ;
73
+ } ) ;
70
74
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 ] ) ;
75
82
76
83
/**
77
84
* It handles scroll event fired on `scrollViewViewportEl` element. If autoScroll is in progress,
@@ -146,7 +153,6 @@ export const ScrollView = React.forwardRef((props, ref) => {
146
153
147
154
useScrollPosition (
148
155
( currentPosition ) => ( handleScrollViewState ( currentPosition ) ) ,
149
- [ isScrolledAtStart , isScrolledAtEnd ] ,
150
156
scrollViewContentEl ,
151
157
scrollViewViewportEl ,
152
158
debounce ,
@@ -163,6 +169,30 @@ export const ScrollView = React.forwardRef((props, ref) => {
163
169
[ autoScroll , autoScrollChildrenKeys , autoScrollChildrenLength ] ,
164
170
) ;
165
171
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
+
166
196
const arrowHandler = ( contentEl , viewportEl , scrollViewDirection , shiftDirection , step ) => {
167
197
const offset = shiftDirection === 'next' ? step : - 1 * step ;
168
198
const differenceX = scrollViewDirection === 'horizontal' ? offset : 0 ;
0 commit comments