---
sidebar_position: 19
---

# Elements reference

The ready-made parts as HTML elements, for any page: no React needed, nothing to build. Each draws on the rooms, calls and streams of the page (`connect()`), and does only what your server rules let the page user do ([permissions](permissions.md)).

They are optional. To draw any of them with your own components instead, use the API they are built on: [your own interface](interface.md) shows it, element by element.

```js
const rt = await connect( config );
await rt.callScreen();     // the call screen and ring, and the elements below but the streams
await rt.streamScreen();   // <wordplus-stream> and <wordplus-studio>
```

`rt.ui()` loads the same script without the calls: who is in a room, the count, typing and the chat, with no call buttons and no ring. An element on the page before its script loads draws once it has.

| Element | What it is |
|---|---|
| [`<wordplus-call>`](#wordplus-call) | a button that calls someone |
| [`<wordplus-room>`](#wordplus-room) | a button that joins a group call |
| [`<wordplus-online>`](#wordplus-online) | who is in a presence room, with call buttons |
| [`<wordplus-online-count>`](#wordplus-online-count) | how many are in a room |
| [`<wordplus-typing>`](#wordplus-typing) | who is typing in a room |
| [`<wordplus-chat>`](#wordplus-chat) | a conversation on a room |
| [`<wordplus-calls>`](#wordplus-calls) | where the call screen draws, with its templates |
| [`<wordplus-stream>`](#wordplus-stream) | a live stream, or one of its parts |
| [`<wordplus-studio>`](#wordplus-studio) | the studio of a live stream, for its host |

## `<wordplus-call>`

```html
<wordplus-call to="34" call="support:{pair}" type="video" name="Ann" avatar="https://…/ann.jpg">Call Ann</wordplus-call>
```

| Attribute | |
|---|---|
| `to` | the user id to call |
| `call` | the name of the call, as your `calls()` rule allows it. `{pair}` is the page user and `to` in order, so either of the two calling names the same call. `{me}` is the page user, `{id}` is `to` |
| `type` | `video` (the default) or `audio` |
| `name`, `avatar` | who is called, for the call window while it rings |

Its content is the text of the button. The button is the part `button`: `wordplus-call::part(button) { … }`.

## `<wordplus-room>`

```html
<wordplus-room room="meeting:daily" type="video" title="Daily meeting">Join the meeting</wordplus-room>
```

| Attribute | |
|---|---|
| `room` | the name of the group call, as your `groupCalls()` rule allows it |
| `type` | `video` (the default) or `audio` |
| `title` | the title of the call window |

Its content is the text of the button, the part `button`.

## `<wordplus-online>`

```html
<wordplus-online room="shop" title="In the shop now" call="support:{pair}" type="video audio"></wordplus-online>
```

| Attribute | |
|---|---|
| `room` | a presence room |
| `title` | above the list, Online by default. Its number of people follows it |
| `call` | the name of a call to each of the others, `{pair}` as above, on the rows of those your `calls()` rule lets the user call. Without it, no call buttons |
| `type` | the call buttons on each row: `video`, `audio`, or both, `video audio` |

Each row shows the name and picture your server gives the member (`info`, or your `profile()`), and an online dot. Template and part: `online-row` ([customizing](customizing.md#on-any-page-the-elements)).

## `<wordplus-online-count>`

```html
<wordplus-online-count room="product:42"></wordplus-online-count>
```

How many are in a room that counts (`count` or `presence`), and nothing while it is empty.

## `<wordplus-typing>`

```html
<wordplus-typing room="chat:34:42" event="typing"></wordplus-typing>
```

| Attribute | |
|---|---|
| `room` | the room |
| `event` | the event a page sends while its user types, `typing` by default, `{ on: true }` and `{ on: false }`, which `<wordplus-chat>` sends |

## `<wordplus-chat>`

```html
<wordplus-chat room="chat:34:42" messages="/api/chat/34/42/messages" placeholder="Write a message" reactions="👍 ❤️ 😂" max-length="2000"
               style="height: 520px"></wordplus-chat>
```

| Attribute | |
|---|---|
| `room` | the room of the conversation, whose rule lets the page send `message`, `typing`, `read` and `reaction` |
| `messages` | your route for the messages your server kept, asked with the page cookies. `?before=<id>` asks for the page before that message. It answers `{ messages: [ { id, from, text, at, reactions } ], more }`, oldest first |
| `placeholder` | the words in the empty composer |
| `reactions` | the reactions to pick from, emoji (`👍 ❤️`) or their code points (`1f44d 2764`), apart by spaces. Empty for none. 👍 ❤️ 😂 😮 😢 🙏 by default |
| `max-length` | the most characters of a message |

| Property | |
|---|---|
| `load` | in place of `messages`: `async ( before ) => ( { messages, more } )`, for a route that needs headers of its own. `before` is `null` for the newest page, or the oldest message shown (`{ id, at }`). It may be set before the element is on the page |

| Event | |
|---|---|
| `sent` | a message of this user the room took, `{ id, room, text, at }` as its `detail`: for your server to keep it and tell the other person where no webhook reaches it ([chat](../use-cases/chat.md#telling-the-other-person)) |

It fills the height the page gives it. With neither `messages` nor `load`, it shows what the room still keeps (5 minutes). What it sends ([events from the page](events.md#ready-made-the-chat)):

| Event | Data |
|---|---|
| `message` | `{ text }`, with an ack |
| `typing` | `{ on }`, volatile |
| `read` | `{ id }`, the newest message seen, volatile |
| `reaction` | `{ id, key }`, `key` empty to take it back, with an ack |

Templates: `message`, `empty-conversation`. Parts: `message`, `composer`, `empty-conversation`.

## `<wordplus-calls>`

The call screen draws by itself, in an element of its own at the end of the page. Write `<wordplus-calls>` on the page to give it templates of your own:

```html
<wordplus-calls>
    <template slot="ring-card">
        <div class="ring"><b data-field="name"></b> is calling
            <button data-action="answer">Pick up</button> <button data-action="reject">Not now</button></div>
    </template>
    <template slot="control" data-control="raise" data-label="Raise hand" data-icon="raisehand"></template>
</wordplus-calls>
```

- **Templates:** `ring-card`, `call-status`, and `control`, a button of yours in the call controls. When it is pressed, the page hears `wordplus-control`, with `detail.control` its name.
- **Parts:** `ring-card`, `call-window`, `call-status`, `video-tile`, `self-view`, `call-controls`, `grid-tile`.

## `<wordplus-stream>`

```html
<wordplus-stream name="show:mugs" title="The new mugs"></wordplus-stream>
```

| Attribute | |
|---|---|
| `name` | the stream, as your `streams()` rule allows it |
| `view` | the whole stream (the default), or one part: `player`, `chat`, `details`, `studio` |
| `title` | the title of the stream |
| `cover` | a picture behind the player before the stream starts and after it ends |
| `url` | the page to share, this one by default |
| `login-url` | where a visitor signs in to write in the chat |
| `studio-url` | a page of its own where the host goes live: here the host sees the way there in place of the studio |
| `chat` | `off` for the stream without its chat |
| `height` | the height of a chat apart, in pixels |
| `sticky` | keeps the player at the top of a phone while live |

- **The parts of one stream** share one join and one chat, wherever they are: `<wordplus-stream name="show:mugs" view="player">` in the page, `view="chat"` in its side column.
- **What the page user sees** follows the answer of your rule: the studio for its host, the player and the chat for everyone else, with what keeps the chat for its `mod`s.
- **A refusal** shows its words in place of the stream: no access, or live streaming not in the plan.
- **Its look** is drawn in the page, not in a shadow root: style its `estream-` classes ([customizing](customizing.md#live-streams)).

## `<wordplus-studio>`

```html
<wordplus-studio name="show:mugs"></wordplus-studio>
```

The studio alone: the camera and microphone, the picture before going live, streaming from OBS, Go live and End stream. Nothing for anyone the rule does not make the host.

## Their words and look

- **Words:** in the language of the page `<html lang>`, in English, German, Spanish, French, Italian, Dutch, Polish, Croatian and Hebrew. `rt.callScreen( { lang, strings } )` and `rt.streamScreen( { lang, strings } )` choose another and change any of them by their English text.
- **Light and dark:** they follow the system, or the page when it says which: `bm-messages-light` or `bm-messages-dark` on `<body>`, or a `color-scheme` naming one alone.
- **Right to left:** a page in Hebrew draws them mirrored.
- **Design tokens,** such as `--bm-color-accent`, go on the elements themselves, since each keeps its own in its shadow root: `wordplus-calls, wordplus-chat, wordplus-online { --bm-color-accent: 37, 99, 235; }`. Set there, they hold in light and dark alike ([customizing](customizing.md#1-the-look)). The streams have a look of their own, their `estream-` classes.
