@morgan-and-morgan/intake-agent 1.0.0-alpha.6 → 1.0.0-alpha.8

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 CHANGED
@@ -21,6 +21,10 @@ placeholder, don't bump it by hand.
21
21
  | `release/**` | `x.y.z-beta.N` | `beta` |
22
22
  | `main` | `x.y.z` | `latest` |
23
23
 
24
+ Each bundle also carries its matching chat environment: development for
25
+ `alpha`, UAT for `beta`, and production for `latest`. `data-chat-url` remains
26
+ an explicit override.
27
+
24
28
  `fix:` bumps the patch, `feat:` the minor, a `BREAKING CHANGE:` footer the
25
29
  major. Every release is tagged `intake-agent-vx.y.z`.
26
30
 
@@ -28,5 +32,5 @@ major. Every release is tagged `intake-agent-vx.y.z`.
28
32
 
29
33
  | Attribute | Default | Purpose |
30
34
  | --- | --- | --- |
31
- | `data-chat-url` | `/embed/intake` | Chat iframe target (resolved against the loader's origin) |
35
+ | `data-chat-url` | Release environment URL | Chat iframe target |
32
36
  | `data-auto-open` | `false` | Open the chat immediately after mount |
Binary file
Binary file
@@ -1,11 +1,12 @@
1
1
  (function() {
2
2
  "use strict";
3
- const DEFAULT_CHAT_PATH = "/embed/intake";
4
3
  const readLoaderConfig = (script, baseUri) => {
5
4
  var _a;
6
5
  const scriptUrl = new URL(script.src, baseUri);
7
- const chatUrl = new URL((_a = script.dataset.chatUrl) != null ? _a : DEFAULT_CHAT_PATH, scriptUrl).href;
6
+ const bundledChatUrl = "https://chat.mx2.dev/embed/intake";
7
+ const chatUrl = new URL((_a = script.dataset.chatUrl) != null ? _a : bundledChatUrl, scriptUrl).href;
8
8
  return {
9
+ assetBaseUrl: new URL(".", scriptUrl).href,
9
10
  autoOpen: script.dataset.autoOpen === "true",
10
11
  chatOrigin: new URL(chatUrl).origin,
11
12
  chatUrl
@@ -124,6 +125,9 @@
124
125
  const EMBED_MESSAGE_TYPE = Object.freeze({
125
126
  HOST_READY: "mm:intake:host-ready",
126
127
  CHILD_READY: "mm:intake:child-ready",
128
+ // Host asks the embedded chat to put the caret in its composer. Kept
129
+ // separate from HOST_READY so signing-card handshakes never steal focus.
130
+ FOCUS_COMPOSER: "mm:intake:focus-composer",
127
131
  SIGNING_REQUESTED: "mm:intake:signing-requested",
128
132
  SIGNING_RECORDED: "mm:intake:signing-recorded",
129
133
  // Chat asks the host page for a signed-in token; the host answers with
@@ -219,10 +223,10 @@
219
223
  "circle-check": '<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',
220
224
  "chevron-down": '<path d="m6 9 6 6 6-6"/>'
221
225
  };
222
- const BUTTON_TEXT_US = "data:image/png;base64,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";
223
226
  const FULL_PAGE_PANEL_QUERY = "(max-width:600px),(max-height:500px)";
224
227
  const lucideIcon = (name, className, strokeWidth = 2) => `<svg class="${className}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${String(strokeWidth)}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${LUCIDE_ICON_PATHS[name]}</svg>`;
225
228
  const OPEN_CLOSE_ICON = lucideIcon("x", "mm-icon mm-icon-close");
229
+ const PROMPT_CLOSE_ICON = lucideIcon("x", "mm-prompt-close-icon", 2.5);
226
230
  const WIDGET_STYLES = [
227
231
  ':host{all:initial;color-scheme:light;--mm-yellow:#fdeb01;--mm-yellow-hover:#f5de00;--mm-yellow-pressed:#e6cc00;--mm-blue:#115099;--mm-blue-hover:#0b3568;--mm-ink:#111;--mm-white:#fff;--mm-surface-blue:#f3f8ff;--mm-chrome:#e8eef2;--mm-line:#e2e8f0;--mm-muted:#545454;--mm-green:#0f9d58;--mm-font:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}',
228
232
  "*,*::before,*::after{box-sizing:border-box}",
@@ -231,6 +235,8 @@
231
235
  "@keyframes mm-close-in{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}",
232
236
  "@keyframes mm-panel-in{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}",
233
237
  "@keyframes mm-panel-out{from{opacity:1;transform:none}to{opacity:0;transform:translateY(10px) scale(.98)}}",
238
+ "@keyframes mm-prompt-backdrop-in{from{opacity:0}to{opacity:1}}",
239
+ "@keyframes mm-prompt-card-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}",
234
240
  "@keyframes mm-dot{0%,100%{opacity:.4;transform:scale(1)}50%{opacity:1;transform:scale(1.2)}}",
235
241
  // Closed: LivePerson TEXT US sticky under the chat layer. Open: swap for a
236
242
  // blue X disc above the chat so there is always a clear close control.
@@ -263,15 +269,31 @@
263
269
  ".mm-dot{width:8px;height:8px;border-radius:999px;background:var(--mm-muted);animation:mm-dot 1.2s ease-in-out infinite}",
264
270
  ".mm-dot:nth-child(2){animation-delay:.15s}",
265
271
  ".mm-dot:nth-child(3){animation-delay:.3s}",
272
+ ".mm-prompt-backdrop{position:fixed;inset:0;z-index:2147483002;display:grid;place-items:center;padding:16px;overscroll-behavior:contain;touch-action:none;background:rgba(0,0,0,.64);animation:mm-prompt-backdrop-in .25s cubic-bezier(.23,1,.32,1) both;font-family:var(--mm-font)}",
273
+ ".mm-prompt-card{position:relative;width:min(632px,calc(100vw - 32px),calc((100vh - 32px)*1.26148));aspect-ratio:632/501;animation:mm-prompt-card-in .25s cubic-bezier(.23,1,.32,1) both}",
274
+ ".mm-prompt-image{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none}",
275
+ ".mm-prompt-open,.mm-prompt-close{position:absolute;border:0;outline:none;background:transparent;cursor:pointer}",
276
+ ".mm-prompt-open{inset:0;border-radius:24px}",
277
+ ".mm-prompt-close{top:4.5%;right:3.1%;z-index:1;display:grid;place-items:center;width:44px;height:44px;border-radius:999px;color:var(--mm-white)}",
278
+ '.mm-prompt-close::before{content:"";position:absolute;width:28px;height:28px;border-radius:999px;background:#050505;box-shadow:0 1px 4px rgba(0,0,0,.35);transition:background-color .12s ease}',
279
+ ".mm-prompt-close-icon{position:relative;display:block;width:16px;height:16px;pointer-events:none}",
280
+ ".mm-prompt-close:hover::before{background:#252525}",
281
+ ".mm-prompt-open:focus-visible{outline:3px solid var(--mm-yellow);outline-offset:-8px}",
282
+ ".mm-prompt-close:focus-visible{outline:none}",
283
+ ".mm-prompt-close:focus-visible::before{background:#050505;box-shadow:inset 0 0 0 2px var(--mm-yellow),0 1px 4px rgba(0,0,0,.35)}",
266
284
  "[hidden]{display:none!important}",
267
285
  `@media ${FULL_PAGE_PANEL_QUERY}{.mm-launcher[aria-expanded="true"]{top:calc(var(--mm-viewport-top,0px) + 10px);right:10px;bottom:auto;width:44px;height:44px}.mm-chat{left:0;right:0;top:var(--mm-viewport-top,auto);bottom:0;width:auto;height:var(--mm-viewport-height,100dvh);min-height:0;border:0;border-radius:0;box-shadow:0 calc(100lvh - 100svh) 0 var(--mm-panel-bottom,var(--mm-chrome))}}`,
268
- "@media(prefers-reduced-motion:reduce){.mm-launcher,.mm-chat{animation:none;transition:none}.mm-dot{animation:none}}"
286
+ "@media(forced-colors:active){.mm-prompt-close:focus-visible{outline:2px solid ButtonText;outline-offset:-9px}}",
287
+ "@media(prefers-reduced-motion:reduce){.mm-launcher,.mm-chat{animation:none;transition:none}.mm-prompt-card{animation-name:mm-prompt-backdrop-in}.mm-dot{animation:none}}"
269
288
  ].join("");
270
- const WIDGET_MARKUP = [
289
+ const widgetMarkup = (launcherImageUrl, promptImageUrl) => [
271
290
  `<style>${WIDGET_STYLES}</style>`,
272
- `<button class="mm-launcher" type="button" aria-label="Open intake chat" aria-expanded="false" draggable="false"><img class="mm-text-us" src="${BUTTON_TEXT_US}" alt="" width="38" height="147" decoding="async" />${OPEN_CLOSE_ICON}</button>`,
291
+ `<button class="mm-launcher" type="button" aria-label="Open intake chat" aria-expanded="false" draggable="false"><img class="mm-text-us" src="${launcherImageUrl}" alt="" width="38" height="147" decoding="async" />${OPEN_CLOSE_ICON}</button>`,
273
292
  '<section class="mm-chat" role="dialog" aria-label="Morgan and Morgan intake chat" inert hidden>',
274
293
  '<div class="mm-frame-wrap"><div class="mm-loading" role="status" aria-label="Loading secure chat"><span class="mm-dot"></span><span class="mm-dot"></span><span class="mm-dot"></span></div><iframe class="mm-frame mm-chat-frame" title="Morgan and Morgan intake chat" referrerpolicy="strict-origin-when-cross-origin"></iframe></div>',
294
+ "</section>",
295
+ '<section class="mm-prompt-backdrop" role="dialog" aria-modal="true" aria-label="Start your free consultation" inert hidden>',
296
+ `<div class="mm-prompt-card"><img class="mm-prompt-image" src="${promptImageUrl}" alt="Our team is available 24/7. Chat with a real person. Click to start your free consultation." width="632" height="501" decoding="async" /><button class="mm-prompt-open" type="button" aria-label="Message us about a free consultation"></button><button class="mm-prompt-close" type="button" aria-label="Dismiss consultation prompt">${PROMPT_CLOSE_ICON}</button></div>`,
275
297
  "</section>"
276
298
  ].join("");
277
299
  const requireElement = (shadow, selector) => {
@@ -281,16 +303,23 @@
281
303
  }
282
304
  return element;
283
305
  };
284
- const renderWidgetShell = (shadow) => {
285
- shadow.innerHTML = WIDGET_MARKUP;
306
+ const renderWidgetShell = (shadow, launcherImageUrl, promptImageUrl) => {
307
+ shadow.innerHTML = widgetMarkup(launcherImageUrl, promptImageUrl);
286
308
  return {
287
309
  chatDialog: requireElement(shadow, ".mm-chat"),
288
310
  chatFrame: requireElement(shadow, ".mm-chat-frame"),
289
311
  chatLoading: requireElement(shadow, ".mm-loading"),
290
- launcher: requireElement(shadow, ".mm-launcher")
312
+ launcher: requireElement(shadow, ".mm-launcher"),
313
+ promptBackdrop: requireElement(shadow, ".mm-prompt-backdrop"),
314
+ promptClose: requireElement(shadow, ".mm-prompt-close"),
315
+ promptOpen: requireElement(shadow, ".mm-prompt-open")
291
316
  };
292
317
  };
293
318
  const PANEL_ANIMATION_MS = 180;
319
+ const PROMPT_DELAY_MS = 6e4;
320
+ const PROMPT_COOLDOWN_MS = 24 * 60 * 60 * 1e3;
321
+ const PROMPT_COOLDOWN_KEY = "mm-intake-widget-prompt-dismissed-at";
322
+ const PROMPT_SESSION_KEY = "mm-intake-widget-prompt-dismissed";
294
323
  const CHAT_CHROME_COLOR = "#e8eef2";
295
324
  const KEYBOARD_MIN_SHRINK_PX = 100;
296
325
  const CHAT_READY_FALLBACK_MS = 4e3;
@@ -300,12 +329,58 @@
300
329
  globalThis.history.replaceState(globalThis.history.state, "", cleanedReturnUrl);
301
330
  }
302
331
  };
332
+ const hasPromptCooldown = () => {
333
+ try {
334
+ if (globalThis.sessionStorage.getItem(PROMPT_SESSION_KEY) === "true") {
335
+ return true;
336
+ }
337
+ } catch {
338
+ }
339
+ try {
340
+ const dismissedAt = Number(globalThis.localStorage.getItem(PROMPT_COOLDOWN_KEY));
341
+ return Number.isFinite(dismissedAt) && dismissedAt > 0 && Date.now() - dismissedAt < PROMPT_COOLDOWN_MS;
342
+ } catch {
343
+ return false;
344
+ }
345
+ };
346
+ const rememberPromptDismissal = () => {
347
+ try {
348
+ globalThis.sessionStorage.setItem(PROMPT_SESSION_KEY, "true");
349
+ } catch {
350
+ }
351
+ try {
352
+ globalThis.localStorage.setItem(PROMPT_COOLDOWN_KEY, String(Date.now()));
353
+ } catch {
354
+ }
355
+ };
356
+ const playPromptSound = async () => {
357
+ try {
358
+ const context = new AudioContext();
359
+ const oscillator = context.createOscillator();
360
+ const gain = context.createGain();
361
+ oscillator.frequency.setValueAtTime(660, context.currentTime);
362
+ oscillator.frequency.exponentialRampToValueAtTime(880, context.currentTime + 0.16);
363
+ gain.gain.setValueAtTime(0.08, context.currentTime);
364
+ gain.gain.exponentialRampToValueAtTime(1e-3, context.currentTime + 0.2);
365
+ oscillator.connect(gain);
366
+ gain.connect(context.destination);
367
+ oscillator.start();
368
+ oscillator.stop(context.currentTime + 0.2);
369
+ oscillator.addEventListener("ended", () => void context.close());
370
+ await context.resume();
371
+ } catch {
372
+ }
373
+ };
303
374
  const mountIntakeWidget = (config, onDestroy) => {
304
375
  var _a;
305
376
  const mount = document.createElement("div");
306
377
  mount.dataset.mmIntakeWidget = "";
307
378
  const shadow = mount.attachShadow({ mode: "open" });
308
- const elements = renderWidgetShell(shadow);
379
+ const assetUrl = (fileName) => {
380
+ var _a2;
381
+ return new URL(fileName, (_a2 = config.assetBaseUrl) != null ? _a2 : `${config.chatOrigin}/intake-widget/`).href;
382
+ };
383
+ const elements = renderWidgetShell(shadow, assetUrl("button-text-us.png"), assetUrl("consultation-prompt.webp"));
309
384
  document.body.append(mount);
310
385
  if (typeof mount.showPopover === "function") {
311
386
  mount.setAttribute("popover", "manual");
@@ -319,6 +394,8 @@
319
394
  let chatHasLoaded = false;
320
395
  let chatCloseTimer;
321
396
  let chatReadyTimer;
397
+ let promptTimer;
398
+ let promptReturnFocus = null;
322
399
  let isKeyboardOpen = false;
323
400
  let hasReleasedKeyboardEarly = false;
324
401
  const syncLauncherLabel = () => {
@@ -352,6 +429,9 @@
352
429
  })
353
430
  );
354
431
  };
432
+ const focusChatComposer = () => {
433
+ postToChat(createEmbedProtocolMessage(EMBED_MESSAGE_TYPE.FOCUS_COMPOSER));
434
+ };
355
435
  const answerAuthTokenRequest = async () => {
356
436
  var _a2;
357
437
  let token;
@@ -374,6 +454,31 @@
374
454
  chatReadyTimer = void 0;
375
455
  elements.chatLoading.hidden = true;
376
456
  };
457
+ const dismissPrompt = (returnFocus = false) => {
458
+ globalThis.clearTimeout(promptTimer);
459
+ promptTimer = void 0;
460
+ const wasVisible = !elements.promptBackdrop.hidden;
461
+ elements.promptBackdrop.hidden = true;
462
+ elements.promptBackdrop.setAttribute("inert", "");
463
+ rememberPromptDismissal();
464
+ if (returnFocus && wasVisible) {
465
+ const focusTarget = (promptReturnFocus == null ? void 0 : promptReturnFocus.isConnected) === true ? promptReturnFocus : elements.launcher;
466
+ promptReturnFocus = null;
467
+ focusTarget.focus();
468
+ }
469
+ };
470
+ const showPrompt = () => {
471
+ globalThis.clearTimeout(promptTimer);
472
+ promptTimer = void 0;
473
+ if (hasPromptCooldown() || elements.chatDialog.dataset.state === "open") {
474
+ return;
475
+ }
476
+ promptReturnFocus = document.activeElement instanceof HTMLElement && document.activeElement !== mount ? document.activeElement : null;
477
+ elements.promptBackdrop.hidden = false;
478
+ elements.promptBackdrop.removeAttribute("inert");
479
+ elements.promptClose.focus();
480
+ void playPromptSound();
481
+ };
377
482
  const syncViewport = () => {
378
483
  const viewport = globalThis.visualViewport;
379
484
  if (!viewport || viewport.height === 0) {
@@ -492,6 +597,7 @@
492
597
  stopViewportTracking();
493
598
  };
494
599
  const openChat = () => {
600
+ dismissPrompt();
495
601
  globalThis.clearTimeout(chatCloseTimer);
496
602
  chatCloseTimer = void 0;
497
603
  elements.chatDialog.hidden = false;
@@ -505,6 +611,7 @@
505
611
  writeOpenState(true);
506
612
  if (chatHasLoaded) {
507
613
  postHostReady();
614
+ focusChatComposer();
508
615
  }
509
616
  };
510
617
  const closeChat = () => {
@@ -540,6 +647,9 @@
540
647
  if (isEmbedProtocolMessage(message, EMBED_MESSAGE_TYPE.CHILD_READY)) {
541
648
  revealChat();
542
649
  postHostReady();
650
+ if (elements.chatDialog.dataset.state === "open") {
651
+ focusChatComposer();
652
+ }
543
653
  return;
544
654
  }
545
655
  if (isEmbedProtocolMessage(message, EMBED_MESSAGE_TYPE.AUTH_TOKEN_REQUEST)) {
@@ -567,9 +677,24 @@
567
677
  }
568
678
  };
569
679
  const handleKeydown = (event) => {
680
+ if (event.key === "Tab" && !elements.promptBackdrop.hidden) {
681
+ const { activeElement } = shadow;
682
+ if (!event.shiftKey && activeElement === elements.promptClose) {
683
+ event.preventDefault();
684
+ elements.promptOpen.focus();
685
+ } else if (event.shiftKey && activeElement === elements.promptOpen) {
686
+ event.preventDefault();
687
+ elements.promptClose.focus();
688
+ }
689
+ return;
690
+ }
570
691
  if (event.key !== "Escape") {
571
692
  return;
572
693
  }
694
+ if (!elements.promptBackdrop.hidden) {
695
+ dismissPrompt(true);
696
+ return;
697
+ }
573
698
  if (elements.chatDialog.dataset.state === "open") {
574
699
  closeChat();
575
700
  }
@@ -578,6 +703,7 @@
578
703
  stopViewportTracking();
579
704
  globalThis.clearTimeout(chatCloseTimer);
580
705
  globalThis.clearTimeout(chatReadyTimer);
706
+ globalThis.clearTimeout(promptTimer);
581
707
  globalThis.removeEventListener("message", handleMessage);
582
708
  document.removeEventListener("keydown", handleKeydown);
583
709
  mount.remove();
@@ -590,6 +716,13 @@
590
716
  openChat();
591
717
  }
592
718
  });
719
+ elements.promptOpen.addEventListener("click", openChat);
720
+ elements.promptClose.addEventListener("click", () => dismissPrompt(true));
721
+ elements.promptBackdrop.addEventListener("click", (event) => {
722
+ if (event.target === elements.promptBackdrop) {
723
+ dismissPrompt(true);
724
+ }
725
+ });
593
726
  elements.chatDialog.addEventListener("animationend", (event) => {
594
727
  if (event.target === elements.chatDialog) {
595
728
  finishChatClose();
@@ -606,11 +739,14 @@
606
739
  syncLauncherLabel();
607
740
  if (returnedFromSigning || readOpenState()) {
608
741
  openChat();
742
+ } else if (!hasPromptCooldown()) {
743
+ promptTimer = globalThis.setTimeout(showPrompt, PROMPT_DELAY_MS);
609
744
  }
610
745
  return Object.freeze({
611
746
  close: closeChat,
612
747
  destroy,
613
748
  open: openChat,
749
+ showPrompt,
614
750
  version: EMBED_PROTOCOL_VERSION
615
751
  });
616
752
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morgan-and-morgan/intake-agent",
3
- "version": "1.0.0-alpha.6",
3
+ "version": "1.0.0-alpha.8",
4
4
  "description": "Embeddable chat widget loader.",
5
5
  "license": "UNLICENSED",
6
6
  "files": [
@@ -23,6 +23,7 @@
23
23
  "build": "pnpm run build:bundle",
24
24
  "build:bundle": "node scripts/generate-icons.mjs && vite build",
25
25
  "generate:icons": "node scripts/generate-icons.mjs",
26
+ "test": "node --test src/release-config.test.mjs",
26
27
  "typecheck": "tsc --noEmit",
27
28
  "lint": "eslint \"src/**/*.ts\" --quiet",
28
29
  "lint:fix": "eslint \"src/**/*.ts\" --quiet --fix",