@paramms/chat-widget 1.0.40 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -12
- package/dist/embed.d.ts +110 -10
- package/dist/embed.js +44 -10
- package/dist/embed.js.map +1 -1
- package/dist/index.js +314 -323
- package/dist/index.js.map +1 -1
- package/dist/outbox.js +5 -5
- package/dist/outbox.js.map +1 -1
- package/dist/renderer.d.ts +1 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,9 @@ Real-time embeddable chat widget for the Relay platform. Drop into any website w
|
|
|
8
8
|
npm install @paramms/chat-widget
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
## Quick start — CDN (no npm, no build)
|
|
11
|
+
## Quick start — CDN, ESM `mount()` (no npm, no build, manual container)
|
|
12
|
+
|
|
13
|
+
This is the ESM path — you control the mount point yourself. For a floating bubble on any site with zero JavaScript (or a config object), see [Script tag](#script-tag-any-website--plain-html-wordpress-shopify-phprailsdjangolaravel-or-literally-anything) below instead — it's usually simpler unless you specifically need to place the widget inline in your own container (`data-relay-*`/`Relay('boot', ...)` don't support choosing a container element; this ESM form does, via `el`).
|
|
12
14
|
|
|
13
15
|
```html
|
|
14
16
|
<div id="chat"></div>
|
|
@@ -111,9 +113,137 @@ Prefer a floating bubble that opens the same app in a panel? `<ChatAppLauncher
|
|
|
111
113
|
|
|
112
114
|
> **Multi-tenancy note:** conversations are created and keyed under the tenant the server resolves *from* `profileId` — guests can't spoof it. For **reading your own inbox**, `ChatApp`/`ChatAppLauncher` (and `useRelayChatList`/`mountChatList`/`GET /conversations/mine`) also accept a **`tenantId`** directly: it lists every conversation the user has with that business across all of its chatrooms, and is equally safe because the list is always self-scoped to the caller's own identity. `scope="tenant"` / `tenantId` never crosses into another business's data.
|
|
113
115
|
|
|
116
|
+
## Script tag (any website — plain HTML, WordPress, Shopify, PHP/Rails/Django/Laravel, or literally anything)
|
|
117
|
+
|
|
118
|
+
This is the path for every site that isn't React: one `<script>` tag, no build step, no framework. It works two ways — pick based on how much JavaScript you're willing to write:
|
|
119
|
+
|
|
120
|
+
- **Zero-JavaScript** — `data-relay-*` attributes right on the `<script>` tag. This is the one that matters most for a plain-HTML site, a WordPress block, or a no-code builder, because it's the *only* option when there's no JavaScript on the page at all — a server template just fills in attribute values.
|
|
121
|
+
- **Full config** — a JS object (`window.relaySettings = {...}` or `Relay('boot', {...})`, same shape either way). Needed the moment you want something an HTML attribute can't hold: a nested object, an array, a function, or changing the widget's identity *after* the page has loaded (e.g. once a visitor logs in).
|
|
122
|
+
|
|
123
|
+
Both configure the exact same widget with the exact same field names as the React components above — `profileId`, `userName`/`userEmail`/`userAvatar`, `contextTitle`/`contextSubtitle`/`contextStatus` (or `listingTitle`/`listingMeta`/`listingPrice`/`listingStatus` for a marketplace-style card), `accent`, `launcher`, `position`, `launcherMessage`. If you already know the React props, you already know these.
|
|
124
|
+
|
|
125
|
+
### Zero-JavaScript — `data-relay-*` attributes
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<script
|
|
129
|
+
async
|
|
130
|
+
src="https://relay.paramms.com/embed.js"
|
|
131
|
+
data-relay-app="YOUR_PROFILE_ID"
|
|
132
|
+
data-relay-user="user_123"
|
|
133
|
+
data-relay-user-name="Jane Doe"
|
|
134
|
+
data-relay-user-email="jane@example.com"
|
|
135
|
+
data-relay-accent="#4F63F5"
|
|
136
|
+
data-relay-position="bottom-right"
|
|
137
|
+
></script>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Drop that before `</body>` and you have a working floating bubble — no other JavaScript needed anywhere on the page. Every attribute is optional except `data-relay-app`.
|
|
141
|
+
|
|
142
|
+
| Attribute | Matches field | Notes |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `data-relay-app` | `profileId` | **Required.** `data-relay-profile-id` works identically — same thing, matches the React prop name |
|
|
145
|
+
| `data-relay-user` | `userId` | Unauthenticated stable id. Omit for an anonymous guest |
|
|
146
|
+
| `data-relay-token` | `token` | Signed ES256 JWT — the production identity tier |
|
|
147
|
+
| `data-relay-user-name` | `userName` | Shown to agents |
|
|
148
|
+
| `data-relay-user-email` | `userEmail` | Shown to agents; also powers the offline email fallback |
|
|
149
|
+
| `data-relay-user-avatar` | `userAvatar` | Shown to agents |
|
|
150
|
+
| `data-relay-listing` | `listingId` | Sugar for `subjectId: "listing_<id>"` |
|
|
151
|
+
| `data-relay-context-title` / `-subtitle` / `-status` | `contextTitle` / `contextSubtitle` / `contextStatus` | Context card (general — an order, ticket, booking) |
|
|
152
|
+
| `data-relay-listing-title` / `-meta` / `-price` / `-status` | `listingTitle` / `listingMeta` / `listingPrice` / `listingStatus` | Marketplace card (a specific item — price + status badge). Use these OR the `context-*` set, both build the same card |
|
|
153
|
+
| `data-relay-accent` | `accent` | Brand colour hex |
|
|
154
|
+
| `data-relay-url` | `url` | Only needed for self-hosted Relay |
|
|
155
|
+
| `data-relay-position` | `position` | `bottom-right` \| `bottom-left` |
|
|
156
|
+
| `data-relay-launcher` | `launcher` | Set to `"false"` for an inline (non-floating) widget |
|
|
157
|
+
| `data-relay-launcher-message` / `data-relay-launcher-subtitle` | `launcherMessage` | Two flat attributes combine into the teaser card — see note below |
|
|
158
|
+
| `data-relay-target` | `el` | CSS selector for an existing element to mount into. Ignored in launcher mode |
|
|
159
|
+
| `data-relay-height` | `height` | Inline container height. Ignored in launcher mode |
|
|
160
|
+
| `data-relay-inbox` | `inbox` | `"true"` adds a back-chevron → full conversation list. Requires `data-relay-launcher="false"` — see the note below the table |
|
|
161
|
+
| `data-relay-inbox-scope` | `inboxScope` | `tenant` (default) \| `profile` |
|
|
162
|
+
|
|
163
|
+
**What's NOT available as an attribute:** `user`/`subject` as nested objects, `quickReplies`, `i18n`, and `refreshToken` — an HTML attribute can only hold a string, so these need the JS-object form below. (`launcherMessage`'s two attributes are a workaround for exactly this: the React prop takes one `{ title, subtitle }` object, which an attribute can't express, so it's split into two flat attributes that get recombined.)
|
|
164
|
+
|
|
165
|
+
**`inbox` requires `data-relay-launcher="false"`** — same limit React has (a launcher+inbox combination needs a different component there, `ChatAppLauncher`); with the default floating launcher, `data-relay-inbox` is silently ignored.
|
|
166
|
+
|
|
167
|
+
### Full config — JS object
|
|
168
|
+
|
|
169
|
+
Same field names, all in one place, same object whether it's set on page load or reacts to something happening later:
|
|
170
|
+
|
|
171
|
+
```html
|
|
172
|
+
<script async src="https://relay.paramms.com/embed.js"></script>
|
|
173
|
+
<script>
|
|
174
|
+
window.relaySettings = {
|
|
175
|
+
profileId: 'YOUR_PROFILE_ID', // required — your chatroom id
|
|
176
|
+
url: undefined, // optional — only for self-hosted Relay
|
|
177
|
+
apiUrl: undefined, // optional — only if REST lives on a different origin than the socket
|
|
178
|
+
|
|
179
|
+
token: undefined, // optional — signed ES256 JWT, production identity (wins over userId)
|
|
180
|
+
userId: 'user_123', // optional — unauthenticated stable id; omit both → anonymous guest
|
|
181
|
+
refreshToken: () => fetchNewToken(), // optional — called when a signed token expires
|
|
182
|
+
|
|
183
|
+
userName: 'Jane Doe', // optional — shown to agents, not identity
|
|
184
|
+
userEmail: 'jane@example.com', // optional — also powers the offline email fallback
|
|
185
|
+
userAvatar: 'https://…/jane.png', // optional
|
|
186
|
+
// or, if it's easier to build one object: user: { name, email, avatar }
|
|
187
|
+
|
|
188
|
+
subjectId: undefined, // optional — pins a dedicated thread; usually just use listingId below
|
|
189
|
+
listingId: '4821', // optional — sugar for subjectId: "listing_4821"
|
|
190
|
+
contextTitle: 'Order #4821', // optional — context card title (general use)
|
|
191
|
+
contextSubtitle: 'Placed Mar 3 · $129.00', // optional — context card subtitle
|
|
192
|
+
contextStatus: 'Shipped', // optional — status badge
|
|
193
|
+
// or, for a marketplace-style card: listingTitle / listingMeta / listingPrice / listingStatus
|
|
194
|
+
// or build the card yourself: subject: { title, subtitle, tags, status }
|
|
195
|
+
|
|
196
|
+
accent: '#4F63F5', // optional — brand colour
|
|
197
|
+
launcher: true, // optional — floating bubble vs inline; default true
|
|
198
|
+
position: 'bottom-right', // optional — 'bottom-right' | 'bottom-left'
|
|
199
|
+
launcherMessage: { title: 'Questions? Chat with us', subtitle: 'Start a conversation' }, // optional — a bare string also works (title only)
|
|
200
|
+
|
|
201
|
+
quickReplies: ['Track my order', 'Return an item'], // optional — reply chips above the input
|
|
202
|
+
i18n: { send: 'Enviar' }, // optional — UI string overrides
|
|
203
|
+
translateLang: undefined, // optional — auto-translate incoming messages (ISO code)
|
|
204
|
+
|
|
205
|
+
// Inline placement (ignored in launcher mode — a floating bubble is a
|
|
206
|
+
// fixed popup mount() owns, not something placed at a point in the page):
|
|
207
|
+
el: '#chat', // optional — CSS selector or element; omit → an auto-created host
|
|
208
|
+
height: '600px', // optional — inline container height
|
|
209
|
+
inbox: false, // optional — back-chevron → full conversation list (inline only, see below)
|
|
210
|
+
inboxScope: 'tenant', // optional — 'tenant' (default, all your chatrooms) | 'profile' (this one only)
|
|
211
|
+
}
|
|
212
|
+
</script>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`Relay('boot', {...})` (below) takes this exact same object — use whichever form fits how the page is built.
|
|
216
|
+
|
|
217
|
+
**`inbox` matches React exactly, including its one limit:** it only works with `launcher: false`. A floating launcher bubble is a fixed-size popup the widget owns; React itself needs a *different* component (`ChatAppLauncher`) for a launcher-with-inbox experience, and the script-tag path draws the same line. With `inbox: true` and `launcher: false`, the widget's header shows a back-chevron; tapping it swaps to the full conversation list (reusing the same list engine the dashboard's own inbox runs on); tapping a row opens that conversation; a ✕ in the list view returns to this widget's original thread.
|
|
218
|
+
|
|
219
|
+
### Commands — the same object, applied later
|
|
220
|
+
|
|
221
|
+
For identity that arrives after the page loads (a visitor logs in), or SPA-style navigation between pages without a full reload, call `Relay(...)` directly instead of (or in addition to) setting `window.relaySettings`. Same field names as above — `Relay('boot'/'identify'/'update', {...})` all take a `RelaySettings` object, just at a different moment:
|
|
222
|
+
|
|
223
|
+
```html
|
|
224
|
+
<script async src="https://relay.paramms.com/embed.js"></script>
|
|
225
|
+
<script>
|
|
226
|
+
Relay('boot', { profileId: 'YOUR_PROFILE_ID' }) // mount immediately, anonymous
|
|
227
|
+
|
|
228
|
+
// later, once the visitor logs in:
|
|
229
|
+
Relay('identify', { userId: currentUser.id, userName: currentUser.name }) // merges their guest history in
|
|
230
|
+
|
|
231
|
+
// on navigation to a different listing/order page:
|
|
232
|
+
Relay('update', { listingId: newListing.id, listingTitle: newListing.title })
|
|
233
|
+
|
|
234
|
+
// on logout:
|
|
235
|
+
Relay('shutdown') // removes the widget + local session
|
|
236
|
+
</script>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
`Relay(...)` is queue-safe — calls made before `embed.js` finishes loading are never lost. `identify`/`update` merge onto whatever's currently running (a fresh `boot` replaces it entirely).
|
|
240
|
+
|
|
241
|
+
**Network requirement:** if the host page sets a Content-Security-Policy, it must allow the relay connection — `connect-src https://api.paramms.com wss://api.paramms.com;` (both are separate origins to the browser; include both), or your self-hosted equivalent.
|
|
242
|
+
|
|
114
243
|
### Old section below (kept for reference)
|
|
115
244
|
|
|
116
245
|
```tsx
|
|
246
|
+
|
|
117
247
|
'use client'
|
|
118
248
|
import { ChatWidget } from '@paramms/chat-widget/react'
|
|
119
249
|
|
|
@@ -214,16 +344,7 @@ arrives automatically over the socket. Pass `launcherMessage` only to override
|
|
|
214
344
|
the dashboard value for one embed (it also renders instantly, before the
|
|
215
345
|
socket connects).
|
|
216
346
|
|
|
217
|
-
Script-tag embeds use data
|
|
218
|
-
|
|
219
|
-
```html
|
|
220
|
-
<script
|
|
221
|
-
src="https://relay.paramms.com/embed.js"
|
|
222
|
-
data-relay-app="YOUR_PROFILE_ID"
|
|
223
|
-
data-relay-launcher-message="Questions? Chat with us"
|
|
224
|
-
data-relay-launcher-subtitle="Start a conversation"
|
|
225
|
-
></script>
|
|
226
|
-
```
|
|
347
|
+
Script-tag embeds use `data-relay-launcher-message` / `data-relay-launcher-subtitle` (or the `launcherMessage: {title,subtitle}` object in JS-object form) — see the [Script tag](#script-tag-any-website--plain-html-wordpress-shopify-phprailsdjangolaravel-or-literally-anything) section above for the full reference.
|
|
227
348
|
|
|
228
349
|
## Internationalisation
|
|
229
350
|
|
|
@@ -234,12 +355,18 @@ Script-tag embeds use data attributes:
|
|
|
234
355
|
i18n={{
|
|
235
356
|
placeholder: 'Écrivez un message…',
|
|
236
357
|
send: 'Envoyer',
|
|
237
|
-
offline: 'Nous sommes
|
|
358
|
+
offline: 'Nous sommes absents pour le moment', // the away notice
|
|
238
359
|
poweredBy: '', // empty string hides the footer
|
|
239
360
|
}}
|
|
240
361
|
/>
|
|
241
362
|
```
|
|
242
363
|
|
|
364
|
+
`offline` is the fallback text for the **away notice** shown above the composer
|
|
365
|
+
outside the chatroom's office hours. It never blocks anything: guests can always
|
|
366
|
+
send, the message is delivered like any other, and an agent replies when they're
|
|
367
|
+
back. The chatroom's own "offline message" (dashboard → *Widget message &
|
|
368
|
+
availability*) takes precedence over this string.
|
|
369
|
+
|
|
243
370
|
RTL is detected automatically for Arabic, Hebrew, Persian and Urdu browsers.
|
|
244
371
|
|
|
245
372
|
## All options
|
package/dist/embed.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { type MountOptions, type UserInfo } from './index.js';
|
|
2
|
+
/** Everything an embedder can pass. All optional except `profileId`. Field
|
|
3
|
+
* names DELIBERATELY mirror the React props (`ChatWidgetProps` /
|
|
4
|
+
* `MarketplaceChatProps` in react.tsx) so the same mental model — and often
|
|
5
|
+
* the same field names — carries over whether you're using React or a plain
|
|
6
|
+
* script tag. Where a name changed over time the old one still works (see
|
|
7
|
+
* the `@deprecated` notes) — this is a published package embedded on live
|
|
8
|
+
* customer sites (WordPress plugin, Shopify theme block), so nothing here is
|
|
9
|
+
* ever removed, only added to. */
|
|
3
10
|
export interface RelaySettings {
|
|
4
|
-
/** The chatroom id (from your Relay dashboard). Required.
|
|
5
|
-
|
|
11
|
+
/** The chatroom id (from your Relay dashboard). Required. Matches the React
|
|
12
|
+
* `profileId` prop name. `appId` is the original alias — still works. */
|
|
6
13
|
profileId?: string;
|
|
14
|
+
/** @deprecated alias for `profileId` — kept working, `profileId` is now the
|
|
15
|
+
* documented name (matches React). */
|
|
16
|
+
appId?: string;
|
|
7
17
|
/** Relay server URL. Defaults to the hosted relay; set for self-hosted. */
|
|
8
18
|
url?: string;
|
|
9
19
|
apiUrl?: string;
|
|
@@ -12,27 +22,117 @@ export interface RelaySettings {
|
|
|
12
22
|
* both for an anonymous visitor. See EMBED.md. */
|
|
13
23
|
token?: string;
|
|
14
24
|
userId?: string;
|
|
15
|
-
/**
|
|
25
|
+
/** Called when a signed `token` is rejected (expired): return a fresh token
|
|
26
|
+
* from your backend to renew the session without a reload. Matches the
|
|
27
|
+
* React `refreshToken` prop. Only usable from `window.relaySettings` /
|
|
28
|
+
* `Relay('boot', ...)` (a function can't be expressed as an HTML
|
|
29
|
+
* attribute) — not available via `data-relay-*`. */
|
|
30
|
+
refreshToken?: () => Promise<string | null>;
|
|
31
|
+
/** Display info shown to agents (not identity) — matches the React
|
|
32
|
+
* `userName` / `userEmail` / `userAvatar` props. */
|
|
33
|
+
userName?: string;
|
|
34
|
+
userEmail?: string;
|
|
35
|
+
userAvatar?: string;
|
|
36
|
+
/** @deprecated flat aliases for `userName` / `userEmail` / `userAvatar` —
|
|
37
|
+
* kept working (the shipped Shopify integration used these names nested
|
|
38
|
+
* under `user`, see `user` below, which is the fix for that; these bare
|
|
39
|
+
* top-level fields predate that and still work standalone). */
|
|
16
40
|
name?: string;
|
|
17
41
|
email?: string;
|
|
18
42
|
avatar?: string;
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
43
|
+
/** Same info as `userName`/`userEmail`/`userAvatar`, as one nested object —
|
|
44
|
+
* matches `MountOptions.user` / React's internal shape exactly, and is
|
|
45
|
+
* what a server-rendered snippet (e.g. Shopify Liquid, WordPress PHP) will
|
|
46
|
+
* most naturally emit: `user: { name: "...", email: "..." }`. Takes
|
|
47
|
+
* precedence over the flat fields if both are somehow given. */
|
|
48
|
+
user?: UserInfo;
|
|
49
|
+
/** Subject the chat is about (e.g. a marketplace listing). `listingId` is
|
|
50
|
+
* sugar for `subjectId: "listing_<id>"`. */
|
|
21
51
|
subjectId?: string;
|
|
22
52
|
listingId?: string;
|
|
53
|
+
/** Context-card fields — matches React's `ChatWidget` `contextTitle` /
|
|
54
|
+
* `contextSubtitle` / `contextStatus` props (a general "here's what this
|
|
55
|
+
* conversation is about" card: an order, ticket, booking, etc). */
|
|
56
|
+
contextTitle?: string;
|
|
57
|
+
contextSubtitle?: string;
|
|
58
|
+
contextStatus?: string;
|
|
59
|
+
/** Marketplace-card fields — matches React's `MarketplaceChat`
|
|
60
|
+
* `listingTitle` / `listingMeta` / `listingPrice` / `listingStatus` props
|
|
61
|
+
* (a specific-item card: price + status badge, e.g. "2019 Camry — $12,500
|
|
62
|
+
* — Available"). Use these OR `contextTitle`/etc — both build the same
|
|
63
|
+
* card, pick whichever vocabulary matches your use case. */
|
|
64
|
+
listingTitle?: string;
|
|
65
|
+
listingMeta?: string;
|
|
66
|
+
listingPrice?: number;
|
|
67
|
+
listingStatus?: string;
|
|
68
|
+
/** @deprecated original flat names for the context/marketplace card —
|
|
69
|
+
* kept working. `contextTitle`/`listingTitle` are now the documented
|
|
70
|
+
* names (matching the two React components). */
|
|
23
71
|
subjectTitle?: string;
|
|
24
72
|
subjectMeta?: string;
|
|
25
73
|
subjectPrice?: number;
|
|
26
74
|
subjectStatus?: string;
|
|
75
|
+
/** The context/marketplace card as one nested object, if you'd rather build
|
|
76
|
+
* it yourself than use the flat fields above — matches
|
|
77
|
+
* `MountOptions.subject` exactly. Takes precedence over every flat field
|
|
78
|
+
* above if given. */
|
|
79
|
+
subject?: {
|
|
80
|
+
title?: string;
|
|
81
|
+
subtitle?: string;
|
|
82
|
+
tags?: string[];
|
|
83
|
+
status?: string;
|
|
84
|
+
ownerLabel?: string;
|
|
85
|
+
};
|
|
86
|
+
/** Pre-set reply chips shown above the input — matches the React
|
|
87
|
+
* `quickReplies` prop. `window.relaySettings` / `Relay('boot', ...)` only
|
|
88
|
+
* (an array can't be expressed as a single `data-relay-*` attribute). */
|
|
89
|
+
quickReplies?: string[];
|
|
90
|
+
/** i18n string overrides — matches the React `i18n` prop. Same restriction
|
|
91
|
+
* as `quickReplies`: object, so JS-object form only. */
|
|
92
|
+
i18n?: MountOptions['i18n'];
|
|
27
93
|
/** Appearance. `launcher` defaults to true (a floating bubble). */
|
|
28
94
|
accent?: string;
|
|
29
95
|
launcher?: boolean;
|
|
30
96
|
position?: 'bottom-right' | 'bottom-left';
|
|
31
|
-
/** Launcher teaser ("optional message" above the bubble).
|
|
32
|
-
*
|
|
33
|
-
|
|
97
|
+
/** Launcher teaser ("optional message" above the bubble). Matches the React
|
|
98
|
+
* `launcherMessage` prop exactly: a bare string (title only), or
|
|
99
|
+
* `{ title, subtitle }`. `launcherSubtitle` below is a SEPARATE flat
|
|
100
|
+
* field kept only so `data-relay-launcher-message` /
|
|
101
|
+
* `data-relay-launcher-subtitle` (two HTML attributes — an attribute
|
|
102
|
+
* can't hold a nested object) can still combine into the same shape; in
|
|
103
|
+
* JS-object form just pass the object directly, same as React. Omit to
|
|
104
|
+
* use the chatroom's manifest value. */
|
|
105
|
+
launcherMessage?: string | {
|
|
106
|
+
title: string;
|
|
107
|
+
subtitle?: string;
|
|
108
|
+
};
|
|
109
|
+
/** @deprecated HTML-attribute-only companion to a string `launcherMessage`
|
|
110
|
+
* — see the note above. Prefer `launcherMessage: { title, subtitle }` in
|
|
111
|
+
* JS-object form. */
|
|
34
112
|
launcherSubtitle?: string;
|
|
35
113
|
translateLang?: string;
|
|
114
|
+
/** Mount INLINE into an existing element instead of the auto-created,
|
|
115
|
+
* body-appended host that the default floating launcher uses. A CSS
|
|
116
|
+
* selector string (works from `data-relay-target` too) or an element
|
|
117
|
+
* reference (JS-object form only). Ignored when `launcher` is true — same
|
|
118
|
+
* restriction as `height`/`inbox` below: a floating launcher panel is a
|
|
119
|
+
* fixed-size popup `mount()` owns, not something you place in the page. */
|
|
120
|
+
el?: string | HTMLElement;
|
|
121
|
+
/** Inline container height — matches the React `height` prop. Only applies
|
|
122
|
+
* when `launcher` is false/omitted. */
|
|
123
|
+
height?: string;
|
|
124
|
+
/** Adds a back-chevron to the widget that swaps it for the full
|
|
125
|
+
* conversation list — matches the React `ChatWidget`/`MarketplaceChat`
|
|
126
|
+
* `inbox` prop, INCLUDING its one limitation: not supported in launcher
|
|
127
|
+
* mode. (React itself requires a different component, `ChatAppLauncher`,
|
|
128
|
+
* for a launcher+inbox combination — same scope boundary here.) Tapping a
|
|
129
|
+
* row opens that conversation; its own back-chevron returns to the list; a
|
|
130
|
+
* ✕ in the list view returns to this widget's original single-thread
|
|
131
|
+
* view. Requires `launcher: false`. */
|
|
132
|
+
inbox?: boolean;
|
|
133
|
+
/** Inbox scope when `inbox` is set: `'tenant'` (default) lists the user's
|
|
134
|
+
* threads across ALL your chatrooms; `'profile'` limits it to this one. */
|
|
135
|
+
inboxScope?: 'tenant' | 'profile';
|
|
36
136
|
}
|
|
37
137
|
export type RelayCommand = 'boot' | 'update' | 'identify' | 'shutdown';
|
|
38
138
|
/** The public command dispatcher exposed as `window.Relay`. */
|