Skip to content

Commit ee91e43

Browse files
committed
Improve followup ui
1 parent 57abbf2 commit ee91e43

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

cli/src/components/tools/suggest-followups.tsx

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useCallback } from 'react'
1+
import React, { useCallback, useState } from 'react'
2+
import { TextAttributes } from '@opentui/core'
23

34
import { Button } from '../button'
45
import { defineToolComponent } from './types'
@@ -22,43 +23,66 @@ const FollowupCard = ({
2223
onSendFollowup,
2324
}: FollowupCardProps) => {
2425
const theme = useTheme()
26+
const [isHovered, setIsHovered] = useState(false)
2527

2628
const handleClick = useCallback(() => {
2729
onSendFollowup(followup.prompt, index)
2830
}, [followup.prompt, index, onSendFollowup])
2931

30-
// Use label if provided, otherwise truncate the prompt
31-
const displayLabel = followup.label || truncateText(followup.prompt, 40)
32+
const handleMouseOver = useCallback(() => setIsHovered(true), [])
33+
const handleMouseOut = useCallback(() => setIsHovered(false), [])
34+
35+
const hasLabel = Boolean(followup.label)
36+
37+
// Determine colors based on state
38+
const borderColor = isClicked
39+
? theme.success
40+
: isHovered
41+
? theme.primary
42+
: theme.border
43+
const labelColor = isClicked ? theme.muted : theme.secondary
44+
const promptColor = isClicked ? theme.muted : theme.foreground
3245

3346
return (
3447
<Button
3548
onClick={handleClick}
49+
onMouseOver={handleMouseOver}
50+
onMouseOut={handleMouseOut}
3651
style={{
3752
paddingLeft: 2,
3853
paddingRight: 2,
3954
paddingTop: 0,
4055
paddingBottom: 0,
41-
backgroundColor: isClicked ? theme.surface : theme.surfaceHover,
42-
borderColor: isClicked ? theme.success : theme.border,
56+
maxWidth: 40,
57+
borderColor,
58+
flexGrow: 1,
4359
}}
4460
>
45-
<text
46-
style={{
47-
fg: isClicked ? theme.muted : theme.foreground,
48-
}}
49-
>
50-
{isClicked && <span fg={theme.success}></span>}
51-
<span>{displayLabel}</span>
52-
</text>
61+
<box style={{ flexDirection: 'column' }}>
62+
{hasLabel && (
63+
<text
64+
style={{
65+
fg: labelColor,
66+
}}
67+
attributes={TextAttributes.BOLD}
68+
>
69+
{isClicked ? <span fg={theme.success}></span> : <span></span>}
70+
<span>{followup.label}</span>
71+
</text>
72+
)}
73+
<text
74+
style={{
75+
fg: promptColor,
76+
}}
77+
>
78+
{!hasLabel && isClicked && <span fg={theme.success}></span>}
79+
<span>{followup.prompt}</span>
80+
</text>
81+
</box>
5382
</Button>
5483
)
5584
}
5685

57-
function truncateText(text: string, maxLength: number): string {
58-
if (text.length <= maxLength) return text
59-
return text.slice(0, maxLength - 1) + '…'
60-
}
61-
6286
interface SuggestFollowupsItemProps {
6387
toolCallId: string
6488
followups: SuggestedFollowup[]
@@ -80,14 +104,19 @@ const SuggestFollowupsItem = ({
80104
: new Set<number>()
81105

82106
return (
83-
<box style={{ flexDirection: 'column', gap: 1, width: '100%' }}>
84-
<text style={{ fg: theme.muted }}>Suggested next steps:</text>
107+
<box
108+
style={{
109+
flexDirection: 'column',
110+
gap: 1,
111+
}}
112+
>
113+
<text style={{ fg: theme.primary }} attributes={TextAttributes.BOLD}>
114+
Suggested next steps:
115+
</text>
85116
<box
86117
style={{
87118
flexDirection: 'row',
88-
gap: 1,
89119
flexWrap: 'wrap',
90-
width: '100%',
91120
}}
92121
>
93122
{followups.map((followup, index) => (

0 commit comments

Comments
 (0)