Files
accounted/components/chat/ChatInput.tsx
T
2026-02-13 14:00:46 +01:00

84 lines
2.2 KiB
TypeScript

'use client'
import { useState, useRef, useCallback, KeyboardEvent } from 'react'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import { Send, Loader2 } from 'lucide-react'
interface ChatInputProps {
onSend: (message: string) => void
disabled?: boolean
isLoading?: boolean
placeholder?: string
}
export function ChatInput({
onSend,
disabled = false,
isLoading = false,
placeholder = 'Skriv ett meddelande...',
}: ChatInputProps) {
const [message, setMessage] = useState('')
const textareaRef = useRef<HTMLTextAreaElement>(null)
const handleSend = useCallback(() => {
const trimmed = message.trim()
if (trimmed && !disabled && !isLoading) {
onSend(trimmed)
setMessage('')
// Reset textarea height
if (textareaRef.current) {
textareaRef.current.style.height = 'auto'
}
}
}, [message, disabled, isLoading, onSend])
const handleKeyDown = useCallback(
(e: KeyboardEvent<HTMLTextAreaElement>) => {
// Send on Enter (without Shift)
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault()
handleSend()
}
},
[handleSend]
)
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setMessage(e.target.value)
// Auto-resize textarea
const textarea = e.target
textarea.style.height = 'auto'
textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`
}
const isDisabled = disabled || isLoading || !message.trim()
return (
<div className="flex gap-2 items-end p-4 border-t bg-background">
<Textarea
ref={textareaRef}
value={message}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder={placeholder}
disabled={disabled || isLoading}
className="min-h-[44px] max-h-[200px] resize-none py-3"
rows={1}
/>
<Button
onClick={handleSend}
disabled={isDisabled}
size="icon"
className="flex-shrink-0 h-[44px] w-[44px]"
>
{isLoading ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Send className="h-4 w-4" />
)}
</Button>
</div>
)
}