Skip to content

Commit cf1a099

Browse files
committed
fix(chat-area): dynamic sizing for select options
1 parent 773e556 commit cf1a099

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
107107
const contextMenuContainerRef = useRef<HTMLDivElement>(null)
108108
const [isEnhancingPrompt, setIsEnhancingPrompt] = useState(false)
109109
const [isFocused, setIsFocused] = useState(false)
110+
const [modeSelectWidth, setModeSelectWidth] = useState(70) // Default min width for mode select
111+
const [apiSelectWidth, setApiSelectWidth] = useState(100) // Default min width for API config select
110112

111113
// Fetch git commits when Git is selected or when typing a hash
112114
useEffect(() => {
@@ -508,6 +510,42 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
508510
setIsMouseDownOnMenu(true)
509511
}, [])
510512

513+
// Utility function to estimate text width
514+
const estimateTextWidth = useCallback((text: string, fontSize: number = 11): number => {
515+
// Approximate character width based on font size (in pixels)
516+
const avgCharWidth = fontSize * 0.6
517+
518+
// Add extra space for the caret icon and padding
519+
const paddingWidth = 30
520+
521+
// Calculate estimated width
522+
return text.length * avgCharWidth + paddingWidth
523+
}, [])
524+
525+
// Update mode select width when mode changes
526+
useEffect(() => {
527+
if (!mode) return
528+
529+
// Get the selected mode's display name
530+
const selectedMode = getAllModes(customModes).find((m) => m.slug === mode)
531+
if (selectedMode) {
532+
const textWidth = estimateTextWidth(selectedMode.name)
533+
// Apply min/max constraints
534+
const newWidth = Math.max(70, Math.min(200, textWidth))
535+
setModeSelectWidth(newWidth)
536+
}
537+
}, [mode, customModes, estimateTextWidth])
538+
539+
// Update API config select width when config changes
540+
useEffect(() => {
541+
if (!currentApiConfigName) return
542+
543+
const textWidth = estimateTextWidth(currentApiConfigName)
544+
// Apply min/max constraints
545+
const newWidth = Math.max(100, Math.min(250, textWidth))
546+
setApiSelectWidth(newWidth)
547+
}, [currentApiConfigName, estimateTextWidth])
548+
511549
const updateHighlights = useCallback(() => {
512550
if (!textAreaRef.current || !highlightLayerRef.current) return
513551

@@ -554,6 +592,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
554592
WebkitAppearance: "none" as const,
555593
MozAppearance: "none" as const,
556594
appearance: "none" as const,
595+
transition: "width 0.2s ease-in-out", // Add smooth transition for width changes
557596
}
558597

559598
const optionStyle = {
@@ -815,7 +854,9 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
815854
}}
816855
style={{
817856
...selectStyle,
857+
width: `${modeSelectWidth}px`, // Use dynamic width from state
818858
minWidth: "70px",
859+
maxWidth: "200px",
819860
flex: "0 0 auto",
820861
}}>
821862
<option
@@ -851,7 +892,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
851892
display: "inline-block",
852893
flex: "1 1 auto",
853894
minWidth: 0,
854-
maxWidth: "150px",
895+
maxWidth: "250px", // Increased max width to match our constraints
855896
overflow: "hidden",
856897
}}>
857898
<select
@@ -871,7 +912,9 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
871912
}}
872913
style={{
873914
...selectStyle,
874-
width: "100%",
915+
width: `${apiSelectWidth}px`, // Use dynamic width from state
916+
minWidth: "100px",
917+
maxWidth: "250px",
875918
textOverflow: "ellipsis",
876919
}}>
877920
{(listApiConfigMeta || []).map((config) => (

0 commit comments

Comments
 (0)