'use client'; /** * Chat Input Component (v3.0) * * Text input onderaan chat panel met Enter to submit en Shift+Enter voor nieuwe regel. * * Epic: E2 (Chat Panel & Messages) * Story: E2.S4 (ChatInput component) */ import { useState, useRef, KeyboardEvent, ChangeEvent, forwardRef, useImperativeHandle } from 'react'; import { Send, Mic } from 'lucide-react'; import { useCortexStore } from '@/stores/cortex-store'; import { cn } from '@/lib/utils'; interface ChatInputProps { placeholder?: string; onSend?: (message: string) => void; disabled?: boolean; } export interface ChatInputHandle { focus: () => void; clear: () => void; } export const ChatInput = forwardRef(function ChatInput({ placeholder = 'Typ of spreek wat je wilt doen...', onSend, disabled = false, }, ref) { const [inputValue, setInputValue] = useState(''); const textareaRef = useRef(null); const addChatMessage = useCortexStore((s) => s.addChatMessage); // Expose focus and clear methods to parent useImperativeHandle(ref, () => ({ focus: () => { textareaRef.current?.focus(); }, clear: () => { setInputValue(''); if (textareaRef.current) { textareaRef.current.style.height = 'auto'; } }, })); // Handle input change and auto-resize const handleChange = (e: ChangeEvent) => { setInputValue(e.target.value); // Auto-resize textarea if (textareaRef.current) { textareaRef.current.style.height = 'auto'; textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`; } }; // Handle submit const handleSubmit = () => { const trimmedValue = inputValue.trim(); if (!trimmedValue || disabled) return; // Add user message to store addChatMessage({ type: 'user', content: trimmedValue, }); // Call optional onSend callback onSend?.(trimmedValue); // Clear input setInputValue(''); // Reset textarea height if (textareaRef.current) { textareaRef.current.style.height = 'auto'; } // Focus back on textarea textareaRef.current?.focus(); }; // Handle keyboard shortcuts const handleKeyDown = (e: KeyboardEvent) => { // Enter to submit (unless Shift is pressed) if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit(); } // Escape to clear input if (e.key === 'Escape') { e.preventDefault(); setInputValue(''); if (textareaRef.current) { textareaRef.current.style.height = 'auto'; } } // Shift+Enter for new line (default behavior, no need to handle) }; return (
{/* Textarea input */}