fix(cli): ensure dialogs stay scrolled to bottom in alternate buffer mode (#20527)

This commit is contained in:
Jacob Richman
2026-02-27 08:00:07 -08:00
committed by GitHub
parent d7320f5425
commit 14dd07be00
6 changed files with 571 additions and 192 deletions
@@ -10,7 +10,7 @@ import {
useImperativeHandle,
useCallback,
useMemo,
useEffect,
useLayoutEffect,
} from 'react';
import type React from 'react';
import {
@@ -105,7 +105,7 @@ function ScrollableList<T>(
smoothScrollState.current.active = false;
}, []);
useEffect(() => stopSmoothScroll, [stopSmoothScroll]);
useLayoutEffect(() => stopSmoothScroll, [stopSmoothScroll]);
const smoothScrollTo = useCallback(
(
@@ -120,15 +120,19 @@ function ScrollableList<T>(
innerHeight: 0,
};
const {
scrollTop: startScrollTop,
scrollTop: rawStartScrollTop,
scrollHeight,
innerHeight,
} = scrollState;
const maxScrollTop = Math.max(0, scrollHeight - innerHeight);
const startScrollTop = Math.min(rawStartScrollTop, maxScrollTop);
let effectiveTarget = targetScrollTop;
if (targetScrollTop === SCROLL_TO_ITEM_END) {
if (
targetScrollTop === SCROLL_TO_ITEM_END ||
targetScrollTop >= maxScrollTop
) {
effectiveTarget = maxScrollTop;
}
@@ -138,8 +142,11 @@ function ScrollableList<T>(
);
if (duration === 0) {
if (targetScrollTop === SCROLL_TO_ITEM_END) {
virtualizedListRef.current?.scrollTo(SCROLL_TO_ITEM_END);
if (
targetScrollTop === SCROLL_TO_ITEM_END ||
targetScrollTop >= maxScrollTop
) {
virtualizedListRef.current?.scrollTo(Number.MAX_SAFE_INTEGER);
} else {
virtualizedListRef.current?.scrollTo(Math.round(clampedTarget));
}
@@ -168,8 +175,11 @@ function ScrollableList<T>(
ease;
if (progress >= 1) {
if (targetScrollTop === SCROLL_TO_ITEM_END) {
virtualizedListRef.current?.scrollTo(SCROLL_TO_ITEM_END);
if (
targetScrollTop === SCROLL_TO_ITEM_END ||
targetScrollTop >= maxScrollTop
) {
virtualizedListRef.current?.scrollTo(Number.MAX_SAFE_INTEGER);
} else {
virtualizedListRef.current?.scrollTo(Math.round(current));
}
@@ -200,9 +210,13 @@ function ScrollableList<T>(
) {
const direction = keyMatchers[Command.PAGE_UP](key) ? -1 : 1;
const scrollState = getScrollState();
const maxScroll = Math.max(
0,
scrollState.scrollHeight - scrollState.innerHeight,
);
const current = smoothScrollState.current.active
? smoothScrollState.current.to
: scrollState.scrollTop;
: Math.min(scrollState.scrollTop, maxScroll);
const innerHeight = scrollState.innerHeight;
smoothScrollTo(current + direction * innerHeight);
return true;