@nameless26/widget 0.1.1 → 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 m, Fragment as E, jsx as e } from "react/jsx-runtime";
2
- import { useState as k, useRef as D, useCallback as I, useEffect as H, forwardRef as z } from "react";
3
- function O(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
+ ] });
234
+ }
235
+ function W(t) {
4
236
  return `nexus_widget_session_${t}`;
5
237
  }
6
- function A(t) {
7
- const n = sessionStorage.getItem(O(t));
8
- if (n) return n;
9
- const r = crypto.randomUUID();
10
- return sessionStorage.setItem(O(t), r), r;
238
+ function K(t) {
239
+ const s = sessionStorage.getItem(W(t));
240
+ if (s) return s;
241
+ const n = crypto.randomUUID();
242
+ return sessionStorage.setItem(W(t), n), n;
11
243
  }
12
- async function* W(t, n) {
13
- const r = new TextDecoder();
14
- let i = "";
244
+ async function* Y(t, s) {
245
+ const n = new TextDecoder();
246
+ let b = "";
15
247
  try {
16
248
  for (; ; ) {
17
- if (n.aborted) return;
18
- const { done: c, value: s } = await t.read();
19
- if (c) return;
20
- i += r.decode(s, { stream: !0 });
21
- const d = i.split(`
249
+ if (s.aborted) return;
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
- i = d.pop() ?? "";
25
- for (const u of d)
26
- for (const g of u.split(`
256
+ b = x.pop() ?? "";
257
+ for (const l of x)
258
+ for (const r of l.split(`
27
259
  `)) {
28
- if (!g.startsWith("data: ")) continue;
29
- const a = g.slice(6).trim();
260
+ if (!r.startsWith("data: ")) continue;
261
+ const p = r.slice(6).trim();
30
262
  try {
31
- yield JSON.parse(a);
263
+ yield JSON.parse(p);
32
264
  } catch {
33
265
  }
34
266
  }
@@ -37,377 +269,375 @@ async function* W(t, n) {
37
269
  t.releaseLock();
38
270
  }
39
271
  }
40
- function L({ agentId: t, baseUrl: n, agentCoreUrl: r, endUserId: i }) {
41
- const [c, s] = k([]), [d, u] = k(!1), [g, a] = k(!0), [N, h] = k(null), [S, y] = k(null), [x, o] = k(null), T = D(A(t)), w = D(null), j = I(async () => {
42
- w.current?.abort(), a(!0), h(null);
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);
43
275
  const v = new AbortController();
44
- w.current = v;
276
+ y.current = v;
45
277
  try {
46
- const f = await fetch(`${n}/widget/session`, {
278
+ const a = await fetch(`${s}/widget/session`, {
47
279
  method: "POST",
48
280
  signal: v.signal,
49
281
  headers: { "Content-Type": "application/json" },
50
282
  body: JSON.stringify({
51
283
  agentId: t,
52
- sessionId: T.current
284
+ sessionId: o.current
53
285
  })
54
286
  });
55
- if (!f.ok)
56
- throw new Error(`HTTP ${f.status}`);
57
- const $ = await f.json();
58
- o($.token);
59
- const p = await fetch(`${n}/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`, {
60
292
  method: "POST",
61
293
  signal: v.signal,
62
294
  headers: {
63
295
  "Content-Type": "application/json",
64
- Authorization: `Bearer ${$.token}`
296
+ Authorization: `Bearer ${C.token}`
65
297
  },
66
298
  body: JSON.stringify({
67
299
  agentId: t,
68
- sessionId: T.current
300
+ sessionId: o.current
69
301
  })
70
302
  });
71
- if (!p.ok)
72
- throw new Error(`HTTP ${p.status}`);
73
- const l = await p.json();
74
- s(l.messages ?? []), y(l.conversationId ?? null);
75
- } catch (f) {
76
- f?.name !== "AbortError" && h("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");
77
313
  } finally {
78
- a(!1);
314
+ p(!1);
79
315
  }
80
316
  }, [t]);
81
- H(() => (j(), () => {
82
- w.current?.abort();
83
- }), [j]);
84
- const P = I(() => {
85
- w.current?.abort(), u(!1);
86
- }, []), _ = I(() => {
87
- w.current?.abort(), s([]), y(null), h(null), u(!1), T.current = crypto.randomUUID(), o(null), j();
88
- }, [j]), B = I(
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(
89
325
  async (v) => {
90
- if (!v.trim() || d || !x) return;
91
- w.current?.abort();
92
- const f = new AbortController();
93
- w.current = f, h(null);
94
- const $ = `u_${Date.now()}`, p = `a_${Date.now()}`;
95
- s((l) => [
96
- ...l,
97
- { id: $, role: "user", content: v.trim() }
98
- ]), u(!0);
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() }
334
+ ]), l(!0);
99
335
  try {
100
- const l = await fetch(`${r}/chat`, {
336
+ const h = await fetch(`${n}/chat`, {
101
337
  method: "POST",
102
- signal: f.signal,
338
+ signal: a.signal,
103
339
  headers: {
104
340
  "Content-Type": "application/json",
105
- Authorization: `Bearer ${x}`
341
+ Authorization: `Bearer ${N}`
106
342
  },
107
343
  body: JSON.stringify({
108
344
  agent_id: t,
109
345
  message: v.trim(),
110
- session_id: T.current,
111
- end_user_id: i
346
+ session_id: o.current
112
347
  })
113
348
  });
114
- if (!l.ok || !l.body)
115
- throw new Error(`HTTP ${l.status}`);
116
- s((b) => [
117
- ...b,
118
- { id: p, 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: "" }
119
354
  ]);
120
- const R = l.body.getReader();
121
- for await (const b of W(R, f.signal))
122
- switch (b.type) {
355
+ const D = h.body.getReader();
356
+ for await (const k of Y(D, a.signal))
357
+ switch (k.type) {
123
358
  case "start":
124
- y(b.conversationId);
359
+ g(k.conversationId);
125
360
  break;
126
361
  case "token":
127
- s(
128
- (M) => M.map(
129
- (C) => C.id === p ? { ...C, content: C.content + b.content } : C
362
+ i(
363
+ (O) => O.map(
364
+ (I) => I.id === w ? { ...I, content: I.content + k.content } : I
130
365
  )
131
366
  );
132
367
  break;
133
368
  case "done":
134
369
  break;
135
370
  case "error":
136
- h(b.message), s(
137
- (M) => M.filter((C) => C.id !== p)
371
+ c(k.message), i(
372
+ (O) => O.filter((I) => I.id !== w)
138
373
  );
139
374
  break;
140
375
  }
141
- } catch (l) {
142
- if (l?.name === "AbortError") return;
143
- h("Something went wrong. Please try again."), s(
144
- (R) => R.filter(
145
- (b) => b.id !== $ && b.id !== p
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
146
381
  )
147
382
  );
148
383
  } finally {
149
- u(!1);
384
+ l(!1);
150
385
  }
151
386
  },
152
- [t, i, d, x]
387
+ [t, b, x, N]
153
388
  );
154
389
  return {
155
- messages: c,
156
- isLoading: d,
157
- historyLoading: g,
158
- error: N,
159
- conversationId: S,
160
- send: B,
161
- reset: _,
162
- cancel: P
390
+ messages: d,
391
+ isLoading: x,
392
+ historyLoading: r,
393
+ error: u,
394
+ conversationId: B,
395
+ send: $,
396
+ reset: R,
397
+ cancel: H
163
398
  };
164
399
  }
165
- function U({ color: t }) {
166
- return /* @__PURE__ */ e("div", { className: `flex items-end gap-1 px-3 py-2.5 rounded-2xl rounded-bl-sm w-fit\r
167
- bg-[rgba(255,255,255,0.06)]`, children: [0, 1, 2].map((n) => /* @__PURE__ */ e(
168
- "span",
169
- {
170
- style: {
171
- width: 6,
172
- height: 6,
173
- borderRadius: "50%",
174
- background: t,
175
- opacity: 0.6,
176
- animation: `nexusBounce 1.2s ease-in-out ${n * 0.2}s infinite`
177
- }
178
- },
179
- n
180
- )) });
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;
181
423
  }
182
- function J({
183
- msg: t,
184
- primaryColor: n
185
- }) {
186
- const r = t.role === "user";
187
- return /* @__PURE__ */ e("div", { className: `flex ${r ? "justify-end" : "justify-start"}`, children: /* @__PURE__ */ e(
188
- "div",
189
- {
190
- style: r ? { background: n } : void 0,
191
- className: `max-w-[82%] px-3 py-2.5 rounded-2xl text-sm leading-relaxed
192
- ${r ? "text-white rounded-br-sm" : "bg-[rgba(255,255,255,0.06)] text-[rgba(255,255,255,0.8)] rounded-bl-sm"}`,
193
- children: t.content
194
- }
195
- ) });
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
+ };
196
436
  }
197
- function K({
198
- agentName: t,
199
- messages: n,
200
- isLoading: r,
201
- error: i,
202
- primaryColor: c,
203
- welcomeMessage: s,
204
- onSend: d,
205
- onReset: u,
206
- onClose: g
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"
207
446
  }) {
208
- const [a, N] = k(""), h = D(null), S = D(null);
209
- H(() => {
210
- h.current?.scrollIntoView({ behavior: "smooth" });
211
- }, [n, r]), H(() => {
212
- S.current?.focus();
213
- }, []);
214
- const y = () => {
215
- !a.trim() || r || (d(a), N(""));
216
- }, x = (o) => {
217
- o.key === "Enter" && !o.shiftKey && (o.preventDefault(), y());
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);
218
449
  };
219
- return /* @__PURE__ */ m(E, { 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: [
220
455
  /* @__PURE__ */ e("style", { children: `
221
- @keyframes nexusBounce {
222
- 0%, 80%, 100% { transform: translateY(0); }
223
- 40% { transform: translateY(-5px); }
224
- }
225
- ` }),
226
- /* @__PURE__ */ m(
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(
227
489
  "div",
228
490
  {
229
- style: { fontFamily: "system-ui, -apple-system, sans-serif" },
230
- className: `flex flex-col overflow-hidden rounded-2xl shadow-2xl\r
231
- border border-[rgba(255,255,255,0.08)]`,
232
- role: "dialog",
233
- "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
+ },
234
500
  children: [
235
- /* @__PURE__ */ m(
501
+ /* @__PURE__ */ e(
236
502
  "div",
237
503
  {
238
- style: { background: c },
239
- className: "flex items-center justify-between px-4 py-3 shrink-0",
240
- children: [
241
- /* @__PURE__ */ m("div", { className: "flex items-center gap-2.5", children: [
242
- /* @__PURE__ */ e("div", { className: "w-2 h-2 rounded-full bg-white/40" }),
243
- /* @__PURE__ */ e("span", { className: "text-white text-sm font-medium", children: t })
244
- ] }),
245
- /* @__PURE__ */ m("div", { className: "flex items-center gap-1", children: [
246
- /* @__PURE__ */ e(
247
- "button",
248
- {
249
- onClick: u,
250
- "aria-label": "Start new conversation",
251
- className: `p-1.5 rounded-full text-white/60 hover:text-white\r
252
- hover:bg-white/15 transition-colors`,
253
- children: /* @__PURE__ */ m(
254
- "svg",
255
- {
256
- width: "14",
257
- height: "14",
258
- viewBox: "0 0 24 24",
259
- fill: "none",
260
- stroke: "currentColor",
261
- strokeWidth: "2",
262
- strokeLinecap: "round",
263
- children: [
264
- /* @__PURE__ */ e("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
265
- /* @__PURE__ */ e("path", { d: "M3 3v5h5" })
266
- ]
267
- }
268
- )
269
- }
270
- ),
271
- /* @__PURE__ */ e(
272
- "button",
273
- {
274
- onClick: g,
275
- "aria-label": "Close chat",
276
- className: `p-1.5 rounded-full text-white/60 hover:text-white\r
277
- hover:bg-white/15 transition-colors`,
278
- children: /* @__PURE__ */ e(
279
- "svg",
280
- {
281
- width: "14",
282
- height: "14",
283
- viewBox: "0 0 24 24",
284
- fill: "none",
285
- stroke: "currentColor",
286
- strokeWidth: "2",
287
- strokeLinecap: "round",
288
- children: /* @__PURE__ */ e("path", { d: "M18 6 6 18M6 6l12 12" })
289
- }
290
- )
291
- }
292
- )
293
- ] })
294
- ]
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
+ )
295
548
  }
296
549
  ),
297
- /* @__PURE__ */ m("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-3 bg-[#0d0d1a]", style: { minHeight: 0 }, children: [
298
- n.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
299
- bg-[rgba(255,255,255,0.06)] text-sm\r
300
- text-[rgba(255,255,255,0.8)] leading-relaxed`, children: s }) }),
301
- n.map((o) => /* @__PURE__ */ e(J, { msg: o, primaryColor: c }, o.id)),
302
- r && /* @__PURE__ */ e("div", { className: "flex justify-start", children: /* @__PURE__ */ e(U, { color: c }) }),
303
- i && /* @__PURE__ */ e("div", { className: "text-center text-xs text-red-400/70 py-1", children: i }),
304
- /* @__PURE__ */ e("div", { ref: h })
305
- ] }),
306
- /* @__PURE__ */ m("div", { className: `px-3 py-3 bg-[#0d0d1a] border-t border-[rgba(255,255,255,0.06)]\r
307
- flex items-end gap-2 shrink-0`, children: [
308
- /* @__PURE__ */ e(
309
- "textarea",
310
- {
311
- ref: S,
312
- rows: 1,
313
- value: a,
314
- onChange: (o) => N(o.target.value),
315
- onKeyDown: x,
316
- placeholder: "Type a message…",
317
- disabled: r,
318
- style: { resize: "none", maxHeight: 100, overflowY: "auto" },
319
- className: `flex-1 bg-[rgba(255,255,255,0.05)] border border-[rgba(255,255,255,0.08)]\r
320
- rounded-xl px-3 py-2.5 text-sm text-white/80 placeholder-white/25\r
321
- focus:outline-none focus:border-[rgba(255,255,255,0.18)]\r
322
- transition-colors disabled:opacity-40`
323
- }
324
- ),
325
- /* @__PURE__ */ e(
326
- "button",
327
- {
328
- onClick: y,
329
- disabled: !a.trim() || r,
330
- "aria-label": "Send message",
331
- style: { background: a.trim() && !r ? c : void 0 },
332
- className: `shrink-0 w-9 h-9 rounded-xl flex items-center justify-center\r
333
- bg-[rgba(255,255,255,0.08)] transition-colors\r
334
- disabled:opacity-40 disabled:cursor-not-allowed`,
335
- children: /* @__PURE__ */ m(
336
- "svg",
337
- {
338
- width: "14",
339
- height: "14",
340
- viewBox: "0 0 24 24",
341
- fill: "none",
342
- stroke: "white",
343
- strokeWidth: "2",
344
- strokeLinecap: "round",
345
- children: [
346
- /* @__PURE__ */ e("path", { d: "m22 2-7 20-4-9-9-4Z" }),
347
- /* @__PURE__ */ e("path", { d: "M22 2 11 13" })
348
- ]
349
- }
350
- )
351
- }
352
- )
353
- ] })
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
+ )
354
635
  ]
355
636
  }
356
637
  )
357
638
  ] });
358
639
  }
359
- const F = z(
360
- ({
361
- agentId: t,
362
- baseUrl: n,
363
- agentCoreUrl: r,
364
- primaryColor: i = "#6366f1",
365
- position: c = "bottom-right",
366
- welcomeMessage: s = "Hi! How can I help you today?",
367
- agentName: d = "Assistant",
368
- endUserId: u
369
- }, g) => {
370
- const {
371
- messages: a,
372
- isLoading: N,
373
- historyLoading: h,
374
- error: S,
375
- conversationId: y,
376
- send: x,
377
- reset: o,
378
- cancel: T
379
- } = L({ agentId: t, baseUrl: n, agentCoreUrl: r, endUserId: u });
380
- return /* @__PURE__ */ e(
381
- "div",
382
- {
383
- ref: g,
384
- style: {
385
- position: "fixed",
386
- [c === "bottom-left" ? "left" : "right"]: "20px",
387
- bottom: "20px",
388
- zIndex: 9999,
389
- fontFamily: "system-ui, -apple-system, sans-serif"
390
- },
391
- children: /* @__PURE__ */ e(
392
- K,
393
- {
394
- agentName: d,
395
- messages: a,
396
- isLoading: N,
397
- error: S,
398
- primaryColor: i,
399
- welcomeMessage: s,
400
- onSend: x,
401
- onReset: o,
402
- onClose: T
403
- }
404
- )
405
- }
406
- );
407
- }
408
- );
409
- F.displayName = "NexusWidget";
410
640
  export {
411
- F as NexusWidget,
412
- L as useChat
641
+ Z as NexusWidget,
642
+ q as useChat
413
643
  };