import React from 'react'; import { cn } from '@/lib/utils'; import { useUIStore } from '@/stores/useUIStore'; import { useI18n } from '@/lib/i18n'; interface CommitInputProps { value: string; onChange: (value: string) => void; placeholder?: string; disabled?: boolean; hasTouchInput?: boolean; isMobile?: boolean; } const MIN_HEIGHT = 38; // Single line height const MAX_HEIGHT = 200; export const CommitInput: React.FC = ({ value, onChange, placeholder, disabled = false, hasTouchInput = false, isMobile = false, }) => { const { t } = useI18n(); const textareaRef = React.useRef(null); const inputSpellcheckEnabled = useUIStore((state) => state.inputSpellcheckEnabled); // Auto-resize based on content (layout phase to avoid mount flicker) React.useLayoutEffect(() => { const textarea = textareaRef.current; if (!textarea) return; const hadFocus = document.activeElement === textarea; const resize = () => { // Reset to baseline to measure content height from a stable line. textarea.style.height = `${MIN_HEIGHT}px`; const contentHeight = textarea.scrollHeight; const newHeight = Math.min(Math.max(contentHeight, MIN_HEIGHT), MAX_HEIGHT); textarea.style.height = `${newHeight}px`; textarea.style.overflowY = contentHeight > MAX_HEIGHT ? 'auto' : 'hidden'; if (contentHeight > MAX_HEIGHT && !hadFocus) { textarea.scrollTop = textarea.scrollHeight; } }; resize(); const frameId = window.requestAnimationFrame(resize); return () => { window.cancelAnimationFrame(frameId); }; }, [value]); return (