@xpert-ai/chatkit-web-component 0.3.4 → 0.3.6

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.
@@ -1138,6 +1138,7 @@ const PET_SUMMARY_GAP = 12;
1138
1138
  const PET_SUMMARY_WIDTH = 320;
1139
1139
  const PET_SUMMARY_MARGIN = 12;
1140
1140
  const PET_CONTEXT_MENU_MARGIN = 8;
1141
+ const PET_SUMMARY_FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
1141
1142
  const PET_OVERLAY_COPY = {
1142
1143
  "en-US": {
1143
1144
  closePetMenuItem: "Close pet",
@@ -1229,6 +1230,65 @@ function resolveCopyLocale(locale) {
1229
1230
  }
1230
1231
  return "en-US";
1231
1232
  }
1233
+ function getSummaryDensityMetrics(density) {
1234
+ switch (density) {
1235
+ case "compact":
1236
+ return {
1237
+ padding: "8px 10px",
1238
+ gap: 6,
1239
+ marginTop: 3,
1240
+ toggleSize: 30,
1241
+ actionSize: 22
1242
+ };
1243
+ case "spacious":
1244
+ return {
1245
+ padding: "14px 16px",
1246
+ gap: 10,
1247
+ marginTop: 6,
1248
+ toggleSize: 38,
1249
+ actionSize: 28
1250
+ };
1251
+ case "normal":
1252
+ default:
1253
+ return {
1254
+ padding: "12px 14px",
1255
+ gap: 8,
1256
+ marginTop: 4,
1257
+ toggleSize: 34,
1258
+ actionSize: 26
1259
+ };
1260
+ }
1261
+ }
1262
+ function getSummaryRadius(radius) {
1263
+ switch (radius) {
1264
+ case "pill":
1265
+ return 24;
1266
+ case "round":
1267
+ return 16;
1268
+ case "sharp":
1269
+ return 0;
1270
+ case "soft":
1271
+ default:
1272
+ return 12;
1273
+ }
1274
+ }
1275
+ function getSummaryThemeMetrics(theme) {
1276
+ var _a2, _b2;
1277
+ const themeObject = typeof theme === "string" ? null : theme;
1278
+ const baseSize = ((_a2 = themeObject == null ? void 0 : themeObject.typography) == null ? void 0 : _a2.baseSize) ?? 16;
1279
+ const density = (themeObject == null ? void 0 : themeObject.density) ?? "normal";
1280
+ const densityOffset = density === "compact" ? -1 : density === "spacious" ? 1 : 0;
1281
+ const bodySize = clampNumber(baseSize - 2 + densityOffset, 11, 17);
1282
+ const densityMetrics = getSummaryDensityMetrics(density);
1283
+ return {
1284
+ ...densityMetrics,
1285
+ bodySize,
1286
+ titleSize: bodySize + 1,
1287
+ iconSize: clampNumber(bodySize + 2, 13, 19),
1288
+ radius: getSummaryRadius(themeObject == null ? void 0 : themeObject.radius),
1289
+ fontFamily: ((_b2 = themeObject == null ? void 0 : themeObject.typography) == null ? void 0 : _b2.fontFamily) ?? PET_SUMMARY_FONT_FAMILY
1290
+ };
1291
+ }
1232
1292
  function isPetState(value) {
1233
1293
  return value === "idle" || value === "running-right" || value === "running-left" || value === "waving" || value === "jumping" || value === "failed" || value === "waiting" || value === "running" || value === "review";
1234
1294
  }
@@ -1264,6 +1324,12 @@ function getThreadSummaryKey(summary) {
1264
1324
  summary.messageId || summary.updatedAt || summary.message
1265
1325
  ].join(":");
1266
1326
  }
1327
+ function getThreadSummaryInteractionKey(summary) {
1328
+ if (!summary) {
1329
+ return null;
1330
+ }
1331
+ return [summary.threadId, summary.messageId ?? ""].join(":");
1332
+ }
1267
1333
  function parseThreadSummaryPayload(value) {
1268
1334
  if (value === null) {
1269
1335
  return { summary: null };
@@ -1305,6 +1371,7 @@ class PetOverlay {
1305
1371
  this.summaryToggleElement = null;
1306
1372
  this.mediaElement = null;
1307
1373
  this.options = null;
1374
+ this.theme = null;
1308
1375
  this.resolved = null;
1309
1376
  this.summary = null;
1310
1377
  this.summaryRenderKey = null;
@@ -1553,10 +1620,11 @@ class PetOverlay {
1553
1620
  this.installReducedMotionListener();
1554
1621
  this.render();
1555
1622
  }
1556
- setOptions(pet) {
1623
+ setOptions(pet, theme) {
1557
1624
  this.closeContextMenu();
1558
1625
  const nextOptions = normalizePetOptions(pet);
1559
1626
  this.options = nextOptions;
1627
+ this.theme = theme ?? null;
1560
1628
  if (!nextOptions) {
1561
1629
  this.isDragging = false;
1562
1630
  this.isHovering = false;
@@ -1606,8 +1674,8 @@ class PetOverlay {
1606
1674
  this.render();
1607
1675
  }
1608
1676
  setThreadSummary(summary) {
1609
- const previousKey = getThreadSummaryKey(this.summary);
1610
- const nextKey = getThreadSummaryKey(summary);
1677
+ const previousKey = getThreadSummaryInteractionKey(this.summary);
1678
+ const nextKey = getThreadSummaryInteractionKey(summary);
1611
1679
  this.summary = summary;
1612
1680
  if (!summary) {
1613
1681
  this.isSummaryCollapsed = false;
@@ -1902,10 +1970,6 @@ class PetOverlay {
1902
1970
  return;
1903
1971
  }
1904
1972
  const nextRenderKey = [
1905
- summaryKey,
1906
- summary.title,
1907
- summary.message,
1908
- summary.status,
1909
1973
  this.copyLocale,
1910
1974
  this.isSummaryExpanded ? "expanded" : "compact",
1911
1975
  this.isSummaryHovering ? "hover" : "rest",
@@ -1930,6 +1994,7 @@ class PetOverlay {
1930
1994
  }, 0);
1931
1995
  }
1932
1996
  }
1997
+ this.updateSummaryBubbleContent(summary);
1933
1998
  this.positionSummaryBubble(position, size);
1934
1999
  }
1935
2000
  renderCollapsedSummary(position, size) {
@@ -1950,7 +2015,7 @@ class PetOverlay {
1950
2015
  return;
1951
2016
  }
1952
2017
  const viewport = getViewportSize();
1953
- const badgeSize = 34;
2018
+ const badgeSize = getSummaryThemeMetrics(this.theme).toggleSize;
1954
2019
  const x = clampNumber(
1955
2020
  position.x + size.width - badgeSize * 0.35,
1956
2021
  PET_SUMMARY_MARGIN,
@@ -1996,6 +2061,7 @@ class PetOverlay {
1996
2061
  }
1997
2062
  createSummaryBubble(summary) {
1998
2063
  const shouldShowReplyButton = this.isSummaryHovering && !this.isReplyOpen;
2064
+ const metrics = getSummaryThemeMetrics(this.theme);
1999
2065
  const bubble = document.createElement("div");
2000
2066
  bubble.setAttribute("data-chatkit-pet-summary", "");
2001
2067
  bubble.addEventListener("pointerenter", this.handleSummaryPointerEnter);
@@ -2006,19 +2072,18 @@ class PetOverlay {
2006
2072
  bubble.style.left = "0";
2007
2073
  bubble.style.boxSizing = "border-box";
2008
2074
  bubble.style.pointerEvents = "auto";
2009
- bubble.style.padding = "12px 14px";
2010
- bubble.style.paddingBottom = "12px";
2075
+ bubble.style.padding = metrics.padding;
2011
2076
  bubble.style.border = "1px solid rgba(148, 163, 184, 0.22)";
2012
- bubble.style.borderRadius = "22px";
2077
+ bubble.style.borderRadius = `${metrics.radius}px`;
2013
2078
  bubble.style.background = "rgba(255, 255, 255, 0.94)";
2014
2079
  bubble.style.color = "#1f2937";
2015
2080
  bubble.style.boxShadow = "0 8px 24px rgba(15, 23, 42, 0.1)";
2016
- bubble.style.font = '500 14px/1.35 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
2081
+ bubble.style.font = `500 ${metrics.bodySize}px/1.35 ${metrics.fontFamily}`;
2017
2082
  bubble.style.backdropFilter = "blur(10px)";
2018
2083
  const header = document.createElement("div");
2019
2084
  header.style.display = "flex";
2020
2085
  header.style.alignItems = "center";
2021
- header.style.gap = "8px";
2086
+ header.style.gap = `${metrics.gap}px`;
2022
2087
  if (this.isSummaryHovering || this.isReplyOpen) {
2023
2088
  header.append(
2024
2089
  this.createSummaryActionButton(
@@ -2036,7 +2101,8 @@ class PetOverlay {
2036
2101
  title.style.textOverflow = "ellipsis";
2037
2102
  title.style.whiteSpace = "nowrap";
2038
2103
  title.style.fontWeight = "700";
2039
- title.style.fontSize = "15px";
2104
+ title.style.fontSize = `${metrics.titleSize}px`;
2105
+ title.dataset.chatkitPetSummaryTitle = "";
2040
2106
  header.append(title);
2041
2107
  if (this.isSummaryHovering || this.isReplyOpen) {
2042
2108
  header.append(
@@ -2051,7 +2117,7 @@ class PetOverlay {
2051
2117
  }
2052
2118
  const message = document.createElement("div");
2053
2119
  message.textContent = summary.message;
2054
- message.style.marginTop = "4px";
2120
+ message.style.marginTop = `${metrics.marginTop}px`;
2055
2121
  message.style.fontWeight = "400";
2056
2122
  message.style.color = "#374151";
2057
2123
  message.style.overflow = "hidden";
@@ -2063,6 +2129,7 @@ class PetOverlay {
2063
2129
  message.style.setProperty("-webkit-line-clamp", "2");
2064
2130
  message.style.setProperty("-webkit-box-orient", "vertical");
2065
2131
  }
2132
+ message.dataset.chatkitPetSummaryMessage = "";
2066
2133
  bubble.append(header, message);
2067
2134
  if (shouldShowReplyButton) {
2068
2135
  const reply = this.createTextButton(
@@ -2079,7 +2146,30 @@ class PetOverlay {
2079
2146
  }
2080
2147
  return bubble;
2081
2148
  }
2149
+ updateSummaryBubbleContent(summary) {
2150
+ var _a2, _b2, _c2;
2151
+ const title = (_a2 = this.summaryElement) == null ? void 0 : _a2.querySelector(
2152
+ "[data-chatkit-pet-summary-title]"
2153
+ );
2154
+ if (title && title.textContent !== summary.title) {
2155
+ title.textContent = summary.title;
2156
+ }
2157
+ const message = (_b2 = this.summaryElement) == null ? void 0 : _b2.querySelector(
2158
+ "[data-chatkit-pet-summary-message]"
2159
+ );
2160
+ if (message && message.textContent !== summary.message) {
2161
+ message.textContent = summary.message;
2162
+ }
2163
+ const statusIcon = (_c2 = this.summaryElement) == null ? void 0 : _c2.querySelector(
2164
+ "[data-chatkit-pet-summary-status]"
2165
+ );
2166
+ if (statusIcon && statusIcon.dataset.chatkitPetSummaryStatus !== summary.status) {
2167
+ const nextIcon = this.createStatusIcon(summary.status);
2168
+ statusIcon.replaceWith(nextIcon);
2169
+ }
2170
+ }
2082
2171
  createSummaryToggleButton(label) {
2172
+ const metrics = getSummaryThemeMetrics(this.theme);
2083
2173
  const button = document.createElement("button");
2084
2174
  button.type = "button";
2085
2175
  button.textContent = label;
@@ -2095,18 +2185,21 @@ class PetOverlay {
2095
2185
  button.style.color = "#475569";
2096
2186
  button.style.boxShadow = "0 6px 18px rgba(15, 23, 42, 0.1)";
2097
2187
  button.style.cursor = "pointer";
2098
- button.style.font = '600 15px/1 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
2188
+ button.style.font = `600 ${metrics.titleSize}px/1 ${metrics.fontFamily}`;
2099
2189
  button.style.display = "flex";
2100
2190
  button.style.alignItems = "center";
2101
2191
  button.style.justifyContent = "center";
2102
2192
  return button;
2103
2193
  }
2104
2194
  createStatusIcon(status) {
2195
+ const metrics = getSummaryThemeMetrics(this.theme);
2196
+ const iconSize = metrics.iconSize;
2105
2197
  const icon = document.createElement("span");
2106
2198
  icon.setAttribute("aria-hidden", "true");
2199
+ icon.dataset.chatkitPetSummaryStatus = status;
2107
2200
  icon.style.display = "inline-flex";
2108
- icon.style.width = "16px";
2109
- icon.style.height = "16px";
2201
+ icon.style.width = `${iconSize}px`;
2202
+ icon.style.height = `${iconSize}px`;
2110
2203
  icon.style.alignItems = "center";
2111
2204
  icon.style.justifyContent = "center";
2112
2205
  icon.style.flex = "0 0 auto";
@@ -2118,7 +2211,7 @@ class PetOverlay {
2118
2211
  return icon;
2119
2212
  }
2120
2213
  icon.style.borderRadius = "999px";
2121
- icon.style.fontSize = "12px";
2214
+ icon.style.fontSize = `${Math.max(10, iconSize - 4)}px`;
2122
2215
  icon.style.fontWeight = "700";
2123
2216
  if (status === "failed") {
2124
2217
  icon.textContent = "!";
@@ -2130,8 +2223,8 @@ class PetOverlay {
2130
2223
  icon.style.border = "2px solid #22c55e";
2131
2224
  icon.style.position = "relative";
2132
2225
  const check = document.createElement("span");
2133
- check.style.width = "7px";
2134
- check.style.height = "4px";
2226
+ check.style.width = `${Math.round(iconSize * 0.44)}px`;
2227
+ check.style.height = `${Math.round(iconSize * 0.25)}px`;
2135
2228
  check.style.borderLeft = "2px solid #22c55e";
2136
2229
  check.style.borderBottom = "2px solid #22c55e";
2137
2230
  check.style.transform = "rotate(-45deg) translate(1px, -1px)";
@@ -2139,6 +2232,7 @@ class PetOverlay {
2139
2232
  return icon;
2140
2233
  }
2141
2234
  createSummaryActionButton(label, title, onClick) {
2235
+ const metrics = getSummaryThemeMetrics(this.theme);
2142
2236
  const button = document.createElement("button");
2143
2237
  button.type = "button";
2144
2238
  button.textContent = label;
@@ -2148,14 +2242,14 @@ class PetOverlay {
2148
2242
  event.stopPropagation();
2149
2243
  onClick();
2150
2244
  });
2151
- button.style.width = "26px";
2152
- button.style.height = "26px";
2245
+ button.style.width = `${metrics.actionSize}px`;
2246
+ button.style.height = `${metrics.actionSize}px`;
2153
2247
  button.style.border = "0";
2154
2248
  button.style.borderRadius = "999px";
2155
2249
  button.style.background = "rgba(241, 245, 249, 0.96)";
2156
2250
  button.style.color = "#475569";
2157
2251
  button.style.cursor = "pointer";
2158
- button.style.font = '600 15px/1 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
2252
+ button.style.font = `600 ${metrics.titleSize}px/1 ${metrics.fontFamily}`;
2159
2253
  return button;
2160
2254
  }
2161
2255
  createTextButton(label, onClick) {
@@ -3095,8 +3189,9 @@ setChatMinimizedToPet_fn = function(minimized) {
3095
3189
  }
3096
3190
  };
3097
3191
  syncPetOverlayOptions_fn = function() {
3192
+ var _a2;
3098
3193
  const overlayPetOptions = __privateMethod(this, _ChatKitElementBase_instances, getOverlayPetOptions_fn).call(this);
3099
- __privateGet(this, _petOverlay).setOptions(overlayPetOptions);
3194
+ __privateGet(this, _petOverlay).setOptions(overlayPetOptions, (_a2 = __privateGet(this, _opts)) == null ? void 0 : _a2.theme);
3100
3195
  if (!overlayPetOptions) {
3101
3196
  __privateMethod(this, _ChatKitElementBase_instances, setChatMinimizedToPet_fn).call(this, false);
3102
3197
  }