Spaces:
Running
Running
| import type { KeyboardEvent } from "react"; | |
| import { Icon } from "./Icon"; | |
| type Props = { | |
| value: string; | |
| onChange: (v: string) => void; | |
| onSend: () => void | Promise<void>; | |
| /** Smaller padding when used inside overlay */ | |
| compact?: boolean; | |
| }; | |
| export function MainChatComposer({ | |
| value, | |
| onChange, | |
| onSend, | |
| compact, | |
| }: Props) { | |
| const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => { | |
| if (e.key === "Enter" && !e.shiftKey) { | |
| e.preventDefault(); | |
| onSend(); | |
| } | |
| }; | |
| return ( | |
| <div | |
| className={`w-full max-w-5xl mx-auto ${compact ? "" : "px-1"}`} | |
| > | |
| <div className="relative rounded-2xl border border-outline-variant bg-white p-2 shadow-md transition-all focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/10"> | |
| <textarea | |
| className={`w-full resize-none border-none bg-transparent font-body-md text-body-md text-on-background placeholder:text-secondary/70 focus:ring-0 ${ | |
| compact ? "min-h-[100px] p-3" : "min-h-[120px] p-4" | |
| }`} | |
| placeholder="Describe your procurement needs (e.g., 'Source 500 units of high-performance laptops for the engineering team...')" | |
| value={value} | |
| onChange={(e) => onChange(e.target.value)} | |
| onKeyDown={handleKeyDown} | |
| rows={compact ? 4 : 5} | |
| aria-label="Procurement request" | |
| /> | |
| <div className="mx-2 border-t border-outline-variant" /> | |
| <div className="flex items-center justify-between px-2 pb-2 pt-2"> | |
| <div className="flex items-center gap-0.5"> | |
| <button | |
| type="button" | |
| className="rounded-full p-2.5 text-secondary transition-colors hover:bg-surface-container-high" | |
| title="Attach file" | |
| aria-label="Attach file" | |
| > | |
| <Icon name="attach_file" className="text-[22px]" /> | |
| </button> | |
| <button | |
| type="button" | |
| className="rounded-full p-2.5 text-secondary transition-colors hover:bg-surface-container-high" | |
| title="Add images" | |
| aria-label="Add images" | |
| > | |
| <Icon name="photo_library" className="text-[22px]" /> | |
| </button> | |
| <button | |
| type="button" | |
| className="rounded-full p-2.5 text-secondary transition-colors hover:bg-surface-container-high" | |
| title="Voice input" | |
| aria-label="Voice input" | |
| > | |
| <Icon name="mic" className="text-[22px]" /> | |
| </button> | |
| </div> | |
| <button | |
| type="button" | |
| onClick={onSend} | |
| className="flex items-center gap-2 rounded-xl bg-primary px-5 py-2.5 font-body-md text-sm font-bold text-on-primary shadow-sm transition-all hover:opacity-95 active:scale-[0.98]" | |
| > | |
| Send Request | |
| <Icon name="send" className="text-lg" /> | |
| </button> | |
| </div> | |
| </div> | |
| {!compact && ( | |
| <p className="mt-4 text-center font-body-sm text-xs text-secondary/60"> | |
| Procure AI can make mistakes. Check important procurement details | |
| before approval. | |
| </p> | |
| )} | |
| </div> | |
| ); | |
| } | |