@xpert-ai/chatkit-ui5 0.3.0 → 0.3.1

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.
@@ -51,7 +51,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
51
51
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
52
52
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
53
53
 
54
- var _a, _b, _setTrainingOptOut_dec, _hideHistory_dec, _showHistory_dec, _sendCustomAction_dec, _shareThread_dec, _setThreadId_dec, _setComposerValue_dec, _sendUserMessage_dec, _fetchUpdates_dec, _focusComposer_dec, _c, _opts, _frameUrl, _frame, _wrapper, _launcherCloseButton, _launcherOpen, _framePetOptionsOverride, _shadow, _petOverlay, _resolveLoaded, _loaded, _messenger, _ChatKitElementBase_instances, emitAndThrow_fn, setOptionsDataAttributes_fn, getDisplayMode_fn, getConfiguredPetOptions_fn, getOverlayPetOptions_fn, resolvePetAssetUrl_fn, resolveOverlayPetOptions_fn, getFrameOptions_fn, setLauncherOpen_fn, handlePetActivate_fn, handlePetReply_fn, handlePetThreadSummaryActivate_fn, _handleLauncherClose, getFrameUrl_fn, setFrameUrl_fn, consumeFrameUrl_fn, _handleFrameLoad, _initialized, maybeInit_fn, _init;
54
+ var _a, _b, _setTrainingOptOut_dec, _hideHistory_dec, _showHistory_dec, _sendCustomAction_dec, _shareThread_dec, _setThreadId_dec, _setComposerValue_dec, _sendUserMessage_dec, _fetchUpdates_dec, _focusComposer_dec, _c, _opts, _frameUrl, _frame, _wrapper, _launcherCloseButton, _launcherOpen, _chatMinimizedToPet, _framePetOptionsOverride, _petClosedByContextMenu, _shadow, _petOverlay, _resolveLoaded, _loaded, _messenger, _ChatKitElementBase_instances, emitAndThrow_fn, setOptionsDataAttributes_fn, getDisplayMode_fn, getConfiguredPetOptions_fn, mergeConfiguredPetPositionDefaults_fn, getOverlayPetOptions_fn, resolvePetAssetUrl_fn, resolveOverlayPetOptions_fn, getFrameOptions_fn, setLauncherOpen_fn, setChatMinimizedToPet_fn, syncPetOverlayOptions_fn, handlePetActivate_fn, handlePetClose_fn, handlePetReply_fn, handlePetThreadSummaryActivate_fn, _handleLauncherClose, getFrameUrl_fn, setFrameUrl_fn, consumeFrameUrl_fn, _handleFrameLoad, _initialized, maybeInit_fn, _init;
55
55
  class EventEmitter {
56
56
  constructor() {
57
57
  __publicField(this, "callbacks", /* @__PURE__ */ new Map());
@@ -895,8 +895,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
895
895
  const PET_SUMMARY_GAP = 12;
896
896
  const PET_SUMMARY_WIDTH = 320;
897
897
  const PET_SUMMARY_MARGIN = 12;
898
+ const PET_CONTEXT_MENU_MARGIN = 8;
899
+ const PET_SUMMARY_FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
898
900
  const PET_OVERLAY_COPY = {
899
901
  "en-US": {
902
+ closePetMenuItem: "Close pet",
900
903
  hideMessage: "Hide message",
901
904
  expandMessage: "Expand message",
902
905
  collapseMessage: "Collapse message",
@@ -908,6 +911,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
908
911
  sendFailed: "Failed to send"
909
912
  },
910
913
  "zh-CN": {
914
+ closePetMenuItem: "关闭宠物",
911
915
  hideMessage: "隐藏消息",
912
916
  expandMessage: "展开消息",
913
917
  collapseMessage: "收起消息",
@@ -984,6 +988,65 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
984
988
  }
985
989
  return "en-US";
986
990
  }
991
+ function getSummaryDensityMetrics(density) {
992
+ switch (density) {
993
+ case "compact":
994
+ return {
995
+ padding: "8px 10px",
996
+ gap: 6,
997
+ marginTop: 3,
998
+ toggleSize: 30,
999
+ actionSize: 22
1000
+ };
1001
+ case "spacious":
1002
+ return {
1003
+ padding: "14px 16px",
1004
+ gap: 10,
1005
+ marginTop: 6,
1006
+ toggleSize: 38,
1007
+ actionSize: 28
1008
+ };
1009
+ case "normal":
1010
+ default:
1011
+ return {
1012
+ padding: "12px 14px",
1013
+ gap: 8,
1014
+ marginTop: 4,
1015
+ toggleSize: 34,
1016
+ actionSize: 26
1017
+ };
1018
+ }
1019
+ }
1020
+ function getSummaryRadius(radius) {
1021
+ switch (radius) {
1022
+ case "pill":
1023
+ return 24;
1024
+ case "round":
1025
+ return 16;
1026
+ case "sharp":
1027
+ return 0;
1028
+ case "soft":
1029
+ default:
1030
+ return 12;
1031
+ }
1032
+ }
1033
+ function getSummaryThemeMetrics(theme) {
1034
+ var _a2, _b2;
1035
+ const themeObject = typeof theme === "string" ? null : theme;
1036
+ const baseSize = ((_a2 = themeObject == null ? void 0 : themeObject.typography) == null ? void 0 : _a2.baseSize) ?? 16;
1037
+ const density = (themeObject == null ? void 0 : themeObject.density) ?? "normal";
1038
+ const densityOffset = density === "compact" ? -1 : density === "spacious" ? 1 : 0;
1039
+ const bodySize = clampNumber(baseSize - 2 + densityOffset, 11, 17);
1040
+ const densityMetrics = getSummaryDensityMetrics(density);
1041
+ return {
1042
+ ...densityMetrics,
1043
+ bodySize,
1044
+ titleSize: bodySize + 1,
1045
+ iconSize: clampNumber(bodySize + 2, 13, 19),
1046
+ radius: getSummaryRadius(themeObject == null ? void 0 : themeObject.radius),
1047
+ fontFamily: ((_b2 = themeObject == null ? void 0 : themeObject.typography) == null ? void 0 : _b2.fontFamily) ?? PET_SUMMARY_FONT_FAMILY
1048
+ };
1049
+ }
987
1050
  function isPetState(value) {
988
1051
  return value === "idle" || value === "running-right" || value === "running-left" || value === "waving" || value === "jumping" || value === "failed" || value === "waiting" || value === "running" || value === "review";
989
1052
  }
@@ -1019,6 +1082,12 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1019
1082
  summary.messageId || summary.updatedAt || summary.message
1020
1083
  ].join(":");
1021
1084
  }
1085
+ function getThreadSummaryInteractionKey(summary) {
1086
+ if (!summary) {
1087
+ return null;
1088
+ }
1089
+ return [summary.threadId, summary.messageId ?? ""].join(":");
1090
+ }
1022
1091
  function parseThreadSummaryPayload(value) {
1023
1092
  if (value === null) {
1024
1093
  return { summary: null };
@@ -1055,10 +1124,12 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1055
1124
  constructor(root, options) {
1056
1125
  this.overlayElement = null;
1057
1126
  this.petElement = null;
1127
+ this.contextMenuElement = null;
1058
1128
  this.summaryElement = null;
1059
1129
  this.summaryToggleElement = null;
1060
1130
  this.mediaElement = null;
1061
1131
  this.options = null;
1132
+ this.theme = null;
1062
1133
  this.resolved = null;
1063
1134
  this.summary = null;
1064
1135
  this.summaryRenderKey = null;
@@ -1095,6 +1166,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1095
1166
  this.mediaQuery = null;
1096
1167
  this.connected = false;
1097
1168
  this.handleViewportChange = () => {
1169
+ this.closeContextMenu();
1098
1170
  this.render();
1099
1171
  };
1100
1172
  this.handleReducedMotionChange = () => {
@@ -1115,6 +1187,36 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1115
1187
  this.enterRestingAfterDelay();
1116
1188
  }
1117
1189
  };
1190
+ this.handleContextMenu = (event) => {
1191
+ event.preventDefault();
1192
+ event.stopPropagation();
1193
+ this.openContextMenu({ x: event.clientX, y: event.clientY });
1194
+ };
1195
+ this.handleContextMenuEvent = (event) => {
1196
+ event.preventDefault();
1197
+ event.stopPropagation();
1198
+ };
1199
+ this.handleContextMenuOutsidePointerDown = (event) => {
1200
+ const menu = this.contextMenuElement;
1201
+ if (menu && event.composedPath().includes(menu)) {
1202
+ return;
1203
+ }
1204
+ this.closeContextMenu();
1205
+ };
1206
+ this.handleContextMenuKeyDown = (event) => {
1207
+ if (event.key !== "Escape") {
1208
+ return;
1209
+ }
1210
+ event.preventDefault();
1211
+ this.closeContextMenu();
1212
+ };
1213
+ this.handleClosePetMenuItemClick = (event) => {
1214
+ var _a2;
1215
+ event.preventDefault();
1216
+ event.stopPropagation();
1217
+ this.closeContextMenu();
1218
+ (_a2 = this.onClose) == null ? void 0 : _a2.call(this);
1219
+ };
1118
1220
  this.handleSummaryPointerEnter = () => {
1119
1221
  this.isSummaryHovering = true;
1120
1222
  this.render();
@@ -1182,7 +1284,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1182
1284
  };
1183
1285
  this.handlePointerDown = (event) => {
1184
1286
  var _a2, _b2;
1185
- if (!((_a2 = this.options) == null ? void 0 : _a2.position.draggable) || event.button !== 0) {
1287
+ if (event.button !== 0 || event.ctrlKey) {
1288
+ return;
1289
+ }
1290
+ this.closeContextMenu();
1291
+ if (!((_a2 = this.options) == null ? void 0 : _a2.position.draggable)) {
1186
1292
  return;
1187
1293
  }
1188
1294
  event.preventDefault();
@@ -1258,6 +1364,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1258
1364
  };
1259
1365
  this.root = root;
1260
1366
  this.onActivate = options == null ? void 0 : options.onActivate;
1367
+ this.onClose = options == null ? void 0 : options.onClose;
1261
1368
  this.onReply = options == null ? void 0 : options.onReply;
1262
1369
  this.onThreadSummaryActivate = options == null ? void 0 : options.onThreadSummaryActivate;
1263
1370
  this.connect();
@@ -1271,9 +1378,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1271
1378
  this.installReducedMotionListener();
1272
1379
  this.render();
1273
1380
  }
1274
- setOptions(pet) {
1381
+ setOptions(pet, theme) {
1382
+ this.closeContextMenu();
1275
1383
  const nextOptions = chatkitTypes.normalizePetOptions(pet);
1276
1384
  this.options = nextOptions;
1385
+ this.theme = theme ?? null;
1277
1386
  if (!nextOptions) {
1278
1387
  this.isDragging = false;
1279
1388
  this.isHovering = false;
@@ -1319,11 +1428,12 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1319
1428
  this.copyLocale = nextLocale;
1320
1429
  this.copy = PET_OVERLAY_COPY[nextLocale];
1321
1430
  this.summaryRenderKey = null;
1431
+ this.closeContextMenu();
1322
1432
  this.render();
1323
1433
  }
1324
1434
  setThreadSummary(summary) {
1325
- const previousKey = getThreadSummaryKey(this.summary);
1326
- const nextKey = getThreadSummaryKey(summary);
1435
+ const previousKey = getThreadSummaryInteractionKey(this.summary);
1436
+ const nextKey = getThreadSummaryInteractionKey(summary);
1327
1437
  this.summary = summary;
1328
1438
  if (!summary) {
1329
1439
  this.isSummaryCollapsed = false;
@@ -1384,8 +1494,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1384
1494
  installViewportListeners() {
1385
1495
  var _a2, _b2;
1386
1496
  window.addEventListener("resize", this.handleViewportChange);
1387
- (_a2 = window.visualViewport) == null ? void 0 : _a2.addEventListener("resize", this.handleViewportChange);
1388
- (_b2 = window.visualViewport) == null ? void 0 : _b2.addEventListener("scroll", this.handleViewportChange);
1497
+ (_a2 = window.visualViewport) == null ? void 0 : _a2.addEventListener(
1498
+ "resize",
1499
+ this.handleViewportChange
1500
+ );
1501
+ (_b2 = window.visualViewport) == null ? void 0 : _b2.addEventListener(
1502
+ "scroll",
1503
+ this.handleViewportChange
1504
+ );
1389
1505
  }
1390
1506
  installReducedMotionListener() {
1391
1507
  var _a2, _b2;
@@ -1436,6 +1552,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1436
1552
  pet.addEventListener("pointerenter", this.handlePointerEnter);
1437
1553
  pet.addEventListener("pointerleave", this.handlePointerLeave);
1438
1554
  pet.addEventListener("pointerdown", this.handlePointerDown);
1555
+ pet.addEventListener("contextmenu", this.handleContextMenu);
1439
1556
  pet.addEventListener("click", this.handleClick);
1440
1557
  overlay.append(style, pet);
1441
1558
  this.root.append(overlay);
@@ -1446,6 +1563,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1446
1563
  var _a2;
1447
1564
  this.clearRestingDelayTimer();
1448
1565
  this.clearTimers();
1566
+ this.closeContextMenu();
1449
1567
  if (this.petElement) {
1450
1568
  this.petElement.removeEventListener(
1451
1569
  "pointerenter",
@@ -1455,7 +1573,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1455
1573
  "pointerleave",
1456
1574
  this.handlePointerLeave
1457
1575
  );
1458
- this.petElement.removeEventListener("pointerdown", this.handlePointerDown);
1576
+ this.petElement.removeEventListener(
1577
+ "pointerdown",
1578
+ this.handlePointerDown
1579
+ );
1580
+ this.petElement.removeEventListener(
1581
+ "contextmenu",
1582
+ this.handleContextMenu
1583
+ );
1459
1584
  this.petElement.removeEventListener("click", this.handleClick);
1460
1585
  }
1461
1586
  this.isHovering = false;
@@ -1603,10 +1728,6 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1603
1728
  return;
1604
1729
  }
1605
1730
  const nextRenderKey = [
1606
- summaryKey,
1607
- summary.title,
1608
- summary.message,
1609
- summary.status,
1610
1731
  this.copyLocale,
1611
1732
  this.isSummaryExpanded ? "expanded" : "compact",
1612
1733
  this.isSummaryHovering ? "hover" : "rest",
@@ -1619,7 +1740,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1619
1740
  (_b2 = this.summaryToggleElement) == null ? void 0 : _b2.remove();
1620
1741
  this.summaryElement = this.createSummaryBubble(summary);
1621
1742
  this.summaryToggleElement = this.createSummaryToggleButton("v");
1622
- (_c2 = this.overlayElement) == null ? void 0 : _c2.append(this.summaryElement, this.summaryToggleElement);
1743
+ (_c2 = this.overlayElement) == null ? void 0 : _c2.append(
1744
+ this.summaryElement,
1745
+ this.summaryToggleElement
1746
+ );
1623
1747
  this.summaryRenderKey = nextRenderKey;
1624
1748
  if (this.isReplyOpen && !this.isReplySubmitting) {
1625
1749
  window.setTimeout(() => {
@@ -1628,6 +1752,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1628
1752
  }, 0);
1629
1753
  }
1630
1754
  }
1755
+ this.updateSummaryBubbleContent(summary);
1631
1756
  this.positionSummaryBubble(position, size);
1632
1757
  }
1633
1758
  renderCollapsedSummary(position, size) {
@@ -1648,7 +1773,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1648
1773
  return;
1649
1774
  }
1650
1775
  const viewport = getViewportSize();
1651
- const badgeSize = 34;
1776
+ const badgeSize = getSummaryThemeMetrics(this.theme).toggleSize;
1652
1777
  const x = clampNumber(
1653
1778
  position.x + size.width - badgeSize * 0.35,
1654
1779
  PET_SUMMARY_MARGIN,
@@ -1671,7 +1796,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1671
1796
  return;
1672
1797
  }
1673
1798
  const viewport = getViewportSize();
1674
- const width = Math.min(PET_SUMMARY_WIDTH, viewport.width - PET_SUMMARY_MARGIN * 2);
1799
+ const width = Math.min(
1800
+ PET_SUMMARY_WIDTH,
1801
+ viewport.width - PET_SUMMARY_MARGIN * 2
1802
+ );
1675
1803
  bubble.style.width = `${width}px`;
1676
1804
  const bubbleHeight = bubble.offsetHeight || 96;
1677
1805
  const aboveY = position.y - bubbleHeight - PET_SUMMARY_GAP;
@@ -1691,6 +1819,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1691
1819
  }
1692
1820
  createSummaryBubble(summary) {
1693
1821
  const shouldShowReplyButton = this.isSummaryHovering && !this.isReplyOpen;
1822
+ const metrics = getSummaryThemeMetrics(this.theme);
1694
1823
  const bubble = document.createElement("div");
1695
1824
  bubble.setAttribute("data-chatkit-pet-summary", "");
1696
1825
  bubble.addEventListener("pointerenter", this.handleSummaryPointerEnter);
@@ -1701,19 +1830,18 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1701
1830
  bubble.style.left = "0";
1702
1831
  bubble.style.boxSizing = "border-box";
1703
1832
  bubble.style.pointerEvents = "auto";
1704
- bubble.style.padding = "12px 14px";
1705
- bubble.style.paddingBottom = "12px";
1833
+ bubble.style.padding = metrics.padding;
1706
1834
  bubble.style.border = "1px solid rgba(148, 163, 184, 0.22)";
1707
- bubble.style.borderRadius = "22px";
1835
+ bubble.style.borderRadius = `${metrics.radius}px`;
1708
1836
  bubble.style.background = "rgba(255, 255, 255, 0.94)";
1709
1837
  bubble.style.color = "#1f2937";
1710
1838
  bubble.style.boxShadow = "0 8px 24px rgba(15, 23, 42, 0.1)";
1711
- bubble.style.font = '500 14px/1.35 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
1839
+ bubble.style.font = `500 ${metrics.bodySize}px/1.35 ${metrics.fontFamily}`;
1712
1840
  bubble.style.backdropFilter = "blur(10px)";
1713
1841
  const header = document.createElement("div");
1714
1842
  header.style.display = "flex";
1715
1843
  header.style.alignItems = "center";
1716
- header.style.gap = "8px";
1844
+ header.style.gap = `${metrics.gap}px`;
1717
1845
  if (this.isSummaryHovering || this.isReplyOpen) {
1718
1846
  header.append(
1719
1847
  this.createSummaryActionButton(
@@ -1731,7 +1859,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1731
1859
  title.style.textOverflow = "ellipsis";
1732
1860
  title.style.whiteSpace = "nowrap";
1733
1861
  title.style.fontWeight = "700";
1734
- title.style.fontSize = "15px";
1862
+ title.style.fontSize = `${metrics.titleSize}px`;
1863
+ title.dataset.chatkitPetSummaryTitle = "";
1735
1864
  header.append(title);
1736
1865
  if (this.isSummaryHovering || this.isReplyOpen) {
1737
1866
  header.append(
@@ -1746,7 +1875,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1746
1875
  }
1747
1876
  const message = document.createElement("div");
1748
1877
  message.textContent = summary.message;
1749
- message.style.marginTop = "4px";
1878
+ message.style.marginTop = `${metrics.marginTop}px`;
1750
1879
  message.style.fontWeight = "400";
1751
1880
  message.style.color = "#374151";
1752
1881
  message.style.overflow = "hidden";
@@ -1758,6 +1887,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1758
1887
  message.style.setProperty("-webkit-line-clamp", "2");
1759
1888
  message.style.setProperty("-webkit-box-orient", "vertical");
1760
1889
  }
1890
+ message.dataset.chatkitPetSummaryMessage = "";
1761
1891
  bubble.append(header, message);
1762
1892
  if (shouldShowReplyButton) {
1763
1893
  const reply = this.createTextButton(
@@ -1774,7 +1904,30 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1774
1904
  }
1775
1905
  return bubble;
1776
1906
  }
1907
+ updateSummaryBubbleContent(summary) {
1908
+ var _a2, _b2, _c2;
1909
+ const title = (_a2 = this.summaryElement) == null ? void 0 : _a2.querySelector(
1910
+ "[data-chatkit-pet-summary-title]"
1911
+ );
1912
+ if (title && title.textContent !== summary.title) {
1913
+ title.textContent = summary.title;
1914
+ }
1915
+ const message = (_b2 = this.summaryElement) == null ? void 0 : _b2.querySelector(
1916
+ "[data-chatkit-pet-summary-message]"
1917
+ );
1918
+ if (message && message.textContent !== summary.message) {
1919
+ message.textContent = summary.message;
1920
+ }
1921
+ const statusIcon = (_c2 = this.summaryElement) == null ? void 0 : _c2.querySelector(
1922
+ "[data-chatkit-pet-summary-status]"
1923
+ );
1924
+ if (statusIcon && statusIcon.dataset.chatkitPetSummaryStatus !== summary.status) {
1925
+ const nextIcon = this.createStatusIcon(summary.status);
1926
+ statusIcon.replaceWith(nextIcon);
1927
+ }
1928
+ }
1777
1929
  createSummaryToggleButton(label) {
1930
+ const metrics = getSummaryThemeMetrics(this.theme);
1778
1931
  const button = document.createElement("button");
1779
1932
  button.type = "button";
1780
1933
  button.textContent = label;
@@ -1790,18 +1943,21 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1790
1943
  button.style.color = "#475569";
1791
1944
  button.style.boxShadow = "0 6px 18px rgba(15, 23, 42, 0.1)";
1792
1945
  button.style.cursor = "pointer";
1793
- button.style.font = '600 15px/1 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
1946
+ button.style.font = `600 ${metrics.titleSize}px/1 ${metrics.fontFamily}`;
1794
1947
  button.style.display = "flex";
1795
1948
  button.style.alignItems = "center";
1796
1949
  button.style.justifyContent = "center";
1797
1950
  return button;
1798
1951
  }
1799
1952
  createStatusIcon(status) {
1953
+ const metrics = getSummaryThemeMetrics(this.theme);
1954
+ const iconSize = metrics.iconSize;
1800
1955
  const icon = document.createElement("span");
1801
1956
  icon.setAttribute("aria-hidden", "true");
1957
+ icon.dataset.chatkitPetSummaryStatus = status;
1802
1958
  icon.style.display = "inline-flex";
1803
- icon.style.width = "16px";
1804
- icon.style.height = "16px";
1959
+ icon.style.width = `${iconSize}px`;
1960
+ icon.style.height = `${iconSize}px`;
1805
1961
  icon.style.alignItems = "center";
1806
1962
  icon.style.justifyContent = "center";
1807
1963
  icon.style.flex = "0 0 auto";
@@ -1813,7 +1969,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1813
1969
  return icon;
1814
1970
  }
1815
1971
  icon.style.borderRadius = "999px";
1816
- icon.style.fontSize = "12px";
1972
+ icon.style.fontSize = `${Math.max(10, iconSize - 4)}px`;
1817
1973
  icon.style.fontWeight = "700";
1818
1974
  if (status === "failed") {
1819
1975
  icon.textContent = "!";
@@ -1825,8 +1981,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1825
1981
  icon.style.border = "2px solid #22c55e";
1826
1982
  icon.style.position = "relative";
1827
1983
  const check = document.createElement("span");
1828
- check.style.width = "7px";
1829
- check.style.height = "4px";
1984
+ check.style.width = `${Math.round(iconSize * 0.44)}px`;
1985
+ check.style.height = `${Math.round(iconSize * 0.25)}px`;
1830
1986
  check.style.borderLeft = "2px solid #22c55e";
1831
1987
  check.style.borderBottom = "2px solid #22c55e";
1832
1988
  check.style.transform = "rotate(-45deg) translate(1px, -1px)";
@@ -1834,6 +1990,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1834
1990
  return icon;
1835
1991
  }
1836
1992
  createSummaryActionButton(label, title, onClick) {
1993
+ const metrics = getSummaryThemeMetrics(this.theme);
1837
1994
  const button = document.createElement("button");
1838
1995
  button.type = "button";
1839
1996
  button.textContent = label;
@@ -1843,14 +2000,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1843
2000
  event.stopPropagation();
1844
2001
  onClick();
1845
2002
  });
1846
- button.style.width = "26px";
1847
- button.style.height = "26px";
2003
+ button.style.width = `${metrics.actionSize}px`;
2004
+ button.style.height = `${metrics.actionSize}px`;
1848
2005
  button.style.border = "0";
1849
2006
  button.style.borderRadius = "999px";
1850
2007
  button.style.background = "rgba(241, 245, 249, 0.96)";
1851
2008
  button.style.color = "#475569";
1852
2009
  button.style.cursor = "pointer";
1853
- button.style.font = '600 15px/1 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
2010
+ button.style.font = `600 ${metrics.titleSize}px/1 ${metrics.fontFamily}`;
1854
2011
  return button;
1855
2012
  }
1856
2013
  createTextButton(label, onClick) {
@@ -1916,6 +2073,95 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
1916
2073
  }
1917
2074
  return form;
1918
2075
  }
2076
+ createContextMenu() {
2077
+ const menu = document.createElement("div");
2078
+ menu.setAttribute("data-chatkit-pet-context-menu", "");
2079
+ menu.setAttribute("role", "menu");
2080
+ menu.addEventListener("contextmenu", this.handleContextMenuEvent);
2081
+ menu.addEventListener("pointerdown", stopEventPropagation);
2082
+ menu.addEventListener("click", stopEventPropagation);
2083
+ menu.style.position = "absolute";
2084
+ menu.style.top = "0";
2085
+ menu.style.left = "0";
2086
+ menu.style.boxSizing = "border-box";
2087
+ menu.style.minWidth = "132px";
2088
+ menu.style.padding = "4px";
2089
+ menu.style.pointerEvents = "auto";
2090
+ menu.style.border = "1px solid rgba(148, 163, 184, 0.28)";
2091
+ menu.style.borderRadius = "10px";
2092
+ menu.style.background = "rgba(255, 255, 255, 0.96)";
2093
+ menu.style.color = "#1f2937";
2094
+ menu.style.boxShadow = "0 12px 28px rgba(15, 23, 42, 0.16)";
2095
+ menu.style.font = '500 13px/1.3 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
2096
+ menu.style.backdropFilter = "blur(10px)";
2097
+ const closeItem = document.createElement("button");
2098
+ closeItem.type = "button";
2099
+ closeItem.textContent = this.copy.closePetMenuItem;
2100
+ closeItem.setAttribute("role", "menuitem");
2101
+ closeItem.addEventListener("click", this.handleClosePetMenuItemClick);
2102
+ closeItem.style.display = "block";
2103
+ closeItem.style.width = "100%";
2104
+ closeItem.style.border = "0";
2105
+ closeItem.style.borderRadius = "7px";
2106
+ closeItem.style.background = "transparent";
2107
+ closeItem.style.color = "inherit";
2108
+ closeItem.style.cursor = "pointer";
2109
+ closeItem.style.padding = "7px 10px";
2110
+ closeItem.style.textAlign = "left";
2111
+ closeItem.style.font = "inherit";
2112
+ menu.append(closeItem);
2113
+ return menu;
2114
+ }
2115
+ openContextMenu(position) {
2116
+ var _a2;
2117
+ const overlay = this.overlayElement;
2118
+ if (!overlay) {
2119
+ return;
2120
+ }
2121
+ this.closeContextMenu();
2122
+ const menu = this.createContextMenu();
2123
+ overlay.append(menu);
2124
+ this.contextMenuElement = menu;
2125
+ this.positionContextMenu(position);
2126
+ (_a2 = menu.querySelector("button")) == null ? void 0 : _a2.focus({ preventScroll: true });
2127
+ window.addEventListener(
2128
+ "pointerdown",
2129
+ this.handleContextMenuOutsidePointerDown,
2130
+ true
2131
+ );
2132
+ window.addEventListener("keydown", this.handleContextMenuKeyDown);
2133
+ }
2134
+ closeContextMenu() {
2135
+ var _a2;
2136
+ (_a2 = this.contextMenuElement) == null ? void 0 : _a2.remove();
2137
+ this.contextMenuElement = null;
2138
+ window.removeEventListener(
2139
+ "pointerdown",
2140
+ this.handleContextMenuOutsidePointerDown,
2141
+ true
2142
+ );
2143
+ window.removeEventListener("keydown", this.handleContextMenuKeyDown);
2144
+ }
2145
+ positionContextMenu(position) {
2146
+ const menu = this.contextMenuElement;
2147
+ if (!menu) {
2148
+ return;
2149
+ }
2150
+ const viewport = getViewportSize();
2151
+ const width = menu.offsetWidth || 132;
2152
+ const height = menu.offsetHeight || 40;
2153
+ const maxX = Math.max(
2154
+ PET_CONTEXT_MENU_MARGIN,
2155
+ viewport.width - width - PET_CONTEXT_MENU_MARGIN
2156
+ );
2157
+ const maxY = Math.max(
2158
+ PET_CONTEXT_MENU_MARGIN,
2159
+ viewport.height - height - PET_CONTEXT_MENU_MARGIN
2160
+ );
2161
+ const x = clampNumber(position.x, PET_CONTEXT_MENU_MARGIN, maxX);
2162
+ const y = clampNumber(position.y, PET_CONTEXT_MENU_MARGIN, maxY);
2163
+ menu.style.transform = `translate3d(${x}px, ${y}px, 0)`;
2164
+ }
1919
2165
  renderAtlas(animationName, animationMode) {
1920
2166
  var _a2;
1921
2167
  if (!this.petElement || ((_a2 = this.resolved) == null ? void 0 : _a2.kind) !== "atlas" || !this.options) {
@@ -2016,13 +2262,16 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2016
2262
  this.rescheduleAnimation();
2017
2263
  }, PET_RESTING_DELAY_MS);
2018
2264
  }
2019
- isPointerOverPet(event) {
2265
+ isPointOverPet(clientX, clientY) {
2020
2266
  var _a2;
2021
2267
  const rect = (_a2 = this.petElement) == null ? void 0 : _a2.getBoundingClientRect();
2022
2268
  if (!rect) {
2023
2269
  return false;
2024
2270
  }
2025
- return event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;
2271
+ return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
2272
+ }
2273
+ isPointerOverPet(event) {
2274
+ return this.isPointOverPet(event.clientX, event.clientY);
2026
2275
  }
2027
2276
  async submitReply() {
2028
2277
  var _a2;
@@ -2097,10 +2346,13 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2097
2346
  __privateAdd(this, _wrapper);
2098
2347
  __privateAdd(this, _launcherCloseButton);
2099
2348
  __privateAdd(this, _launcherOpen, false);
2349
+ __privateAdd(this, _chatMinimizedToPet, false);
2100
2350
  __privateAdd(this, _framePetOptionsOverride);
2351
+ __privateAdd(this, _petClosedByContextMenu, false);
2101
2352
  __privateAdd(this, _shadow, this.attachShadow({ mode: "open" }));
2102
2353
  __privateAdd(this, _petOverlay, new PetOverlay(__privateGet(this, _shadow), {
2103
2354
  onActivate: () => __privateMethod(this, _ChatKitElementBase_instances, handlePetActivate_fn).call(this),
2355
+ onClose: () => __privateMethod(this, _ChatKitElementBase_instances, handlePetClose_fn).call(this),
2104
2356
  onReply: (text) => __privateMethod(this, _ChatKitElementBase_instances, handlePetReply_fn).call(this, text),
2105
2357
  onThreadSummaryActivate: (threadId) => void __privateMethod(this, _ChatKitElementBase_instances, handlePetThreadSummaryActivate_fn).call(this, threadId)
2106
2358
  }));
@@ -2231,6 +2483,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2231
2483
  :host([data-display-mode="pet"]) {
2232
2484
  display: contents;
2233
2485
  }
2486
+ :host([data-chat-minimized-to-pet="true"]) {
2487
+ display: contents;
2488
+ }
2234
2489
  .ck-iframe {
2235
2490
  border: none;
2236
2491
  position: absolute;
@@ -2341,6 +2596,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2341
2596
  :host([data-loaded="true"]) .ck-wrapper {
2342
2597
  opacity: 1;
2343
2598
  }
2599
+ :host([data-chat-minimized-to-pet="true"]) .ck-wrapper {
2600
+ opacity: 0;
2601
+ pointer-events: none;
2602
+ visibility: hidden;
2603
+ }
2344
2604
  :host([data-display-mode="pet"]:not([data-chat-open="true"])) .ck-wrapper {
2345
2605
  opacity: 0;
2346
2606
  }
@@ -2423,8 +2683,21 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2423
2683
  __privateGet(this, _messenger).on("pet_options_change", (data) => {
2424
2684
  const payload = parsePetOptionsChangePayload(data);
2425
2685
  if (payload) {
2686
+ if (!__privateGet(this, _petClosedByContextMenu) || payload.pet === null) {
2687
+ __privateSet(this, _petClosedByContextMenu, false);
2688
+ }
2426
2689
  __privateSet(this, _framePetOptionsOverride, payload.pet);
2427
- __privateGet(this, _petOverlay).setOptions(__privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this));
2690
+ __privateMethod(this, _ChatKitElementBase_instances, syncPetOverlayOptions_fn).call(this);
2691
+ }
2692
+ });
2693
+ __privateGet(this, _messenger).on("chat_minimize_change", (data) => {
2694
+ const minimized = typeof data === "object" && data !== null && "minimized" in data && data.minimized === true;
2695
+ if (minimized && !__privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this)) {
2696
+ return;
2697
+ }
2698
+ __privateMethod(this, _ChatKitElementBase_instances, setChatMinimizedToPet_fn).call(this, minimized);
2699
+ if (minimized) {
2700
+ __privateMethod(this, _ChatKitElementBase_instances, setLauncherOpen_fn).call(this, false);
2428
2701
  }
2429
2702
  });
2430
2703
  __privateGet(this, _messenger).on("unmount", () => {
@@ -2460,8 +2733,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2460
2733
  }
2461
2734
  applySanitizedOptions(newOptions) {
2462
2735
  __privateSet(this, _opts, newOptions);
2736
+ __privateSet(this, _petClosedByContextMenu, false);
2463
2737
  __privateGet(this, _petOverlay).setLocale(newOptions.locale);
2464
- __privateGet(this, _petOverlay).setOptions(__privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this));
2738
+ __privateMethod(this, _ChatKitElementBase_instances, syncPetOverlayOptions_fn).call(this);
2465
2739
  if (__privateGet(this, _initialized)) {
2466
2740
  __privateMethod(this, _ChatKitElementBase_instances, setOptionsDataAttributes_fn).call(this, __privateGet(this, _opts));
2467
2741
  __privateGet(this, _loaded).then(() => {
@@ -2541,7 +2815,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2541
2815
  _wrapper = new WeakMap();
2542
2816
  _launcherCloseButton = new WeakMap();
2543
2817
  _launcherOpen = new WeakMap();
2818
+ _chatMinimizedToPet = new WeakMap();
2544
2819
  _framePetOptionsOverride = new WeakMap();
2820
+ _petClosedByContextMenu = new WeakMap();
2545
2821
  _shadow = new WeakMap();
2546
2822
  _petOverlay = new WeakMap();
2547
2823
  _resolveLoaded = new WeakMap();
@@ -2572,8 +2848,42 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2572
2848
  }
2573
2849
  return options.pet ?? null;
2574
2850
  };
2851
+ mergeConfiguredPetPositionDefaults_fn = function(pet) {
2852
+ if (!pet) {
2853
+ return pet;
2854
+ }
2855
+ const configured = chatkitTypes.normalizePetOptions(
2856
+ __privateMethod(this, _ChatKitElementBase_instances, getConfiguredPetOptions_fn).call(this) ?? null
2857
+ );
2858
+ if (!configured) {
2859
+ return pet;
2860
+ }
2861
+ if (pet === true) {
2862
+ return { position: configured.position };
2863
+ }
2864
+ if (!pet.position) {
2865
+ return { ...pet, position: configured.position };
2866
+ }
2867
+ return {
2868
+ ...pet,
2869
+ position: {
2870
+ ...configured.position,
2871
+ ...pet.position,
2872
+ boundsPadding: pet.position.boundsPadding ?? configured.position.boundsPadding,
2873
+ pin: "pin" in pet.position ? pet.position.pin : configured.position.pin
2874
+ }
2875
+ };
2876
+ };
2575
2877
  getOverlayPetOptions_fn = function() {
2576
- let pet = __privateGet(this, _framePetOptionsOverride) !== void 0 ? __privateGet(this, _framePetOptionsOverride) : __privateMethod(this, _ChatKitElementBase_instances, getConfiguredPetOptions_fn).call(this);
2878
+ if (__privateGet(this, _petClosedByContextMenu)) {
2879
+ return null;
2880
+ }
2881
+ let pet;
2882
+ if (__privateGet(this, _framePetOptionsOverride) !== void 0) {
2883
+ pet = __privateMethod(this, _ChatKitElementBase_instances, mergeConfiguredPetPositionDefaults_fn).call(this, __privateGet(this, _framePetOptionsOverride));
2884
+ } else {
2885
+ pet = __privateMethod(this, _ChatKitElementBase_instances, getConfiguredPetOptions_fn).call(this);
2886
+ }
2577
2887
  if (__privateMethod(this, _ChatKitElementBase_instances, getDisplayMode_fn).call(this) === "pet" && !chatkitTypes.normalizePetOptions(pet ?? null)) {
2578
2888
  pet = true;
2579
2889
  }
@@ -2627,13 +2937,49 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2627
2937
  delete this.dataset.chatOpen;
2628
2938
  }
2629
2939
  };
2940
+ setChatMinimizedToPet_fn = function(minimized) {
2941
+ const next = minimized && Boolean(__privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this));
2942
+ __privateSet(this, _chatMinimizedToPet, next);
2943
+ if (next) {
2944
+ this.dataset.chatMinimizedToPet = "true";
2945
+ } else {
2946
+ delete this.dataset.chatMinimizedToPet;
2947
+ }
2948
+ };
2949
+ syncPetOverlayOptions_fn = function() {
2950
+ var _a2;
2951
+ const overlayPetOptions = __privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this);
2952
+ __privateGet(this, _petOverlay).setOptions(overlayPetOptions, (_a2 = __privateGet(this, _opts)) == null ? void 0 : _a2.theme);
2953
+ if (!overlayPetOptions) {
2954
+ __privateMethod(this, _ChatKitElementBase_instances, setChatMinimizedToPet_fn).call(this, false);
2955
+ }
2956
+ };
2630
2957
  handlePetActivate_fn = function() {
2958
+ if (__privateGet(this, _chatMinimizedToPet)) {
2959
+ __privateMethod(this, _ChatKitElementBase_instances, setChatMinimizedToPet_fn).call(this, false);
2960
+ if (__privateMethod(this, _ChatKitElementBase_instances, getDisplayMode_fn).call(this) === "pet") {
2961
+ __privateMethod(this, _ChatKitElementBase_instances, setLauncherOpen_fn).call(this, true);
2962
+ }
2963
+ __privateGet(this, _loaded).then(() => this.focusComposer()).catch(() => void 0);
2964
+ return;
2965
+ }
2631
2966
  if (__privateMethod(this, _ChatKitElementBase_instances, getDisplayMode_fn).call(this) !== "pet") {
2632
2967
  return;
2633
2968
  }
2634
2969
  __privateMethod(this, _ChatKitElementBase_instances, setLauncherOpen_fn).call(this, true);
2635
2970
  __privateGet(this, _loaded).then(() => this.focusComposer()).catch(() => void 0);
2636
2971
  };
2972
+ handlePetClose_fn = function() {
2973
+ __privateSet(this, _petClosedByContextMenu, true);
2974
+ __privateSet(this, _framePetOptionsOverride, null);
2975
+ __privateMethod(this, _ChatKitElementBase_instances, setChatMinimizedToPet_fn).call(this, false);
2976
+ __privateMethod(this, _ChatKitElementBase_instances, setLauncherOpen_fn).call(this, false);
2977
+ __privateGet(this, _petOverlay).setOptions(null);
2978
+ if (__privateMethod(this, _ChatKitElementBase_instances, getDisplayMode_fn).call(this) === "pet") {
2979
+ return;
2980
+ }
2981
+ __privateGet(this, _loaded).then(() => __privateGet(this, _messenger).commands.setPetEnabled({ enabled: false })).catch(() => void 0);
2982
+ };
2637
2983
  handlePetReply_fn = async function(text) {
2638
2984
  await this.sendUserMessage({ text });
2639
2985
  };