UNPKG

laif-ds

Version:

Design System di Laif con componenti React basati su principi di Atomic Design

132 lines (107 loc) 4.84 kB
# MessageInput ## Overview Chat composer with autosizing textarea, optional file attachments, voice input (record/transcribe), and intelligent Enter-to-send behavior with interruption prompts. --- ## Props Extends native `<textarea>` props. | Prop | Type | Default | Description | | ------------------ | ---------------------------------------------- | ---------- | ----------- | | `value` | `string` | **required** | Controlled text value. | | `isGenerating` | `boolean` | `false` | If true, shows stop button and may display interrupt prompt. | | `submitOnEnter` | `boolean` | `true` | Press Enter to submit (Shift+Enter for newline). | | `stop` | `() => void` | `undefined`| Stop generation handler (used with `isGenerating`). | | `enableInterrupt` | `boolean` | `true` | If true, pressing Enter while generating shows confirm to interrupt. | | `transcribeAudio` | `(blob: Blob) => Promise<string>` | `undefined`| Optional audio-to-text function. | | `allowAttachments` | `boolean` | `false` | Enable file attachments UI. | | `files` | `File[] | null` | `null` | Current attached files (when `allowAttachments`). | | `setFiles` | `React.Dispatch<React.SetStateAction<File[] | null>>` | `undefined`| Setter for attachments. | --- ## Behavior - **Enter to submit**: If `submitOnEnter` and not `shiftKey`, calls `form.requestSubmit()`. - **Interrupt flow**: If `isGenerating` and `stop` and `enableInterrupt`, pressing Enter shows a prompt to confirm stopping the generation and sending the new message. - **Autosize**: Textarea grows up to a max height, then scrolls. - **Attachments**: Drag & drop, paste files; long pasted text (> 500 chars) becomes a text file. Uses `FilePreview` to show chips. - **Voice input**: If supported, toggles microphone recording; shows visualizer while recording and a "transcribing" overlay after. - **Actions**: Right-aligned action buttons: attach, mic, send/stop. --- ## Examples ### Basic ```tsx import * as React from "react"; import { MessageInput } from "laif-ds"; export function BasicComposer() { const [value, setValue] = React.useState(""); const onSubmit = (e: React.FormEvent) => { e.preventDefault(); console.log("Messaggio inviato:", value); setValue(""); }; return ( <form onSubmit={onSubmit} className="w-full max-w-2xl"> <MessageInput value={value} onChange={(e) => setValue(e.target.value)} isGenerating={false} /> </form> ); } ``` ### With Attachments ```tsx import * as React from "react"; import { MessageInput } from "laif-ds"; export function WithAttachments() { const [value, setValue] = React.useState(""); const [files, setFiles] = React.useState<File[] | null>(null); const onSubmit = (e: React.FormEvent) => { e.preventDefault(); console.log("Messaggio inviato:", value, files); setValue(""); setFiles(null); }; return ( <form onSubmit={onSubmit} className="w-full max-w-2xl"> <MessageInput value={value} onChange={(e) => setValue(e.target.value)} isGenerating={false} allowAttachments files={files} setFiles={setFiles} placeholder="Scrivi un messaggio o trascina file qui..." /> </form> ); } ``` ### Generating + Interrupt ```tsx import * as React from "react"; import { MessageInput } from "laif-ds"; export function Generating() { const [value, setValue] = React.useState(""); const [isGenerating, setIsGenerating] = React.useState(true); const stop = () => setIsGenerating(false); const onSubmit = (e: React.FormEvent) => { e.preventDefault(); if (isGenerating) return; console.log("Messaggio inviato:", value); setValue(""); setIsGenerating(true); setTimeout(() => setIsGenerating(false), 3000); }; return ( <form onSubmit={onSubmit} className="w-full max-w-2xl"> <MessageInput value={value} onChange={(e) => setValue(e.target.value)} isGenerating={isGenerating} stop={stop} placeholder="L'AI sta generando una risposta..." /> </form> ); } ``` --- ## Notes - **File preview**: Uses `FilePreview` for attachment chips. - **Paste handling**: Long text paste becomes a `.txt` file when attachments are enabled. - **A11y**: Textarea has aria-label; action buttons have aria-labels as well.