@@ -9,6 +9,9 @@ const SCROLL_NEAR_BOTTOM_THRESHOLD = 1
99const ANIMATION_FRAME_INTERVAL_MS = 16 // ~60fps
1010const DEFAULT_SCROLL_ANIMATION_DURATION_MS = 200
1111
12+ // Page scroll amount (fraction of viewport height)
13+ const PAGE_SCROLL_FRACTION = 0.8
14+
1215// Delay before auto-scrolling after content changes
1316const AUTO_SCROLL_DELAY_MS = 50
1417
@@ -86,6 +89,30 @@ export const useChatScrollbox = (
8689 animateScrollTo ( maxScroll )
8790 } , [ scrollRef , animateScrollTo ] )
8891
92+ const scrollUp = useCallback ( ( ) : void => {
93+ const scrollbox = scrollRef . current
94+ if ( ! scrollbox ) return
95+
96+ const viewportHeight = scrollbox . viewport . height
97+ const scrollAmount = Math . floor ( viewportHeight * PAGE_SCROLL_FRACTION )
98+ const targetScroll = Math . max ( 0 , scrollbox . scrollTop - scrollAmount )
99+ animateScrollTo ( targetScroll )
100+ } , [ scrollRef , animateScrollTo ] )
101+
102+ const scrollDown = useCallback ( ( ) : void => {
103+ const scrollbox = scrollRef . current
104+ if ( ! scrollbox ) return
105+
106+ const viewportHeight = scrollbox . viewport . height
107+ const maxScroll = Math . max (
108+ 0 ,
109+ scrollbox . scrollHeight - viewportHeight ,
110+ )
111+ const scrollAmount = Math . floor ( viewportHeight * PAGE_SCROLL_FRACTION )
112+ const targetScroll = Math . min ( maxScroll , scrollbox . scrollTop + scrollAmount )
113+ animateScrollTo ( targetScroll )
114+ } , [ scrollRef , animateScrollTo ] )
115+
89116 useEffect ( ( ) => {
90117 const scrollbox = scrollRef . current
91118 if ( ! scrollbox ) return
@@ -149,6 +176,8 @@ export const useChatScrollbox = (
149176
150177 return {
151178 scrollToLatest,
179+ scrollUp,
180+ scrollDown,
152181 scrollboxProps : { } ,
153182 isAtBottom,
154183 }
0 commit comments