ui-nyla/src/components/Chat/ChatInput.tsx
2026-04-11 19:44:52 +02:00

105 lines
2.8 KiB
TypeScript

/**
* ChatInput -- Shared chat input component.
*
* Simple text input with send button, usable by both Workspace and Editor.
*/
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { useLanguage } from '../../providers/language/LanguageContext';
interface ChatInputProps {
onSend: (message: string) => void;
isProcessing?: boolean;
placeholder?: string;
disabled?: boolean;
autoFocus?: boolean;
style?: React.CSSProperties;
}
export const ChatInput: React.FC<ChatInputProps> = ({
onSend,
isProcessing,
placeholder,
disabled,
autoFocus = true,
style,
}) => {
const { t } = useLanguage();
const resolvedPlaceholder = placeholder ?? t('Nachricht eingeben…');
const [value, setValue] = useState('');
const inputRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
if (autoFocus) inputRef.current?.focus();
}, [autoFocus]);
const _handleSend = useCallback(() => {
const trimmed = value.trim();
if (!trimmed || isProcessing || disabled) return;
onSend(trimmed);
setValue('');
}, [value, isProcessing, disabled, onSend]);
const _handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
_handleSend();
}
},
[_handleSend]
);
return (
<div
style={{
display: 'flex',
gap: '8px',
padding: '8px 12px',
borderTop: '1px solid var(--border-color, #e0e0e0)',
alignItems: 'flex-end',
...style,
}}
>
<textarea
ref={inputRef}
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={_handleKeyDown}
placeholder={resolvedPlaceholder}
disabled={isProcessing || disabled}
rows={1}
style={{
flex: 1,
resize: 'none',
border: '1px solid var(--border-color, #ddd)',
borderRadius: '8px',
padding: '8px 12px',
fontSize: '13px',
fontFamily: 'inherit',
outline: 'none',
minHeight: '36px',
maxHeight: '120px',
background: 'var(--bg-primary, #fff)',
color: 'var(--text-primary, #333)',
}}
/>
<button
onClick={_handleSend}
disabled={!value.trim() || isProcessing || disabled}
style={{
padding: '8px 16px',
borderRadius: '8px',
border: 'none',
background: !value.trim() || isProcessing || disabled ? '#ccc' : 'var(--color-primary, #2563eb)',
color: '#fff',
fontSize: '13px',
fontWeight: 600,
cursor: !value.trim() || isProcessing || disabled ? 'not-allowed' : 'pointer',
whiteSpace: 'nowrap',
}}
>
{isProcessing ? '…' : t('Senden')}
</button>
</div>
);
};