@getnexorai/sdk 0.1.5 → 0.1.7

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/dist/chat.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as NexorClient, d as ChatInitOptions, c as ChatHandle } from './config-C39P5Aax.cjs';
2
- export { a as ChatChannelKey, b as ChatChannels, e as ChatLeadCapture } from './config-C39P5Aax.cjs';
1
+ import { N as NexorClient, d as ChatInitOptions, c as ChatHandle } from './config-DBEY3q4Q.cjs';
2
+ export { a as ChatChannelKey, b as ChatChannels, e as ChatLeadCapture } from './config-DBEY3q4Q.cjs';
3
3
 
4
4
  /**
5
5
  * Chat widget orchestrator.
package/dist/chat.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as NexorClient, d as ChatInitOptions, c as ChatHandle } from './config-C39P5Aax.js';
2
- export { a as ChatChannelKey, b as ChatChannels, e as ChatLeadCapture } from './config-C39P5Aax.js';
1
+ import { N as NexorClient, d as ChatInitOptions, c as ChatHandle } from './config-DBEY3q4Q.js';
2
+ export { a as ChatChannelKey, b as ChatChannels, e as ChatLeadCapture } from './config-DBEY3q4Q.js';
3
3
 
4
4
  /**
5
5
  * Chat widget orchestrator.
package/dist/chat.js CHANGED
@@ -1,3 +1,3 @@
1
- export { initChat } from './chunk-EGZR7CCR.js';
1
+ export { initChat } from './chunk-DSKP6MXM.js';
2
2
  //# sourceMappingURL=chat.js.map
3
3
  //# sourceMappingURL=chat.js.map
@@ -710,6 +710,40 @@ var widgetCss = (accent, accentText) => `
710
710
  }
711
711
  .nexor-chat__msg--bot .nexor-chat__msg-time { text-align: left; }
712
712
 
713
+ /* File Library attachment: the image itself is the bubble (no padding/bg). */
714
+ .nexor-chat__msg--media {
715
+ padding: 0;
716
+ background: transparent;
717
+ border: none;
718
+ box-shadow: none;
719
+ overflow: hidden;
720
+ }
721
+ .nexor-chat__media-img {
722
+ display: block;
723
+ max-width: 100%;
724
+ max-height: 260px;
725
+ width: auto;
726
+ height: auto;
727
+ border-radius: 14px;
728
+ border-bottom-left-radius: 4px;
729
+ object-fit: cover;
730
+ }
731
+ .nexor-chat__media-doc {
732
+ display: inline-flex;
733
+ align-items: center;
734
+ gap: 6px;
735
+ padding: 8px 12px;
736
+ border-radius: 14px;
737
+ border-bottom-left-radius: 4px;
738
+ background: #fff;
739
+ border: 1px solid rgba(0,0,0,0.06);
740
+ color: ${accent};
741
+ text-decoration: none;
742
+ font-size: 13px;
743
+ font-weight: 500;
744
+ }
745
+ .nexor-chat__media-doc::before { content: "\\1F4CE"; }
746
+
713
747
  @keyframes nexor-msg-in {
714
748
  from { transform: translateY(8px) scale(0.96); opacity: 0; }
715
749
  to { transform: translateY(0) scale(1); opacity: 1; }
@@ -849,7 +883,8 @@ var widgetCss = (accent, accentText) => `
849
883
  transition: border-color 140ms ease, box-shadow 140ms ease;
850
884
  }
851
885
  /* Composer textarea: auto-grows (height managed in JS) up to ~4 lines, then
852
- scrolls. resize:none disables the manual drag handle. */
886
+ scrolls. resize:none disables the manual drag handle. Filled style: neutral
887
+ pill at rest that "lights up" white on focus \u2014 calmer than a glowing ring. */
853
888
  textarea.nexor-chat__input {
854
889
  display: block;
855
890
  resize: none;
@@ -858,11 +893,22 @@ textarea.nexor-chat__input {
858
893
  max-height: 98px; /* 4 lines (20\xD74) + 16 padding + 2 border */
859
894
  white-space: pre-wrap;
860
895
  word-break: break-word;
896
+ background: #f3f4f6;
897
+ border-color: transparent;
898
+ border-radius: 19px;
899
+ padding: 8px 14px;
900
+ transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
861
901
  }
902
+ textarea.nexor-chat__input::placeholder { color: #9ca3af; }
862
903
  .nexor-chat__input:focus,
863
904
  .nexor-chat__capture input:focus {
864
905
  border-color: ${accent};
865
- box-shadow: 0 0 0 3px ${accent}33;
906
+ box-shadow: 0 0 0 2px ${accent}1f;
907
+ }
908
+ textarea.nexor-chat__input:focus {
909
+ background: #fff;
910
+ border-color: ${accent}99;
911
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
866
912
  }
867
913
  .nexor-chat__input--error,
868
914
  .nexor-chat__capture input.nexor-chat__input--error {
@@ -1003,21 +1049,26 @@ textarea.nexor-chat__input {
1003
1049
  background: ${accent};
1004
1050
  color: ${accentText};
1005
1051
  border: none;
1006
- border-radius: 8px;
1007
- padding: 0 14px;
1052
+ border-radius: 9999px; /* circle, matches the pill composer */
1053
+ padding: 0;
1008
1054
  font: inherit;
1009
1055
  font-weight: 600;
1010
1056
  cursor: pointer;
1011
- min-width: 44px;
1057
+ width: 38px;
1012
1058
  height: 38px; /* matches the one-line textarea height */
1013
1059
  flex: none;
1014
1060
  display: flex;
1015
1061
  align-items: center;
1016
1062
  justify-content: center;
1017
- transition: transform 140ms ease, filter 140ms ease;
1063
+ box-shadow: 0 1px 3px rgba(0,0,0,0.12);
1064
+ transition: transform 140ms ease, filter 140ms ease, box-shadow 140ms ease;
1065
+ }
1066
+ .nexor-chat__send:hover {
1067
+ filter: brightness(1.08);
1068
+ box-shadow: 0 2px 6px rgba(0,0,0,0.18);
1069
+ transform: translateY(-1px);
1018
1070
  }
1019
- .nexor-chat__send:hover { filter: brightness(1.08); }
1020
- .nexor-chat__send:active { transform: scale(0.95); }
1071
+ .nexor-chat__send:active { transform: scale(0.93); }
1021
1072
  .nexor-chat__send[disabled] {
1022
1073
  opacity: 0.6;
1023
1074
  cursor: not-allowed;
@@ -1028,7 +1079,7 @@ textarea.nexor-chat__input {
1028
1079
  height: 18px;
1029
1080
  transition: transform 200ms ease;
1030
1081
  }
1031
- .nexor-chat__send:not([disabled]):hover svg { transform: translateX(2px); }
1082
+ .nexor-chat__send:not([disabled]):hover svg { transform: translateY(-1.5px); }
1032
1083
 
1033
1084
  /* Small spinner inside the send button while a turn is in flight */
1034
1085
  .nexor-chat__send--loading svg { display: none; }
@@ -1181,11 +1232,13 @@ textarea.nexor-chat__input {
1181
1232
  // src/chat/dom.ts
1182
1233
  var STYLE_ATTR = "data-nexor-chat-styles";
1183
1234
  function injectStyles(accent, accentText) {
1184
- if (document.querySelector(`style[${STYLE_ATTR}]`)) return;
1185
- const style = document.createElement("style");
1186
- style.setAttribute(STYLE_ATTR, "1");
1235
+ let style = document.querySelector(`style[${STYLE_ATTR}]`);
1236
+ if (!style) {
1237
+ style = document.createElement("style");
1238
+ style.setAttribute(STYLE_ATTR, "1");
1239
+ document.head.appendChild(style);
1240
+ }
1187
1241
  style.textContent = widgetCss(accent, accentText);
1188
- document.head.appendChild(style);
1189
1242
  }
1190
1243
  var CHAT_ICON = `
1191
1244
  <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
@@ -1548,8 +1601,8 @@ function buildComposer(cfg) {
1548
1601
  send.setAttribute("aria-label", "Send message");
1549
1602
  send.innerHTML = `
1550
1603
  <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
1551
- <path d="M3.4 11.2 20.5 4.3c.7-.3 1.4.4 1.1 1.1l-6.9 17.1c-.3.8-1.4.8-1.8 0L10 14l-7.5-3c-.8-.3-.8-1.5 0-1.8Z"
1552
- stroke="currentColor" stroke-width="1.6" stroke-linejoin="round" fill="currentColor"/>
1604
+ <path d="M12 19V5.8M5.8 12 12 5.8 18.2 12"
1605
+ stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
1553
1606
  </svg>
1554
1607
  `;
1555
1608
  form.appendChild(input);
@@ -1591,6 +1644,28 @@ function buildMessage(role, text, ts, locale) {
1591
1644
  }
1592
1645
  return el;
1593
1646
  }
1647
+ function buildMediaMessage(item) {
1648
+ const el = document.createElement("div");
1649
+ el.className = "nexor-chat__msg nexor-chat__msg--bot nexor-chat__msg--media";
1650
+ if (item.type === "image") {
1651
+ const img = document.createElement("img");
1652
+ img.className = "nexor-chat__media-img";
1653
+ img.src = item.url;
1654
+ img.alt = item.filename || "";
1655
+ img.loading = "lazy";
1656
+ img.addEventListener("error", () => el.remove());
1657
+ el.appendChild(img);
1658
+ } else {
1659
+ const a = document.createElement("a");
1660
+ a.className = "nexor-chat__media-doc";
1661
+ a.href = item.url;
1662
+ a.target = "_blank";
1663
+ a.rel = "noopener noreferrer";
1664
+ a.textContent = item.filename || "Descargar archivo";
1665
+ el.appendChild(a);
1666
+ }
1667
+ return el;
1668
+ }
1594
1669
  function formatRelativeTime(ts, locale, now = Date.now()) {
1595
1670
  try {
1596
1671
  const diff = Math.max(0, now - ts);
@@ -1768,7 +1843,8 @@ function initChat(client, options) {
1768
1843
  setView("chat");
1769
1844
  renderResumeBanner();
1770
1845
  for (const m of persisted.history) {
1771
- appendBubble(m.role === "user" ? "user" : "bot", m.text, m.ts);
1846
+ if (m.media) appendNode(buildMediaMessage(m.media));
1847
+ else appendBubble(m.role === "user" ? "user" : "bot", m.text, m.ts);
1772
1848
  }
1773
1849
  scrollToBottom();
1774
1850
  }
@@ -2301,9 +2377,12 @@ function initChat(client, options) {
2301
2377
  renderResumeBanner(true);
2302
2378
  }
2303
2379
  const reply = (res.reply ?? "").trim();
2380
+ const hasMedia = Array.isArray(res.media) && res.media.length > 0;
2304
2381
  hideTyping();
2305
2382
  if (reply) {
2306
- appendBotReply(reply);
2383
+ appendBotReply(reply, hasMedia ? () => appendBotMedia(res.media) : void 0);
2384
+ } else if (hasMedia) {
2385
+ appendBotMedia(res.media);
2307
2386
  } else {
2308
2387
  appendSystem(cfg.errorText);
2309
2388
  cfg.onError?.(new Error("Nexor SDK: empty reply from server"));
@@ -2338,10 +2417,21 @@ function initChat(client, options) {
2338
2417
  if (!state.isOpen) bumpUnread();
2339
2418
  cfg.onMessage?.({ role: "bot", text });
2340
2419
  }
2341
- function appendBotReply(text) {
2420
+ function appendBotMedia(items) {
2421
+ if (!Array.isArray(items) || items.length === 0) return;
2422
+ for (const item of items) {
2423
+ if (!item || typeof item.url !== "string" || !item.url) continue;
2424
+ appendNode(buildMediaMessage(item));
2425
+ state.history.push({ role: "bot", text: "", ts: Date.now(), media: item });
2426
+ }
2427
+ saveHistory();
2428
+ if (!state.isOpen) bumpUnread();
2429
+ }
2430
+ function appendBotReply(text, after) {
2342
2431
  const parts = cfg.splitReplies ? splitReply(text) : [text];
2343
2432
  if (parts.length <= 1) {
2344
2433
  appendBot(text);
2434
+ after?.();
2345
2435
  return;
2346
2436
  }
2347
2437
  const [first, ...rest] = parts;
@@ -2349,7 +2439,10 @@ function initChat(client, options) {
2349
2439
  let i = 0;
2350
2440
  const sendNext = () => {
2351
2441
  const part = rest[i];
2352
- if (part === void 0) return;
2442
+ if (part === void 0) {
2443
+ after?.();
2444
+ return;
2445
+ }
2353
2446
  const isLast = i === rest.length - 1;
2354
2447
  i++;
2355
2448
  showTyping();
@@ -2490,5 +2583,5 @@ function readCaptureFields(panel) {
2490
2583
  }
2491
2584
 
2492
2585
  export { initChat };
2493
- //# sourceMappingURL=chunk-EGZR7CCR.js.map
2494
- //# sourceMappingURL=chunk-EGZR7CCR.js.map
2586
+ //# sourceMappingURL=chunk-DSKP6MXM.js.map
2587
+ //# sourceMappingURL=chunk-DSKP6MXM.js.map