@smooai/chat-widget 0.10.0 → 0.10.2
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 +1 -0
- package/dist/chat-widget.global.js +56 -12
- package/dist/chat-widget.global.js.map +1 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +7 -0
- package/src/element.ts +44 -4
- package/src/styles.ts +30 -8
package/README.md
CHANGED
|
@@ -228,6 +228,7 @@ Declarative attributes mirror the programmatic [`ChatWidgetConfig`](./src/config
|
|
|
228
228
|
| `greeting` | `greeting` | Shown before the first message. |
|
|
229
229
|
| `mode` | `mode` | `popover` (default) or `fullpage`. |
|
|
230
230
|
| `start-open` | `startOpen` | Open the panel immediately (no launcher click). |
|
|
231
|
+
| `hide-branding` | `hideBranding` | Hide the "powered by smooth-operator" tag + footer link. Default shown. |
|
|
231
232
|
| — | `theme` | Brand colors (see [Theming](#theming)). |
|
|
232
233
|
| — | `userName` / `userEmail` | Optional participant identity. |
|
|
233
234
|
|
|
@@ -11772,6 +11772,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
11772
11772
|
greeting: config.greeting ?? "Hi! How can I help you today?",
|
|
11773
11773
|
connectionErrorMessage: config.connectionErrorMessage ?? "We couldn't reach the chat. Please try again in a moment.",
|
|
11774
11774
|
startOpen: config.startOpen ?? false,
|
|
11775
|
+
hideBranding: config.hideBranding ?? false,
|
|
11775
11776
|
examplePrompts: (config.examplePrompts ?? []).filter((p) => p.trim().length > 0).slice(0, 5),
|
|
11776
11777
|
requireName: config.requireName ?? false,
|
|
11777
11778
|
requireEmail: config.requireEmail ?? false,
|
|
@@ -13518,11 +13519,11 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13518
13519
|
--sac-ease: cubic-bezier(.16, 1, .3, 1);
|
|
13519
13520
|
|
|
13520
13521
|
${mode === "fullpage" ? `/* Full-page: fill the host's box (sized by its container, else the viewport). */
|
|
13521
|
-
display:
|
|
13522
|
+
display: flex;
|
|
13523
|
+
flex-direction: column;
|
|
13522
13524
|
position: relative;
|
|
13523
13525
|
width: 100%;
|
|
13524
|
-
height: 100
|
|
13525
|
-
min-height: 100vh;` : `/* Popover: float in the bottom-right corner. */
|
|
13526
|
+
height: 100%;` : `/* Popover: float in the bottom-right corner. */
|
|
13526
13527
|
position: fixed;
|
|
13527
13528
|
bottom: 24px;
|
|
13528
13529
|
right: 24px;
|
|
@@ -13530,7 +13531,20 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13530
13531
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
13531
13532
|
-webkit-font-smoothing: antialiased;
|
|
13532
13533
|
}
|
|
13533
|
-
|
|
13534
|
+
${mode === "fullpage" ? `
|
|
13535
|
+
/* Viewport fallback — the element sets this attribute only when the host's
|
|
13536
|
+
container gives it no resolved height (e.g. mounted straight into an
|
|
13537
|
+
auto-height <body>). A sized container always wins, so an embed inside a
|
|
13538
|
+
fixed-height box never overflows it (composer stays visible). */
|
|
13539
|
+
:host([data-viewport-fallback]) { min-height: 100dvh; }
|
|
13540
|
+
/* The render wrapper passes the host's box down to the panel via flex. */
|
|
13541
|
+
.wrap {
|
|
13542
|
+
flex: 1;
|
|
13543
|
+
display: flex;
|
|
13544
|
+
flex-direction: column;
|
|
13545
|
+
min-height: 0;
|
|
13546
|
+
}
|
|
13547
|
+
` : ""}
|
|
13534
13548
|
* { box-sizing: border-box; }
|
|
13535
13549
|
|
|
13536
13550
|
/* ───────────────────────────── Launcher ───────────────────────────── */
|
|
@@ -13612,11 +13626,13 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13612
13626
|
pointer-events: none;
|
|
13613
13627
|
background: radial-gradient(120% 100% at 50% 0%, color-mix(in srgb, var(--sac-primary) 22%, transparent), transparent 70%);
|
|
13614
13628
|
}
|
|
13615
|
-
/* Full-page: the panel becomes the whole surface
|
|
13629
|
+
/* Full-page: the panel becomes the whole surface — it follows the host's box
|
|
13630
|
+
(via the .wrap flex chain), never a hardcoded viewport unit. */
|
|
13616
13631
|
.panel.fullpage {
|
|
13617
13632
|
width: 100%;
|
|
13618
|
-
|
|
13619
|
-
|
|
13633
|
+
flex: 1;
|
|
13634
|
+
height: auto;
|
|
13635
|
+
min-height: 0;
|
|
13620
13636
|
max-width: none;
|
|
13621
13637
|
max-height: none;
|
|
13622
13638
|
border: none;
|
|
@@ -13692,7 +13708,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13692
13708
|
}
|
|
13693
13709
|
.close:hover { background: color-mix(in srgb, var(--sac-text) 12%, transparent); transform: translateY(1px); }
|
|
13694
13710
|
.close svg { width: 16px; height: 16px; opacity: .8; }
|
|
13695
|
-
.powered { margin-left: auto; font-size: 10.5px; letter-spacing: .02em; opacity: .6; }
|
|
13711
|
+
.powered { margin-left: auto; font-size: 10.5px; letter-spacing: .02em; opacity: .6; color: inherit; text-decoration: none; }
|
|
13712
|
+
.powered:hover { opacity: .85; text-decoration: underline; }
|
|
13696
13713
|
.header-sep { height: 1px; margin: 0 16px; background: linear-gradient(90deg, transparent, var(--sac-border), transparent); }
|
|
13697
13714
|
|
|
13698
13715
|
/* Full-page header: taller, logo-led, no close. */
|
|
@@ -13964,6 +13981,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
13964
13981
|
color: color-mix(in srgb, var(--sac-text) 38%, transparent);
|
|
13965
13982
|
}
|
|
13966
13983
|
.footer b { font-weight: 600; color: color-mix(in srgb, var(--sac-text) 55%, transparent); }
|
|
13984
|
+
.footer a { color: inherit; text-decoration: none; }
|
|
13985
|
+
.footer a:hover { text-decoration: underline; }
|
|
13967
13986
|
|
|
13968
13987
|
/* ─────────────────── Pre-chat identity form ───────────────────────── */
|
|
13969
13988
|
.prechat { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 18px; padding: 22px 20px; }
|
|
@@ -14217,6 +14236,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14217
14236
|
return null;
|
|
14218
14237
|
}
|
|
14219
14238
|
}
|
|
14239
|
+
/** Public smooth-operator repo — the "powered by" header tag + footer link here. */
|
|
14240
|
+
const SMOOTH_OPERATOR_URL = "https://github.com/SmooAI/smooth-operator";
|
|
14220
14241
|
const OBSERVED = [
|
|
14221
14242
|
"endpoint",
|
|
14222
14243
|
"agent-id",
|
|
@@ -14225,7 +14246,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14225
14246
|
"placeholder",
|
|
14226
14247
|
"greeting",
|
|
14227
14248
|
"start-open",
|
|
14228
|
-
"mode"
|
|
14249
|
+
"mode",
|
|
14250
|
+
"hide-branding"
|
|
14229
14251
|
];
|
|
14230
14252
|
/**
|
|
14231
14253
|
* Inline SVG icons (static, trusted strings — never interpolated with user data).
|
|
@@ -14342,6 +14364,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14342
14364
|
greeting: this.overrides.greeting ?? this.getAttribute("greeting") ?? void 0,
|
|
14343
14365
|
connectionErrorMessage: this.overrides.connectionErrorMessage,
|
|
14344
14366
|
startOpen: this.overrides.startOpen ?? this.hasAttribute("start-open"),
|
|
14367
|
+
hideBranding: this.overrides.hideBranding ?? this.hasAttribute("hide-branding"),
|
|
14345
14368
|
examplePrompts: this.overrides.examplePrompts,
|
|
14346
14369
|
requireName: this.overrides.requireName,
|
|
14347
14370
|
requireEmail: this.overrides.requireEmail,
|
|
@@ -14395,7 +14418,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14395
14418
|
<span class="title">${escapeHtml(resolved.agentName)}</span>
|
|
14396
14419
|
<span class="status"><span class="dot off"></span><span class="status-text"></span></span>
|
|
14397
14420
|
</div>
|
|
14398
|
-
|
|
14421
|
+
${resolved.hideBranding ? "" : `<a class="powered" href="${SMOOTH_OPERATOR_URL}" target="_blank" rel="noopener noreferrer">powered by smooth-operator</a>`}
|
|
14399
14422
|
</div>` : `<div class="header">
|
|
14400
14423
|
<div class="avatar">${monogram}</div>
|
|
14401
14424
|
<div class="meta">
|
|
@@ -14429,7 +14452,8 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14429
14452
|
<button type="submit" class="pc-submit">Start chat</button>
|
|
14430
14453
|
</form>
|
|
14431
14454
|
</div>`;
|
|
14432
|
-
const
|
|
14455
|
+
const footerInner = [resolved.hideBranding ? "" : `<a href="${SMOOTH_OPERATOR_URL}" target="_blank" rel="noopener noreferrer">powered by <b>smooth‑operator</b></a>`, this.allowChatRestore ? `<button type="button" class="restore-link">Restore my chats</button>` : ""].filter(Boolean).join(" · ");
|
|
14456
|
+
const footerHtml = footerInner ? `<div class="footer">${footerInner}</div>` : "";
|
|
14433
14457
|
const chatHtml = `
|
|
14434
14458
|
<div class="messages"></div>
|
|
14435
14459
|
<div class="interrupt hidden"></div>
|
|
@@ -14438,9 +14462,10 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14438
14462
|
<textarea rows="1" placeholder="${escapeHtml(resolved.placeholder)}"></textarea>
|
|
14439
14463
|
<button class="send" type="button" aria-label="Send message">${ICON.send}</button>
|
|
14440
14464
|
</div>
|
|
14441
|
-
|
|
14465
|
+
${footerHtml}
|
|
14442
14466
|
</div>`;
|
|
14443
14467
|
const container = document.createElement("div");
|
|
14468
|
+
container.className = "wrap";
|
|
14444
14469
|
container.innerHTML = `
|
|
14445
14470
|
${fullpage ? "" : `<button class="launcher" part="launcher" aria-label="Open chat">${ICON.spark}</button>`}
|
|
14446
14471
|
<div class="panel${fullpage ? " fullpage" : " hidden"}" part="panel" role="${fullpage ? "region" : "dialog"}" aria-label="${escapeHtml(resolved.agentName)} chat">
|
|
@@ -14484,6 +14509,7 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14484
14509
|
await this.controller?.connect().catch(() => {});
|
|
14485
14510
|
})();
|
|
14486
14511
|
});
|
|
14512
|
+
if (fullpage) this.syncViewportFallback();
|
|
14487
14513
|
if (fullpage && !gating) this.controller?.connect().catch(() => {});
|
|
14488
14514
|
this.syncOpenState();
|
|
14489
14515
|
if (!gating) this.renderMessages();
|
|
@@ -14973,6 +14999,24 @@ var SmoothAgentChat = (function(exports) {
|
|
|
14973
14999
|
this.streamBubbleEl.textContent = this.streamTarget;
|
|
14974
15000
|
}
|
|
14975
15001
|
}
|
|
15002
|
+
/**
|
|
15003
|
+
* Full-page sizing probe: decide whether the host's container gives it a
|
|
15004
|
+
* real box. With the `.wrap` flex chain hidden, `height: 100%` of a SIZED
|
|
15005
|
+
* container still resolves (clientHeight > 0), while an auto-height parent
|
|
15006
|
+
* (e.g. mounted straight into `<body>`) collapses to ~0. Only the latter
|
|
15007
|
+
* gets `data-viewport-fallback`, whose CSS applies `min-height: 100dvh` —
|
|
15008
|
+
* so an embed inside a fixed-height box never overflows it (the composer
|
|
15009
|
+
* stays visible), and a bare full-page route still fills the viewport.
|
|
15010
|
+
*/
|
|
15011
|
+
syncViewportFallback() {
|
|
15012
|
+
const wrap = this.shadowRoot?.querySelector(".wrap");
|
|
15013
|
+
if (!wrap) return;
|
|
15014
|
+
const prev = wrap.style.display;
|
|
15015
|
+
wrap.style.display = "none";
|
|
15016
|
+
const heightless = this.clientHeight < 8;
|
|
15017
|
+
wrap.style.display = prev;
|
|
15018
|
+
this.toggleAttribute("data-viewport-fallback", heightless);
|
|
15019
|
+
}
|
|
14976
15020
|
/** Cancel any in-flight reveal loop and clear its state (called on full rebuild). */
|
|
14977
15021
|
resetReveal() {
|
|
14978
15022
|
if (this.rafId && typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.rafId);
|