Skip to content

Commit 65d2025

Browse files
committed
improve: increase scroll indicator touch target with padding
Add paddingLeft and paddingRight to scroll indicator box to create a larger hover/click area without changing the visual size of the arrow. This makes it easier to interact with the minimized indicator.
1 parent e4725e4 commit 65d2025

File tree

1 file changed

+49
-16
lines changed

1 file changed

+49
-16
lines changed

cli/src/chat.tsx

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,39 @@ export const Chat = ({
555555
<StatusElapsedTime streamStatus={streamStatus} timerStartTime={timerStartTime} />
556556
)
557557

558+
// Calculate available width for queue preview based on actual content
559+
const calculateQueuePreviewWidth = () => {
560+
// Estimate status text length
561+
let statusTextLength = 0
562+
if (nextCtrlCWillExit) {
563+
statusTextLength = 27 // "Press Ctrl-C again to exit"
564+
} else if (clipboardMessage) {
565+
statusTextLength = clipboardMessage.length
566+
} else if (streamStatus === 'waiting') {
567+
statusTextLength = 11 // "thinking..."
568+
} else if (streamStatus === 'streaming') {
569+
statusTextLength = 10 // "working..."
570+
}
571+
572+
// Estimate scroll indicator (1 char normally, 20 when hovered, use 1 for calculation)
573+
const scrollIndicatorLength = !isAtBottom ? 1 : 0
574+
575+
// Estimate elapsed time length (typically 2-7 chars like "5s" or "1m 30s")
576+
const elapsedTimeLength = streamStatus !== 'idle' ? 7 : 0
577+
578+
// Account for padding, gaps, and margins (~10 chars)
579+
const overhead = 10
580+
581+
// Calculate available space
582+
const availableWidth =
583+
terminalWidth - statusTextLength - scrollIndicatorLength - elapsedTimeLength - overhead
584+
585+
// Return reasonable bounds: minimum 20, maximum 60
586+
return Math.max(20, Math.min(60, availableWidth))
587+
}
588+
589+
const queuePreviewWidth = calculateQueuePreviewWidth()
590+
558591
const validationBanner = useValidationBanner({
559592
liveValidationErrors: validationErrors,
560593
loadedAgentsData,
@@ -668,10 +701,7 @@ export const Chat = ({
668701
{shouldShowQueuePreview && (
669702
<text style={{ wrapMode: 'none' }}>
670703
<span fg={theme.secondary} bg={theme.inputFocusedBg}>
671-
{` ${formatQueuedPreview(
672-
queuedMessages,
673-
Math.max(30, terminalWidth - 25),
674-
)} `}
704+
{` ${formatQueuedPreview(queuedMessages, queuePreviewWidth)} `}
675705
</span>
676706
</text>
677707
)}
@@ -680,22 +710,25 @@ export const Chat = ({
680710
{/* Center section - scroll indicator (always centered) */}
681711
<box style={{ flexShrink: 0 }}>
682712
{!isAtBottom && (
683-
<text
713+
<box
714+
style={{ paddingLeft: 2, paddingRight: 2 }}
684715
onMouseDown={() => scrollToLatest()}
685716
onMouseOver={() => setScrollIndicatorHovered(true)}
686717
onMouseOut={() => setScrollIndicatorHovered(false)}
687718
>
688-
<span
689-
fg={theme.info}
690-
attributes={
691-
scrollIndicatorHovered
692-
? TextAttributes.BOLD
693-
: TextAttributes.DIM
694-
}
695-
>
696-
{scrollIndicatorHovered ? '↓ Scroll to bottom ↓' : '↓'}
697-
</span>
698-
</text>
719+
<text>
720+
<span
721+
fg={theme.info}
722+
attributes={
723+
scrollIndicatorHovered
724+
? TextAttributes.BOLD
725+
: TextAttributes.DIM
726+
}
727+
>
728+
{scrollIndicatorHovered ? '↓ Scroll to bottom ↓' : '↓'}
729+
</span>
730+
</text>
731+
</box>
699732
)}
700733
</box>
701734

0 commit comments

Comments
 (0)