@@ -7,43 +7,77 @@ const NOOP = () => {}
77
88export const useAutoScroll = ( hostRef , shadowBodySizeRef , selectedTab ) => {
99 const scrollPositionRef = useRef ( 0 )
10- const scrollIntervalRef = useRef ( null )
10+ const animationFrameRef = useRef ( null )
11+ const isScrollingRef = useRef ( false )
12+
13+ const smoothScrollToBottom = ( shadowDomBody , targetScrollTop ) => {
14+ if ( ! shadowDomBody || ! isScrollingRef . current ) {
15+ return
16+ }
17+
18+ const currentScrollTop = shadowDomBody . scrollTop
19+ const distance = targetScrollTop - currentScrollTop
20+ const totalDistance = shadowBodySizeRef . current . maxScrollTop
21+ const progress = 1 - ( distance / totalDistance ) // 0 at start, 1 at end
22+
23+ // If we're close enough to the target, stop scrolling
24+ if ( Math . abs ( distance ) < 1 ) {
25+ isScrollingRef . current = false
26+ return
27+ }
28+
29+ // Bell curve: faster ramp up, starts at reasonable speed, peaks in middle
30+ // Creates a more aggressive acceleration and deceleration pattern
31+ const bellCurve = 10 * progress * ( 1 - progress ) // Peaks at 2.0 in the middle
32+ const baseSpeed = 15 // Base speed multiplier
33+ const scrollStep = Math . max ( baseSpeed * bellCurve , 5 ) // Minimum 1.5px for better start
34+
35+ // Apply the scroll step
36+ shadowDomBody . scrollTop = currentScrollTop + scrollStep
37+ scrollPositionRef . current = shadowDomBody . scrollTop
38+
39+ // Continue scrolling on next frame
40+ animationFrameRef . current = requestAnimationFrame ( ( ) =>
41+ smoothScrollToBottom ( shadowDomBody , targetScrollTop )
42+ )
43+ }
1144
1245 const onMouseOverImpl = ( ) => {
1346 const shadowDomBody = hostRef ?. current ?. shadowRoot ?. querySelector ?. ( 'body' )
1447 if ( shadowDomBody && shadowBodySizeRef . current ) {
48+ // Reset scroll position and start smooth scrolling
1549 scrollPositionRef . current = 0
50+ isScrollingRef . current = true
51+
1652 setTimeout ( ( ) => {
17- if ( scrollPositionRef . current === - 1 ) {
53+ if ( scrollPositionRef . current === - 1 || ! isScrollingRef . current ) {
1854 return
1955 }
2056
21- if ( scrollIntervalRef . current ) {
22- clearInterval ( scrollIntervalRef . current )
57+ // Clear any existing animation
58+ if ( animationFrameRef . current ) {
59+ cancelAnimationFrame ( animationFrameRef . current )
2360 }
2461
25- scrollIntervalRef . current = setInterval ( ( ) => {
26- const scrollDifference = shadowBodySizeRef . current . maxScrollTop - scrollPositionRef . current
27- const shouldScroll = shadowBodySizeRef . current . maxScrollTop - scrollPositionRef . current > 0
28-
29- if ( ! shadowDomBody || ! shouldScroll ) {
30- clearInterval ( scrollIntervalRef . current )
31- return
32- }
33-
34- const scrollBy = scrollDifference >= 20 ? 20 : scrollDifference
35- shadowDomBody . scrollTop = scrollPositionRef . current + scrollBy
36- scrollPositionRef . current += scrollBy
37- } , 60 )
62+ // Start smooth scrolling to bottom
63+ const targetScrollTop = shadowBodySizeRef . current . maxScrollTop
64+ if ( targetScrollTop > 0 ) {
65+ smoothScrollToBottom ( shadowDomBody , targetScrollTop )
66+ }
3867 } , 1000 )
3968 }
4069 }
4170
4271 const onMouseOutImpl = ( ) => {
4372 const shadowDomBody = hostRef ?. current ?. shadowRoot ?. querySelector ?. ( 'body' )
4473 if ( shadowDomBody ) {
45- clearInterval ( scrollIntervalRef . current )
46- scrollIntervalRef . current = null
74+ // Stop scrolling and smoothly return to top
75+ isScrollingRef . current = false
76+ if ( animationFrameRef . current ) {
77+ cancelAnimationFrame ( animationFrameRef . current )
78+ animationFrameRef . current = null
79+ }
80+
4781 shadowDomBody . scrollTo ( {
4882 top : 0 ,
4983 behavior : 'smooth' ,
@@ -53,8 +87,12 @@ export const useAutoScroll = ( hostRef, shadowBodySizeRef, selectedTab ) => {
5387 }
5488
5589 const onMouseDownImpl = ( ) => {
56- clearInterval ( scrollIntervalRef . current )
57- scrollIntervalRef . current = null
90+ // Stop auto-scrolling when user interacts
91+ isScrollingRef . current = false
92+ if ( animationFrameRef . current ) {
93+ cancelAnimationFrame ( animationFrameRef . current )
94+ animationFrameRef . current = null
95+ }
5896 scrollPositionRef . current = - 1
5997 }
6098
0 commit comments