fix(git): convert to auto-resizing commit input

This commit is contained in:
Bohdan Triapitsyn
2025-12-19 16:06:21 +02:00
parent 1c15feac6c
commit f772000d88
@@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
@@ -10,65 +9,41 @@ interface CommitInputProps {
disabled?: boolean; disabled?: boolean;
} }
const MIN_HEIGHT = 38; // Single line height
const MAX_HEIGHT = 200;
export const CommitInput: React.FC<CommitInputProps> = ({ export const CommitInput: React.FC<CommitInputProps> = ({
value, value,
onChange, onChange,
placeholder = 'Commit message', placeholder = 'Commit message',
disabled = false, disabled = false,
}) => { }) => {
const [isExpanded, setIsExpanded] = React.useState(false);
const hasMultipleLines = value.includes('\n');
const textareaRef = React.useRef<HTMLTextAreaElement>(null); const textareaRef = React.useRef<HTMLTextAreaElement>(null);
const shouldShowTextarea = isExpanded || hasMultipleLines; // Auto-resize based on content
const handleInputFocus = () => {
setIsExpanded(true);
};
const handleTextareaBlur = () => {
if (!hasMultipleLines && !value.trim()) {
setIsExpanded(false);
}
};
React.useEffect(() => { React.useEffect(() => {
if (shouldShowTextarea && textareaRef.current) { const textarea = textareaRef.current;
textareaRef.current.focus(); if (!textarea) return;
const len = textareaRef.current.value.length;
textareaRef.current.setSelectionRange(len, len);
}
}, [shouldShowTextarea]);
if (shouldShowTextarea) { // Reset height to measure scrollHeight accurately
return ( textarea.style.height = `${MIN_HEIGHT}px`;
<Textarea const newHeight = Math.min(Math.max(textarea.scrollHeight, MIN_HEIGHT), MAX_HEIGHT);
ref={textareaRef} textarea.style.height = `${newHeight}px`;
value={value} }, [value]);
onChange={(e) => onChange(e.target.value)}
onBlur={handleTextareaBlur}
placeholder={placeholder}
rows={4}
disabled={disabled}
className={cn(
'rounded-lg bg-background/80 resize-none min-h-[100px]',
disabled && 'opacity-50'
)}
/>
);
}
return ( return (
<Input <Textarea
ref={textareaRef}
value={value} value={value}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
onFocus={handleInputFocus}
placeholder={placeholder} placeholder={placeholder}
rows={1}
disabled={disabled} disabled={disabled}
className={cn( className={cn(
'rounded-lg bg-background/80', 'rounded-lg bg-background/80 resize-none overflow-y-auto',
disabled && 'opacity-50' disabled && 'opacity-50'
)} )}
style={{ minHeight: MIN_HEIGHT, maxHeight: MAX_HEIGHT }}
/> />
); );
}; };