import { useState, useCallback, useImperativeHandle, forwardRef, useRef, type FormEvent, type KeyboardEvent } from 'react'; import { Input } from './ui/input'; import { Button } from './ui/button'; interface MessageInputProps { onSend: (text: string) => Promise; disabled: boolean; placeholder?: string; } export interface MessageInputHandle { appendText: (text: string) => void; } export const MessageInput = forwardRef( function MessageInput({ onSend, disabled, placeholder }, ref) { const [text, setText] = useState(''); const [sending, setSending] = useState(false); const inputRef = useRef(null); useImperativeHandle(ref, () => ({ appendText: (appendedText: string) => { setText((prev) => prev + appendedText); // Focus the input after appending inputRef.current?.focus(); }, })); const handleSubmit = useCallback( async (e: FormEvent) => { e.preventDefault(); const trimmed = text.trim(); if (!trimmed || sending || disabled) return; setSending(true); try { await onSend(trimmed); setText(''); } catch (err) { console.error('Failed to send message:', err); } finally { setSending(false); } }, [text, sending, disabled, onSend] ); const handleKeyDown = useCallback( (e: KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit(e as unknown as FormEvent); } }, [handleSubmit] ); return (
setText(e.target.value)} onKeyDown={handleKeyDown} placeholder={placeholder || 'Type a message...'} disabled={disabled || sending} className="flex-1" />
); });