@nonoun/native-chat 0.4.0 → 0.5.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/{chat-input-structured-element-C80qP8yg.js → chat-input-structured-element-uXGIe-HI.js} +172 -42
- package/dist/chat-panel-element.d.ts +21 -0
- package/dist/chat-panel-element.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/message/chat-message-element.d.ts +3 -0
- package/dist/message/chat-message-element.d.ts.map +1 -1
- package/dist/message/chat-messages-element.d.ts +1 -0
- package/dist/message/chat-messages-element.d.ts.map +1 -1
- package/dist/native-chat.css +67 -4
- package/dist/native-chat.js +1 -1
- package/dist/register.js +1 -1
- package/package.json +1 -1
package/dist/{chat-input-structured-element-C80qP8yg.js → chat-input-structured-element-uXGIe-HI.js}
RENAMED
|
@@ -132,13 +132,20 @@ var i = class extends e {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
}, a = class extends e {
|
|
135
|
-
static observedAttributes = [
|
|
135
|
+
static observedAttributes = [
|
|
136
|
+
"show-stop",
|
|
137
|
+
"show-restart",
|
|
138
|
+
"auto-focus-policy",
|
|
139
|
+
"open"
|
|
140
|
+
];
|
|
136
141
|
#e = r(!1);
|
|
137
142
|
#t = r(!1);
|
|
138
|
-
#n =
|
|
139
|
-
#r =
|
|
143
|
+
#n = r("open-request");
|
|
144
|
+
#r = r(!1);
|
|
140
145
|
#i = null;
|
|
141
146
|
#a = null;
|
|
147
|
+
#o = null;
|
|
148
|
+
#s = null;
|
|
142
149
|
attributeChangedCallback(e, t, n) {
|
|
143
150
|
if (t !== n) {
|
|
144
151
|
switch (e) {
|
|
@@ -148,6 +155,14 @@ var i = class extends e {
|
|
|
148
155
|
case "show-restart":
|
|
149
156
|
this.#t.value = n !== null;
|
|
150
157
|
break;
|
|
158
|
+
case "auto-focus-policy":
|
|
159
|
+
this.#n.value = n ?? "open-request";
|
|
160
|
+
break;
|
|
161
|
+
case "open": {
|
|
162
|
+
let e = this.#r.value;
|
|
163
|
+
this.#r.value = n !== null, !e && n !== null ? this.#f(void 0, !1) : e && n === null && this.#p(void 0);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
151
166
|
}
|
|
152
167
|
super.attributeChangedCallback(e, t, n);
|
|
153
168
|
}
|
|
@@ -164,8 +179,30 @@ var i = class extends e {
|
|
|
164
179
|
set showRestart(e) {
|
|
165
180
|
this.#t.value = e, this.toggleAttribute("show-restart", e);
|
|
166
181
|
}
|
|
182
|
+
get autoFocusPolicy() {
|
|
183
|
+
return this.#n.value;
|
|
184
|
+
}
|
|
185
|
+
set autoFocusPolicy(e) {
|
|
186
|
+
this.#n.value = e, this.setAttribute("auto-focus-policy", e);
|
|
187
|
+
}
|
|
188
|
+
/** Open the panel. Optionally focus the composer. */
|
|
189
|
+
open(e) {
|
|
190
|
+
let t = this.#r.value;
|
|
191
|
+
this.#r.value = !0, this.toggleAttribute("open", !0);
|
|
192
|
+
let n = this.#n.value, r = e?.focusComposer ?? !1, i = n !== "never" && (n === "open-request" ? r : !1);
|
|
193
|
+
t || this.#f(e?.reason, i), i && this.focusComposer({ cursor: "end" }, "api");
|
|
194
|
+
}
|
|
195
|
+
/** Close the panel. */
|
|
196
|
+
close(e) {
|
|
197
|
+
let t = this.#r.value;
|
|
198
|
+
this.#r.value = !1, this.removeAttribute("open"), t && this.#p(e);
|
|
199
|
+
}
|
|
200
|
+
/** Focus the composer input. */
|
|
201
|
+
focusComposer(e, t = "api") {
|
|
202
|
+
this.#l(e ?? {}, t, 0);
|
|
203
|
+
}
|
|
167
204
|
setup() {
|
|
168
|
-
super.setup();
|
|
205
|
+
super.setup(), this.hasAttribute("open") && (this.#r.value = !0);
|
|
169
206
|
let e = document.createElement("n-header");
|
|
170
207
|
e.setAttribute("dividers", "");
|
|
171
208
|
let t = document.createElement("n-icon");
|
|
@@ -173,11 +210,11 @@ var i = class extends e {
|
|
|
173
210
|
let n = document.createElement("span");
|
|
174
211
|
n.setAttribute("slot", "label"), n.textContent = "Assistant", e.appendChild(n);
|
|
175
212
|
let r = document.createElement("span");
|
|
176
|
-
r.setAttribute("slot", "trailing"), r.style.display = "inline-flex", r.style.alignItems = "center", r.style.gap = "calc(var(--n-space) * 2)", e.appendChild(r), this.#
|
|
213
|
+
r.setAttribute("slot", "trailing"), r.style.display = "inline-flex", r.style.alignItems = "center", r.style.gap = "calc(var(--n-space) * 2)", e.appendChild(r), this.#s = r;
|
|
177
214
|
let i = document.createElement("n-body"), a = document.createElement("n-chat-content");
|
|
178
215
|
i.appendChild(a);
|
|
179
216
|
let o = document.createElement("n-footer");
|
|
180
|
-
o.setAttribute("dividers", ""), this.#
|
|
217
|
+
o.setAttribute("dividers", ""), this.#i = o;
|
|
181
218
|
let s = document.createElement("n-chat-input");
|
|
182
219
|
s.setAttribute("variant", "plain");
|
|
183
220
|
let c = document.createElement("n-textarea");
|
|
@@ -189,41 +226,117 @@ var i = class extends e {
|
|
|
189
226
|
let f = document.createElement("n-button");
|
|
190
227
|
f.setAttribute("variant", "primary"), f.setAttribute("intent", "accent"), f.setAttribute("radius", "round"), f.setAttribute("inline", ""), f.setAttribute("disabled", ""), f.classList.add("submit-btn"), f.innerHTML = "<n-icon name=\"arrow-up\"></n-icon>", l.appendChild(f), s.appendChild(l), o.appendChild(s), this.append(e, i, o), this.addEffect(() => {
|
|
191
228
|
let e = this.#e.value;
|
|
192
|
-
if (e && !this.#
|
|
229
|
+
if (e && !this.#a) {
|
|
193
230
|
let e = document.createElement("n-button");
|
|
194
|
-
e.setAttribute("variant", "ghost"), e.setAttribute("inline", ""), e.setAttribute("aria-label", "Stop"), e.innerHTML = "<n-icon name=\"stop\"></n-icon>", e.addEventListener("native:press", this.#
|
|
195
|
-
} else !e && this.#
|
|
231
|
+
e.setAttribute("variant", "ghost"), e.setAttribute("inline", ""), e.setAttribute("aria-label", "Stop"), e.innerHTML = "<n-icon name=\"stop\"></n-icon>", e.addEventListener("native:press", this.#h), this.#a = e, this.#s?.prepend(e);
|
|
232
|
+
} else !e && this.#a && (this.#a.removeEventListener("native:press", this.#h), this.#a.remove(), this.#a = null);
|
|
196
233
|
}), this.addEffect(() => {
|
|
197
234
|
let e = this.#t.value;
|
|
198
|
-
if (e && !this.#
|
|
235
|
+
if (e && !this.#o) {
|
|
199
236
|
let e = document.createElement("n-button");
|
|
200
|
-
e.setAttribute("variant", "ghost"), e.setAttribute("inline", ""), e.setAttribute("aria-label", "Restart"), e.innerHTML = "<n-icon name=\"arrow-counter-clockwise\"></n-icon>", e.addEventListener("native:press", this.#
|
|
201
|
-
let t = this.#
|
|
202
|
-
this.#
|
|
203
|
-
} else !e && this.#
|
|
237
|
+
e.setAttribute("variant", "ghost"), e.setAttribute("inline", ""), e.setAttribute("aria-label", "Restart"), e.innerHTML = "<n-icon name=\"arrow-counter-clockwise\"></n-icon>", e.addEventListener("native:press", this.#g), this.#o = e;
|
|
238
|
+
let t = this.#a?.nextSibling ?? this.#s?.firstChild ?? null;
|
|
239
|
+
this.#s?.insertBefore(e, t);
|
|
240
|
+
} else !e && this.#o && (this.#o.removeEventListener("native:press", this.#g), this.#o.remove(), this.#o = null);
|
|
204
241
|
}), this.deferChildren(() => {
|
|
205
|
-
this.#
|
|
242
|
+
this.#c();
|
|
243
|
+
}), this.#n.value === "ready" && queueMicrotask(() => {
|
|
244
|
+
this.isConnected && this.focusComposer({ cursor: "end" }, "policy");
|
|
206
245
|
});
|
|
207
246
|
}
|
|
208
247
|
teardown() {
|
|
209
|
-
this.#
|
|
248
|
+
this.#a && this.#a.removeEventListener("native:press", this.#h), this.#o && this.#o.removeEventListener("native:press", this.#g), this.#i = null, this.#a = null, this.#o = null, this.#s = null, this.innerHTML = "", super.teardown();
|
|
210
249
|
}
|
|
211
|
-
#
|
|
250
|
+
#c() {
|
|
212
251
|
let e = this.querySelector(":scope > [slot=\"header-trailing\"]");
|
|
213
|
-
e && this.#
|
|
252
|
+
e && this.#s && this.#s.appendChild(e);
|
|
214
253
|
let t = this.querySelector(":scope > [slot=\"footer-leading\"]");
|
|
215
|
-
if (t && this.#
|
|
216
|
-
let e = this.#
|
|
217
|
-
this.#
|
|
254
|
+
if (t && this.#i) {
|
|
255
|
+
let e = this.#i.querySelector(":scope > n-chat-input");
|
|
256
|
+
this.#i.insertBefore(t, e);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
#l(e, t, n) {
|
|
260
|
+
let r = this.#u();
|
|
261
|
+
if (!r) {
|
|
262
|
+
if (n < 2) {
|
|
263
|
+
queueMicrotask(() => this.#l(e, t, n + 1));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.#m("composer-unavailable", 3);
|
|
267
|
+
return;
|
|
218
268
|
}
|
|
269
|
+
if (r.disabled) {
|
|
270
|
+
if (n < 2) {
|
|
271
|
+
queueMicrotask(() => this.#l(e, t, n + 1));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.#m("disabled", 3);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
let i = r.querySelector("n-textarea"), a = i ?? r;
|
|
278
|
+
try {
|
|
279
|
+
a.focus();
|
|
280
|
+
} catch {
|
|
281
|
+
if (n < 2) {
|
|
282
|
+
queueMicrotask(() => this.#l(e, t, n + 1));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this.#m("blocked", 3);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
e.cursor && e.cursor !== "preserve" && i && this.#d(i, e.cursor), this.dispatchEvent(new CustomEvent("native:composer-focused", {
|
|
289
|
+
bubbles: !0,
|
|
290
|
+
composed: !0,
|
|
291
|
+
detail: { by: t }
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
#u() {
|
|
295
|
+
return this.querySelector("n-chat-input");
|
|
296
|
+
}
|
|
297
|
+
#d(e, t) {
|
|
298
|
+
let n = e.ownerDocument.getSelection?.();
|
|
299
|
+
if (!n) return;
|
|
300
|
+
let r = e.firstChild ?? e, i = t === "end" ? r.textContent?.length ?? 0 : 0;
|
|
301
|
+
try {
|
|
302
|
+
let e = document.createRange();
|
|
303
|
+
e.setStart(r, i), e.collapse(!0), n.removeAllRanges(), n.addRange(e);
|
|
304
|
+
} catch {}
|
|
305
|
+
}
|
|
306
|
+
#f(e, t) {
|
|
307
|
+
this.dispatchEvent(new CustomEvent("native:chat-opened", {
|
|
308
|
+
bubbles: !0,
|
|
309
|
+
composed: !0,
|
|
310
|
+
detail: {
|
|
311
|
+
source: e,
|
|
312
|
+
focusComposer: t
|
|
313
|
+
}
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
316
|
+
#p(e) {
|
|
317
|
+
this.dispatchEvent(new CustomEvent("native:chat-closed", {
|
|
318
|
+
bubbles: !0,
|
|
319
|
+
composed: !0,
|
|
320
|
+
detail: { reason: e }
|
|
321
|
+
}));
|
|
219
322
|
}
|
|
220
|
-
#
|
|
323
|
+
#m(e, t) {
|
|
324
|
+
this.dispatchEvent(new CustomEvent("native:composer-focus-failed", {
|
|
325
|
+
bubbles: !0,
|
|
326
|
+
composed: !0,
|
|
327
|
+
detail: {
|
|
328
|
+
reason: e,
|
|
329
|
+
attempts: t
|
|
330
|
+
}
|
|
331
|
+
}));
|
|
332
|
+
}
|
|
333
|
+
#h = () => {
|
|
221
334
|
this.dispatchEvent(new CustomEvent("native:chat-stop", {
|
|
222
335
|
bubbles: !0,
|
|
223
336
|
composed: !0
|
|
224
337
|
}));
|
|
225
338
|
};
|
|
226
|
-
#
|
|
339
|
+
#g = () => {
|
|
227
340
|
this.dispatchEvent(new CustomEvent("native:chat-restart", {
|
|
228
341
|
bubbles: !0,
|
|
229
342
|
composed: !0
|
|
@@ -458,6 +571,7 @@ const u = {
|
|
|
458
571
|
* @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
|
|
459
572
|
* @attr {string} actions - Comma-separated action list, or `"none"` to suppress
|
|
460
573
|
* @attr {string} actions-style - `"label"` (default) | `"icon"` | `"icon-label"`
|
|
574
|
+
* @attr {string} actions-position - `"inside"` (default) | `"below"` — toolbar placement
|
|
461
575
|
* @fires native:message-action - Fired when an action button is clicked
|
|
462
576
|
* @fires native:continue-request - Fired when continue is requested for a partial message
|
|
463
577
|
*/
|
|
@@ -468,14 +582,16 @@ var f = class extends e {
|
|
|
468
582
|
"timestamp",
|
|
469
583
|
"status",
|
|
470
584
|
"actions",
|
|
471
|
-
"actions-style"
|
|
585
|
+
"actions-style",
|
|
586
|
+
"actions-position"
|
|
472
587
|
];
|
|
473
588
|
#e;
|
|
474
589
|
#t = r("assistant");
|
|
475
590
|
#n = r("sent");
|
|
476
591
|
#r = r(null);
|
|
477
592
|
#i = r("label");
|
|
478
|
-
#a =
|
|
593
|
+
#a = r("inside");
|
|
594
|
+
#o = null;
|
|
479
595
|
constructor() {
|
|
480
596
|
super(), this.#e = this.attachInternals();
|
|
481
597
|
}
|
|
@@ -509,6 +625,12 @@ var f = class extends e {
|
|
|
509
625
|
set actionsStyle(e) {
|
|
510
626
|
this.#i.value = e, this.setAttribute("actions-style", e);
|
|
511
627
|
}
|
|
628
|
+
get actionsPosition() {
|
|
629
|
+
return this.#a.value;
|
|
630
|
+
}
|
|
631
|
+
set actionsPosition(e) {
|
|
632
|
+
this.#a.value = e, this.setAttribute("actions-position", e);
|
|
633
|
+
}
|
|
512
634
|
attributeChangedCallback(e, t, n) {
|
|
513
635
|
if (t !== n) {
|
|
514
636
|
switch (e) {
|
|
@@ -524,34 +646,37 @@ var f = class extends e {
|
|
|
524
646
|
case "actions-style":
|
|
525
647
|
this.#i.value = n ?? "label";
|
|
526
648
|
break;
|
|
649
|
+
case "actions-position":
|
|
650
|
+
this.#a.value = n ?? "inside";
|
|
651
|
+
break;
|
|
527
652
|
}
|
|
528
653
|
super.attributeChangedCallback(e, t, n);
|
|
529
654
|
}
|
|
530
655
|
}
|
|
531
656
|
setup() {
|
|
532
657
|
super.setup(), this.addEffect(() => {
|
|
533
|
-
let e = this.#t.value, t = this.#r.value, n = this.#i.value, r = this.#n.value;
|
|
534
|
-
this.#
|
|
535
|
-
}), this.#e.role = "article", this.addEventListener("native:press", this.#
|
|
658
|
+
let e = this.#t.value, t = this.#r.value, n = this.#i.value, r = this.#a.value, i = this.#n.value;
|
|
659
|
+
this.#s(e, t, n, r, i);
|
|
660
|
+
}), this.#e.role = "article", this.addEventListener("native:press", this.#c);
|
|
536
661
|
}
|
|
537
662
|
teardown() {
|
|
538
|
-
this.removeEventListener("native:press", this.#
|
|
539
|
-
}
|
|
540
|
-
#
|
|
541
|
-
if (this.#
|
|
542
|
-
let
|
|
543
|
-
if (
|
|
544
|
-
let
|
|
545
|
-
|
|
546
|
-
for (let e of
|
|
663
|
+
this.removeEventListener("native:press", this.#c), this.#o = null, super.teardown();
|
|
664
|
+
}
|
|
665
|
+
#s(e, t, n, r, i) {
|
|
666
|
+
if (this.#o &&= (this.#o.remove(), null), t === "none" || this.querySelector("[slot=\"actions\"]")) return;
|
|
667
|
+
let a;
|
|
668
|
+
if (a = t ? t.split(",").map((e) => e.trim()).filter(Boolean) : d[e] ?? [], i === "partial" && !a.includes("continue") && (a = [...a, "continue"]), a.length === 0) return;
|
|
669
|
+
let o = document.createElement("n-toolbar");
|
|
670
|
+
o.className = "n-chat-message-actions", o.setAttribute("padding", "none"), o.setAttribute("aria-label", "Message actions"), n !== "label" && o.setAttribute("data-style", n);
|
|
671
|
+
for (let e of a) {
|
|
547
672
|
let t = u[e];
|
|
548
|
-
t &&
|
|
673
|
+
t && o.appendChild(p(e, t, n));
|
|
549
674
|
}
|
|
550
|
-
|
|
675
|
+
o.children.length !== 0 && (r === "below" ? this.after(o) : this.appendChild(o), this.#o = o);
|
|
551
676
|
}
|
|
552
|
-
#
|
|
677
|
+
#c = (e) => {
|
|
553
678
|
let t = e.target, n = t?.getAttribute("data-action");
|
|
554
|
-
if (n && this.#
|
|
679
|
+
if (n && this.#o?.contains(t)) {
|
|
555
680
|
if (e.stopPropagation(), n === "continue") {
|
|
556
681
|
this.dispatchEvent(new CustomEvent("native:continue-request", {
|
|
557
682
|
bubbles: !0,
|
|
@@ -596,9 +721,14 @@ function p(e, t, n) {
|
|
|
596
721
|
*
|
|
597
722
|
* @attr {string} role - `user` | `assistant` | `system`
|
|
598
723
|
* @attr {string} sender - Display name of the sender
|
|
724
|
+
* @attr {string} avatar-align - `"top"` (default) | `"center"` | `"bottom"` — avatar vertical alignment
|
|
599
725
|
*/
|
|
600
726
|
var m = class extends e {
|
|
601
|
-
static observedAttributes = [
|
|
727
|
+
static observedAttributes = [
|
|
728
|
+
"role",
|
|
729
|
+
"sender",
|
|
730
|
+
"avatar-align"
|
|
731
|
+
];
|
|
602
732
|
#e;
|
|
603
733
|
constructor() {
|
|
604
734
|
super(), this.#e = this.attachInternals();
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { NativeElement } from '@nonoun/native-ui';
|
|
2
|
+
export type AutoFocusPolicy = 'open-request' | 'ready' | 'never';
|
|
3
|
+
export interface ChatPanelOpenOptions {
|
|
4
|
+
focusComposer?: boolean;
|
|
5
|
+
reason?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FocusComposerOptions {
|
|
8
|
+
cursor?: 'start' | 'end' | 'preserve';
|
|
9
|
+
}
|
|
2
10
|
/**
|
|
3
11
|
* Stamped panel for the chat interface.
|
|
4
12
|
*
|
|
@@ -28,9 +36,14 @@ import { NativeElement } from '@nonoun/native-ui';
|
|
|
28
36
|
* ```
|
|
29
37
|
* @attr {boolean} show-stop - Show a stop button in the header; fires `native:chat-stop`
|
|
30
38
|
* @attr {boolean} show-restart - Show a restart button in the header; fires `native:chat-restart`
|
|
39
|
+
* @attr {string} auto-focus-policy - When to auto-focus the composer: 'open-request' (default), 'ready', 'never'
|
|
31
40
|
* @fires native:chat-stop - Fired when the stop button is pressed
|
|
32
41
|
* @fires native:chat-restart - Fired when the restart button is pressed
|
|
33
42
|
* @fires native:send - Fired on submit with `{ value }` detail
|
|
43
|
+
* @fires native:chat-opened - Fired when the panel opens
|
|
44
|
+
* @fires native:chat-closed - Fired when the panel closes
|
|
45
|
+
* @fires native:composer-focused - Fired when the composer receives focus via API/policy
|
|
46
|
+
* @fires native:composer-focus-failed - Fired when focusComposer() fails after retries
|
|
34
47
|
*/
|
|
35
48
|
export declare class NChatPanel extends NativeElement {
|
|
36
49
|
#private;
|
|
@@ -40,6 +53,14 @@ export declare class NChatPanel extends NativeElement {
|
|
|
40
53
|
set showStop(val: boolean);
|
|
41
54
|
get showRestart(): boolean;
|
|
42
55
|
set showRestart(val: boolean);
|
|
56
|
+
get autoFocusPolicy(): AutoFocusPolicy;
|
|
57
|
+
set autoFocusPolicy(val: AutoFocusPolicy);
|
|
58
|
+
/** Open the panel. Optionally focus the composer. */
|
|
59
|
+
open(options?: ChatPanelOpenOptions): void;
|
|
60
|
+
/** Close the panel. */
|
|
61
|
+
close(reason?: string): void;
|
|
62
|
+
/** Focus the composer input. */
|
|
63
|
+
focusComposer(options?: FocusComposerOptions, by?: 'api' | 'user' | 'policy'): void;
|
|
43
64
|
setup(): void;
|
|
44
65
|
teardown(): void;
|
|
45
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-panel-element.d.ts","sourceRoot":"","sources":["../src/chat-panel-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"chat-panel-element.d.ts","sourceRoot":"","sources":["../src/chat-panel-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,UAAW,SAAQ,aAAa;;IAC3C,MAAM,CAAC,kBAAkB,WAA8D;IAevF,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IA4BpF,IAAI,QAAQ,IAAI,OAAO,CAAiC;IACxD,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,EAGxB;IAED,IAAI,WAAW,IAAI,OAAO,CAAoC;IAC9D,IAAI,WAAW,CAAC,GAAG,EAAE,OAAO,EAG3B;IAED,IAAI,eAAe,IAAI,eAAe,CAAwC;IAC9E,IAAI,eAAe,CAAC,GAAG,EAAE,eAAe,EAGvC;IAED,qDAAqD;IACrD,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI;IAkB1C,uBAAuB;IACvB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAU5B,gCAAgC;IAChC,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,EAAE,EAAE,GAAE,KAAK,GAAG,MAAM,GAAG,QAAgB,GAAG,IAAI;IAM1F,KAAK,IAAI,IAAI;IA0Ib,QAAQ,IAAI,IAAI;CA2JjB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import './register.ts';
|
|
2
2
|
export { NChatInput } from './chat-input-element.ts';
|
|
3
3
|
export { NChatPanel } from './chat-panel-element.ts';
|
|
4
|
+
export type { AutoFocusPolicy, ChatPanelOpenOptions, FocusComposerOptions } from './chat-panel-element.ts';
|
|
4
5
|
export { NChatFeed } from './feed/index.ts';
|
|
5
6
|
export { NChatAvatar } from './avatar/index.ts';
|
|
6
7
|
export { NChatMessage, NChatMessages, NChatMessageText, NChatMessageActivity, NChatMessageSeed, NChatMessageGenUI, NChatInputStructured, } from './message/index.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG3G,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGnF,YAAY,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAGpG,YAAY,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
|
|
@@ -17,6 +17,7 @@ export declare const ROLE_DEFAULTS: Record<string, string[]>;
|
|
|
17
17
|
* @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
|
|
18
18
|
* @attr {string} actions - Comma-separated action list, or `"none"` to suppress
|
|
19
19
|
* @attr {string} actions-style - `"label"` (default) | `"icon"` | `"icon-label"`
|
|
20
|
+
* @attr {string} actions-position - `"inside"` (default) | `"below"` — toolbar placement
|
|
20
21
|
* @fires native:message-action - Fired when an action button is clicked
|
|
21
22
|
* @fires native:continue-request - Fired when continue is requested for a partial message
|
|
22
23
|
*/
|
|
@@ -34,6 +35,8 @@ export declare class NChatMessage extends NativeElement {
|
|
|
34
35
|
set actions(val: string | null);
|
|
35
36
|
get actionsStyle(): string;
|
|
36
37
|
set actionsStyle(val: string);
|
|
38
|
+
get actionsPosition(): string;
|
|
39
|
+
set actionsPosition(val: string);
|
|
37
40
|
attributeChangedCallback(name: string, old: string | null, val: string | null): void;
|
|
38
41
|
setup(): void;
|
|
39
42
|
teardown(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-message-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-message-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAOhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGlD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"chat-message-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-message-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAOhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGlD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAa,SAAQ,aAAa;;IAC7C,MAAM,CAAC,kBAAkB,WAAiG;;IAiB1H,IAAI,IAAI,IAAI,MAAM,CAA6B;IAC/C,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAGnB;IAED,IAAI,SAAS,IAAI,MAAM,CAAkD;IAEzE,IAAI,SAAS,IAAI,MAAM,CAAwD;IAE/E,IAAI,MAAM,IAAI,MAAM,CAA+B;IACnD,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,EAGrB;IAED,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAAgC;IAC5D,IAAI,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAO7B;IAED,IAAI,YAAY,IAAI,MAAM,CAAqC;IAC/D,IAAI,YAAY,CAAC,GAAG,EAAE,MAAM,EAG3B;IAED,IAAI,eAAe,IAAI,MAAM,CAAwC;IACrE,IAAI,eAAe,CAAC,GAAG,EAAE,MAAM,EAG9B;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAcpF,KAAK,IAAI,IAAI;IAmBb,QAAQ,IAAI,IAAI;CA0FjB"}
|
|
@@ -16,6 +16,7 @@ import { NativeElement } from '@nonoun/native-ui';
|
|
|
16
16
|
*
|
|
17
17
|
* @attr {string} role - `user` | `assistant` | `system`
|
|
18
18
|
* @attr {string} sender - Display name of the sender
|
|
19
|
+
* @attr {string} avatar-align - `"top"` (default) | `"center"` | `"bottom"` — avatar vertical alignment
|
|
19
20
|
*/
|
|
20
21
|
export declare class NChatMessages extends NativeElement {
|
|
21
22
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-messages-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-messages-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD
|
|
1
|
+
{"version":3,"file":"chat-messages-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-messages-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,aAAc,SAAQ,aAAa;;IAC9C,MAAM,CAAC,kBAAkB,WAAsC;;IAS/D,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKpF,KAAK,IAAI,IAAI;IASb,QAAQ,IAAI,IAAI;CAGjB"}
|
package/dist/native-chat.css
CHANGED
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
--n-chat-bubble-assistant: var(--n-card);
|
|
34
34
|
--n-chat-bubble-assistant-color: var(--n-ink);
|
|
35
35
|
--n-chat-bubble-radius: var(--n-radius);
|
|
36
|
+
--n-chat-bubble-radius-avatar-side: var(--n-chat-bubble-radius);
|
|
37
|
+
--n-chat-bubble-radius-far-side: var(--n-chat-bubble-radius);
|
|
36
38
|
--n-chat-bubble-padding-block: calc(var(--n-space) * 2);
|
|
37
39
|
--n-chat-bubble-padding-inline: calc(var(--n-space) * 3);
|
|
38
40
|
--n-chat-bubble-max-width: 85%;
|
|
@@ -67,6 +69,15 @@
|
|
|
67
69
|
:where(native-chat-panel) {
|
|
68
70
|
--n-ground: var(--n-panel);
|
|
69
71
|
|
|
72
|
+
/* Section surface token hooks — override on native-chat-panel to theme sections */
|
|
73
|
+
--n-chat-panel-header-background: transparent;
|
|
74
|
+
--n-chat-panel-header-border: var(--n-border-muted);
|
|
75
|
+
--n-chat-panel-header-label-font-weight: inherit;
|
|
76
|
+
--n-chat-panel-header-label-letter-spacing: inherit;
|
|
77
|
+
--n-chat-panel-body-background: transparent;
|
|
78
|
+
--n-chat-panel-footer-background: transparent;
|
|
79
|
+
--n-chat-panel-footer-border: var(--n-border-muted);
|
|
80
|
+
|
|
70
81
|
container-type: inline-size;
|
|
71
82
|
display: flex;
|
|
72
83
|
flex: 1 1 0%;
|
|
@@ -83,11 +94,22 @@
|
|
|
83
94
|
/* ── Sub-container integration ── */
|
|
84
95
|
|
|
85
96
|
:where(native-chat-panel) > :where(n-header) {
|
|
86
|
-
|
|
97
|
+
background: var(--n-chat-panel-header-background);
|
|
98
|
+
border-bottom: 1px solid var(--n-chat-panel-header-border);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
:where(native-chat-panel) > :where(n-header) :where([slot="label"]) {
|
|
102
|
+
font-weight: var(--n-chat-panel-header-label-font-weight);
|
|
103
|
+
letter-spacing: var(--n-chat-panel-header-label-letter-spacing);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
:where(native-chat-panel) > :where(n-body) {
|
|
107
|
+
background: var(--n-chat-panel-body-background);
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
:where(native-chat-panel) > :where(n-footer) {
|
|
90
|
-
|
|
111
|
+
background: var(--n-chat-panel-footer-background);
|
|
112
|
+
border-top: 1px solid var(--n-chat-panel-footer-border);
|
|
91
113
|
}
|
|
92
114
|
|
|
93
115
|
/* WHY: Wide padding only above 22rem — asides (280–480px) keep compact defaults. */
|
|
@@ -193,6 +215,15 @@
|
|
|
193
215
|
min-width: 0;
|
|
194
216
|
}
|
|
195
217
|
|
|
218
|
+
/* Avatar alignment */
|
|
219
|
+
[avatar-align="center"]:where(n-chat-messages) {
|
|
220
|
+
align-items: center;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
[avatar-align="bottom"]:where(n-chat-messages) {
|
|
224
|
+
align-items: flex-end;
|
|
225
|
+
}
|
|
226
|
+
|
|
196
227
|
:where(n-chat-messages[hidden]) { display: none; }
|
|
197
228
|
|
|
198
229
|
/* ══════════════════════════════════════════════════
|
|
@@ -242,7 +273,13 @@
|
|
|
242
273
|
|
|
243
274
|
padding-block: var(--n-chat-bubble-padding-block);
|
|
244
275
|
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
245
|
-
|
|
276
|
+
|
|
277
|
+
/* Asymmetric radius: assistant = avatar on left */
|
|
278
|
+
border-radius:
|
|
279
|
+
var(--n-chat-bubble-radius-avatar-side)
|
|
280
|
+
var(--n-chat-bubble-radius-far-side)
|
|
281
|
+
var(--n-chat-bubble-radius-far-side)
|
|
282
|
+
var(--n-chat-bubble-radius-avatar-side);
|
|
246
283
|
|
|
247
284
|
background: var(--n-chat-bubble-assistant);
|
|
248
285
|
color: var(--n-chat-bubble-assistant-color);
|
|
@@ -251,8 +288,14 @@
|
|
|
251
288
|
overflow-wrap: break-word;
|
|
252
289
|
}
|
|
253
290
|
|
|
254
|
-
/* User bubble */
|
|
291
|
+
/* User bubble: avatar on right — flip avatar-side / far-side corners */
|
|
255
292
|
[role="user"]:where(n-chat-message) {
|
|
293
|
+
border-radius:
|
|
294
|
+
var(--n-chat-bubble-radius-far-side)
|
|
295
|
+
var(--n-chat-bubble-radius-avatar-side)
|
|
296
|
+
var(--n-chat-bubble-radius-avatar-side)
|
|
297
|
+
var(--n-chat-bubble-radius-far-side);
|
|
298
|
+
|
|
256
299
|
background: var(--n-chat-bubble-user);
|
|
257
300
|
color: var(--n-chat-bubble-user-color);
|
|
258
301
|
}
|
|
@@ -290,6 +333,26 @@
|
|
|
290
333
|
opacity: 1;
|
|
291
334
|
}
|
|
292
335
|
|
|
336
|
+
/* ── Below-bubble actions position ── */
|
|
337
|
+
|
|
338
|
+
/* When actions-position="below", the toolbar is a sibling of n-chat-message
|
|
339
|
+
in the message column. Show on message hover via adjacent sibling. */
|
|
340
|
+
[actions-position="below"]:where(n-chat-message) + :where(.n-chat-message-actions) {
|
|
341
|
+
opacity: 0;
|
|
342
|
+
transition: opacity var(--n-duration) var(--n-easing);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
[actions-position="below"]:where(n-chat-message):hover + :where(.n-chat-message-actions),
|
|
346
|
+
[actions-position="below"]:where(n-chat-message[force-hover]) + :where(.n-chat-message-actions),
|
|
347
|
+
[actions-position="below"]:where(n-chat-message) + :where(.n-chat-message-actions):focus-within {
|
|
348
|
+
opacity: 1;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* Partial status — always show below-bubble actions */
|
|
352
|
+
[status="partial"][actions-position="below"]:where(n-chat-message) + :where(.n-chat-message-actions) {
|
|
353
|
+
opacity: 1;
|
|
354
|
+
}
|
|
355
|
+
|
|
293
356
|
:where(n-chat-message[hidden]) { display: none; }
|
|
294
357
|
|
|
295
358
|
/* ══════════════════════════════════════════════════
|
package/dist/native-chat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "./chat-input-structured-element-
|
|
1
|
+
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "./chat-input-structured-element-uXGIe-HI.js";
|
|
2
2
|
/**
|
|
3
3
|
* Parse a Server-Sent Events (SSE) response stream into ChatStreamChunk values.
|
|
4
4
|
*
|
package/dist/register.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, d as t, g as n, h as r, i, l as a, m as o, n as s, p as c, r as l, t as u } from "./chat-input-structured-element-
|
|
1
|
+
import { a as e, d as t, g as n, h as r, i, l as a, m as o, n as s, p as c, r as l, t as u } from "./chat-input-structured-element-uXGIe-HI.js";
|
|
2
2
|
import { NButton as d, NCard as f, NDialog as p, NIcon as m, NTextarea as h, NToolbar as g, define as _, registerIcon as v } from "@nonoun/native-ui";
|
|
3
3
|
_("n-chat-input", n), _("native-chat-panel", r), _("n-chat-feed", o), _("n-chat-avatar", c), _("n-chat-message", t), _("n-chat-messages", a), _("n-chat-message-text", e), _("n-chat-message-activity", i), _("n-chat-message-seed", l), _("n-chat-message-genui", s), _("n-chat-input-structured", u), _("n-textarea", h), _("n-button", d), _("n-icon", m), _("n-toolbar", g), _("n-dialog", p), _("n-card", f), v("chat-dots", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M116,128a12,12,0,1,1,12,12A12,12,0,0,1,116,128ZM84,140a12,12,0,1,0-12-12A12,12,0,0,0,84,140Zm88,0a12,12,0,1,0-12-12A12,12,0,0,0,172,140Zm60-76V192a16,16,0,0,1-16,16H83l-32.6,28.16-.09.07A15.89,15.89,0,0,1,40,240a16.13,16.13,0,0,1-6.8-1.52A15.85,15.85,0,0,1,24,224V64A16,16,0,0,1,40,48H216A16,16,0,0,1,232,64ZM40,224h0ZM216,64H40V224l34.77-30A8,8,0,0,1,80,192H216Z\"/></svg>"), v("user", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M230.92,212c-15.23-26.33-38.7-45.21-66.09-54.16a72,72,0,1,0-73.66,0C63.78,166.78,40.31,185.66,25.08,212a8,8,0,1,0,13.85,8C55.71,194.74,89.05,176,128,176s72.29,18.74,89.07,44a8,8,0,0,0,13.85-8ZM72,96a56,56,0,1,1,56,56A56.06,56.06,0,0,1,72,96Z\"/></svg>"), v("stop", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M200,40H56A16,16,0,0,0,40,56V200a16,16,0,0,0,16,16H200a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,160H56V56H200V200Z\"/></svg>"), v("arrow-counter-clockwise", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M224,128a96,96,0,0,1-94.71,96H128A95.38,95.38,0,0,1,62.1,197.8a8,8,0,0,1,11-11.63A80,80,0,1,0,71.43,71.39a3.07,3.07,0,0,1-.26.25L44.59,96H72a8,8,0,0,1,0,16H24a8,8,0,0,1-8-8V56a8,8,0,0,1,16,0V85.8L60.25,60A96,96,0,0,1,224,128Z\"/></svg>");
|
|
4
4
|
export { c as NChatAvatar, o as NChatFeed, n as NChatInput, u as NChatInputStructured, t as NChatMessage, i as NChatMessageActivity, s as NChatMessageGenUI, l as NChatMessageSeed, e as NChatMessageText, a as NChatMessages, r as NChatPanel };
|