# `hb-toast` — integrator guide

**Category:** overlays · **Tags:** overlays, notifications · **Package:** `@htmlbricks/hb-toast` · **Custom element:** `hb-toast`

## Summary

`hb-toast` is a **Bulma-styled** floating notification: a dismissible card with optional status chip, body copy, optional action buttons, and an optional **bottom progress bar**. It is positioned in a corner or edge of the viewport (configurable), uses **Bootstrap Icons** for built-in status icons, and communicates with the host through **`changeVisibility`** and **`action`** custom events.

Use it for transient messages, timed auto-dismiss, upload or task **progress**, or **confirm / cancel** flows without a full modal.

## Props and attributes

Attributes use **snake_case**. In HTML, values are **strings** only: use **`yes`** / **`no`** for visibility, numbers as strings (for example **`timeout="5000"`**), and **`buttons`** as a **JSON array** string. From JavaScript you may assign properties with richer types where your bindings support it (for example a parsed `buttons` array).

| Attribute | Required | Description |
|-----------|----------|-------------|
| `show` | Yes | **`yes`** shows the toast; **`no`** hides it and clears timers. |
| `title` | Yes | Bold header line (also mirrored if the `header_strong` slot is empty). |
| `content` | Yes | Main message HTML is not assumed; plain text is shown in the default body (slot `body` overrides). |
| `img` | Yes (per typings) | String (URL or data URI). Present on the public **`Component`** type and catalog examples; the current implementation does **not** render this value in the shadow tree. Use the **`header_icon`** slot for a custom image or icon. |
| `id` | No | Included in event `detail` for correlation when multiple toasts exist. |
| `style` | No | On the TypeScript interface for host-level styling; not forwarded into inner markup in the current source. |
| `small` | No | Fixed **status chip** text. When set, it overrides automatic status (countdown, progress label, or elapsed time). |
| `level` | No | Semantic tone: **`primary`**, **`secondary`** (link hue), **`success`**, **`danger`**, **`warning`**, **`info`**, **`light`**, **`dark`**. Default **`info`**. Sets **`--hb-toast-accent`** as `hsl(var(--bulma-*-h), …)` (Bulma has no single `var(--bulma-primary)` paint) for start border, icon/status tint, and progress fill; card uses **`--bulma-background`** / **`--bulma-text`**. |
| `position` | No | **`top-left`**, **`top-center`**, **`top-right`**, **`bottom-left`**, **`bottom-center`**, **`bottom-right`**. Default **`bottom-right`**. |
| `timeout` | No | Auto-dismiss delay in **milliseconds** (coerced with `Number`). When set and greater than zero, and **`progress`** is not a valid 0–100 value, the toast closes when the timer elapses and the bar animates from 0% to 100% over that interval. |
| `progress` | No | String parsed as a number **0–100**. When valid, drives the bar width and status text (percentage) unless **`small`** is set. When the value reaches **100%** while visible, the toast **auto-closes** after its fade-out (same path as timeout completion). |
| `buttons` | No | JSON string (or array from JS) of **`TToastButton`** objects: **`type`** **`confirm`** | **`cancel`**; optional **`action`**, **`text`**, **`icon`** (Bootstrap Icons class, e.g. **`bi-check-lg`**), **`themeColor`**, **`color`** (inline background on the button). Defaults supply label, theme, and icon per type. |

### Button objects (`buttons`)

Each entry is merged with defaults:

- **`confirm`:** default text “Confirm”, theme **`success`**, icon **`bi-check-lg`**.
- **`cancel`:** default text “Cancel”, theme **`secondary`** (rendered as Bulma **`is-light`** for secondary), icon **`bi-x-lg`**.

Clicking a button dispatches **`action`** with the button’s **`action`** string, then closes the toast.

## Runtime behavior

- **Visibility:** With **`show="yes"`**, the toast enters with a short fade-in. With **`show="no"`**, timers and intervals are cleared.
- **Close control:** The corner **delete** control calls **`close`**: timers stop, **`show`** becomes **`no`**, and **`changeVisibility`** fires with **`show: false`** (no **`disappear`** flag).
- **Timed dismiss:** If **`timeout`** is a positive number and there is no external numeric **`progress`**, a single timer runs for that many milliseconds, the progress bar fills over the same period, then **`autoClose`** runs: after the fade-out buffer, **`changeVisibility`** fires with **`show: false`** and **`disappear: true`**.
- **Status chip:** If **`small`** is a non-empty string, it is always shown as the chip text. Otherwise: if **`progress`** parses to a number, the chip shows **`{percentage}%`**; if **`timeout`** is positive, the chip shows a **human-readable remaining** countdown (for example “2 minutes 30 seconds remaining”); if neither applies, the chip shows **elapsed** time since open (“now”, then “1 second ago”, and so on). An explicit empty **`small`** suppresses that computed line unless you fill **`header_small`**.
- **Progress bar:** Shown when **`progress`** is a valid percentage **or** when **`timeout`** is positive (timeout mode). External **`progress`** clamps to 0–100; invalid or empty **`progress`** falls back to timeout-driven animation only.
- **Icons in the chip:** Context icons are **`bi-tag`** (custom **`small`**), **`bi-reception-4`** (percentage), **`bi-hourglass-split`** (countdown), **`bi-clock-history`** (elapsed).

## Events

| Event | `detail` |
|-------|----------|
| `changeVisibility` | **`{ id: string; show: boolean; disappear?: boolean }`** — fired when the toast is hidden programmatically, by the user, or after auto-dismiss. **`disappear: true`** is set on **auto** close after timeout or when progress reaches 100%. |
| `action` | **`{ id: string; action?: string }`** — fired when an action button is pressed; **`action`** matches the **`action`** field on the clicked **`TToastButton`**. |

### Example (vanilla JS)

```js
const toast = document.querySelector("hb-toast");

toast.addEventListener("changeVisibility", (e) => {
  console.log(e.detail); // { id, show, disappear? }
});

toast.addEventListener("action", (e) => {
  console.log(e.detail); // { id, action? }
});
```

## Styling (Bulma)

Shadow styles forward **Bulma 1.x** from `styles/bulma.scss`. Theme the host from the light DOM with **`--bulma-*`** variables (see [Bulma CSS variables](https://bulma.io/documentation/features/css-variables/)).

Documented **`styleSetup`** variables (`extra/docs.ts`):

| Variable | Type | Role |
|----------|------|------|
| `--bulma-column-gap` | number | Edge insets and internal gaps in the toast shell. |
| `--bulma-radius` | number | Corner radius of the floating panel. |
| `--bulma-border-weak` | color | Hairline border and dividers. |
| `--bulma-shadow` | string | Drop shadow for the panel. |
| `--bulma-text` | color | Secondary and meta text. |
| `--bulma-text-strong` | color | Title and strong header tone. |
| `--bulma-block-spacing` | number | Vertical rhythm in header and footer stacks. |

## CSS `::part`

| Part | Description |
|------|-------------|
| `toast` | Outer card: theme background + text; `level` drives `--hb-toast-accent` (border, progress, icons). |
| `status` | Status row under the title: countdown, **`progress`** percentage, **`small`** text, or slot-driven content. |

## Slots

| Slot | Description |
|------|-------------|
| `header_icon` | Leading icon area; default is a **Bootstrap Icons** bell (**`bi-bell`**). |
| `header_strong` | Optional content **before** the **`title`** text in the title line (slot is empty by default; **`title`** still renders). |
| `header_small` | Overrides the default status chip text (same surface as automatic timeout / progress / elapsed). |
| `body` | Main copy; default content is **`content`**. |

## Examples

### Basic open toast

```html
<hb-toast
  show="yes"
  title="Notice"
  content="Hello, world! This is a toast message."
  img=""
  level="info"
></hb-toast>
```

### Timed auto-dismiss (5 seconds)

```html
<hb-toast
  show="yes"
  title="Saved"
  content="Your changes were stored."
  img=""
  timeout="5000"
  level="success"
></hb-toast>
```

### Fixed progress (string 0–100)

```html
<hb-toast
  show="yes"
  title="Upload"
  content="Uploading your file…"
  img=""
  progress="42"
  level="warning"
></hb-toast>
```

### Confirm / cancel (`buttons` as JSON)

```html
<hb-toast
  id="confirm-1"
  show="yes"
  title="Confirm"
  content="Proceed with this action?"
  img=""
  level="light"
  buttons='[{"type":"cancel","action":"dismiss"},{"type":"confirm","action":"proceed","text":"Yes","icon":"bi-check-circle"}]'
></hb-toast>
```

### Custom leading icon (slot)

```html
<hb-toast show="yes" title="Alert" content="Something happened." img="" level="danger">
  <span slot="header_icon" class="icon is-medium">
    <i class="bi bi-exclamation-triangle" aria-hidden="true"></i>
  </span>
</hb-toast>
```
