@nonoun/native-chat 0.3.0 → 0.5.1

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.
@@ -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;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,UAAW,SAAQ,aAAa;;IAC3C,MAAM,CAAC,kBAAkB,WAAiC;IAa1D,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAepF,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;IAID,KAAK,IAAI,IAAI;IA4Hb,QAAQ,IAAI,IAAI;CA6CjB"}
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"}
@@ -12,8 +12,21 @@ import { NativeElement } from '@nonoun/native-ui';
12
12
  * </n-chat-feed>
13
13
  * ```
14
14
  *
15
+ * ### Virtualization (opt-in)
16
+ *
17
+ * ```html
18
+ * <n-chat-feed virtual virtual-item-height="80" virtual-overscan="8">
19
+ * </n-chat-feed>
20
+ * ```
21
+ *
22
+ * Set `items` and `itemRenderer` properties for programmatic data-driven rendering.
23
+ *
15
24
  * @attr {boolean} auto-scroll - Enable auto-scroll to bottom on new content (default: true)
25
+ * @attr {boolean} virtual - Enable virtual scroll windowing
26
+ * @attr {string} virtual-item-height - Estimated item height in px (default: 80)
27
+ * @attr {string} virtual-overscan - Number of extra items to render outside viewport (default: 5)
16
28
  * @fires native:feed-scroll - Fired when scroll pinned state changes
29
+ * @fires native:range-change - Fired when virtual scroll range changes
17
30
  */
18
31
  export declare class NChatFeed extends NativeElement {
19
32
  #private;
@@ -22,6 +35,12 @@ export declare class NChatFeed extends NativeElement {
22
35
  get isPinned(): boolean;
23
36
  /** Scroll to the bottom of the feed. */
24
37
  scrollToBottom(smooth?: boolean): void;
38
+ /** Data items for virtual rendering. */
39
+ get items(): unknown[];
40
+ set items(val: unknown[]);
41
+ /** Callback that creates an HTMLElement from a data item. */
42
+ get itemRenderer(): ((item: unknown, index: number) => HTMLElement) | null;
43
+ set itemRenderer(fn: ((item: unknown, index: number) => HTMLElement) | null);
25
44
  attributeChangedCallback(name: string, old: string | null, val: string | null): void;
26
45
  setup(): void;
27
46
  teardown(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-feed-element.d.ts","sourceRoot":"","sources":["../../src/feed/chat-feed-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,MAAM,mBAAmB,CAAC;AAI1D;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,SAAU,SAAQ,aAAa;;IAC1C,MAAM,CAAC,kBAAkB,WAAiC;;IAc1D,IAAI,QAAQ,IAAI,OAAO,CAAiC;IAExD,wCAAwC;IACxC,cAAc,CAAC,MAAM,UAAO,GAAG,IAAI;IAUnC,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUpF,KAAK,IAAI,IAAI;IA4Bb,QAAQ,IAAI,IAAI;CAuCjB"}
1
+ {"version":3,"file":"chat-feed-element.d.ts","sourceRoot":"","sources":["../../src/feed/chat-feed-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAmC,MAAM,mBAAmB,CAAC;AAInF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,SAAU,SAAQ,aAAa;;IAC1C,MAAM,CAAC,kBAAkB,WAAuF;;IAoBhH,IAAI,QAAQ,IAAI,OAAO,CAAiC;IAExD,wCAAwC;IACxC,cAAc,CAAC,MAAM,UAAO,GAAG,IAAI;IAQnC,wCAAwC;IACxC,IAAI,KAAK,IAAI,OAAO,EAAE,CAA8B;IACpD,IAAI,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,EAKvB;IAED,6DAA6D;IAC7D,IAAI,YAAY,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,GAAG,IAAI,CAA+B;IACzG,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,GAAG,IAAI,EAE1E;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IA0BpF,KAAK,IAAI,IAAI;IAiCb,QAAQ,IAAI,IAAI;CA6HjB"}
package/dist/index.d.ts CHANGED
@@ -1,15 +1,18 @@
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';
8
+ export type { ChatMessageActionDef } from './message/chat-message-element.ts';
9
+ export { ACTION_REGISTRY, ROLE_DEFAULTS } from './message/chat-message-element.ts';
7
10
  export type { SeedOption } from './message/chat-message-seed-element.ts';
8
11
  export type { StructuredOption } from './message/chat-input-structured-element.ts';
9
12
  export type { GenUINode } from './message/chat-message-genui-element.ts';
10
13
  export { renderMarkdown, renderInline, sanitizeHtml } from './message/chat-message-text-element.ts';
11
- export type { ChatStreamChunk, StreamFormat, ChatTransportOptions, ChatStreamEvent, ChatTransport, } from './stream/index.ts';
12
- export { parseSSE, parseNDJSON, parseJSON, detectFormat, createChatStream, createChatTransport, } from './stream/index.ts';
14
+ export type { ChatStreamChunk, StreamFormat, ChatTransportOptions, ChatStreamEvent, ChatTransport, TransportState, TransportStatus, TransportStateCallback, RetryOptions, StreamEndReason, } from './stream/index.ts';
15
+ export { parseSSE, parseNDJSON, parseJSON, detectFormat, createChatStream, createChatTransport, classifyStreamEnd, classifyHttpError, backoffDelay, } from './stream/index.ts';
13
16
  export type { TelemetryCorrelation, TelemetryTiming, TelemetryRetry, TelemetryLevel, TelemetryEvent, TelemetryRedactor, } from './telemetry/index.ts';
14
17
  export { CHAT_EVENTS, SAFE_FIELDS, SENSITIVE_FIELDS, scrubPII, createDefaultRedactor, TelemetryEmitter, } from './telemetry/index.ts';
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAGrD,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,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,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GACpB,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"}
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"}
@@ -1,4 +1,10 @@
1
1
  import { NativeElement } from '@nonoun/native-ui';
2
+ export interface ChatMessageActionDef {
3
+ label: string;
4
+ icon: string;
5
+ }
6
+ export declare const ACTION_REGISTRY: Record<string, ChatMessageActionDef>;
7
+ export declare const ROLE_DEFAULTS: Record<string, string[]>;
2
8
  /**
3
9
  * Individual chat message bubble.
4
10
  *
@@ -8,8 +14,12 @@ import { NativeElement } from '@nonoun/native-ui';
8
14
  * @attr {string} role - `user` | `assistant` | `system`
9
15
  * @attr {string} message-id - Unique message identifier
10
16
  * @attr {string} timestamp - Epoch milliseconds
11
- * @attr {string} status - `sending` | `sent` | `error` | `streaming`
17
+ * @attr {string} status - `sending` | `sent` | `error` | `streaming` | `partial`
18
+ * @attr {string} actions - Comma-separated action list, or `"none"` to suppress
19
+ * @attr {string} actions-style - `"label"` (default) | `"icon"` | `"icon-label"`
20
+ * @attr {string} actions-position - `"inside"` (default) | `"below"` — toolbar placement
12
21
  * @fires native:message-action - Fired when an action button is clicked
22
+ * @fires native:continue-request - Fired when continue is requested for a partial message
13
23
  */
14
24
  export declare class NChatMessage extends NativeElement {
15
25
  #private;
@@ -21,6 +31,12 @@ export declare class NChatMessage extends NativeElement {
21
31
  get timestamp(): number;
22
32
  get status(): string;
23
33
  set status(val: string);
34
+ get actions(): string | null;
35
+ set actions(val: string | null);
36
+ get actionsStyle(): string;
37
+ set actionsStyle(val: string);
38
+ get actionsPosition(): string;
39
+ set actionsPosition(val: string);
24
40
  attributeChangedCallback(name: string, old: string | null, val: string | null): void;
25
41
  setup(): void;
26
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;AAE1D;;;;;;;;;;;GAWG;AACH,qBAAa,YAAa,SAAQ,aAAa;;IAC7C,MAAM,CAAC,kBAAkB,WAAiD;;IAc1E,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;IAID,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAWpF,KAAK,IAAI,IAAI;IAeb,QAAQ,IAAI,IAAI;CAsDjB"}
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;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAc,SAAQ,aAAa;;IAC9C,MAAM,CAAC,kBAAkB,WAAsB;;IAS/C,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"}
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"}
@@ -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
- border-bottom: 1px solid var(--n-border-muted);
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
- border-top: 1px solid var(--n-border-muted);
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. */
@@ -150,6 +172,19 @@
150
172
  user-select: none;
151
173
  }
152
174
 
175
+ /* ── Virtual scroll spacers ── */
176
+
177
+ :where(n-chat-feed) > :where(.n-chat-feed-virtual-container) {
178
+ display: flex;
179
+ flex-direction: column;
180
+ gap: var(--n-chat-gap);
181
+ }
182
+
183
+ :where(n-chat-feed) :where(.n-virtual-spacer-top),
184
+ :where(n-chat-feed) :where(.n-virtual-spacer-bottom) {
185
+ flex-shrink: 0;
186
+ }
187
+
153
188
  :where(n-chat-feed[hidden]) { display: none; }
154
189
 
155
190
  /* ══════════════════════════════════════════════════
@@ -180,6 +215,15 @@
180
215
  min-width: 0;
181
216
  }
182
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
+
183
227
  :where(n-chat-messages[hidden]) { display: none; }
184
228
 
185
229
  /* ══════════════════════════════════════════════════
@@ -229,7 +273,13 @@
229
273
 
230
274
  padding-block: var(--n-chat-bubble-padding-block);
231
275
  padding-inline: var(--n-chat-bubble-padding-inline);
232
- border-radius: var(--n-chat-bubble-radius);
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);
233
283
 
234
284
  background: var(--n-chat-bubble-assistant);
235
285
  color: var(--n-chat-bubble-assistant-color);
@@ -238,8 +288,14 @@
238
288
  overflow-wrap: break-word;
239
289
  }
240
290
 
241
- /* User bubble */
291
+ /* User bubble: avatar on right — flip avatar-side / far-side corners */
242
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
+
243
299
  background: var(--n-chat-bubble-user);
244
300
  color: var(--n-chat-bubble-user-color);
245
301
  }
@@ -254,6 +310,11 @@
254
310
  border: 1px solid var(--n-border-danger);
255
311
  }
256
312
 
313
+ /* Partial status — stream ended without explicit completion */
314
+ [status="partial"]:where(n-chat-message) {
315
+ border-bottom: 2px dashed var(--n-border-muted);
316
+ }
317
+
257
318
  /* ── Message actions toolbar ── */
258
319
 
259
320
  :where(n-chat-message) > :where(.n-chat-message-actions) {
@@ -267,6 +328,31 @@
267
328
  opacity: 1;
268
329
  }
269
330
 
331
+ /* Partial status — always show actions (contains continue button) */
332
+ [status="partial"]:where(n-chat-message) > :where(.n-chat-message-actions) {
333
+ opacity: 1;
334
+ }
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
+
270
356
  :where(n-chat-message[hidden]) { display: none; }
271
357
 
272
358
  /* ══════════════════════════════════════════════════