Download src/components/chat/ChatInput.tsx from HonzaH/Letschat: direct link, hf CLI and curl.
- Browser
- Download file 2.38 kB
-
https://huggingface.co/spaces/HonzaH/Letschat/resolve/main/src/components/chat/ChatInput.tsx
- Command line
-
hf download hf://spaces/HonzaH/Letschat/src/components/chat/ChatInput.tsx
-
curl -L -o ChatInput.tsx https://huggingface.co/spaces/HonzaH/Letschat/resolve/main/src/components/chat/ChatInput.tsx
2.38 kB
| 'use client' | |
| import { useState, FormEvent, KeyboardEvent } from 'react' | |
| import { Button } from 'components/ui/button' | |
| interface ChatInputProps { | |
| onSend: (message: string) => Promise<void> | |
| disabled?: boolean | |
| placeholder?: string | |
| } | |
| export function ChatInput({ onSend, disabled, placeholder = "Napište zprávu..." }: ChatInputProps) { | |
| const [message, setMessage] = useState('') | |
| const [sending, setSending] = useState(false) | |
| const handleSubmit = async (e: FormEvent) => { | |
| e.preventDefault() | |
| const trimmed = message.trim() | |
| if (!trimmed || sending || disabled) return | |
| setSending(true) | |
| try { | |
| await onSend(trimmed) | |
| setMessage('') | |
| } catch (error) { | |
| console.error('Failed to send message:', error) | |
| } finally { | |
| setSending(false) | |
| } | |
| } | |
| const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault() | |
| handleSubmit(e as unknown as FormEvent) | |
| } | |
| } | |
| return ( | |
| <form onSubmit={handleSubmit} className="p-4 border-t bg-white"> | |
| <div className="flex items-end gap-3"> | |
| <div className="flex-1 relative"> | |
| <textarea | |
| value={message} | |
| onChange={(e) => setMessage(e.target.value)} | |
| onKeyDown={handleKeyDown} | |
| placeholder={placeholder} | |
| disabled={disabled || sending} | |
| className="w-full resize-none rounded-2xl border border-gray-300 px-4 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500 disabled:opacity-50" | |
| rows={1} | |
| style={{ minHeight: '44px', maxHeight: '120px' }} | |
| /> | |
| </div> | |
| <Button | |
| type="submit" | |
| size="sm" | |
| disabled={!message.trim() || disabled || sending} | |
| className="rounded-full h-11 w-11 p-0" | |
| > | |
| {sending ? ( | |
| <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" /> | |
| ) : ( | |
| <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" /> | |
| </svg> | |
| )} | |
| </Button> | |
| </div> | |
| </form> | |
| ) | |
| } |