@nonoun/native-chat 0.5.3 → 0.5.8
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/README.md +332 -0
- package/dist/{chat-input-structured-element-uXGIe-HI.js → chat-input-structured-element-DPKHlnRm.js} +150 -82
- package/dist/message/chat-message-element.d.ts +2 -2
- package/dist/message/chat-message-element.d.ts.map +1 -1
- package/dist/message/chat-messages-element.d.ts +16 -6
- package/dist/message/chat-messages-element.d.ts.map +1 -1
- package/dist/native-chat.css +111 -37
- package/dist/native-chat.js +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +2 -2
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# @nonoun/native-chat
|
|
2
|
+
|
|
3
|
+
Chat UI components for `@nonoun/native-ui` — message feed, composer input, streaming transport, and a top-level panel with imperative host-integration APIs.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @nonoun/native-chat @nonoun/native-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<link rel="stylesheet" href="node_modules/@nonoun/native-ui/dist/native-ui.css" />
|
|
15
|
+
<link rel="stylesheet" href="node_modules/@nonoun/native-chat/dist/native-chat.css" />
|
|
16
|
+
|
|
17
|
+
<script type="module">
|
|
18
|
+
import '@nonoun/native-ui/register';
|
|
19
|
+
import '@nonoun/native-chat/register';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<native-chat-panel auto-focus-policy="open-request">
|
|
23
|
+
<!-- panel stamps its own children: header, feed, composer -->
|
|
24
|
+
</native-chat-panel>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Components
|
|
28
|
+
|
|
29
|
+
| Element | Description |
|
|
30
|
+
|---------|-------------|
|
|
31
|
+
| `native-chat-panel` | Top-level panel — owns lifecycle, focus policy, header actions |
|
|
32
|
+
| `n-chat-feed` | Scrollable message feed with optional virtualization |
|
|
33
|
+
| `n-chat-messages` | Message list wrapper (inside feed) |
|
|
34
|
+
| `n-chat-message` | Single message container with role, status, actions |
|
|
35
|
+
| `n-chat-message-text` | Markdown-rendered text bubble |
|
|
36
|
+
| `n-chat-message-activity` | Typing / system activity indicator |
|
|
37
|
+
| `n-chat-message-seed` | Seed prompt card |
|
|
38
|
+
| `n-chat-message-genui` | Generative UI node renderer |
|
|
39
|
+
| `n-chat-avatar` | Message avatar |
|
|
40
|
+
| `n-chat-input` | Composer with submit, formatting, slash commands |
|
|
41
|
+
| `n-chat-input-structured` | Multi-option structured input picker |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Embedding Guide
|
|
46
|
+
|
|
47
|
+
### Panel Host API
|
|
48
|
+
|
|
49
|
+
`native-chat-panel` exposes three imperative methods for host orchestration:
|
|
50
|
+
|
|
51
|
+
#### `open(options?)`
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
panel.open();
|
|
55
|
+
panel.open({ focusComposer: true, reason: 'deeplink' });
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Option | Type | Default | Description |
|
|
59
|
+
|--------|------|---------|-------------|
|
|
60
|
+
| `focusComposer` | `boolean` | `false` | Request composer focus after opening |
|
|
61
|
+
| `reason` | `string` | — | Why the panel opened (telemetry / debugging) |
|
|
62
|
+
|
|
63
|
+
Sets the `[open]` attribute. Idempotent — calling `open()` when already open does not re-emit events.
|
|
64
|
+
|
|
65
|
+
#### `close(reason?)`
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
panel.close();
|
|
69
|
+
panel.close('user-dismiss');
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Removes the `[open]` attribute. Idempotent.
|
|
73
|
+
|
|
74
|
+
#### `focusComposer(options?, by?)`
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
panel.focusComposer();
|
|
78
|
+
panel.focusComposer({ cursor: 'end' }, 'api');
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Option | Type | Default | Description |
|
|
82
|
+
|--------|------|---------|-------------|
|
|
83
|
+
| `cursor` | `'start' \| 'end' \| 'preserve'` | `'end'` | Caret placement after focus |
|
|
84
|
+
| `by` | `'api' \| 'user' \| 'policy'` | `'api'` | Focus source (included in events) |
|
|
85
|
+
|
|
86
|
+
Retries up to 3 times via microtask if the composer is not yet available or disabled. On success dispatches `native:composer-focused`; on failure dispatches `native:composer-focus-failed`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Lifecycle Events
|
|
91
|
+
|
|
92
|
+
All events bubble and are composed (cross shadow DOM). Listen on the panel or any ancestor:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const panel = document.querySelector('native-chat-panel');
|
|
96
|
+
|
|
97
|
+
panel.addEventListener('native:chat-opened', (e) => {
|
|
98
|
+
console.log('opened', e.detail.source, e.detail.focusComposer);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
panel.addEventListener('native:chat-closed', (e) => {
|
|
102
|
+
console.log('closed', e.detail.reason);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
panel.addEventListener('native:send', (e) => {
|
|
106
|
+
console.log('user sent:', e.detail.value);
|
|
107
|
+
// Call e.preventDefault() to block auto-clear
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| Event | Detail | Notes |
|
|
112
|
+
|-------|--------|-------|
|
|
113
|
+
| `native:chat-opened` | `{ source?: string, focusComposer: boolean }` | After panel opens |
|
|
114
|
+
| `native:chat-closed` | `{ reason?: string }` | After panel closes |
|
|
115
|
+
| `native:composer-focused` | `{ by: 'api' \| 'user' \| 'policy' }` | Composer received focus |
|
|
116
|
+
| `native:composer-focus-failed` | `{ reason: string, attempts: number }` | All focus retries exhausted |
|
|
117
|
+
| `native:send` | `{ value: string }` | User submitted message (**cancelable**) |
|
|
118
|
+
| `native:chat-stop` | — | User clicked stop button |
|
|
119
|
+
| `native:chat-restart` | — | User clicked restart button |
|
|
120
|
+
| `native:message-action` | `{ action: string, messageId: string }` | Message action triggered |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Focus Policy
|
|
125
|
+
|
|
126
|
+
The `auto-focus-policy` attribute controls when the composer auto-focuses:
|
|
127
|
+
|
|
128
|
+
| Value | Behavior |
|
|
129
|
+
|-------|----------|
|
|
130
|
+
| `open-request` (default) | Focus composer only when `open({ focusComposer: true })` is called |
|
|
131
|
+
| `ready` | Auto-focus once at panel initialization |
|
|
132
|
+
| `never` | Never auto-focus — host must call `focusComposer()` explicitly |
|
|
133
|
+
|
|
134
|
+
**Recommended default:** `open-request` — gives the host full control over focus timing.
|
|
135
|
+
|
|
136
|
+
#### Focus Failure Handling
|
|
137
|
+
|
|
138
|
+
When `focusComposer()` cannot reach the textarea (not rendered, disabled, or blocked), the panel emits `native:composer-focus-failed` after 3 retry attempts:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
panel.addEventListener('native:composer-focus-failed', (e) => {
|
|
142
|
+
const { reason, attempts } = e.detail;
|
|
143
|
+
// reason: 'composer-unavailable' | 'disabled' | 'blocked'
|
|
144
|
+
// Show a fallback hint or retry button
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Recommended UX:** Keep the panel open, show a subtle status hint, and let the user retry manually.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Host Orchestration Patterns
|
|
153
|
+
|
|
154
|
+
#### Deeplink
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
// Parse URL: ?openChat=1
|
|
158
|
+
if (new URLSearchParams(location.search).has('openChat')) {
|
|
159
|
+
panel.open({ focusComposer: true, reason: 'deeplink' });
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Notification or External Action
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
notificationButton.addEventListener('click', () => {
|
|
167
|
+
panel.open({ focusComposer: false, reason: 'notification' });
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### Intercepting Send
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
panel.addEventListener('native:send', (e) => {
|
|
175
|
+
const { value } = e.detail;
|
|
176
|
+
if (!value.trim()) {
|
|
177
|
+
e.preventDefault(); // block auto-clear, ignore empty
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
myTransport.send(value);
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Transport Error & Retry
|
|
187
|
+
|
|
188
|
+
`createChatTransport()` provides a streaming transport layer with built-in error classification and retry logic.
|
|
189
|
+
|
|
190
|
+
#### Transport States
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
idle → sending → streaming → ready
|
|
194
|
+
↘ retrying → sending (retry loop)
|
|
195
|
+
↘ rate-limited (429)
|
|
196
|
+
↘ auth-required (401/403)
|
|
197
|
+
↘ server-error (5xx / network)
|
|
198
|
+
↘ offline (DNS / TypeError)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### Usage
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { createChatTransport } from '@nonoun/native-chat';
|
|
205
|
+
|
|
206
|
+
const transport = createChatTransport({
|
|
207
|
+
baseUrl: '/api/chat',
|
|
208
|
+
format: 'sse',
|
|
209
|
+
retry: { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000 },
|
|
210
|
+
onStateChange(status) {
|
|
211
|
+
// status: { state, statusCode?, retryInMs?, attempt?, maxAttempts?, error? }
|
|
212
|
+
switch (status.state) {
|
|
213
|
+
case 'sending': showSpinner(); break;
|
|
214
|
+
case 'streaming': hideSpinner(); break;
|
|
215
|
+
case 'retrying': showRetryBanner(status.retryInMs); break;
|
|
216
|
+
case 'rate-limited': showRateLimitNotice(status.retryInMs); break;
|
|
217
|
+
case 'auth-required': redirectToLogin(); break;
|
|
218
|
+
case 'server-error': showErrorBanner(status.error); break;
|
|
219
|
+
case 'offline': showOfflineBanner(); break;
|
|
220
|
+
case 'ready': clearAllBanners(); break;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Defaults & Behavior
|
|
227
|
+
|
|
228
|
+
| Behavior | Default |
|
|
229
|
+
|----------|---------|
|
|
230
|
+
| Retry | Disabled (`maxAttempts: 1`) |
|
|
231
|
+
| Retryable errors | 429 (rate-limited), 5xx (server error) |
|
|
232
|
+
| Non-retryable | 401/403 (auth-required) — never retried |
|
|
233
|
+
| 429 delay | Respects `Retry-After` header (seconds or HTTP-date) |
|
|
234
|
+
| Backoff | Exponential: `min(maxDelay, baseDelay * 2^attempt + jitter)` |
|
|
235
|
+
| Stream formats | `'sse'`, `'ndjson'`, `'json'` (auto-detected via `detectFormat()`) |
|
|
236
|
+
|
|
237
|
+
#### Stream End Classification
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { classifyStreamEnd } from '@nonoun/native-chat';
|
|
241
|
+
|
|
242
|
+
// Returns: 'complete' | 'partial' | 'error' | 'stopped'
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
| Reason | Meaning |
|
|
246
|
+
|--------|---------|
|
|
247
|
+
| `complete` | Server sent explicit done signal |
|
|
248
|
+
| `partial` | Stream ended without completion (truncated) |
|
|
249
|
+
| `error` | Transport or parse error |
|
|
250
|
+
| `stopped` | Consumer aborted (user clicked stop) |
|
|
251
|
+
|
|
252
|
+
Use `partial` status on messages to offer a "Continue" action.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Message Actions
|
|
257
|
+
|
|
258
|
+
Messages show contextual action buttons (copy, regenerate, edit, feedback):
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<n-chat-message role="assistant" actions="copy,regenerate,thumbs-up,thumbs-down">
|
|
262
|
+
<n-chat-message-text>Hello!</n-chat-message-text>
|
|
263
|
+
</n-chat-message>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
| Attribute | Values | Default |
|
|
267
|
+
|-----------|--------|---------|
|
|
268
|
+
| `actions` | Comma-separated action IDs, or `"none"` | Role-based defaults |
|
|
269
|
+
| `actions-style` | `'icon' \| 'label' \| 'icon-label'` | `'icon'` |
|
|
270
|
+
| `actions-position` | `'below' \| 'inside'` | `'below'` |
|
|
271
|
+
|
|
272
|
+
Listen for actions on any ancestor:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
panel.addEventListener('native:message-action', (e) => {
|
|
276
|
+
const { action, messageId } = e.detail;
|
|
277
|
+
if (action === 'copy') navigator.clipboard.writeText(getMessageText(messageId));
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### Feed Virtualization
|
|
284
|
+
|
|
285
|
+
For long transcripts, enable virtual scrolling on the feed:
|
|
286
|
+
|
|
287
|
+
```html
|
|
288
|
+
<n-chat-feed virtual virtual-item-height="80" virtual-overscan="5">
|
|
289
|
+
<n-chat-messages>...</n-chat-messages>
|
|
290
|
+
</n-chat-feed>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Only visible items (plus overscan buffer) are rendered. The feed emits `native:range-change` with `{ start, end, total }` as the viewport scrolls.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Exports
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
// Components
|
|
301
|
+
import {
|
|
302
|
+
NChatPanel, NChatInput, NChatFeed, NChatMessage,
|
|
303
|
+
NChatMessages, NChatMessageText, NChatMessageActivity,
|
|
304
|
+
NChatAvatar, NChatMessageSeed, NChatMessageGenUI,
|
|
305
|
+
NChatInputStructured,
|
|
306
|
+
} from '@nonoun/native-chat';
|
|
307
|
+
|
|
308
|
+
// Stream / Transport
|
|
309
|
+
import {
|
|
310
|
+
createChatTransport, createChatStream,
|
|
311
|
+
parseSSE, parseNDJSON, parseJSON, detectFormat,
|
|
312
|
+
classifyHttpError, classifyStreamEnd, backoffDelay,
|
|
313
|
+
} from '@nonoun/native-chat';
|
|
314
|
+
|
|
315
|
+
// Types
|
|
316
|
+
import type {
|
|
317
|
+
AutoFocusPolicy, ChatPanelOpenOptions, FocusComposerOptions,
|
|
318
|
+
ChatTransportOptions, TransportState, TransportStatus, RetryOptions,
|
|
319
|
+
ChatStreamEvent, ChatStreamChunk, StreamFormat, StreamEndReason,
|
|
320
|
+
} from '@nonoun/native-chat';
|
|
321
|
+
|
|
322
|
+
// Utilities
|
|
323
|
+
import { renderMarkdown, renderInline, sanitizeHtml } from '@nonoun/native-chat';
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Peer Dependency
|
|
327
|
+
|
|
328
|
+
Requires `@nonoun/native-ui >= 0.6.0`.
|
|
329
|
+
|
|
330
|
+
## License
|
|
331
|
+
|
|
332
|
+
MIT
|
package/dist/{chat-input-structured-element-uXGIe-HI.js → chat-input-structured-element-DPKHlnRm.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NativeElement as e, VirtualScrollController as t, createDisabledEffect as n, signal as r } from "@nonoun/native-ui";
|
|
1
|
+
import { NativeElement as e, VirtualScrollController as t, createDisabledEffect as n, signal as r, uid as i } from "@nonoun/native-ui";
|
|
2
2
|
/**
|
|
3
3
|
* Chat message input with textarea, submit button, and Enter-to-send behavior.
|
|
4
4
|
* @attr {boolean} disabled - Disables interaction
|
|
@@ -10,7 +10,7 @@ import { NativeElement as e, VirtualScrollController as t, createDisabledEffect
|
|
|
10
10
|
* @fires native:composer-focus - Fired when the composer textarea gains focus
|
|
11
11
|
* @fires native:composer-blur - Fired when the composer textarea loses focus
|
|
12
12
|
*/
|
|
13
|
-
var
|
|
13
|
+
var a = class extends e {
|
|
14
14
|
static observedAttributes = ["disabled", "busy"];
|
|
15
15
|
#e;
|
|
16
16
|
#t = r(!1);
|
|
@@ -131,7 +131,7 @@ var i = class extends e {
|
|
|
131
131
|
})) && !this.hasAttribute("no-auto-clear") && (this.value = "", this.#i?.setAttribute("disabled", ""));
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
},
|
|
134
|
+
}, o = class extends e {
|
|
135
135
|
static observedAttributes = [
|
|
136
136
|
"show-stop",
|
|
137
137
|
"show-restart",
|
|
@@ -224,7 +224,7 @@ var i = class extends e {
|
|
|
224
224
|
let d = document.createElement("n-button");
|
|
225
225
|
d.setAttribute("variant", "ghost"), d.setAttribute("inline", ""), d.innerHTML = "<n-icon name=\"microphone\"></n-icon>", l.appendChild(d);
|
|
226
226
|
let f = document.createElement("n-button");
|
|
227
|
-
f.setAttribute("variant", "primary"), f.setAttribute("intent", "accent"), f.setAttribute("radius", "round"), f.setAttribute("inline", ""), f.setAttribute("disabled", ""), f.
|
|
227
|
+
f.setAttribute("variant", "primary"), f.setAttribute("intent", "accent"), f.setAttribute("radius", "round"), f.setAttribute("inline", ""), f.setAttribute("disabled", ""), f.dataset.role = "submit", 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(() => {
|
|
228
228
|
let e = this.#e.value;
|
|
229
229
|
if (e && !this.#a) {
|
|
230
230
|
let e = document.createElement("n-button");
|
|
@@ -342,7 +342,7 @@ var i = class extends e {
|
|
|
342
342
|
composed: !0
|
|
343
343
|
}));
|
|
344
344
|
};
|
|
345
|
-
},
|
|
345
|
+
}, s = 40, c = class extends e {
|
|
346
346
|
static observedAttributes = [
|
|
347
347
|
"auto-scroll",
|
|
348
348
|
"scrollable",
|
|
@@ -451,7 +451,7 @@ var i = class extends e {
|
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
453
|
#f = () => {
|
|
454
|
-
let e = this.#n.value, t = this.scrollTop + this.clientHeight >= this.scrollHeight -
|
|
454
|
+
let e = this.#n.value, t = this.scrollTop + this.clientHeight >= this.scrollHeight - s;
|
|
455
455
|
this.#n.value = t, t !== e && this.dispatchEvent(new CustomEvent("native:feed-scroll", {
|
|
456
456
|
bubbles: !0,
|
|
457
457
|
composed: !0,
|
|
@@ -470,7 +470,7 @@ var i = class extends e {
|
|
|
470
470
|
});
|
|
471
471
|
};
|
|
472
472
|
#m = (e) => {};
|
|
473
|
-
},
|
|
473
|
+
}, l = class extends e {
|
|
474
474
|
static observedAttributes = [
|
|
475
475
|
"src",
|
|
476
476
|
"name",
|
|
@@ -510,7 +510,7 @@ var i = class extends e {
|
|
|
510
510
|
}
|
|
511
511
|
if (n) {
|
|
512
512
|
let e = document.createElement("span");
|
|
513
|
-
e.className = "n-chat-avatar-initials", e.textContent =
|
|
513
|
+
e.className = "n-chat-avatar-initials", e.textContent = u(n), e.setAttribute("aria-hidden", "true"), this.appendChild(e);
|
|
514
514
|
return;
|
|
515
515
|
}
|
|
516
516
|
let r = document.createElement("n-icon");
|
|
@@ -521,11 +521,11 @@ var i = class extends e {
|
|
|
521
521
|
this.textContent = "", super.teardown();
|
|
522
522
|
}
|
|
523
523
|
};
|
|
524
|
-
function
|
|
524
|
+
function u(e) {
|
|
525
525
|
let t = e.trim().split(/\s+/);
|
|
526
526
|
return t.length === 0 ? "" : t.length === 1 ? t[0][0].toUpperCase() : (t[0][0] + t[t.length - 1][0]).toUpperCase();
|
|
527
527
|
}
|
|
528
|
-
const
|
|
528
|
+
const d = {
|
|
529
529
|
copy: {
|
|
530
530
|
label: "Copy",
|
|
531
531
|
icon: "copy"
|
|
@@ -550,7 +550,7 @@ const u = {
|
|
|
550
550
|
label: "Continue",
|
|
551
551
|
icon: "arrow-right"
|
|
552
552
|
}
|
|
553
|
-
},
|
|
553
|
+
}, f = {
|
|
554
554
|
assistant: [
|
|
555
555
|
"copy",
|
|
556
556
|
"retry",
|
|
@@ -570,12 +570,12 @@ const u = {
|
|
|
570
570
|
* @attr {string} timestamp - Epoch milliseconds
|
|
571
571
|
* @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
|
|
572
572
|
* @attr {string} actions - Comma-separated action list, or `"none"` to suppress
|
|
573
|
-
* @attr {string} actions-style - `"
|
|
574
|
-
* @attr {string} actions-position - `"
|
|
573
|
+
* @attr {string} actions-style - `"icon"` (default) | `"label"` | `"icon-label"`
|
|
574
|
+
* @attr {string} actions-position - `"below"` (default) | `"inside"` — toolbar placement
|
|
575
575
|
* @fires native:message-action - Fired when an action button is clicked
|
|
576
576
|
* @fires native:continue-request - Fired when continue is requested for a partial message
|
|
577
577
|
*/
|
|
578
|
-
var
|
|
578
|
+
var p = class extends e {
|
|
579
579
|
static observedAttributes = [
|
|
580
580
|
"role",
|
|
581
581
|
"message-id",
|
|
@@ -589,9 +589,12 @@ var f = class extends e {
|
|
|
589
589
|
#t = r("assistant");
|
|
590
590
|
#n = r("sent");
|
|
591
591
|
#r = r(null);
|
|
592
|
-
#i = r("
|
|
593
|
-
#a = r("
|
|
592
|
+
#i = r("icon");
|
|
593
|
+
#a = r("below");
|
|
594
594
|
#o = null;
|
|
595
|
+
#s = !1;
|
|
596
|
+
#c = 0;
|
|
597
|
+
#l = 0;
|
|
595
598
|
constructor() {
|
|
596
599
|
super(), this.#e = this.attachInternals();
|
|
597
600
|
}
|
|
@@ -644,40 +647,73 @@ var f = class extends e {
|
|
|
644
647
|
this.#r.value = n;
|
|
645
648
|
break;
|
|
646
649
|
case "actions-style":
|
|
647
|
-
this.#i.value = n ?? "
|
|
650
|
+
this.#i.value = n ?? "icon";
|
|
648
651
|
break;
|
|
649
652
|
case "actions-position":
|
|
650
|
-
this.#a.value = n ?? "
|
|
653
|
+
this.#a.value = n ?? "below";
|
|
651
654
|
break;
|
|
652
655
|
}
|
|
653
656
|
super.attributeChangedCallback(e, t, n);
|
|
654
657
|
}
|
|
655
658
|
}
|
|
656
659
|
setup() {
|
|
657
|
-
super.setup(), this.addEffect(() => {
|
|
660
|
+
super.setup(), this.addEventListener("pointerenter", this.#u), this.addEventListener("pointerleave", this.#d), this.addEffect(() => {
|
|
658
661
|
let e = this.#t.value, t = this.#r.value, n = this.#i.value, r = this.#a.value, i = this.#n.value;
|
|
659
|
-
this.#
|
|
660
|
-
}), this.#e.role = "article"
|
|
662
|
+
this.#p(e, t, n, r, i);
|
|
663
|
+
}), this.#e.role = "article";
|
|
661
664
|
}
|
|
662
665
|
teardown() {
|
|
663
|
-
this.removeEventListener("
|
|
664
|
-
}
|
|
665
|
-
#
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
666
|
+
this.removeEventListener("pointerenter", this.#u), this.removeEventListener("pointerleave", this.#d), clearTimeout(this.#c), clearTimeout(this.#l), this.#o &&= (this.#f(), null), super.teardown();
|
|
667
|
+
}
|
|
668
|
+
#u = () => {
|
|
669
|
+
clearTimeout(this.#l), !(!this.#o || !this.#s || this.#n.value === "partial") && (clearTimeout(this.#c), this.#c = window.setTimeout(() => {
|
|
670
|
+
try {
|
|
671
|
+
this.#o?.showPopover();
|
|
672
|
+
} catch {}
|
|
673
|
+
}, 300));
|
|
674
|
+
};
|
|
675
|
+
#d = () => {
|
|
676
|
+
!this.#s || this.#n.value === "partial" || (clearTimeout(this.#c), clearTimeout(this.#l), this.#l = window.setTimeout(() => {
|
|
677
|
+
try {
|
|
678
|
+
this.#o?.hidePopover();
|
|
679
|
+
} catch {}
|
|
680
|
+
}, 150));
|
|
681
|
+
};
|
|
682
|
+
#f() {
|
|
683
|
+
if (this.#o) {
|
|
684
|
+
if (this.#s) {
|
|
685
|
+
this.#o.removeEventListener("pointerenter", this.#u), this.#o.removeEventListener("pointerleave", this.#d), this.#o.removeEventListener("focusin", this.#u), this.#o.removeEventListener("focusout", this.#d);
|
|
686
|
+
try {
|
|
687
|
+
this.#o.hidePopover();
|
|
688
|
+
} catch {}
|
|
689
|
+
this.style.removeProperty("anchor-name"), this.#s = !1;
|
|
690
|
+
}
|
|
691
|
+
this.#o.removeEventListener("native:press", this.#m), this.#o.remove();
|
|
674
692
|
}
|
|
675
|
-
o.children.length !== 0 && (r === "below" ? this.after(o) : this.appendChild(o), this.#o = o);
|
|
676
693
|
}
|
|
677
|
-
#
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
694
|
+
#p(e, t, n, r, a) {
|
|
695
|
+
if (this.#o &&= (this.#f(), null), clearTimeout(this.#l), t === "none" || this.querySelector("[slot=\"actions\"]")) return;
|
|
696
|
+
let o;
|
|
697
|
+
if (o = t ? t.split(",").map((e) => e.trim()).filter(Boolean) : f[e] ?? [], a === "partial" && !o.includes("continue") && (o = [...o, "continue"]), o.length === 0) return;
|
|
698
|
+
let s = document.createElement("n-toolbar");
|
|
699
|
+
s.dataset.role = "actions", s.setAttribute("padding", "tight"), s.setAttribute("aria-label", "Message actions"), n !== "label" && s.setAttribute("data-style", n);
|
|
700
|
+
for (let e of o) {
|
|
701
|
+
let t = d[e];
|
|
702
|
+
t && s.appendChild(m(e, t, n));
|
|
703
|
+
}
|
|
704
|
+
if (s.children.length !== 0) {
|
|
705
|
+
if (s.addEventListener("native:press", this.#m), r === "below") {
|
|
706
|
+
s.setAttribute("popover", "manual");
|
|
707
|
+
let e = i("msg");
|
|
708
|
+
this.style.setProperty("anchor-name", `--${e}`), s.style.setProperty("position-anchor", `--${e}`), this.appendChild(s), this.#s = !0, s.addEventListener("pointerenter", this.#u), s.addEventListener("pointerleave", this.#d), s.addEventListener("focusin", this.#u), s.addEventListener("focusout", this.#d), a === "partial" && s.showPopover();
|
|
709
|
+
} else this.appendChild(s);
|
|
710
|
+
this.#o = s;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
#m = (e) => {
|
|
714
|
+
let t = e.target?.getAttribute("data-action");
|
|
715
|
+
if (t) {
|
|
716
|
+
if (e.stopPropagation(), t === "continue") {
|
|
681
717
|
this.dispatchEvent(new CustomEvent("native:continue-request", {
|
|
682
718
|
bubbles: !0,
|
|
683
719
|
composed: !0,
|
|
@@ -689,14 +725,14 @@ var f = class extends e {
|
|
|
689
725
|
bubbles: !0,
|
|
690
726
|
composed: !0,
|
|
691
727
|
detail: {
|
|
692
|
-
action:
|
|
728
|
+
action: t,
|
|
693
729
|
messageId: this.messageId
|
|
694
730
|
}
|
|
695
731
|
}));
|
|
696
732
|
}
|
|
697
733
|
};
|
|
698
734
|
};
|
|
699
|
-
function
|
|
735
|
+
function m(e, t, n) {
|
|
700
736
|
let r = document.createElement("n-button");
|
|
701
737
|
if (r.setAttribute("variant", "ghost"), r.setAttribute("size", "sm"), r.setAttribute("inline", ""), r.setAttribute("data-action", e), r.setAttribute("aria-label", t.label), n === "icon" || n === "icon-label") {
|
|
702
738
|
let e = document.createElement("n-icon");
|
|
@@ -707,13 +743,23 @@ function p(e, t, n) {
|
|
|
707
743
|
/**
|
|
708
744
|
* Message group — cluster of messages from the same sender.
|
|
709
745
|
*
|
|
710
|
-
* Provides
|
|
711
|
-
*
|
|
746
|
+
* Provides a 2×2 grid layout:
|
|
747
|
+
* - Col 1, row 1–2: avatar (bottom-aligned)
|
|
748
|
+
* - Col 2, row 1: context area (metadata, reasoning, timestamps)
|
|
749
|
+
* - Col 2, row 2: messages area (chat bubbles, flex column)
|
|
750
|
+
*
|
|
751
|
+
* On setup, non-avatar children are sorted into two wrapper divs:
|
|
752
|
+
* - `.n-chat-context` — non-message children (row 1)
|
|
753
|
+
* - `.n-chat-bubbles` — `n-chat-message` children (row 2)
|
|
754
|
+
*
|
|
755
|
+
* A MutationObserver routes dynamically added children into the
|
|
756
|
+
* correct wrapper automatically.
|
|
712
757
|
*
|
|
713
758
|
* ```html
|
|
714
|
-
* <n-chat-messages role="
|
|
715
|
-
* <n-chat-avatar
|
|
716
|
-
* <
|
|
759
|
+
* <n-chat-messages role="assistant" sender="AI">
|
|
760
|
+
* <n-chat-avatar>AI</n-chat-avatar>
|
|
761
|
+
* <span class="reasoning">Thinking...</span>
|
|
762
|
+
* <n-chat-message role="assistant">
|
|
717
763
|
* <n-chat-message-text>Hello!</n-chat-message-text>
|
|
718
764
|
* </n-chat-message>
|
|
719
765
|
* </n-chat-messages>
|
|
@@ -721,15 +767,18 @@ function p(e, t, n) {
|
|
|
721
767
|
*
|
|
722
768
|
* @attr {string} role - `user` | `assistant` | `system`
|
|
723
769
|
* @attr {string} sender - Display name of the sender
|
|
724
|
-
* @attr {string} avatar-align - `"top"`
|
|
770
|
+
* @attr {string} avatar-align - `"top"` | `"center"` | `"bottom"` (default) — avatar vertical alignment
|
|
725
771
|
*/
|
|
726
|
-
var
|
|
772
|
+
var h = class extends e {
|
|
727
773
|
static observedAttributes = [
|
|
728
774
|
"role",
|
|
729
775
|
"sender",
|
|
730
776
|
"avatar-align"
|
|
731
777
|
];
|
|
732
778
|
#e;
|
|
779
|
+
#t = null;
|
|
780
|
+
#n = null;
|
|
781
|
+
#r = null;
|
|
733
782
|
constructor() {
|
|
734
783
|
super(), this.#e = this.attachInternals();
|
|
735
784
|
}
|
|
@@ -739,12 +788,31 @@ var m = class extends e {
|
|
|
739
788
|
setup() {
|
|
740
789
|
super.setup(), this.#e.role = "group";
|
|
741
790
|
let e = this.getAttribute("sender");
|
|
742
|
-
e && (this.#e.ariaLabel = `Messages from ${e}`)
|
|
791
|
+
e && (this.#e.ariaLabel = `Messages from ${e}`), this.#i(), this.#r = new MutationObserver((e) => {
|
|
792
|
+
for (let t of e) for (let e of t.addedNodes) e instanceof Element && e.localName !== "n-chat-avatar" && (e === this.#t || e === this.#n || (e.localName === "n-chat-message" ? this.#n?.appendChild(e) : this.#t?.appendChild(e)));
|
|
793
|
+
}), this.#r.observe(this, { childList: !0 });
|
|
743
794
|
}
|
|
744
795
|
teardown() {
|
|
796
|
+
if (this.#r?.disconnect(), this.#r = null, this.#n) {
|
|
797
|
+
for (; this.#n.firstChild;) this.appendChild(this.#n.firstChild);
|
|
798
|
+
this.#n.remove(), this.#n = null;
|
|
799
|
+
}
|
|
800
|
+
if (this.#t) {
|
|
801
|
+
for (; this.#t.firstChild;) this.appendChild(this.#t.firstChild);
|
|
802
|
+
this.#t.remove(), this.#t = null;
|
|
803
|
+
}
|
|
745
804
|
super.teardown();
|
|
746
805
|
}
|
|
747
|
-
|
|
806
|
+
#i() {
|
|
807
|
+
let e = document.createElement("div");
|
|
808
|
+
e.className = "n-chat-context";
|
|
809
|
+
let t = document.createElement("div");
|
|
810
|
+
t.className = "n-chat-bubbles";
|
|
811
|
+
let n = Array.from(this.childNodes);
|
|
812
|
+
for (let r of n) r instanceof Element && r.localName === "n-chat-avatar" || (r instanceof Element && r.localName === "n-chat-message" ? t.appendChild(r) : e.appendChild(r));
|
|
813
|
+
this.appendChild(e), this.appendChild(t), this.#t = e, this.#n = t;
|
|
814
|
+
}
|
|
815
|
+
}, g = class extends e {
|
|
748
816
|
static observedAttributes = ["format"];
|
|
749
817
|
#e = r("markdown");
|
|
750
818
|
#t = r("");
|
|
@@ -768,14 +836,14 @@ var m = class extends e {
|
|
|
768
836
|
super.setup(), this.deferChildren(() => {
|
|
769
837
|
!this.#t.value && this.textContent?.trim() && (this.#t.value = this.textContent.trim()), this.#n = document.createElement("div"), this.#n.className = "n-chat-prose", this.textContent = "", this.appendChild(this.#n), this.addEffect(() => {
|
|
770
838
|
let e = this.#t.value, t = this.#e.value;
|
|
771
|
-
this.#n && (t === "plain" ? this.#n.textContent = e : this.#n.innerHTML =
|
|
839
|
+
this.#n && (t === "plain" ? this.#n.textContent = e : this.#n.innerHTML = b(e));
|
|
772
840
|
});
|
|
773
841
|
});
|
|
774
842
|
}
|
|
775
843
|
teardown() {
|
|
776
844
|
this.#n = null, super.teardown();
|
|
777
845
|
}
|
|
778
|
-
},
|
|
846
|
+
}, _ = new Set([
|
|
779
847
|
"p",
|
|
780
848
|
"br",
|
|
781
849
|
"strong",
|
|
@@ -795,14 +863,14 @@ var m = class extends e {
|
|
|
795
863
|
"blockquote",
|
|
796
864
|
"hr"
|
|
797
865
|
]);
|
|
798
|
-
function
|
|
866
|
+
function v(e) {
|
|
799
867
|
return e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
800
868
|
}
|
|
801
|
-
function
|
|
802
|
-
let t =
|
|
869
|
+
function y(e) {
|
|
870
|
+
let t = v(e);
|
|
803
871
|
return t = t.replace(/`([^`]+)`/g, "<code>$1</code>"), t = t.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), t = t.replace(/__(.+?)__/g, "<strong>$1</strong>"), t = t.replace(/\*(.+?)\*/g, "<em>$1</em>"), t = t.replace(/(?<!\w)_(.+?)_(?!\w)/g, "<em>$1</em>"), t = t.replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, "<a href=\"$2\" rel=\"noopener noreferrer\" target=\"_blank\">$1</a>"), t;
|
|
804
872
|
}
|
|
805
|
-
function
|
|
873
|
+
function b(e) {
|
|
806
874
|
if (!e) return "";
|
|
807
875
|
let t = e.split("\n"), n = [], r = 0;
|
|
808
876
|
for (; r < t.length;) {
|
|
@@ -811,14 +879,14 @@ function y(e) {
|
|
|
811
879
|
let i = e.slice(3).trim(), a = [];
|
|
812
880
|
for (r += 1; r < t.length && !t[r].startsWith("```");) a.push(t[r]), r += 1;
|
|
813
881
|
r += 1;
|
|
814
|
-
let o = i ? ` data-lang="${
|
|
815
|
-
n.push(`<pre${o}><code>${
|
|
882
|
+
let o = i ? ` data-lang="${v(i)}"` : "";
|
|
883
|
+
n.push(`<pre${o}><code>${v(a.join("\n"))}</code></pre>`);
|
|
816
884
|
continue;
|
|
817
885
|
}
|
|
818
886
|
let i = e.match(/^(#{1,6})\s+(.+)/);
|
|
819
887
|
if (i) {
|
|
820
888
|
let e = i[1].length;
|
|
821
|
-
n.push(`<h${e}>${
|
|
889
|
+
n.push(`<h${e}>${y(i[2])}</h${e}>`), r += 1;
|
|
822
890
|
continue;
|
|
823
891
|
}
|
|
824
892
|
if (/^---+$/.test(e.trim()) || /^\*\*\*+$/.test(e.trim())) {
|
|
@@ -828,19 +896,19 @@ function y(e) {
|
|
|
828
896
|
if (e.startsWith("> ")) {
|
|
829
897
|
let e = [];
|
|
830
898
|
for (; r < t.length && t[r].startsWith("> ");) e.push(t[r].slice(2)), r += 1;
|
|
831
|
-
n.push(`<blockquote>${
|
|
899
|
+
n.push(`<blockquote>${b(e.join("\n"))}</blockquote>`);
|
|
832
900
|
continue;
|
|
833
901
|
}
|
|
834
902
|
if (/^[-*+]\s/.test(e)) {
|
|
835
903
|
let e = [];
|
|
836
904
|
for (; r < t.length && /^[-*+]\s/.test(t[r]);) e.push(t[r].replace(/^[-*+]\s/, "")), r += 1;
|
|
837
|
-
n.push("<ul>" + e.map((e) => `<li>${
|
|
905
|
+
n.push("<ul>" + e.map((e) => `<li>${y(e)}</li>`).join("") + "</ul>");
|
|
838
906
|
continue;
|
|
839
907
|
}
|
|
840
908
|
if (/^\d+\.\s/.test(e)) {
|
|
841
909
|
let e = [];
|
|
842
910
|
for (; r < t.length && /^\d+\.\s/.test(t[r]);) e.push(t[r].replace(/^\d+\.\s/, "")), r += 1;
|
|
843
|
-
n.push("<ol>" + e.map((e) => `<li>${
|
|
911
|
+
n.push("<ol>" + e.map((e) => `<li>${y(e)}</li>`).join("") + "</ol>");
|
|
844
912
|
continue;
|
|
845
913
|
}
|
|
846
914
|
if (!e.trim()) {
|
|
@@ -849,15 +917,15 @@ function y(e) {
|
|
|
849
917
|
}
|
|
850
918
|
let a = [];
|
|
851
919
|
for (; r < t.length && t[r].trim() && !t[r].startsWith("#") && !t[r].startsWith("```") && !t[r].startsWith("> ") && !/^[-*+]\s/.test(t[r]) && !/^\d+\.\s/.test(t[r]) && !/^---+$/.test(t[r].trim());) a.push(t[r]), r += 1;
|
|
852
|
-
a.length > 0 && n.push(`<p>${
|
|
920
|
+
a.length > 0 && n.push(`<p>${y(a.join("\n"))}</p>`);
|
|
853
921
|
}
|
|
854
922
|
return n.join("");
|
|
855
923
|
}
|
|
856
924
|
/** Sanitize rendered HTML — strip any tags not in allowlist. */
|
|
857
|
-
function
|
|
925
|
+
function x(e) {
|
|
858
926
|
return e.replace(/<\/?([a-zA-Z][a-zA-Z0-9]*)[^>]*>/g, (e, t) => {
|
|
859
927
|
let n = t.toLowerCase();
|
|
860
|
-
return
|
|
928
|
+
return _.has(n) ? e : "";
|
|
861
929
|
});
|
|
862
930
|
}
|
|
863
931
|
/**
|
|
@@ -878,7 +946,7 @@ function b(e) {
|
|
|
878
946
|
* @attr {boolean} expandable - Allow click to expand trace content
|
|
879
947
|
* @fires native:activity-toggle - Fired when trace is expanded/collapsed
|
|
880
948
|
*/
|
|
881
|
-
var
|
|
949
|
+
var S = class extends e {
|
|
882
950
|
static observedAttributes = [
|
|
883
951
|
"type",
|
|
884
952
|
"label",
|
|
@@ -936,7 +1004,7 @@ var x = class extends e {
|
|
|
936
1004
|
this.#r.value ? (this.#p(), this.#e.states.add("active")) : (this.#m(), this.#e.states.delete("active"));
|
|
937
1005
|
}), this.addEffect(() => {
|
|
938
1006
|
if (!this.#c) return;
|
|
939
|
-
let e = this.#n.value ||
|
|
1007
|
+
let e = this.#n.value || C(this.#t.value);
|
|
940
1008
|
this.#c.textContent = e;
|
|
941
1009
|
}), this.addEffect(() => {
|
|
942
1010
|
this.#u && (this.#u.hidden = !this.#r.value);
|
|
@@ -966,7 +1034,7 @@ var x = class extends e {
|
|
|
966
1034
|
#h = () => {
|
|
967
1035
|
if (!this.#r.value || !this.#l) return;
|
|
968
1036
|
let e = performance.now() - this.#o;
|
|
969
|
-
this.#l.textContent =
|
|
1037
|
+
this.#l.textContent = w(e), this.#s = requestAnimationFrame(this.#h);
|
|
970
1038
|
};
|
|
971
1039
|
#g = () => {
|
|
972
1040
|
this.#i.value && (this.#a.value = !this.#a.value, this.toggleAttribute("expanded", this.#a.value), this.dispatchEvent(new CustomEvent("native:activity-toggle", {
|
|
@@ -976,14 +1044,14 @@ var x = class extends e {
|
|
|
976
1044
|
})));
|
|
977
1045
|
};
|
|
978
1046
|
};
|
|
979
|
-
function
|
|
1047
|
+
function C(e) {
|
|
980
1048
|
switch (e) {
|
|
981
1049
|
case "thinking": return "Thinking…";
|
|
982
1050
|
case "tool-use": return "Using tools…";
|
|
983
1051
|
default: return "Host is typing…";
|
|
984
1052
|
}
|
|
985
1053
|
}
|
|
986
|
-
function
|
|
1054
|
+
function w(e) {
|
|
987
1055
|
let t = Math.floor(e / 1e3);
|
|
988
1056
|
if (t < 60) return `${t}s`;
|
|
989
1057
|
let n = Math.floor(t / 60), r = t % 60;
|
|
@@ -1003,7 +1071,7 @@ function C(e) {
|
|
|
1003
1071
|
* @attr {boolean} disabled - Disables all chips
|
|
1004
1072
|
* @fires native:seed-select - Fired when a chip is clicked
|
|
1005
1073
|
*/
|
|
1006
|
-
var
|
|
1074
|
+
var T = class extends e {
|
|
1007
1075
|
static observedAttributes = ["options", "disabled"];
|
|
1008
1076
|
#e;
|
|
1009
1077
|
#t = r([]);
|
|
@@ -1072,7 +1140,7 @@ var w = class extends e {
|
|
|
1072
1140
|
}
|
|
1073
1141
|
}));
|
|
1074
1142
|
};
|
|
1075
|
-
},
|
|
1143
|
+
}, E = new Set([
|
|
1076
1144
|
"script",
|
|
1077
1145
|
"style",
|
|
1078
1146
|
"link",
|
|
@@ -1089,7 +1157,7 @@ var w = class extends e {
|
|
|
1089
1157
|
"frame",
|
|
1090
1158
|
"frameset",
|
|
1091
1159
|
"noscript"
|
|
1092
|
-
]),
|
|
1160
|
+
]), D = class extends e {
|
|
1093
1161
|
static observedAttributes = ["schema-type", "mode"];
|
|
1094
1162
|
#e;
|
|
1095
1163
|
#t = r("a2ui");
|
|
@@ -1134,7 +1202,7 @@ var w = class extends e {
|
|
|
1134
1202
|
super.setup(), this.#i = document.createElement("div"), this.#i.className = "n-chat-genui-container", this.appendChild(this.#i), this.addEffect(() => {
|
|
1135
1203
|
let e = this.#r.value, t = this.#n.value;
|
|
1136
1204
|
if (!this.#i || (this.#i.textContent = "", !e)) return;
|
|
1137
|
-
let n =
|
|
1205
|
+
let n = O(e);
|
|
1138
1206
|
if (n.length > 0) {
|
|
1139
1207
|
this.#a(n), this.dispatchEvent(new CustomEvent("native:genui-error", {
|
|
1140
1208
|
bubbles: !0,
|
|
@@ -1145,7 +1213,7 @@ var w = class extends e {
|
|
|
1145
1213
|
}
|
|
1146
1214
|
if (t === "lightbox") this.#o(e);
|
|
1147
1215
|
else {
|
|
1148
|
-
let t =
|
|
1216
|
+
let t = k(e);
|
|
1149
1217
|
t && this.#i.appendChild(t);
|
|
1150
1218
|
}
|
|
1151
1219
|
this.#e.states.add("rendered");
|
|
@@ -1162,14 +1230,14 @@ var w = class extends e {
|
|
|
1162
1230
|
#o(e) {
|
|
1163
1231
|
if (!this.#i) return;
|
|
1164
1232
|
let t = document.createElement("n-card");
|
|
1165
|
-
t.
|
|
1233
|
+
t.dataset.role = "preview";
|
|
1166
1234
|
let n = document.createElement("span");
|
|
1167
1235
|
n.textContent = `Interactive UI (${e.tag})`, t.appendChild(n);
|
|
1168
1236
|
let r = document.createElement("n-button");
|
|
1169
1237
|
r.setAttribute("variant", "outline"), r.setAttribute("size", "sm"), r.setAttribute("inline", ""), r.textContent = "Open", r.addEventListener("click", () => this.#s(e)), t.appendChild(r), this.#i.appendChild(t);
|
|
1170
1238
|
}
|
|
1171
1239
|
#s(e) {
|
|
1172
|
-
let t = document.createElement("n-dialog"), n =
|
|
1240
|
+
let t = document.createElement("n-dialog"), n = k(e);
|
|
1173
1241
|
n && t.appendChild(n), this.appendChild(t), requestAnimationFrame(() => {
|
|
1174
1242
|
let e = t.querySelector("dialog");
|
|
1175
1243
|
e && e.showModal();
|
|
@@ -1189,20 +1257,20 @@ var w = class extends e {
|
|
|
1189
1257
|
}));
|
|
1190
1258
|
};
|
|
1191
1259
|
};
|
|
1192
|
-
function
|
|
1260
|
+
function O(e, t = 0) {
|
|
1193
1261
|
let n = [];
|
|
1194
1262
|
if (t > 20) return n.push("Maximum nesting depth (20) exceeded"), n;
|
|
1195
1263
|
if (!e.tag || typeof e.tag != "string") return n.push("Node missing required \"tag\" property"), n;
|
|
1196
|
-
if (
|
|
1264
|
+
if (E.has(e.tag.toLowerCase()) && n.push(`Forbidden tag: <${e.tag}>`), e.children) for (let r of e.children) n.push(...O(r, t + 1));
|
|
1197
1265
|
return n;
|
|
1198
1266
|
}
|
|
1199
|
-
function
|
|
1200
|
-
if (
|
|
1267
|
+
function k(e) {
|
|
1268
|
+
if (E.has(e.tag.toLowerCase())) return null;
|
|
1201
1269
|
let t = document.createElement(e.tag);
|
|
1202
1270
|
if (e.id && (t.id = e.id), e.slot && (t.slot = e.slot), e.attributes) for (let [n, r] of Object.entries(e.attributes)) t.setAttribute(n, r);
|
|
1203
1271
|
if (e.properties) for (let [n, r] of Object.entries(e.properties)) t[n] = r;
|
|
1204
1272
|
if (e.text && (t.textContent = e.text), e.children) for (let n of e.children) {
|
|
1205
|
-
let e =
|
|
1273
|
+
let e = k(n);
|
|
1206
1274
|
e && t.appendChild(e);
|
|
1207
1275
|
}
|
|
1208
1276
|
return t;
|
|
@@ -1227,7 +1295,7 @@ function O(e) {
|
|
|
1227
1295
|
* @fires native:structured-submit - Fired on submit with selections
|
|
1228
1296
|
* @fires native:structured-cancel - Fired when dismissed without selecting
|
|
1229
1297
|
*/
|
|
1230
|
-
var
|
|
1298
|
+
var A = class extends e {
|
|
1231
1299
|
static observedAttributes = [
|
|
1232
1300
|
"question",
|
|
1233
1301
|
"type",
|
|
@@ -1353,4 +1421,4 @@ var k = class extends e {
|
|
|
1353
1421
|
}));
|
|
1354
1422
|
};
|
|
1355
1423
|
};
|
|
1356
|
-
export {
|
|
1424
|
+
export { g as a, x as c, p as d, f, a as g, o as h, S as i, h as l, c as m, D as n, y as o, l as p, T as r, b as s, A as t, d as u };
|
|
@@ -16,8 +16,8 @@ export declare const ROLE_DEFAULTS: Record<string, string[]>;
|
|
|
16
16
|
* @attr {string} timestamp - Epoch milliseconds
|
|
17
17
|
* @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
|
|
18
18
|
* @attr {string} actions - Comma-separated action list, or `"none"` to suppress
|
|
19
|
-
* @attr {string} actions-style - `"
|
|
20
|
-
* @attr {string} actions-position - `"
|
|
19
|
+
* @attr {string} actions-style - `"icon"` (default) | `"label"` | `"icon-label"`
|
|
20
|
+
* @attr {string} actions-position - `"below"` (default) | `"inside"` — toolbar placement
|
|
21
21
|
* @fires native:message-action - Fired when an action button is clicked
|
|
22
22
|
* @fires native:continue-request - Fired when continue is requested for a partial message
|
|
23
23
|
*/
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"chat-message-element.d.ts","sourceRoot":"","sources":["../../src/message/chat-message-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;AAI/D,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;;IAoB1H,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;IAqBb,QAAQ,IAAI,IAAI;CAoJjB"}
|
|
@@ -2,13 +2,23 @@ import { NativeElement } from '@nonoun/native-ui';
|
|
|
2
2
|
/**
|
|
3
3
|
* Message group — cluster of messages from the same sender.
|
|
4
4
|
*
|
|
5
|
-
* Provides
|
|
6
|
-
*
|
|
5
|
+
* Provides a 2×2 grid layout:
|
|
6
|
+
* - Col 1, row 1–2: avatar (bottom-aligned)
|
|
7
|
+
* - Col 2, row 1: context area (metadata, reasoning, timestamps)
|
|
8
|
+
* - Col 2, row 2: messages area (chat bubbles, flex column)
|
|
9
|
+
*
|
|
10
|
+
* On setup, non-avatar children are sorted into two wrapper divs:
|
|
11
|
+
* - `.n-chat-context` — non-message children (row 1)
|
|
12
|
+
* - `.n-chat-bubbles` — `n-chat-message` children (row 2)
|
|
13
|
+
*
|
|
14
|
+
* A MutationObserver routes dynamically added children into the
|
|
15
|
+
* correct wrapper automatically.
|
|
7
16
|
*
|
|
8
17
|
* ```html
|
|
9
|
-
* <n-chat-messages role="
|
|
10
|
-
* <n-chat-avatar
|
|
11
|
-
* <
|
|
18
|
+
* <n-chat-messages role="assistant" sender="AI">
|
|
19
|
+
* <n-chat-avatar>AI</n-chat-avatar>
|
|
20
|
+
* <span class="reasoning">Thinking...</span>
|
|
21
|
+
* <n-chat-message role="assistant">
|
|
12
22
|
* <n-chat-message-text>Hello!</n-chat-message-text>
|
|
13
23
|
* </n-chat-message>
|
|
14
24
|
* </n-chat-messages>
|
|
@@ -16,7 +26,7 @@ import { NativeElement } from '@nonoun/native-ui';
|
|
|
16
26
|
*
|
|
17
27
|
* @attr {string} role - `user` | `assistant` | `system`
|
|
18
28
|
* @attr {string} sender - Display name of the sender
|
|
19
|
-
* @attr {string} avatar-align - `"top"`
|
|
29
|
+
* @attr {string} avatar-align - `"top"` | `"center"` | `"bottom"` (default) — avatar vertical alignment
|
|
20
30
|
*/
|
|
21
31
|
export declare class NChatMessages extends NativeElement {
|
|
22
32
|
#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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,aAAc,SAAQ,aAAa;;IAC9C,MAAM,CAAC,kBAAkB,WAAsC;;IAY/D,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKpF,KAAK,IAAI,IAAI;IA8Bb,QAAQ,IAAI,IAAI;CA4CjB"}
|
package/dist/native-chat.css
CHANGED
|
@@ -191,37 +191,85 @@
|
|
|
191
191
|
n-chat-messages — message group (bubble cluster)
|
|
192
192
|
══════════════════════════════════════════════════ */
|
|
193
193
|
|
|
194
|
+
/* 2×2 grid: avatar | context + bubbles.
|
|
195
|
+
Col 1: avatar (spans both rows, bottom-aligned)
|
|
196
|
+
Col 2 row 1: .n-chat-context — metadata, reasoning, timestamps
|
|
197
|
+
Col 2 row 2: .n-chat-bubbles — message bubbles (flex column) */
|
|
194
198
|
:where(n-chat-messages) {
|
|
195
|
-
display:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
gap: var(--n-chat-message-gap);
|
|
199
|
+
display: grid;
|
|
200
|
+
grid-template-columns: auto 1fr;
|
|
201
|
+
grid-template-rows: auto 1fr;
|
|
202
|
+
column-gap: var(--n-chat-message-gap);
|
|
199
203
|
align-self: flex-start;
|
|
204
|
+
max-width: var(--n-chat-bubble-max-width);
|
|
200
205
|
min-width: 0;
|
|
201
206
|
}
|
|
202
207
|
|
|
203
|
-
/*
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
/* Avatar: col 1, spans both rows, bottom-align */
|
|
209
|
+
:where(n-chat-messages) > :where(n-chat-avatar) {
|
|
210
|
+
grid-column: 1;
|
|
211
|
+
grid-row: 1 / -1;
|
|
212
|
+
align-self: end;
|
|
207
213
|
}
|
|
208
214
|
|
|
209
|
-
/*
|
|
210
|
-
:where(n-chat-messages) > :where(
|
|
215
|
+
/* Context area: col 2, row 1 — metadata above messages */
|
|
216
|
+
:where(n-chat-messages) > :where(.n-chat-context) {
|
|
217
|
+
grid-column: 2;
|
|
218
|
+
grid-row: 1;
|
|
211
219
|
display: flex;
|
|
212
220
|
flex-direction: column;
|
|
213
|
-
gap:
|
|
214
|
-
max-width: var(--n-chat-bubble-max-width);
|
|
221
|
+
gap: var(--n-space);
|
|
215
222
|
min-width: 0;
|
|
216
223
|
}
|
|
217
224
|
|
|
218
|
-
/*
|
|
219
|
-
|
|
220
|
-
|
|
225
|
+
/* Empty context collapses */
|
|
226
|
+
:where(n-chat-messages) > :where(.n-chat-context:empty) {
|
|
227
|
+
display: none;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* Bubbles area: col 2, row 2 — flex column of messages */
|
|
231
|
+
:where(n-chat-messages) > :where(.n-chat-bubbles) {
|
|
232
|
+
grid-column: 2;
|
|
233
|
+
grid-row: 2;
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-direction: column;
|
|
236
|
+
gap: var(--n-space);
|
|
237
|
+
min-width: 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Messages shrink-wrap to content width */
|
|
241
|
+
:where(.n-chat-bubbles) > :where(n-chat-message) {
|
|
242
|
+
width: fit-content;
|
|
243
|
+
max-width: 100%;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Avatar alignment overrides */
|
|
247
|
+
[avatar-align="top"]:where(n-chat-messages) > :where(n-chat-avatar) {
|
|
248
|
+
align-self: start;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
[avatar-align="center"]:where(n-chat-messages) > :where(n-chat-avatar) {
|
|
252
|
+
align-self: center;
|
|
221
253
|
}
|
|
222
254
|
|
|
223
|
-
|
|
224
|
-
|
|
255
|
+
/* User messages: right-aligned, avatar on right */
|
|
256
|
+
[role="user"]:where(n-chat-messages) {
|
|
257
|
+
grid-template-columns: 1fr auto;
|
|
258
|
+
align-self: flex-end;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
[role="user"]:where(n-chat-messages) > :where(n-chat-avatar) {
|
|
262
|
+
grid-column: 2;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
[role="user"]:where(n-chat-messages) > :where(.n-chat-context),
|
|
266
|
+
[role="user"]:where(n-chat-messages) > :where(.n-chat-bubbles) {
|
|
267
|
+
grid-column: 1;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* User bubbles align to the right edge */
|
|
271
|
+
[role="user"]:where(n-chat-messages) :where(.n-chat-bubbles) > :where(n-chat-message) {
|
|
272
|
+
align-self: flex-end;
|
|
225
273
|
}
|
|
226
274
|
|
|
227
275
|
:where(n-chat-messages[hidden]) { display: none; }
|
|
@@ -270,9 +318,7 @@
|
|
|
270
318
|
display: flex;
|
|
271
319
|
flex-direction: column;
|
|
272
320
|
gap: var(--n-space);
|
|
273
|
-
|
|
274
|
-
padding-block: var(--n-chat-bubble-padding-block);
|
|
275
|
-
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
321
|
+
overflow: hidden;
|
|
276
322
|
|
|
277
323
|
/* Asymmetric radius: assistant = avatar on left */
|
|
278
324
|
border-radius:
|
|
@@ -317,40 +363,64 @@
|
|
|
317
363
|
|
|
318
364
|
/* ── Message actions toolbar ── */
|
|
319
365
|
|
|
320
|
-
:where(n-chat-message) > :where(
|
|
366
|
+
:where(n-chat-message) > :where(n-toolbar[data-role="actions"]) {
|
|
321
367
|
opacity: 0;
|
|
322
368
|
transition: opacity var(--n-duration) var(--n-easing);
|
|
369
|
+
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
323
370
|
}
|
|
324
371
|
|
|
325
|
-
:where(n-chat-message):hover > :where(
|
|
326
|
-
:where(n-chat-message):focus-within > :where(
|
|
327
|
-
:where(n-chat-message[force-hover]) > :where(
|
|
372
|
+
:where(n-chat-message):hover > :where(n-toolbar[data-role="actions"]),
|
|
373
|
+
:where(n-chat-message):focus-within > :where(n-toolbar[data-role="actions"]),
|
|
374
|
+
:where(n-chat-message[force-hover]) > :where(n-toolbar[data-role="actions"]) {
|
|
328
375
|
opacity: 1;
|
|
329
376
|
}
|
|
330
377
|
|
|
331
378
|
/* Partial status — always show actions (contains continue button) */
|
|
332
|
-
[status="partial"]:where(n-chat-message) > :where(
|
|
379
|
+
[status="partial"]:where(n-chat-message) > :where(n-toolbar[data-role="actions"]) {
|
|
333
380
|
opacity: 1;
|
|
334
381
|
}
|
|
335
382
|
|
|
336
|
-
/* ── Below-bubble
|
|
383
|
+
/* ── Below-bubble popover toolbar ── */
|
|
337
384
|
|
|
338
|
-
/*
|
|
339
|
-
|
|
340
|
-
|
|
385
|
+
/* Popover toolbar: anchored below the message via CSS anchor positioning.
|
|
386
|
+
Toolbar is a child of n-chat-message with popover="manual", rendered in the
|
|
387
|
+
top layer. JS shows/hides via pointerenter/pointerleave + showPopover().
|
|
388
|
+
Entry/exit transition mirrors n-listbox[popover] (perspective + scale). */
|
|
389
|
+
:where(n-chat-message) > :where(n-toolbar[data-role="actions"][popover]) {
|
|
390
|
+
position: fixed;
|
|
391
|
+
inset: auto;
|
|
392
|
+
top: anchor(bottom);
|
|
393
|
+
left: anchor(center);
|
|
394
|
+
translate: -50% 0;
|
|
395
|
+
margin: 2px 0 0;
|
|
396
|
+
width: max-content;
|
|
397
|
+
|
|
398
|
+
transform-origin: top center;
|
|
341
399
|
opacity: 0;
|
|
342
|
-
|
|
400
|
+
transform: perspective(800px) scale(0.96) rotateX(-20deg);
|
|
401
|
+
|
|
402
|
+
transition:
|
|
403
|
+
opacity var(--n-duration) var(--n-easing),
|
|
404
|
+
transform var(--n-duration) var(--n-easing),
|
|
405
|
+
display var(--n-duration) var(--n-easing) allow-discrete,
|
|
406
|
+
overlay var(--n-duration) var(--n-easing) allow-discrete;
|
|
343
407
|
}
|
|
344
408
|
|
|
345
|
-
|
|
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 {
|
|
409
|
+
:where(n-chat-message) > :where(n-toolbar[data-role="actions"][popover]):popover-open {
|
|
348
410
|
opacity: 1;
|
|
411
|
+
transform: none;
|
|
349
412
|
}
|
|
350
413
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
414
|
+
@starting-style {
|
|
415
|
+
:where(n-chat-message) > :where(n-toolbar[data-role="actions"][popover]):popover-open {
|
|
416
|
+
opacity: 0;
|
|
417
|
+
transform: perspective(800px) scale(0.96) rotateX(-20deg);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* Override n-toolbar display to respect popover hidden state */
|
|
422
|
+
:where(n-toolbar[data-role="actions"][popover]):not(:popover-open) {
|
|
423
|
+
display: none;
|
|
354
424
|
}
|
|
355
425
|
|
|
356
426
|
:where(n-chat-message[hidden]) { display: none; }
|
|
@@ -361,6 +431,8 @@
|
|
|
361
431
|
|
|
362
432
|
:where(n-chat-message-text) {
|
|
363
433
|
display: block;
|
|
434
|
+
padding-block: var(--n-chat-bubble-padding-block);
|
|
435
|
+
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
364
436
|
}
|
|
365
437
|
|
|
366
438
|
/* ── Prose reset — typography inside rendered markdown ── */
|
|
@@ -453,6 +525,7 @@
|
|
|
453
525
|
color: var(--n-chat-activity-color);
|
|
454
526
|
font-size: var(--n-font-size-sm);
|
|
455
527
|
padding-block: var(--n-space);
|
|
528
|
+
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
456
529
|
align-self: flex-start;
|
|
457
530
|
}
|
|
458
531
|
|
|
@@ -545,6 +618,7 @@
|
|
|
545
618
|
flex-wrap: wrap;
|
|
546
619
|
gap: var(--n-space);
|
|
547
620
|
padding-block: var(--n-space);
|
|
621
|
+
padding-inline: var(--n-chat-bubble-padding-inline);
|
|
548
622
|
align-self: flex-start;
|
|
549
623
|
}
|
|
550
624
|
|
|
@@ -575,7 +649,7 @@
|
|
|
575
649
|
font-size: var(--n-font-size-sm);
|
|
576
650
|
}
|
|
577
651
|
|
|
578
|
-
:where(n-chat-message-genui) :where(
|
|
652
|
+
:where(n-chat-message-genui) :where(n-card[data-role="preview"]) {
|
|
579
653
|
display: flex;
|
|
580
654
|
align-items: center;
|
|
581
655
|
justify-content: space-between;
|
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-DPKHlnRm.js";
|
|
2
2
|
/**
|
|
3
3
|
* Parse a Server-Sent Events (SSE) response stream into ChatStreamChunk values.
|
|
4
4
|
*
|
package/dist/register.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAqClF,OAAO,EACL,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,CAAC"}
|
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-DPKHlnRm.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
|
-
_("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>");
|
|
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>"), v("copy", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M216,32H88a8,8,0,0,0-8,8V80H40a8,8,0,0,0-8,8V216a8,8,0,0,0,8,8H168a8,8,0,0,0,8-8V176h40a8,8,0,0,0,8-8V40A8,8,0,0,0,216,32ZM160,208H48V96H160Zm48-48H176V88a8,8,0,0,0-8-8H96V48H208Z\"/></svg>"), v("arrow-clockwise", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16H211.4L184.81,71.64l-.25-.24a80,80,0,1,0-1.67,114.78,8,8,0,0,1,11,11.63A95.44,95.44,0,0,1,128,224h-1.32A96,96,0,1,1,195.75,60L224,85.8V56a8,8,0,1,1,16,0Z\"/></svg>"), v("pencil-simple", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M227.31,73.37,182.63,28.68a16,16,0,0,0-22.63,0L36.69,152A15.86,15.86,0,0,0,32,163.31V208a16,16,0,0,0,16,16H92.69A15.86,15.86,0,0,0,104,219.31L227.31,96a16,16,0,0,0,0-22.63ZM92.69,208H48V163.31l88-88L180.69,120ZM192,108.68,147.31,64l24-24L216,84.68Z\"/></svg>"), v("thumbs-up", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M234,80.12A24,24,0,0,0,216,72H160V56a40,40,0,0,0-40-40,8,8,0,0,0-7.16,4.42L75.06,96H32a16,16,0,0,0-16,16v88a16,16,0,0,0,16,16H204a24,24,0,0,0,23.82-21l12-96A24,24,0,0,0,234,80.12ZM32,112H72v88H32ZM223.94,97l-12,96a8,8,0,0,1-7.94,7H88V105.89l36.71-73.43A24,24,0,0,1,144,56V80a8,8,0,0,0,8,8h64a8,8,0,0,1,7.94,9Z\"/></svg>"), v("thumbs-down", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M239.82,157l-12-96A24,24,0,0,0,204,40H32A16,16,0,0,0,16,56v88a16,16,0,0,0,16,16H75.06l37.78,75.58A8,8,0,0,0,120,240a40,40,0,0,0,40-40V184h56a24,24,0,0,0,23.82-27ZM72,144H32V56H72Zm150,21.29a7.88,7.88,0,0,1-6,2.71H152a8,8,0,0,0-8,8v24a24,24,0,0,1-19.29,23.54L88,150.11V56H204a8,8,0,0,1,7.94,7l12,96A7.87,7.87,0,0,1,222,165.29Z\"/></svg>"), v("arrow-right", "<svg viewBox=\"0 0 256 256\" fill=\"currentColor\"><path d=\"M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z\"/></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 };
|