# `hb-messages-send`

**Category:** messaging · **Tags:** messaging, chat · **Package:** `@htmlbricks/hb-messages-send`

## Overview

`hb-messages-send` is a message composer for chat-style UIs. Users type in a textarea, optionally attach files, toggle tag chips, and send with the send control or **Enter** (**Shift+Enter** inserts a newline). When the message is sent, the element dispatches a **`sendMessage`** custom event whose `detail` carries the current text, your optional **`id`**, the selected tag ids, and the staged files.

The UI is built with **Bulma 1.x** inside the shadow root. **Bootstrap Icons** are loaded from jsDelivr in the component head for attach, send, tag, maximize, and file-type icons.

## Behavior

- **Text:** Bound to the composer. The send button stays disabled until there is non-empty text **or** at least one attached file.
- **Send:** Click the send button, or press **Enter** without **Shift**. An empty composer with no files logs a console warning and does not dispatch.
- **Expandable (`expandable`):** When enabled, the textarea grows with content up to an internal cap; when that cap is reached, a **maximize / minimize** control appears so users can expand the writing area (400px height while maximized).
- **Files (`files`):** If you pass a `files` configuration object, a paperclip control appears. **`mode: "single"`** keeps at most one file; **`mode: "multiple"`** allows many. Images get a thumbnail preview; other types show an icon by MIME type. Users can remove attachments before sending.
- **Tags (`tags`):** Optional chip buttons built from your definitions. Each tag must have an **`id`** (used in the event payload). **`icon`** is the Bootstrap Icons glyph name **without** the `bi-` prefix (the markup uses `bi bi-{icon}`). **`label`** is shown on the chip. **`color`** is optional; if omitted, the component picks a color for that chip.

## Styling (Bulma and CSS variables)

The component applies Bulma’s **light and dark** theme tokens on `:host` (including **`prefers-color-scheme: dark`** and **`data-theme` / `.theme-*`** on `html` or `body`, or `data-theme` on the element itself), so surfaces and borders track your app theme. Bulma also emits internal defaults as **`--bulma-hb-def-*`** on that same `:host`; the shadow styles resolve `var(--bulma-…, var(--bulma-hb-def-…))` so the composer never falls back to a hard-coded light surface when public `--bulma-*` are unset. Prefer **`--bulma-*`** (and the component **`--tag-color`**) from the host page when you need overrides. See [Bulma CSS variables](https://bulma.io/documentation/features/css-variables/).

| Variable | Role |
|----------|------|
| `--bulma-primary` | Send button fill (light theme) or outline color (dark theme: outlined send control). |
| `--bulma-primary-invert` | Icon color on the Send button in light theme (solid fill). |
| `--bulma-link` | Focus ring, file-attach accent, maximize control. |
| `--bulma-border` | Panel and file card borders. |
| `--bulma-text` | Default input and label color for readable text on the composer surface. |
| `--bulma-text-weak` | Muted text and disabled send state. |
| `--bulma-scheme-main` | Composer surface background. |
| `--bulma-scheme-main-bis` | File strip and toolbar background. |
| `--tag-color` | Accent for tag and file controls (per-tag overrides use inline `--tag-color` from each tag’s `color` or a fallback palette). |

### CSS parts

None.

### HTML slots

None.

## Custom element

`hb-messages-send`

## Attributes and properties (HTML consumers)

Web component **attributes** are strings. Use **`yes`** / **`no`** for booleans where noted (the implementation also treats the string **`true`** as enabled for **`expandable`**). Pass **objects and arrays as JSON strings** (e.g. `tags`, `files`).

| Name | Required | Description |
|------|----------|-------------|
| `id` | No | String echoed back on **`sendMessage`** so you can correlate the composer instance (e.g. thread or channel id). |
| `text` | No | Initial / current message text. |
| `expandable` | No | **`yes`** / **`no`** (or **`true`** / other) — taller minimum textarea, auto-grow, and maximize affordance when content hits the cap. |
| `tags` | No | JSON array of `{ id: string; label?: string; icon?: string; color?: string }`. **`id`** is required for selection; **`icon`** is a Bootstrap Icons name without the `bi-` prefix. |
| `files` | No | JSON object `{ "mode": "single" \| "multiple" }`. When set, the file attach control is shown and enforces single vs multi selection. |

The authoring **`Component`** type may list **`style`** for TypeScript wrappers; the inner UI is themed with **CSS variables** on `:host`, not that prop.

## Events

| Name | `detail` shape |
|------|----------------|
| `sendMessage` | **`text`:** `string` — composer text. **`id`:** `string` — value of the `id` prop. **`tags`:** `string[]` — ids of tags the user toggled on. **`files`:** array of staged items (`MessageSendFileItem`): **`id`**, **`name`**, **`mimetype`**, **`fileSize`**, **`content`** (`File`), optional **`objectUrl`**. Use **`detail.files.map((f) => f.content)`** when you need plain **`File`** instances. |

## TypeScript (authoring / wrappers)

```typescript
export type MessageSendFileItem = {
  id: string;
  name: string;
  mimetype: string;
  fileSize: number;
  content: File;
  objectUrl?: string;
};

export type Component = {
  id?: string;
  style?: string;
  text?: string;
  expandable?: boolean;
  tags?: {
    label?: string;
    icon?: string;
    id: string;
    color?: string;
  }[];
  files?: {
    mode: "single" | "multiple";
  };
};

export type Events = {
  sendMessage: {
    text?: string;
    id: string;
    tags: string[];
    files: MessageSendFileItem[];
  };
};
```

## Examples

### Minimal

```html
<hb-messages-send expandable="yes"></hb-messages-send>
```

### Tags, single file, and initial text

```html
<hb-messages-send
  id="thread-42"
  text="Reply here…"
  expandable="yes"
  tags='[{"id":"idea","label":"Idea","icon":"lightbulb"},{"id":"bug","label":"Bug","icon":"bug-fill"}]'
  files='{"mode":"single"}'
></hb-messages-send>
```

### Listen for sends (vanilla JS)

```javascript
const el = document.querySelector("hb-messages-send");
el.addEventListener("sendMessage", (e) => {
  const { text, id, tags, files } = e.detail;
  const blobs = files.map((f) => f.content);
  // Upload blobs, append to thread, clear composer via property if needed, etc.
});
```
