From b4157df8abfac7698bfb675e5eba6ccc0b46bee3 Mon Sep 17 00:00:00 2001 From: Marve10s Date: Thu, 25 Dec 2025 15:15:59 +0300 Subject: [PATCH] feat(tui): show scrollbar on hover in chat history Add hover-based scrollbar visibility for the left column (chat history) in the CLI TUI session view: - Scrollbar appears when hovering over the chat history area - Only shows when there are 2+ messages (enough content to scroll) - Respects the existing toggle setting (can be disabled via command) - Preserves all existing keyboard navigation and scroll behavior --- .../src/cli/cmd/tui/routes/session/index.tsx | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 818b96da43b..4321d4a85db 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -125,9 +125,16 @@ export function Session() { const [showTimestamps, setShowTimestamps] = createSignal(kv.get("timestamps", "hide") === "show") const [usernameVisible, setUsernameVisible] = createSignal(kv.get("username_visible", true)) const [showDetails, setShowDetails] = createSignal(kv.get("tool_details_visibility", true)) - const [showScrollbar, setShowScrollbar] = createSignal(kv.get("scrollbar_visible", false)) + const [showScrollbar, setShowScrollbar] = createSignal(kv.get("scrollbar_visible", true)) const [userMessageMarkdown, setUserMessageMarkdown] = createSignal(kv.get("user_message_markdown", true)) const [diffWrapMode, setDiffWrapMode] = createSignal<"word" | "none">("word") + const [leftColumnHover, setLeftColumnHover] = createSignal(false) + const [canScroll, setCanScroll] = createSignal(false) + + const scrollbarVisible = createMemo(() => { + if (!showScrollbar()) return false + return canScroll() && leftColumnHover() + }) const wide = createMemo(() => dimensions().width > 120) const sidebarVisible = createMemo(() => { @@ -202,6 +209,16 @@ export function Session() { let prompt: PromptRef const keybind = useKeybind() + createEffect(() => { + messages() + leftColumnHover() + if (scroll) { + setTimeout(() => { + setCanScroll(scroll.scrollHeight > scroll.height) + }, 0) + } + }) + // Helper: Find next visible message boundary in direction const findNextVisibleMessage = (direction: "next" | "prev"): string | null => { const children = scroll.getChildren() @@ -960,7 +977,16 @@ export function Session() { }} > - + setLeftColumnHover(true)} + onMouseOut={() => setLeftColumnHover(false)} + >
@@ -968,11 +994,11 @@ export function Session() { (scroll = r)} viewportOptions={{ - paddingRight: showScrollbar() ? 1 : 0, + paddingRight: scrollbarVisible() ? 1 : 0, }} verticalScrollbarOptions={{ paddingLeft: 1, - visible: showScrollbar(), + visible: scrollbarVisible(), trackOptions: { backgroundColor: theme.backgroundElement, foregroundColor: theme.border,