@morgan-and-morgan/intake-agent 1.6.0 → 1.8.0
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 +6 -0
- package/dist/mm-intake-widget.js +27 -40
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -34,3 +34,9 @@ major. Every release is tagged `intake-agent-vx.y.z`.
|
|
|
34
34
|
| --- | --- | --- |
|
|
35
35
|
| `data-chat-url` | Release environment URL | Chat iframe target |
|
|
36
36
|
| `data-auto-open` | `false` | Open the chat immediately after mount |
|
|
37
|
+
|
|
38
|
+
The consultation modal reads `window.drupalSettings.mxPopup`, falling back to
|
|
39
|
+
`window.mxChatbotSettings.mxPopup` when the Drupal field is absent. Only the
|
|
40
|
+
boolean `false` suppresses the modal, including calls to `showPrompt()`.
|
|
41
|
+
Missing settings preserve the usual display rules. Settings are read when the
|
|
42
|
+
modal is about to appear; the launcher and chat remain available.
|
package/dist/mm-intake-widget.js
CHANGED
|
@@ -328,6 +328,10 @@
|
|
|
328
328
|
const PROMPT_COOLDOWN_KEY = "mm-intake-widget-prompt-dismissed-at";
|
|
329
329
|
const PROMPT_SESSION_KEY = "mm-intake-widget-prompt-dismissed";
|
|
330
330
|
const CHAT_CHROME_COLOR = "#e8eef2";
|
|
331
|
+
const matchMediaQuery = (query) => {
|
|
332
|
+
var _a;
|
|
333
|
+
return (_a = globalThis.matchMedia) == null ? void 0 : _a.call(globalThis, query);
|
|
334
|
+
};
|
|
331
335
|
const KEYBOARD_MIN_SHRINK_PX = 100;
|
|
332
336
|
const CHAT_READY_FALLBACK_MS = 4e3;
|
|
333
337
|
const cleanSigningReturnUrl = () => {
|
|
@@ -360,32 +364,13 @@
|
|
|
360
364
|
} catch {
|
|
361
365
|
}
|
|
362
366
|
};
|
|
363
|
-
const playPromptSound = async () => {
|
|
364
|
-
try {
|
|
365
|
-
const context = new AudioContext();
|
|
366
|
-
const oscillator = context.createOscillator();
|
|
367
|
-
const gain = context.createGain();
|
|
368
|
-
oscillator.frequency.setValueAtTime(660, context.currentTime);
|
|
369
|
-
oscillator.frequency.exponentialRampToValueAtTime(880, context.currentTime + 0.16);
|
|
370
|
-
gain.gain.setValueAtTime(0.08, context.currentTime);
|
|
371
|
-
gain.gain.exponentialRampToValueAtTime(1e-3, context.currentTime + 0.2);
|
|
372
|
-
oscillator.connect(gain);
|
|
373
|
-
gain.connect(context.destination);
|
|
374
|
-
oscillator.start();
|
|
375
|
-
oscillator.stop(context.currentTime + 0.2);
|
|
376
|
-
oscillator.addEventListener("ended", () => void context.close());
|
|
377
|
-
await context.resume();
|
|
378
|
-
} catch {
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
367
|
const mountIntakeWidget = (config, onDestroy) => {
|
|
382
|
-
var _a;
|
|
383
368
|
const mount = document.createElement("div");
|
|
384
369
|
mount.dataset.mmIntakeWidget = "";
|
|
385
370
|
const shadow = mount.attachShadow({ mode: "open" });
|
|
386
371
|
const assetUrl = (fileName) => {
|
|
387
|
-
var
|
|
388
|
-
return new URL(fileName, (
|
|
372
|
+
var _a;
|
|
373
|
+
return new URL(fileName, (_a = config.assetBaseUrl) != null ? _a : `${config.chatOrigin}/intake-widget/`).href;
|
|
389
374
|
};
|
|
390
375
|
const elements = renderWidgetShell(shadow, assetUrl("button-text-us.png"), assetUrl("consultation-prompt.webp"));
|
|
391
376
|
document.body.append(mount);
|
|
@@ -411,8 +396,8 @@
|
|
|
411
396
|
elements.launcher.setAttribute("aria-label", isOpen ? "Close intake chat" : "Open intake chat");
|
|
412
397
|
};
|
|
413
398
|
const postToChat = (message) => {
|
|
414
|
-
var
|
|
415
|
-
(
|
|
399
|
+
var _a;
|
|
400
|
+
(_a = elements.chatFrame.contentWindow) == null ? void 0 : _a.postMessage(message, config.chatOrigin);
|
|
416
401
|
};
|
|
417
402
|
const postHostReady = () => {
|
|
418
403
|
const currentUrl = globalThis.location.href;
|
|
@@ -440,10 +425,10 @@
|
|
|
440
425
|
postToChat(createEmbedProtocolMessage(EMBED_MESSAGE_TYPE.FOCUS_COMPOSER));
|
|
441
426
|
};
|
|
442
427
|
const answerAuthTokenRequest = async () => {
|
|
443
|
-
var
|
|
428
|
+
var _a;
|
|
444
429
|
let token;
|
|
445
430
|
try {
|
|
446
|
-
token = await ((
|
|
431
|
+
token = await ((_a = config.getAuthToken) == null ? void 0 : _a.call(config));
|
|
447
432
|
} catch {
|
|
448
433
|
token = void 0;
|
|
449
434
|
}
|
|
@@ -464,7 +449,7 @@
|
|
|
464
449
|
const dismissPrompt = (returnFocus = false) => {
|
|
465
450
|
globalThis.clearTimeout(promptTimer);
|
|
466
451
|
promptTimer = void 0;
|
|
467
|
-
const wasVisible =
|
|
452
|
+
const wasVisible = elements.promptBackdrop.hidden === false;
|
|
468
453
|
elements.promptBackdrop.hidden = true;
|
|
469
454
|
elements.promptBackdrop.setAttribute("inert", "");
|
|
470
455
|
rememberPromptDismissal();
|
|
@@ -475,16 +460,18 @@
|
|
|
475
460
|
}
|
|
476
461
|
};
|
|
477
462
|
const showPrompt = () => {
|
|
463
|
+
var _a, _b, _c;
|
|
478
464
|
globalThis.clearTimeout(promptTimer);
|
|
479
465
|
promptTimer = void 0;
|
|
480
|
-
|
|
466
|
+
const host = globalThis;
|
|
467
|
+
const mxPopup = (_c = (_a = host.drupalSettings) == null ? void 0 : _a.mxPopup) != null ? _c : (_b = host.mxChatbotSettings) == null ? void 0 : _b.mxPopup;
|
|
468
|
+
if (mxPopup === false || hasPromptCooldown() || elements.chatDialog.dataset.state === "open") {
|
|
481
469
|
return;
|
|
482
470
|
}
|
|
483
471
|
promptReturnFocus = document.activeElement instanceof HTMLElement && document.activeElement !== mount ? document.activeElement : null;
|
|
484
472
|
elements.promptBackdrop.hidden = false;
|
|
485
473
|
elements.promptBackdrop.removeAttribute("inert");
|
|
486
474
|
elements.promptClose.focus();
|
|
487
|
-
void playPromptSound();
|
|
488
475
|
};
|
|
489
476
|
const syncViewport = () => {
|
|
490
477
|
const viewport = globalThis.visualViewport;
|
|
@@ -511,7 +498,7 @@
|
|
|
511
498
|
hasReleasedKeyboardEarly = true;
|
|
512
499
|
setKeyboardOpen(false);
|
|
513
500
|
};
|
|
514
|
-
const fullPagePanelQuery = (
|
|
501
|
+
const fullPagePanelQuery = matchMediaQuery(FULL_PAGE_PANEL_QUERY);
|
|
515
502
|
let themeColorBackup = null;
|
|
516
503
|
let createdThemeColor = null;
|
|
517
504
|
const hostRoots = [document.documentElement, document.body];
|
|
@@ -539,7 +526,7 @@
|
|
|
539
526
|
}
|
|
540
527
|
};
|
|
541
528
|
const restoreHostChrome = () => {
|
|
542
|
-
var
|
|
529
|
+
var _a, _b;
|
|
543
530
|
if (themeColorBackup === null) {
|
|
544
531
|
return;
|
|
545
532
|
}
|
|
@@ -550,7 +537,7 @@
|
|
|
550
537
|
createdThemeColor = null;
|
|
551
538
|
themeColorBackup = null;
|
|
552
539
|
for (const [index, root] of hostRoots.entries()) {
|
|
553
|
-
root.style.backgroundColor = (
|
|
540
|
+
root.style.backgroundColor = (_a = hostBackgroundColorBackup == null ? void 0 : hostBackgroundColorBackup[index]) != null ? _a : "";
|
|
554
541
|
root.style.overflow = (_b = hostOverflowBackup == null ? void 0 : hostOverflowBackup[index]) != null ? _b : "";
|
|
555
542
|
}
|
|
556
543
|
hostBackgroundColorBackup = null;
|
|
@@ -560,7 +547,7 @@
|
|
|
560
547
|
if (elements.chatDialog.dataset.state !== "open") {
|
|
561
548
|
return;
|
|
562
549
|
}
|
|
563
|
-
if (fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.matches) {
|
|
550
|
+
if ((fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.matches) === true) {
|
|
564
551
|
borrowHostChrome();
|
|
565
552
|
} else {
|
|
566
553
|
restoreHostChrome();
|
|
@@ -576,16 +563,16 @@
|
|
|
576
563
|
syncHostChrome();
|
|
577
564
|
}
|
|
578
565
|
const startViewportTracking = () => {
|
|
579
|
-
var
|
|
580
|
-
(
|
|
566
|
+
var _a, _b;
|
|
567
|
+
(_a = globalThis.visualViewport) == null ? void 0 : _a.addEventListener("resize", syncViewport);
|
|
581
568
|
(_b = globalThis.visualViewport) == null ? void 0 : _b.addEventListener("scroll", syncViewport);
|
|
582
569
|
fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.addEventListener("change", syncHostChrome);
|
|
583
570
|
syncViewport();
|
|
584
571
|
syncHostChrome();
|
|
585
572
|
};
|
|
586
573
|
const stopViewportTracking = () => {
|
|
587
|
-
var
|
|
588
|
-
(
|
|
574
|
+
var _a, _b;
|
|
575
|
+
(_a = globalThis.visualViewport) == null ? void 0 : _a.removeEventListener("resize", syncViewport);
|
|
589
576
|
(_b = globalThis.visualViewport) == null ? void 0 : _b.removeEventListener("scroll", syncViewport);
|
|
590
577
|
fullPagePanelQuery == null ? void 0 : fullPagePanelQuery.removeEventListener("change", syncHostChrome);
|
|
591
578
|
setKeyboardOpen(false);
|
|
@@ -622,7 +609,7 @@
|
|
|
622
609
|
}
|
|
623
610
|
};
|
|
624
611
|
const closeChat = () => {
|
|
625
|
-
var
|
|
612
|
+
var _a;
|
|
626
613
|
elements.launcher.focus();
|
|
627
614
|
writeOpenState(false);
|
|
628
615
|
const wasOpen = elements.chatDialog.dataset.state === "open";
|
|
@@ -635,7 +622,7 @@
|
|
|
635
622
|
if (!wasOpen) {
|
|
636
623
|
return;
|
|
637
624
|
}
|
|
638
|
-
if ((
|
|
625
|
+
if (((_a = matchMediaQuery("(prefers-reduced-motion: reduce)")) == null ? void 0 : _a.matches) === true) {
|
|
639
626
|
finishChatClose();
|
|
640
627
|
return;
|
|
641
628
|
}
|
|
@@ -688,7 +675,7 @@
|
|
|
688
675
|
}
|
|
689
676
|
};
|
|
690
677
|
const handleKeydown = (event) => {
|
|
691
|
-
if (event.key === "Tab" &&
|
|
678
|
+
if (event.key === "Tab" && elements.promptBackdrop.hidden === false) {
|
|
692
679
|
const { activeElement } = shadow;
|
|
693
680
|
if (!event.shiftKey && activeElement === elements.promptClose) {
|
|
694
681
|
event.preventDefault();
|
|
@@ -702,7 +689,7 @@
|
|
|
702
689
|
if (event.key !== "Escape") {
|
|
703
690
|
return;
|
|
704
691
|
}
|
|
705
|
-
if (
|
|
692
|
+
if (elements.promptBackdrop.hidden === false) {
|
|
706
693
|
dismissPrompt(true);
|
|
707
694
|
return;
|
|
708
695
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morgan-and-morgan/intake-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Embeddable chat widget loader.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"files": [
|
|
@@ -24,15 +24,14 @@
|
|
|
24
24
|
"build:bundle": "node scripts/generate-icons.mjs && vite build",
|
|
25
25
|
"generate:icons": "node scripts/generate-icons.mjs",
|
|
26
26
|
"test": "node --test 'src/*.test.mjs'",
|
|
27
|
-
"typecheck": "
|
|
28
|
-
"lint": "eslint \"src/**/*.ts\" --quiet",
|
|
29
|
-
"lint:fix": "eslint \"src/**/*.ts\" --quiet --fix",
|
|
27
|
+
"typecheck": "tsgo --noEmit",
|
|
30
28
|
"prepublishOnly": "pnpm run build:bundle"
|
|
31
29
|
},
|
|
32
30
|
"devDependencies": {
|
|
33
|
-
"@mmcp/eslint-config": "workspace:*",
|
|
34
31
|
"@mmcp/tsconfig": "workspace:*",
|
|
35
|
-
"
|
|
32
|
+
"@types/jest": "catalog:",
|
|
33
|
+
"@types/node": "catalog:",
|
|
34
|
+
"@typescript/native-preview": "catalog:",
|
|
36
35
|
"lucide-react-native": "^0.562.0",
|
|
37
36
|
"typescript": "~5.9.3",
|
|
38
37
|
"vite": "^7.3.6"
|