| import { useState } from "react"; |
| import { Loader2, Send } from "lucide-react"; |
| import { HelpSkillButton } from "./HelpSkillButton"; |
|
|
| interface ChatInputProps { |
| disabled?: boolean; |
| streaming?: boolean; |
| onSend: (message: string) => void; |
| onHelp: () => void; |
| } |
|
|
| export function ChatInput({ disabled, streaming, onSend, onHelp }: ChatInputProps) { |
| const [message, setMessage] = useState(""); |
| const canSend = message.trim().length > 0 && !disabled && !streaming; |
|
|
| const submit = (event: React.FormEvent) => { |
| event.preventDefault(); |
| if (!canSend) return; |
| onSend(message.trim()); |
| setMessage(""); |
| }; |
|
|
| return ( |
| <form onSubmit={submit} className="flex-shrink-0 border-t border-slate-200 bg-white p-4"> |
| <div className="mx-auto flex max-w-5xl flex-col gap-2 sm:flex-row sm:items-end"> |
| <textarea |
| aria-label="Chat message" |
| value={message} |
| onChange={(event) => setMessage(event.target.value)} |
| onKeyDown={(event) => { |
| if (event.key === "Enter" && !event.shiftKey) { |
| event.preventDefault(); |
| submit(event); |
| } |
| }} |
| disabled={disabled || streaming} |
| rows={2} |
| placeholder="Ask the agent about this analysis" |
| className="min-h-10 min-w-0 flex-1 resize-none rounded-md border border-slate-200 bg-white px-3 py-2 text-sm leading-6 text-slate-900 outline-none transition placeholder:text-slate-400 focus:border-emerald-500 focus:ring-2 focus:ring-emerald-100 disabled:bg-slate-50" |
| /> |
| <div className="flex gap-2"> |
| <HelpSkillButton disabled={disabled || streaming} onClick={onHelp} /> |
| <button |
| type="submit" |
| aria-label="Send message" |
| disabled={!canSend} |
| className="inline-flex h-10 items-center gap-2 rounded-md bg-emerald-600 px-4 text-sm font-medium text-white hover:bg-emerald-700 disabled:cursor-not-allowed disabled:opacity-50" |
| > |
| {streaming ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />} |
| Send |
| </button> |
| </div> |
| </div> |
| </form> |
| ); |
| } |
|
|