@nameless26/widget 0.1.0 → 0.1.2

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/index.es.js CHANGED
@@ -1,34 +1,266 @@
1
- import { jsxs as p, Fragment as B, jsx as e } from "react/jsx-runtime";
2
- import { useState as k, useRef as D, useCallback as I, useEffect as H, forwardRef as E } from "react";
3
- function O(t) {
4
- return `nexus_widget_session_${t}`;
1
+ import { jsxs as f, Fragment as P, jsx as e } from "react/jsx-runtime";
2
+ import { useState as m, useRef as S, useEffect as j, useCallback as E } from "react";
3
+ function _({ color: t }) {
4
+ return /* @__PURE__ */ e(
5
+ "div",
6
+ {
7
+ style: { background: "var(--nx-surface)" },
8
+ className: `flex items-end gap-1 px-3 py-2.5 rounded-2xl rounded-bl-sm w-fit\r
9
+ bg-[rgba(255,255,255,0.06)]`,
10
+ children: [0, 1, 2].map((s) => /* @__PURE__ */ e(
11
+ "span",
12
+ {
13
+ style: {
14
+ width: 6,
15
+ height: 6,
16
+ borderRadius: "50%",
17
+ background: t,
18
+ opacity: 0.6,
19
+ animation: `nexusBounce 1.2s ease-in-out ${s * 0.2}s infinite`
20
+ }
21
+ },
22
+ s
23
+ ))
24
+ }
25
+ );
26
+ }
27
+ function U({
28
+ msg: t,
29
+ primaryColor: s
30
+ }) {
31
+ const n = t.role === "user";
32
+ return t.content ? /* @__PURE__ */ e("div", { className: `flex ${n ? "justify-end" : "justify-start"}`, children: /* @__PURE__ */ e(
33
+ "div",
34
+ {
35
+ style: n ? { background: s } : { background: "var(--nx-surface)", color: "var(--nx-text)" },
36
+ className: `max-w-[82%] px-3 py-2.5 rounded-2xl text-sm leading-relaxed
37
+ ${n ? "text-white rounded-br-sm" : "bg-[rgba(255,255,255,0.06)] text-[rgba(255,255,255,0.8)] rounded-bl-sm"}`,
38
+ children: t.content
39
+ }
40
+ ) }) : /* @__PURE__ */ e(P, {});
41
+ }
42
+ function J({
43
+ agentName: t,
44
+ messages: s,
45
+ isLoading: n,
46
+ error: b,
47
+ primaryColor: d,
48
+ welcomeMessage: i,
49
+ onSend: x,
50
+ onClose: l,
51
+ isFullView: r,
52
+ onToggleFullView: p
53
+ }) {
54
+ const [u, c] = m(""), B = S(null), g = S(null);
55
+ j(() => {
56
+ B.current?.scrollIntoView({ behavior: "smooth" });
57
+ }, [s, n]), j(() => {
58
+ g.current?.focus();
59
+ }, []);
60
+ const N = () => {
61
+ !u.trim() || n || (x(u), c(""));
62
+ }, T = (o) => {
63
+ o.key === "Enter" && !o.shiftKey && (o.preventDefault(), N());
64
+ };
65
+ return /* @__PURE__ */ f(P, { children: [
66
+ /* @__PURE__ */ e("style", { children: `
67
+ @keyframes nexusBounce {
68
+ 0%, 80%, 100% { transform: translateY(0); }
69
+ 40% { transform: translateY(-5px); }
70
+ }
71
+ button {
72
+ cursor: pointer;
73
+ }
74
+ ` }),
75
+ /* @__PURE__ */ f(
76
+ "div",
77
+ {
78
+ style: {
79
+ fontFamily: "system-ui, -apple-system, sans-serif",
80
+ position: "relative",
81
+ background: "var(--nx-bg)",
82
+ borderColor: r ? "none" : "var(--nx-border)"
83
+ },
84
+ className: `flex flex-col overflow-hidden shadow-2xl h-full ${r ? "" : "rounded-2xl border"}`,
85
+ role: "dialog",
86
+ "aria-label": `${t} chat`,
87
+ children: [
88
+ !r && /* @__PURE__ */ f(
89
+ "div",
90
+ {
91
+ style: { background: "var(--nx-bg)", borderBottom: "1px solid var(--nx-border)" },
92
+ className: "flex items-center justify-between px-4 py-3 shrink-0",
93
+ children: [
94
+ /* @__PURE__ */ f("div", { className: "flex items-center gap-2.5", children: [
95
+ /* @__PURE__ */ e("div", { className: "w-2 h-2 rounded-full bg-[var(--nx-text)]/40" }),
96
+ /* @__PURE__ */ e("span", { style: { color: d }, className: "text-sm font-medium", children: t })
97
+ ] }),
98
+ /* @__PURE__ */ f("div", { className: "flex items-center gap-1", children: [
99
+ /* @__PURE__ */ e(
100
+ "button",
101
+ {
102
+ onClick: p,
103
+ "aria-label": "Expand to full view",
104
+ className: "nexus-ctrl-btn p-2",
105
+ children: /* @__PURE__ */ e("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ e("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" }) })
106
+ }
107
+ ),
108
+ /* @__PURE__ */ e(
109
+ "button",
110
+ {
111
+ onClick: l,
112
+ "aria-label": "Close chat",
113
+ className: "nexus-ctrl-btn p-2",
114
+ children: /* @__PURE__ */ e("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ e("path", { d: "M18 6 6 18M6 6l12 12" }) })
115
+ }
116
+ )
117
+ ] })
118
+ ]
119
+ }
120
+ ),
121
+ r && /* @__PURE__ */ f("div", { className: "absolute top-4 right-4 flex items-center gap-2", style: { zIndex: 10 }, children: [
122
+ /* @__PURE__ */ e(
123
+ "button",
124
+ {
125
+ onClick: p,
126
+ "aria-label": "Exit full view",
127
+ className: "nexus-ctrl-btn p-2",
128
+ children: /* @__PURE__ */ e("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ e("path", { d: "M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" }) })
129
+ }
130
+ ),
131
+ /* @__PURE__ */ e(
132
+ "button",
133
+ {
134
+ onClick: l,
135
+ "aria-label": "Close chat",
136
+ className: "nexus-ctrl-btn p-2",
137
+ children: /* @__PURE__ */ e("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ e("path", { d: "M18 6 6 18M6 6l12 12" }) })
138
+ }
139
+ )
140
+ ] }),
141
+ /* @__PURE__ */ e(
142
+ "div",
143
+ {
144
+ className: "flex-1 overflow-y-auto",
145
+ style: { minHeight: 0, background: "var(--nx-bg)" },
146
+ children: /* @__PURE__ */ f(
147
+ "div",
148
+ {
149
+ className: "space-y-3 p-2",
150
+ style: r ? { maxWidth: 720, margin: "0 auto" } : void 0,
151
+ children: [
152
+ s.length === 0 && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e(
153
+ "div",
154
+ {
155
+ style: { background: "var(--nx-surface)", color: "var(--nx-text)" },
156
+ className: "max-w-[82%] px-3 py-2.5 rounded-2xl rounded-bl-sm text-sm leading-relaxed",
157
+ children: i
158
+ }
159
+ ) }),
160
+ s.map((o) => /* @__PURE__ */ e(U, { msg: o, primaryColor: d }, o.id)),
161
+ n && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e(_, { color: d }) }),
162
+ b && /* @__PURE__ */ e("div", { className: "text-center text-xs text-red-400/70 py-1", children: b }),
163
+ /* @__PURE__ */ e("div", { ref: B })
164
+ ]
165
+ }
166
+ )
167
+ }
168
+ ),
169
+ /* @__PURE__ */ e(
170
+ "div",
171
+ {
172
+ style: {
173
+ background: "var(--nx-bg)",
174
+ borderColor: r ? "none" : "var(--nx-border)"
175
+ },
176
+ className: `${!r && "border-t"} shrink-0 px-2.5`,
177
+ children: /* @__PURE__ */ f(
178
+ "div",
179
+ {
180
+ className: "relative w-full mx-auto flex items-center shadow rounded-xl",
181
+ style: { maxWidth: r ? 720 : "none", marginBottom: r ? 20 : 12, marginTop: r ? 0 : 10 },
182
+ children: [
183
+ /* @__PURE__ */ e(
184
+ "textarea",
185
+ {
186
+ ref: g,
187
+ rows: 1,
188
+ value: u,
189
+ onChange: (o) => {
190
+ c(o.target.value), o.target.style.height = "auto", o.target.style.height = `${Math.min(o.target.scrollHeight, 100)}px`;
191
+ },
192
+ onKeyDown: T,
193
+ placeholder: "Type a message…",
194
+ disabled: n,
195
+ style: {
196
+ resize: "none",
197
+ minHeight: 44,
198
+ maxHeight: 100,
199
+ overflowY: "auto",
200
+ paddingRight: 52
201
+ // room for send button
202
+ },
203
+ className: `nexus-input w-full border rounded-xl px-3 py-2.5 text-sm\r
204
+ transition-colors disabled:opacity-40`
205
+ }
206
+ ),
207
+ /* @__PURE__ */ e(
208
+ "button",
209
+ {
210
+ onClick: N,
211
+ disabled: !u.trim() || n,
212
+ "aria-label": "Send message",
213
+ style: {
214
+ position: "absolute",
215
+ right: 6,
216
+ bottom: 6,
217
+ background: u.trim() && !n ? d : "var(--nx-surface)"
218
+ },
219
+ className: `w-8 h-8 rounded-lg flex items-center justify-center\r
220
+ transition-colors disabled:opacity-40\r
221
+ disabled:cursor-not-allowed`,
222
+ children: /* @__PURE__ */ e("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: u.trim() && !n ? "white" : "var(--nx-text-muted)", viewBox: "0 0 16 16", children: /* @__PURE__ */ e("path", { fillRule: "evenodd", d: "M8 12a.5.5 0 0 0 .5-.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 .5.5" }) })
223
+ }
224
+ )
225
+ ]
226
+ }
227
+ )
228
+ }
229
+ )
230
+ ]
231
+ }
232
+ )
233
+ ] });
5
234
  }
6
235
  function W(t) {
7
- const s = sessionStorage.getItem(O(t));
236
+ return `nexus_widget_session_${t}`;
237
+ }
238
+ function K(t) {
239
+ const s = sessionStorage.getItem(W(t));
8
240
  if (s) return s;
9
- const r = crypto.randomUUID();
10
- return sessionStorage.setItem(O(t), r), r;
241
+ const n = crypto.randomUUID();
242
+ return sessionStorage.setItem(W(t), n), n;
11
243
  }
12
- async function* A(t, s) {
13
- const r = new TextDecoder();
14
- let d = "";
244
+ async function* Y(t, s) {
245
+ const n = new TextDecoder();
246
+ let b = "";
15
247
  try {
16
248
  for (; ; ) {
17
249
  if (s.aborted) return;
18
- const { done: o, value: f } = await t.read();
19
- if (o) return;
20
- d += r.decode(f, { stream: !0 });
21
- const l = d.split(`
250
+ const { done: d, value: i } = await t.read();
251
+ if (d) return;
252
+ b += n.decode(i, { stream: !0 });
253
+ const x = b.split(`
22
254
 
23
255
  `);
24
- d = l.pop() ?? "";
25
- for (const y of l)
26
- for (const b of y.split(`
256
+ b = x.pop() ?? "";
257
+ for (const l of x)
258
+ for (const r of l.split(`
27
259
  `)) {
28
- if (!b.startsWith("data: ")) continue;
29
- const c = b.slice(6).trim();
260
+ if (!r.startsWith("data: ")) continue;
261
+ const p = r.slice(6).trim();
30
262
  try {
31
- yield JSON.parse(c);
263
+ yield JSON.parse(p);
32
264
  } catch {
33
265
  }
34
266
  }
@@ -37,383 +269,375 @@ async function* A(t, s) {
37
269
  t.releaseLock();
38
270
  }
39
271
  }
40
- function J({ agentId: t, baseUrl: s = "http://localhost:8000/api", endUserId: r }) {
41
- const [d, o] = k([]), [f, l] = k(!1), [y, b] = k(!0), [c, u] = k(null), [N, x] = k(null), [g, S] = k(null), n = D(W(t)), w = D(null), j = I(async () => {
42
- var T;
43
- (T = w.current) == null || T.abort(), b(!0), u(null);
44
- const a = new AbortController();
45
- w.current = a;
272
+ function q({ agentId: t, baseUrl: s, agentCoreUrl: n, endUserId: b }) {
273
+ const [d, i] = m([]), [x, l] = m(!1), [r, p] = m(!0), [u, c] = m(null), [B, g] = m(null), [N, T] = m(null), o = S(K(t)), y = S(null), M = E(async () => {
274
+ y.current?.abort(), p(!0), c(null);
275
+ const v = new AbortController();
276
+ y.current = v;
46
277
  try {
47
- const h = await fetch(`${s}/widget/session`, {
278
+ const a = await fetch(`${s}/widget/session`, {
48
279
  method: "POST",
49
- signal: a.signal,
280
+ signal: v.signal,
50
281
  headers: { "Content-Type": "application/json" },
51
282
  body: JSON.stringify({
52
283
  agentId: t,
53
- sessionId: n.current
284
+ sessionId: o.current
54
285
  })
55
286
  });
56
- if (!h.ok)
57
- throw new Error(`HTTP ${h.status}`);
58
- const v = await h.json();
59
- S(v.token);
60
- const C = await fetch(`${s}/chat/history`, {
287
+ if (!a.ok)
288
+ throw new Error(`HTTP ${a.status}`);
289
+ const C = await a.json();
290
+ T(C.token);
291
+ const w = await fetch(`${s}/chat/history`, {
61
292
  method: "POST",
62
- signal: a.signal,
293
+ signal: v.signal,
63
294
  headers: {
64
295
  "Content-Type": "application/json",
65
- Authorization: `Bearer ${v.token}`
296
+ Authorization: `Bearer ${C.token}`
66
297
  },
67
298
  body: JSON.stringify({
68
299
  agentId: t,
69
- sessionId: n.current
300
+ sessionId: o.current
70
301
  })
71
302
  });
72
- if (!C.ok)
73
- throw new Error(`HTTP ${C.status}`);
74
- const i = await C.json();
75
- o(i.messages ?? []), x(i.conversationId ?? null);
76
- } catch (h) {
77
- (h == null ? void 0 : h.name) !== "AbortError" && u("Unable to initialize widget session.");
303
+ if (w.status == 404) {
304
+ i([]), g(null);
305
+ return;
306
+ }
307
+ if (!w.ok)
308
+ throw new Error(`HTTP ${w.status}`);
309
+ const h = await w.json();
310
+ i(h.messages ?? []), g(h.conversationId ?? null);
311
+ } catch (a) {
312
+ console.log(a), a.status != 404 && a?.name !== "AbortError" && c("Error Loading History");
78
313
  } finally {
79
- b(!1);
314
+ p(!1);
80
315
  }
81
316
  }, [t]);
82
- H(() => (j(), () => {
83
- var a;
84
- (a = w.current) == null || a.abort();
85
- }), [j]);
86
- const P = I(() => {
87
- var a;
88
- (a = w.current) == null || a.abort(), l(!1);
89
- }, []), _ = I(() => {
90
- var a;
91
- (a = w.current) == null || a.abort(), o([]), x(null), u(null), l(!1), n.current = crypto.randomUUID(), S(null), j();
92
- }, [j]), z = I(
93
- async (a) => {
94
- var C;
95
- if (!a.trim() || f || !g) return;
96
- (C = w.current) == null || C.abort();
97
- const T = new AbortController();
98
- w.current = T, u(null);
99
- const h = `u_${Date.now()}`, v = `a_${Date.now()}`;
100
- o((i) => [
101
- ...i,
102
- { id: h, role: "user", content: a.trim() }
317
+ j(() => (M(), () => {
318
+ y.current?.abort();
319
+ }), [M]);
320
+ const H = E(() => {
321
+ y.current?.abort(), l(!1);
322
+ }, []), R = E(() => {
323
+ y.current?.abort(), i([]), g(null), c(null), l(!1), o.current = crypto.randomUUID(), T(null), M();
324
+ }, [M]), $ = E(
325
+ async (v) => {
326
+ if (!v.trim() || x || !N) return;
327
+ y.current?.abort();
328
+ const a = new AbortController();
329
+ y.current = a, c(null);
330
+ const C = `u_${Date.now()}`, w = `a_${Date.now()}`;
331
+ i((h) => [
332
+ ...h,
333
+ { id: C, role: "user", content: v.trim() }
103
334
  ]), l(!0);
104
335
  try {
105
- const i = await fetch(`${s}/chat`, {
336
+ const h = await fetch(`${n}/chat`, {
106
337
  method: "POST",
107
- signal: T.signal,
338
+ signal: a.signal,
108
339
  headers: {
109
340
  "Content-Type": "application/json",
110
- Authorization: `Bearer ${g}`
341
+ Authorization: `Bearer ${N}`
111
342
  },
112
343
  body: JSON.stringify({
113
344
  agent_id: t,
114
- message: a.trim(),
115
- session_id: n.current,
116
- end_user_id: r
345
+ message: v.trim(),
346
+ session_id: o.current
117
347
  })
118
348
  });
119
- if (!i.ok || !i.body)
120
- throw new Error(`HTTP ${i.status}`);
121
- o((m) => [
122
- ...m,
123
- { id: v, role: "assistant", content: "" }
349
+ if (!h.ok || !h.body)
350
+ throw new Error(`HTTP ${h.status}`);
351
+ i((k) => [
352
+ ...k,
353
+ { id: w, role: "assistant", content: "" }
124
354
  ]);
125
- const M = i.body.getReader();
126
- for await (const m of A(M, T.signal))
127
- switch (m.type) {
355
+ const D = h.body.getReader();
356
+ for await (const k of Y(D, a.signal))
357
+ switch (k.type) {
128
358
  case "start":
129
- x(m.conversationId);
359
+ g(k.conversationId);
130
360
  break;
131
361
  case "token":
132
- o(
133
- (R) => R.map(
134
- ($) => $.id === v ? { ...$, content: $.content + m.content } : $
362
+ i(
363
+ (O) => O.map(
364
+ (I) => I.id === w ? { ...I, content: I.content + k.content } : I
135
365
  )
136
366
  );
137
367
  break;
138
368
  case "done":
139
369
  break;
140
370
  case "error":
141
- u(m.message), o(
142
- (R) => R.filter(($) => $.id !== v)
371
+ c(k.message), i(
372
+ (O) => O.filter((I) => I.id !== w)
143
373
  );
144
374
  break;
145
375
  }
146
- } catch (i) {
147
- if ((i == null ? void 0 : i.name) === "AbortError") return;
148
- u("Something went wrong. Please try again."), o(
149
- (M) => M.filter(
150
- (m) => m.id !== h && m.id !== v
376
+ } catch (h) {
377
+ if (h?.name === "AbortError") return;
378
+ c("Something went wrong. Please try again."), i(
379
+ (D) => D.filter(
380
+ (k) => k.id !== C && k.id !== w
151
381
  )
152
382
  );
153
383
  } finally {
154
384
  l(!1);
155
385
  }
156
386
  },
157
- [t, r, f, g]
387
+ [t, b, x, N]
158
388
  );
159
389
  return {
160
390
  messages: d,
161
- isLoading: f,
162
- historyLoading: y,
163
- error: c,
164
- conversationId: N,
165
- send: z,
166
- reset: _,
167
- cancel: P
391
+ isLoading: x,
392
+ historyLoading: r,
393
+ error: u,
394
+ conversationId: B,
395
+ send: $,
396
+ reset: R,
397
+ cancel: H
168
398
  };
169
399
  }
170
- function K({ color: t }) {
171
- return /* @__PURE__ */ e("div", { className: `flex items-end gap-1 px-3 py-2.5 rounded-2xl rounded-bl-sm w-fit\r
172
- bg-[rgba(255,255,255,0.06)]`, children: [0, 1, 2].map((s) => /* @__PURE__ */ e(
173
- "span",
174
- {
175
- style: {
176
- width: 6,
177
- height: 6,
178
- borderRadius: "50%",
179
- background: t,
180
- opacity: 0.6,
181
- animation: `nexusBounce 1.2s ease-in-out ${s * 0.2}s infinite`
182
- }
183
- },
184
- s
185
- )) });
400
+ const L = {
401
+ bg: "#0d0d1a",
402
+ surface: "rgba(255,255,255,0.06)",
403
+ border: "rgba(255,255,255,0.08)",
404
+ text: "rgba(255,255,255,0.82)",
405
+ textMuted: "rgba(255,255,255,0.25)",
406
+ inputBg: "rgba(255,255,255,0.05)",
407
+ inputBorder: "rgba(255,255,255,0.08)",
408
+ inputBorderFocus: "rgba(255,255,255,0.20)",
409
+ error: "rgba(248,113,113,0.75)"
410
+ }, A = {
411
+ bg: "#f8f9fb",
412
+ surface: "rgba(0,0,0,0.055)",
413
+ border: "rgba(0,0,0,0.09)",
414
+ text: "rgba(0,0,0,0.82)",
415
+ textMuted: "rgba(0,0,0,0.38)",
416
+ inputBg: "rgba(0,0,0,0.04)",
417
+ inputBorder: "rgba(0,0,0,0.10)",
418
+ inputBorderFocus: "rgba(0,0,0,0.22)",
419
+ error: "rgba(220,38,38,0.80)"
420
+ };
421
+ function z(t) {
422
+ return t === "system" ? typeof window < "u" && window.matchMedia("(prefers-color-scheme: dark)").matches ? L : A : t === "dark" ? L : A;
186
423
  }
187
- function L({
188
- msg: t,
189
- primaryColor: s
190
- }) {
191
- const r = t.role === "user";
192
- return /* @__PURE__ */ e("div", { className: `flex ${r ? "justify-end" : "justify-start"}`, children: /* @__PURE__ */ e(
193
- "div",
194
- {
195
- style: r ? { background: s } : void 0,
196
- className: `max-w-[82%] px-3 py-2.5 rounded-2xl text-sm leading-relaxed
197
- ${r ? "text-white rounded-br-sm" : "bg-[rgba(255,255,255,0.06)] text-[rgba(255,255,255,0.8)] rounded-bl-sm"}`,
198
- children: t.content
199
- }
200
- ) });
424
+ function G(t) {
425
+ return {
426
+ "--nx-bg": t.bg,
427
+ "--nx-surface": t.surface,
428
+ "--nx-border": t.border,
429
+ "--nx-text": t.text,
430
+ "--nx-text-muted": t.textMuted,
431
+ "--nx-input-bg": t.inputBg,
432
+ "--nx-input-border": t.inputBorder,
433
+ "--nx-input-border-focus": t.inputBorderFocus,
434
+ "--nx-error": t.error
435
+ };
201
436
  }
202
- function U({
203
- agentName: t,
204
- messages: s,
205
- isLoading: r,
206
- error: d,
207
- primaryColor: o,
208
- welcomeMessage: f,
209
- onSend: l,
210
- onReset: y,
211
- onClose: b
437
+ function Z({
438
+ agentId: t,
439
+ agentName: s,
440
+ baseUrl: n,
441
+ agentCoreUrl: b,
442
+ primaryColor: d = "#6366f1",
443
+ welcomeMessage: i = "Hi! How can I help you?",
444
+ position: x = "bottom-right",
445
+ theme: l = "dark"
212
446
  }) {
213
- const [c, u] = k(""), N = D(null), x = D(null);
214
- H(() => {
215
- var n;
216
- (n = N.current) == null || n.scrollIntoView({ behavior: "smooth" });
217
- }, [s, r]), H(() => {
218
- var n;
219
- (n = x.current) == null || n.focus();
220
- }, []);
221
- const g = () => {
222
- !c.trim() || r || (l(c), u(""));
223
- }, S = (n) => {
224
- n.key === "Enter" && !n.shiftKey && (n.preventDefault(), g());
447
+ const [r, p] = m(!1), [u, c] = m(!1), [B, g] = m(() => z(l)), N = S(null), { messages: T, isLoading: o, error: y, send: M, reset: H, cancel: R } = q({ agentId: t, baseUrl: n, agentCoreUrl: b }), $ = x !== "bottom-left", v = () => {
448
+ R(), p(!1), c(!1);
225
449
  };
226
- return /* @__PURE__ */ p(B, { children: [
450
+ return j(() => {
451
+ if (g(z(l)), l !== "system") return;
452
+ const a = window.matchMedia("(prefers-color-scheme: dark)"), C = () => g(z("system"));
453
+ return a.addEventListener("change", C), () => a.removeEventListener("change", C);
454
+ }, [l]), /* @__PURE__ */ f(P, { children: [
227
455
  /* @__PURE__ */ e("style", { children: `
228
- @keyframes nexusBounce {
229
- 0%, 80%, 100% { transform: translateY(0); }
230
- 40% { transform: translateY(-5px); }
231
- }
232
- ` }),
233
- /* @__PURE__ */ p(
456
+ .nexus-bubble-btn {
457
+ transition: transform 0.2s ease, box-shadow 0.15s ease, opacity 0.18s ease;
458
+ }
459
+ .nexus-bubble-btn:hover {
460
+ transform: scale(1.07) !important;
461
+ box-shadow: 0 6px 28px rgba(0, 0, 0, 0.35) !important;
462
+ }
463
+ .nexus-bubble-btn:active { transform: scale(0.96) !important; }
464
+ .nexus-input::-webkit-scrollbar {
465
+ display: none;
466
+ }
467
+ .nexus-input {
468
+ background: var(--nx-input-bg);
469
+ border-color: var(--nx-input-border);
470
+ color: var(--nx-text);
471
+ width: 100%;
472
+ scrollbar-width: none;
473
+ -ms-overflow-style: none;
474
+ }
475
+ .nexus-input::placeholder { color: var(--nx-text-muted); }
476
+ .nexus-input:focus { border-color: var(--nx-input-border-focus); outline: none; }
477
+
478
+ .nexus-ctrl-btn {
479
+ color: var(--nx-text-muted);
480
+ transition: color 0.15s ease, background 0.15s ease;
481
+ border-radius: 50%;
482
+ }
483
+ .nexus-ctrl-btn:hover {
484
+ color: var(--nx-text);
485
+ background: var(--nx-surface);
486
+ }
487
+ ` }),
488
+ /* @__PURE__ */ f(
234
489
  "div",
235
490
  {
236
- style: { fontFamily: "system-ui, -apple-system, sans-serif" },
237
- className: `flex flex-col overflow-hidden rounded-2xl shadow-2xl\r
238
- border border-[rgba(255,255,255,0.08)]`,
239
- role: "dialog",
240
- "aria-label": `${t} chat`,
491
+ ref: N,
492
+ style: {
493
+ position: "fixed",
494
+ inset: 0,
495
+ zIndex: 9999,
496
+ pointerEvents: "none",
497
+ fontFamily: "system-ui, -apple-system, sans-serif",
498
+ ...G(B)
499
+ },
241
500
  children: [
242
- /* @__PURE__ */ p(
501
+ /* @__PURE__ */ e(
243
502
  "div",
244
503
  {
245
- style: { background: o },
246
- className: "flex items-center justify-between px-4 py-3 shrink-0",
247
- children: [
248
- /* @__PURE__ */ p("div", { className: "flex items-center gap-2.5", children: [
249
- /* @__PURE__ */ e("div", { className: "w-2 h-2 rounded-full bg-white/40" }),
250
- /* @__PURE__ */ e("span", { className: "text-white text-sm font-medium", children: t })
251
- ] }),
252
- /* @__PURE__ */ p("div", { className: "flex items-center gap-1", children: [
253
- /* @__PURE__ */ e(
254
- "button",
255
- {
256
- onClick: y,
257
- "aria-label": "Start new conversation",
258
- className: `p-1.5 rounded-full text-white/60 hover:text-white\r
259
- hover:bg-white/15 transition-colors`,
260
- children: /* @__PURE__ */ p(
261
- "svg",
262
- {
263
- width: "14",
264
- height: "14",
265
- viewBox: "0 0 24 24",
266
- fill: "none",
267
- stroke: "currentColor",
268
- strokeWidth: "2",
269
- strokeLinecap: "round",
270
- children: [
271
- /* @__PURE__ */ e("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
272
- /* @__PURE__ */ e("path", { d: "M3 3v5h5" })
273
- ]
274
- }
275
- )
276
- }
277
- ),
278
- /* @__PURE__ */ e(
279
- "button",
280
- {
281
- onClick: b,
282
- "aria-label": "Close chat",
283
- className: `p-1.5 rounded-full text-white/60 hover:text-white\r
284
- hover:bg-white/15 transition-colors`,
285
- children: /* @__PURE__ */ e(
286
- "svg",
287
- {
288
- width: "14",
289
- height: "14",
290
- viewBox: "0 0 24 24",
291
- fill: "none",
292
- stroke: "currentColor",
293
- strokeWidth: "2",
294
- strokeLinecap: "round",
295
- children: /* @__PURE__ */ e("path", { d: "M18 6 6 18M6 6l12 12" })
296
- }
297
- )
298
- }
299
- )
300
- ] })
301
- ]
504
+ style: u ? {
505
+ position: "absolute",
506
+ inset: 0,
507
+ opacity: 1,
508
+ pointerEvents: "auto",
509
+ transition: "all 0.25s ease"
510
+ } : r ? {
511
+ position: "absolute",
512
+ [$ ? "right" : "left"]: 0,
513
+ top: 0,
514
+ bottom: 0,
515
+ width: 380,
516
+ opacity: 1,
517
+ pointerEvents: "auto",
518
+ transition: "all 0.28s cubic-bezier(0.34, 1.45, 0.64, 1)"
519
+ } : {
520
+ position: "absolute",
521
+ [$ ? "right" : "left"]: 20,
522
+ bottom: 88,
523
+ width: 420,
524
+ height: "calc(100vh - 108px)",
525
+ border: "1px solid var(--nx-border)",
526
+ opacity: 0,
527
+ transform: "scale(0.82) translateY(12px)",
528
+ transformOrigin: `bottom ${$ ? "right" : "left"}`,
529
+ pointerEvents: "none",
530
+ transition: "all 0.2s ease-in"
531
+ },
532
+ children: r && /* @__PURE__ */ e(
533
+ J,
534
+ {
535
+ agentName: s ?? "Assistant",
536
+ messages: T,
537
+ isLoading: o,
538
+ error: y ?? null,
539
+ primaryColor: d,
540
+ welcomeMessage: i,
541
+ onSend: M,
542
+ onReset: H,
543
+ onClose: v,
544
+ onToggleFullView: () => c((a) => !a),
545
+ isFullView: u
546
+ }
547
+ )
302
548
  }
303
549
  ),
304
- /* @__PURE__ */ p("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-3 bg-[#0d0d1a]", style: { minHeight: 0 }, children: [
305
- s.length === 0 && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e("div", { className: `max-w-[82%] px-3 py-2.5 rounded-2xl rounded-bl-sm\r
306
- bg-[rgba(255,255,255,0.06)] text-sm\r
307
- text-[rgba(255,255,255,0.8)] leading-relaxed`, children: f }) }),
308
- s.map((n) => /* @__PURE__ */ e(L, { msg: n, primaryColor: o }, n.id)),
309
- r && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e(K, { color: o }) }),
310
- d && /* @__PURE__ */ e("div", { className: "text-center text-xs text-red-400/70 py-1", children: d }),
311
- /* @__PURE__ */ e("div", { ref: N })
312
- ] }),
313
- /* @__PURE__ */ p("div", { className: `px-3 py-3 bg-[#0d0d1a] border-t border-[rgba(255,255,255,0.06)]\r
314
- flex items-end gap-2 shrink-0`, children: [
315
- /* @__PURE__ */ e(
316
- "textarea",
317
- {
318
- ref: x,
319
- rows: 1,
320
- value: c,
321
- onChange: (n) => u(n.target.value),
322
- onKeyDown: S,
323
- placeholder: "Type a message…",
324
- disabled: r,
325
- style: { resize: "none", maxHeight: 100, overflowY: "auto" },
326
- className: `flex-1 bg-[rgba(255,255,255,0.05)] border border-[rgba(255,255,255,0.08)]\r
327
- rounded-xl px-3 py-2.5 text-sm text-white/80 placeholder-white/25\r
328
- focus:outline-none focus:border-[rgba(255,255,255,0.18)]\r
329
- transition-colors disabled:opacity-40`
330
- }
331
- ),
332
- /* @__PURE__ */ e(
333
- "button",
334
- {
335
- onClick: g,
336
- disabled: !c.trim() || r,
337
- "aria-label": "Send message",
338
- style: { background: c.trim() && !r ? o : void 0 },
339
- className: `shrink-0 w-9 h-9 rounded-xl flex items-center justify-center\r
340
- bg-[rgba(255,255,255,0.08)] transition-colors\r
341
- disabled:opacity-40 disabled:cursor-not-allowed`,
342
- children: /* @__PURE__ */ p(
343
- "svg",
344
- {
345
- width: "14",
346
- height: "14",
347
- viewBox: "0 0 24 24",
348
- fill: "none",
349
- stroke: "white",
350
- strokeWidth: "2",
351
- strokeLinecap: "round",
352
- children: [
353
- /* @__PURE__ */ e("path", { d: "m22 2-7 20-4-9-9-4Z" }),
354
- /* @__PURE__ */ e("path", { d: "M22 2 11 13" })
355
- ]
356
- }
357
- )
358
- }
359
- )
360
- ] })
550
+ /* @__PURE__ */ e(
551
+ "button",
552
+ {
553
+ className: "nexus-bubble-btn",
554
+ onClick: () => p((a) => !a),
555
+ "aria-label": r ? "Close chat" : "Open chat",
556
+ "aria-expanded": r,
557
+ style: {
558
+ position: "absolute",
559
+ [$ ? "right" : "left"]: 20,
560
+ bottom: 20,
561
+ width: 56,
562
+ height: 56,
563
+ borderRadius: "50%",
564
+ background: d,
565
+ border: "none",
566
+ cursor: "pointer",
567
+ display: "flex",
568
+ alignItems: "center",
569
+ justifyContent: "center",
570
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.28)",
571
+ pointerEvents: "auto",
572
+ opacity: r ? 0 : 1,
573
+ transform: r ? "scale(0.5)" : "scale(1)"
574
+ },
575
+ children: /* @__PURE__ */ e("span", { style: { position: "relative", width: 40, height: 40 }, children: /* @__PURE__ */ e(
576
+ "span",
577
+ {
578
+ style: {
579
+ position: "absolute",
580
+ inset: 0,
581
+ display: "flex",
582
+ alignItems: "center",
583
+ justifyContent: "center",
584
+ transition: "opacity 0.2s ease, transform 0.2s ease",
585
+ opacity: r ? 0 : 1,
586
+ transform: r ? "scale(0.65) rotate(-15deg)" : "scale(1) rotate(0deg)"
587
+ },
588
+ children: /* @__PURE__ */ f("svg", { width: "512", height: "512", viewBox: "0 0 512 512", xmlns: "http://www.w3.org/2000/svg", children: [
589
+ /* @__PURE__ */ e("circle", { cx: "256", cy: "256", r: "220", fill: "#6366f1" }),
590
+ /* @__PURE__ */ e("rect", { x: "156", y: "150", width: "200", height: "170", rx: "36", fill: "white" }),
591
+ /* @__PURE__ */ e(
592
+ "line",
593
+ {
594
+ x1: "256",
595
+ y1: "120",
596
+ x2: "256",
597
+ y2: "150",
598
+ stroke: "white",
599
+ "stroke-width": "10",
600
+ "stroke-linecap": "round"
601
+ }
602
+ ),
603
+ /* @__PURE__ */ e("circle", { cx: "256", cy: "105", r: "14", fill: "white" }),
604
+ /* @__PURE__ */ e("circle", { cx: "210", cy: "220", r: "18", fill: "#6366f1" }),
605
+ /* @__PURE__ */ e("circle", { cx: "302", cy: "220", r: "18", fill: "#6366f1" }),
606
+ /* @__PURE__ */ e("rect", { x: "206", y: "265", width: "100", height: "16", rx: "8", fill: "#6366f1" }),
607
+ /* @__PURE__ */ e("rect", { x: "132", y: "205", width: "24", height: "60", rx: "12", fill: "white" }),
608
+ /* @__PURE__ */ e("rect", { x: "356", y: "205", width: "24", height: "60", rx: "12", fill: "white" }),
609
+ /* @__PURE__ */ e(
610
+ "path",
611
+ {
612
+ d: `M180 340
613
+ h152
614
+ a24 24 0 0 1 24 24
615
+ v20
616
+ a24 24 0 0 1 -24 24
617
+ h-80
618
+ l-28 24
619
+ 8-24
620
+ h-52
621
+ a24 24 0 0 1 -24 -24
622
+ v-20
623
+ a24 24 0 0 1 24 -24z`,
624
+ fill: "white"
625
+ }
626
+ ),
627
+ /* @__PURE__ */ e("circle", { cx: "220", cy: "374", r: "8", fill: "#6366f1" }),
628
+ /* @__PURE__ */ e("circle", { cx: "256", cy: "374", r: "8", fill: "#6366f1" }),
629
+ /* @__PURE__ */ e("circle", { cx: "292", cy: "374", r: "8", fill: "#6366f1" })
630
+ ] })
631
+ }
632
+ ) })
633
+ }
634
+ )
361
635
  ]
362
636
  }
363
637
  )
364
638
  ] });
365
639
  }
366
- const F = E(
367
- ({
368
- agentId: t,
369
- baseUrl: s,
370
- primaryColor: r = "#6366f1",
371
- position: d = "bottom-right",
372
- welcomeMessage: o = "Hi! How can I help you today?",
373
- agentName: f = "Assistant",
374
- endUserId: l
375
- }, y) => {
376
- const {
377
- messages: b,
378
- isLoading: c,
379
- historyLoading: u,
380
- error: N,
381
- conversationId: x,
382
- send: g,
383
- reset: S,
384
- cancel: n
385
- } = J({ agentId: t, baseUrl: s, endUserId: l });
386
- return /* @__PURE__ */ e(
387
- "div",
388
- {
389
- ref: y,
390
- style: {
391
- position: "fixed",
392
- [d === "bottom-left" ? "left" : "right"]: "20px",
393
- bottom: "20px",
394
- zIndex: 9999,
395
- fontFamily: "system-ui, -apple-system, sans-serif"
396
- },
397
- children: /* @__PURE__ */ e(
398
- U,
399
- {
400
- agentName: f,
401
- messages: b,
402
- isLoading: c,
403
- error: N,
404
- primaryColor: r,
405
- welcomeMessage: o,
406
- onSend: g,
407
- onReset: S,
408
- onClose: n
409
- }
410
- )
411
- }
412
- );
413
- }
414
- );
415
- F.displayName = "NexusWidget";
416
640
  export {
417
- F as NexusWidget,
418
- J as useChat
641
+ Z as NexusWidget,
642
+ q as useChat
419
643
  };