

<Preview name="MessageDefaultExample" />

## Overview [#overview]

`Message` provides layout and visual treatment for user and assistant messages. It does not own message records, streaming state, or persistence.

Use `MessageResponse` for assistant-authored markdown. It wraps Streamdown, so normal markdown rendering works through the component without importing Streamdown at the call site.

## Usage [#usage]

```tsx
import {
  Attachment,
  AttachmentPreview,
  Attachments,
  Message,
  MessageAction,
  MessageActions,
  MessageContent,
  MessageResponse,
  MessageToolbar,
} from "@tilt-legal/cubitt-components/chat-elements";
```

## Examples [#examples]

### Default [#default]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="MessageDefaultExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    <Message from="assistant">
      <MessageContent>
        <MessageResponse>
          The draft gives the tenant an early termination right after year three.
        </MessageResponse>
      </MessageContent>
      <MessageToolbar>
        <MessageActions>
          <MessageAction tooltip="Copy response">...</MessageAction>
          <MessageAction tooltip="Regenerate response">...</MessageAction>
        </MessageActions>
      </MessageToolbar>
    </Message>
    ```
  </Tab>
</Tabs>

### Markdown [#markdown]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="MessageMarkdownExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    const content = [
      "## Lease review summary",
      "",
      "The **maintenance recovery clause** is the main blocker.",
      "",
      "| Issue | Risk | Next step |",
      "| --- | --- | --- |",
      "| Recovery cap | High | Ask for an annual cap. |",
    ].join("\n");

    <Message from="assistant">
      <MessageContent>
        <MessageResponse>{content}</MessageResponse>
      </MessageContent>
    </Message>;
    ```
  </Tab>
</Tabs>

### Attachments [#attachments]

<Tabs items="['Preview', 'Code']">
  <Tab value="Preview">
    <Preview name="MessageAttachmentsExample" />
  </Tab>

  <Tab value="Code">
    ```tsx
    <Message from="user">
      <Attachments variant="grid">
        {files.map((file) => (
          <Attachment data={file} key={file.url}>
            <AttachmentPreview />
          </Attachment>
        ))}
      </Attachments>
      <MessageContent>Use these files when checking the clause.</MessageContent>
    </Message>
    ```
  </Tab>
</Tabs>

## API Reference [#api-reference]

### Message [#message]

Root message shell. Extends all HTML `div` props.

| Prop        | Type                                | Default | Description                                     |
| ----------- | ----------------------------------- | ------- | ----------------------------------------------- |
| `from`      | `"system" \| "user" \| "assistant"` | -       | Message role. Required.                         |
| `children`  | `React.ReactNode`                   | -       | Message content, toolbar, branches, or actions. |
| `className` | `string`                            | -       | Additional CSS classes for the message shell.   |

### MessageContent [#messagecontent]

Styled message content container. Extends all HTML `div` props.

| Prop        | Type              | Default | Description                                 |
| ----------- | ----------------- | ------- | ------------------------------------------- |
| `children`  | `React.ReactNode` | -       | Text, markdown response, or custom content. |
| `className` | `string`          | -       | Additional CSS classes for the content.     |

### MessageResponse [#messageresponse]

Markdown response renderer powered by Streamdown. Extends Streamdown props.

| Prop        | Type              | Default | Description                                     |
| ----------- | ----------------- | ------- | ----------------------------------------------- |
| `children`  | `React.ReactNode` | -       | Markdown content to render.                     |
| `className` | `string`          | -       | Additional CSS classes for the Streamdown root. |

### MessageToolbar [#messagetoolbar]

Toolbar row for message actions or branch controls. Extends all HTML `div` props.

| Prop        | Type              | Default | Description                             |
| ----------- | ----------------- | ------- | --------------------------------------- |
| `children`  | `React.ReactNode` | -       | Toolbar content.                        |
| `className` | `string`          | -       | Additional CSS classes for the toolbar. |

### MessageActions [#messageactions]

Action group inside a toolbar. Extends all HTML `div` props.

| Prop        | Type              | Default | Description                                  |
| ----------- | ----------------- | ------- | -------------------------------------------- |
| `children`  | `React.ReactNode` | -       | `MessageAction` buttons.                     |
| `className` | `string`          | -       | Additional CSS classes for the action group. |

### MessageAction [#messageaction]

Icon action button with optional tooltip. Extends Button props.

| Prop       | Type                     | Default   | Description                                                               |
| ---------- | ------------------------ | --------- | ------------------------------------------------------------------------- |
| `tooltip`  | `string`                 | -         | Tooltip content. Also used as screen-reader text when `label` is omitted. |
| `label`    | `string`                 | -         | Screen-reader text for the action.                                        |
| `variant`  | `ButtonProps["variant"]` | `"ghost"` | Button variant.                                                           |
| `mode`     | `ButtonProps["mode"]`    | `"icon"`  | Button mode.                                                              |
| `size`     | `ButtonProps["size"]`    | `"sm"`    | Button size.                                                              |
| `children` | `React.ReactNode`        | -         | Icon or custom action content.                                            |

### MessageAttachment [#messageattachment]

Attachment convenience component for messages. Extends `Attachment` props except `data`, and requires chat attachment data.

| Prop         | Type                     | Default                    | Description                                     |
| ------------ | ------------------------ | -------------------------- | ----------------------------------------------- |
| `data`       | `ChatAttachmentFileData` | -                          | File attachment data. Required.                 |
| `onRemove`   | `() => void`             | -                          | Enables the built-in remove button.             |
| `aria-label` | `string`                 | generated attachment label | Accessible label for the attachment.            |
| `title`      | `string`                 | generated attachment label | Title attribute for the attachment.             |
| `className`  | `string`                 | -                          | Additional CSS classes for the attachment item. |

### MessageAttachments [#messageattachments]

Message attachment container. Extends `Attachments` props.

| Prop        | Type                           | Default  | Description                                          |
| ----------- | ------------------------------ | -------- | ---------------------------------------------------- |
| `variant`   | `"grid" \| "inline" \| "list"` | `"grid"` | Attachment layout variant.                           |
| `children`  | `React.ReactNode`              | -        | Attachment items. Renders nothing when omitted.      |
| `className` | `string`                       | -        | Additional CSS classes for the attachment container. |

### MessageBranch [#messagebranch]

Stateful branch container for alternate message responses. Extends all HTML `div` props.

| Prop             | Type                            | Default | Description                                       |
| ---------------- | ------------------------------- | ------- | ------------------------------------------------- |
| `defaultBranch`  | `number`                        | `0`     | Initial selected branch index.                    |
| `onBranchChange` | `(branchIndex: number) => void` | -       | Callback fired when previous/next changes branch. |
| `children`       | `React.ReactNode`               | -       | Branch content and branch controls.               |
| `className`      | `string`                        | -       | Additional CSS classes for the branch container.  |

### MessageBranchContent [#messagebranchcontent]

Branch content switcher. Each child is treated as one branch. Extends all HTML `div` props.

| Prop        | Type              | Default | Description                                     |
| ----------- | ----------------- | ------- | ----------------------------------------------- |
| `children`  | `React.ReactNode` | -       | Branch children to register and switch between. |
| `className` | `string`          | -       | Additional CSS classes for each branch wrapper. |

### MessageBranchSelector [#messagebranchselector]

Wrapper for branch navigation controls. Extends all HTML `div` props and renders nothing when there is only one branch.

| Prop        | Type                                | Default | Description                                           |
| ----------- | ----------------------------------- | ------- | ----------------------------------------------------- |
| `from`      | `"system" \| "user" \| "assistant"` | -       | Message role value. Required by the public prop type. |
| `children`  | `React.ReactNode`                   | -       | Previous/page/next branch controls.                   |
| `className` | `string`                            | -       | Additional CSS classes for the selector wrapper.      |

### MessageBranchPrevious [#messagebranchprevious]

Previous branch button. Extends Button props and must be used inside `MessageBranch`.

| Prop        | Type              | Default           | Description                                    |
| ----------- | ----------------- | ----------------- | ---------------------------------------------- |
| `children`  | `React.ReactNode` | left chevron icon | Custom previous icon/content.                  |
| `disabled`  | `boolean`         | derived           | Disabled automatically when one branch exists. |
| `className` | `string`          | -                 | Additional CSS classes for the button.         |

### MessageBranchNext [#messagebranchnext]

Next branch button. Extends Button props and must be used inside `MessageBranch`.

| Prop        | Type              | Default            | Description                                    |
| ----------- | ----------------- | ------------------ | ---------------------------------------------- |
| `children`  | `React.ReactNode` | right chevron icon | Custom next icon/content.                      |
| `disabled`  | `boolean`         | derived            | Disabled automatically when one branch exists. |
| `className` | `string`          | -                  | Additional CSS classes for the button.         |

### MessageBranchPage [#messagebranchpage]

Current branch page indicator. Extends all HTML `span` props.

| Prop        | Type     | Default | Description                                |
| ----------- | -------- | ------- | ------------------------------------------ |
| `className` | `string` | -       | Additional CSS classes for the page label. |

The rendered text is generated from the current branch and total branch count.
