Skip to content

Commit f9cbd6b

Browse files
committed
fix(cli): reduce scrollbar jitter by tracking overflow state changes with ref
1 parent c042bae commit f9cbd6b

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

cli/src/chat.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ export const Chat = ({
8383
continueChatId?: string
8484
}) => {
8585
const scrollRef = useRef<ScrollBoxRenderable | null>(null)
86-
const [showScrollbar, setShowScrollbar] = useState(false)
87-
const hasShownScrollbarRef = useRef(false)
86+
const [hasOverflow, setHasOverflow] = useState(false)
87+
const hasOverflowRef = useRef(false)
8888

8989
const { separatorWidth, terminalWidth, terminalHeight } =
9090
useTerminalDimensions()
@@ -325,6 +325,32 @@ export const Chat = ({
325325
isUserCollapsing,
326326
)
327327

328+
// Check if content has overflowed and needs scrolling
329+
useEffect(() => {
330+
const scrollbox = scrollRef.current
331+
if (!scrollbox) return
332+
333+
const checkOverflow = () => {
334+
const contentHeight = scrollbox.scrollHeight
335+
const viewportHeight = scrollbox.viewport.height
336+
const isOverflowing = contentHeight > viewportHeight
337+
338+
// Only update state if overflow status actually changed
339+
if (hasOverflowRef.current !== isOverflowing) {
340+
hasOverflowRef.current = isOverflowing
341+
setHasOverflow(isOverflowing)
342+
}
343+
}
344+
345+
// Check initially and whenever scroll state changes
346+
checkOverflow()
347+
scrollbox.verticalScrollBar.on('change', checkOverflow)
348+
349+
return () => {
350+
scrollbox.verticalScrollBar.off('change', checkOverflow)
351+
}
352+
}, [])
353+
328354

329355

330356
const inertialScrollAcceleration = useMemo(
@@ -586,12 +612,6 @@ export const Chat = ({
586612
const handleSubmit = useCallback(async () => {
587613
ensureQueueActiveBeforeSubmit()
588614

589-
// Show scrollbar on first message
590-
if (!hasShownScrollbarRef.current) {
591-
hasShownScrollbarRef.current = true
592-
setShowScrollbar(true)
593-
}
594-
595615
const result = await routeUserPrompt({
596616
abortControllerRef,
597617
agentMode,
@@ -809,7 +829,7 @@ export const Chat = ({
809829
stickyStart="bottom"
810830
scrollX={false}
811831
scrollbarOptions={{ visible: false }}
812-
verticalScrollbarOptions={{ visible: showScrollbar, trackOptions: { width: 1 } }}
832+
verticalScrollbarOptions={{ visible: !isStreaming && hasOverflow, trackOptions: { width: 1 } }}
813833
{...appliedScrollboxProps}
814834
style={{
815835
flexGrow: 1,

0 commit comments

Comments
 (0)