# Chat

## Overview

Complete chat interface: message list with markdown rendering, auto-scroll and typing indicator; composer with text, attachments, and voice; optional suggestions for empty state; message actions (copy, rate, save) and inline edit of assistant messages.

---

## Props

| Prop                | Type                                                   | Default                 | Description                                                                |
| ------------------- | ------------------------------------------------------ | ----------------------- | -------------------------------------------------------------------------- | ---------------------- |
| `messages`          | `Message[]`                                            | **required**            | Messages to render. See `ChatMessage` for shape.                           |
| `input`             | `string`                                               | **required**            | Current input value.                                                       |
| `handleSubmit`      | `(event?, opts?) => void`                              | **required**            | Called on form submit. Supports `{ experimental_attachments?: FileList }`. |
| `handleInputChange` | `React.ChangeEventHandler<HTMLTextAreaElement>`        | **required**            | Input change handler.                                                      |
| `isGenerating`      | `boolean`                                              | `false`                 | Whether assistant is generating. Enables interrupt UI.                     |
| `stop`              | `() => void`                                           | `undefined`             | Stop generation callback.                                                  |
| `allowAttachments`  | `boolean`                                              | `false`                 | Enable file attachments UI.                                                |
| `transcribeAudio`   | `(blob: Blob) => Promise<string>`                      | `undefined`             | Speech-to-text function for voice input.                                   |
| `onEdit`            | `(messageId: string, newContent: string) => void`      | `undefined`             | Enable inline edit on assistant messages.                                  |
| `onMessageSave`     | `(messageId: string, content: string) => void`         | `undefined`             | Enable save action on assistant messages.                                  |
| `onRateResponse`    | `(messageId: string, rating: "thumbs-up"               | "thumbs-down") => void` | `undefined`                                                                | Enable rating actions. |
| `append`            | `(message: { role: "user"; content: string }) => void` | `undefined`             | Show prompt suggestions and handle clicks.                                 |
| `suggestions`       | `string[]`                                             | `undefined`             | Suggestions displayed when empty. Requires `append`.                       |
| `className`         | `string`                                               | `undefined`             | Wrapper classes.                                                           |
| `welcomeTitle`      | `string`                                               | `"Da dove iniziamo?"`   | Title shown in empty state.                                                |

---

## Behavior

- **Auto-scroll**: Scrolls to latest messages unless user scrolls up (then shows "scroll to bottom").
- **Composer**: `MessageInput` supports Enter-to-send, attachments, and voice input with transcription.
- **Actions**: Copy, save, thumbs up/down per assistant message.
- **Edit**: Inline edit of assistant messages with Enter to save / Esc to cancel.
- **Suggestions**: When `messages` is empty and `suggestions` provided, renders clickable suggestions via `append`.

---

## Examples

### Default

```tsx
import * as React from "react";
import { Chat } from "laif-ds";
import type { Message } from "laif-ds";

export function BasicChat() {
  const [messages, setMessages] = React.useState<Message[]>([
    { id: "1", role: "user", content: "Hello!", createdAt: new Date() },
    {
      id: "2",
      role: "assistant",
      content: "How can I help?",
      createdAt: new Date(),
    },
  ]);
  const [input, setInput] = React.useState("");

  const handleSubmit = () => {
    if (!input.trim()) return;
    setMessages((prev) => [
      ...prev,
      {
        id: Date.now().toString(),
        role: "user",
        content: input,
        createdAt: new Date(),
      },
    ]);
    setInput("");
  };

  return (
    <div className="h-[500px] w-full max-w-3xl">
      <Chat
        messages={messages}
        input={input}
        handleInputChange={(e) => setInput(e.target.value)}
        handleSubmit={handleSubmit}
        isGenerating={false}
      />
    </div>
  );
}
```

### With Attachments and Actions

```tsx
import * as React from "react";
import { Chat } from "laif-ds";

export function FullChat() {
  const [input, setInput] = React.useState("");
  return (
    <div className="h-[600px] w-full">
      <Chat
        messages={[]}
        input={input}
        handleInputChange={(e) => setInput(e.target.value)}
        handleSubmit={() => {}}
        isGenerating={false}
        allowAttachments
        onMessageSave={(id, content) => console.log("save", id, content)}
        onRateResponse={(id, rating) => console.log("rate", id, rating)}
      />
    </div>
  );
}
```

---

## Notes

- **Types**: See `Message` in `chat-message.tsx` for full shape (supports tool invocations and parts).
- **Interrupt**: When `isGenerating` is true and `stop` provided, `Enter` prompts to stop then submit.
- **Composition**: Chat uses `MessageList`, `MessageInput`, and utilities like `CopyButton` and `PromptSuggestions`.
