@salla.sa/ui-ai-kit-core 2.1.0 → 2.2.0

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.
Files changed (128) hide show
  1. package/dist/cjs/ai-agent-error.cjs.entry.js +3 -3
  2. package/dist/cjs/ai-card.cjs.entry.js +3 -3
  3. package/dist/cjs/ai-chat-container.cjs.entry.js +74 -14
  4. package/dist/cjs/ai-chat-header.cjs.entry.js +64 -8
  5. package/dist/cjs/ai-chat-message.cjs.entry.js +10 -4
  6. package/dist/cjs/ai-conversation-list.cjs.entry.js +38 -22
  7. package/dist/cjs/ai-conversation-summary.cjs.entry.js +3 -3
  8. package/dist/cjs/ai-icon.cjs.entry.js +2 -2
  9. package/dist/cjs/ai-in-chat-browser.cjs.entry.js +68 -0
  10. package/dist/cjs/ai-link.cjs.entry.js +3 -3
  11. package/dist/cjs/ai-loading.cjs.entry.js +3 -3
  12. package/dist/cjs/ai-message-input.cjs.entry.js +12 -7
  13. package/dist/cjs/ai-rating.cjs.entry.js +26 -18
  14. package/dist/cjs/ai-route-decision.cjs.entry.js +3 -3
  15. package/dist/cjs/ai-suggestion.cjs.entry.js +3 -3
  16. package/dist/cjs/ai-voice-input.cjs.entry.js +2 -2
  17. package/dist/cjs/icon-registry-D-m8GW4D.js +126 -0
  18. package/dist/cjs/{index-Bs23yVuF.js → index-BQ8Az7-D.js} +71 -1
  19. package/dist/cjs/loader.cjs.js +2 -2
  20. package/dist/cjs/ui-ai-kit.cjs.js +2 -2
  21. package/dist/collection/collection-manifest.json +2 -1
  22. package/dist/collection/components/ai-agent-error/ai-agent-error.js +1 -1
  23. package/dist/collection/components/ai-card/ai-card.js +2 -2
  24. package/dist/collection/components/ai-chat-container/ai-chat-container.css +175 -3
  25. package/dist/collection/components/ai-chat-container/ai-chat-container.js +166 -11
  26. package/dist/collection/components/ai-chat-header/ai-chat-header.css +107 -0
  27. package/dist/collection/components/ai-chat-header/ai-chat-header.js +242 -8
  28. package/dist/collection/components/ai-chat-message/ai-chat-message.js +8 -2
  29. package/dist/collection/components/ai-conversation-list/ai-conversation-list.css +116 -7
  30. package/dist/collection/components/ai-conversation-list/ai-conversation-list.js +140 -26
  31. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.js +1 -1
  32. package/dist/collection/components/ai-icon/ai-icon.js +1 -1
  33. package/dist/collection/components/ai-in-chat-browser/ai-in-chat-browser.css +88 -0
  34. package/dist/collection/components/ai-in-chat-browser/ai-in-chat-browser.js +171 -0
  35. package/dist/collection/components/ai-link/ai-link.js +1 -1
  36. package/dist/collection/components/ai-loading/ai-loading.js +1 -1
  37. package/dist/collection/components/ai-message-input/ai-message-input.css +46 -5
  38. package/dist/collection/components/ai-message-input/ai-message-input.js +10 -5
  39. package/dist/collection/components/ai-rating/ai-rating.css +22 -2
  40. package/dist/collection/components/ai-rating/ai-rating.js +46 -17
  41. package/dist/collection/components/ai-route-decision/ai-route-decision.js +1 -1
  42. package/dist/collection/components/ai-suggestion/ai-suggestion.js +2 -2
  43. package/dist/collection/components/ai-voice-input/ai-voice-input.js +1 -1
  44. package/dist/collection/utils/icon-registry.js +27 -7
  45. package/dist/components/ai-agent-error.js +1 -1
  46. package/dist/components/ai-card.js +1 -1
  47. package/dist/components/ai-chat-container.js +1 -1
  48. package/dist/components/ai-chat-header.js +1 -1
  49. package/dist/components/ai-chat-message.js +2 -2
  50. package/dist/components/ai-conversation-list.js +1 -1
  51. package/dist/components/ai-conversation-summary.js +1 -1
  52. package/dist/components/ai-icon.js +1 -1
  53. package/dist/components/ai-in-chat-browser.d.ts +11 -0
  54. package/dist/components/ai-in-chat-browser.js +1 -0
  55. package/dist/components/ai-link.js +1 -1
  56. package/dist/components/ai-loading.js +1 -1
  57. package/dist/components/ai-message-input.js +1 -1
  58. package/dist/components/ai-rating.js +1 -1
  59. package/dist/components/ai-route-decision.js +1 -1
  60. package/dist/components/ai-suggestion.js +1 -1
  61. package/dist/components/ai-voice-input.js +1 -1
  62. package/dist/components/index.js +1 -1
  63. package/dist/components/p-B3gdcdCK.js +1 -0
  64. package/dist/components/{p-Bbmjx9lq.js → p-C2LB8D3t.js} +1 -1
  65. package/dist/components/p-CXJ3iEt8.js +1 -0
  66. package/dist/components/p-D4mVoP6B.js +1 -0
  67. package/dist/components/p-DKsh1ZQX.js +1 -0
  68. package/dist/components/p-DlD8m3rf.js +1 -0
  69. package/dist/components/{p-C5gkZloN.js → p-NKAwri_g.js} +1 -1
  70. package/dist/esm/ai-agent-error.entry.js +3 -3
  71. package/dist/esm/ai-card.entry.js +3 -3
  72. package/dist/esm/ai-chat-container.entry.js +74 -14
  73. package/dist/esm/ai-chat-header.entry.js +64 -8
  74. package/dist/esm/ai-chat-message.entry.js +10 -4
  75. package/dist/esm/ai-conversation-list.entry.js +38 -22
  76. package/dist/esm/ai-conversation-summary.entry.js +3 -3
  77. package/dist/esm/ai-icon.entry.js +2 -2
  78. package/dist/esm/ai-in-chat-browser.entry.js +66 -0
  79. package/dist/esm/ai-link.entry.js +3 -3
  80. package/dist/esm/ai-loading.entry.js +3 -3
  81. package/dist/esm/ai-message-input.entry.js +12 -7
  82. package/dist/esm/ai-rating.entry.js +26 -18
  83. package/dist/esm/ai-route-decision.entry.js +3 -3
  84. package/dist/esm/ai-suggestion.entry.js +3 -3
  85. package/dist/esm/ai-voice-input.entry.js +2 -2
  86. package/dist/esm/icon-registry-DlD8m3rf.js +124 -0
  87. package/dist/esm/{index-hxWjzqcH.js → index-BSQ0GkzI.js} +71 -1
  88. package/dist/esm/loader.js +3 -3
  89. package/dist/esm/ui-ai-kit.js +3 -3
  90. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +18 -1
  91. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +27 -1
  92. package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +12 -2
  93. package/dist/types/components/ai-in-chat-browser/ai-in-chat-browser.d.ts +22 -0
  94. package/dist/types/components/ai-rating/ai-rating.d.ts +4 -1
  95. package/dist/types/components.d.ts +283 -8
  96. package/dist/types/utils/icon-registry.d.ts +1 -1
  97. package/dist/ui-ai-kit/{p-889c6b00.entry.js → p-1e8e6440.entry.js} +1 -1
  98. package/dist/ui-ai-kit/p-29d84924.entry.js +1 -0
  99. package/dist/ui-ai-kit/p-39a2d4c3.entry.js +1 -0
  100. package/dist/ui-ai-kit/{p-ccaec7b4.entry.js → p-3a86919b.entry.js} +1 -1
  101. package/dist/ui-ai-kit/{p-5ea933a4.entry.js → p-47797619.entry.js} +1 -1
  102. package/dist/ui-ai-kit/{p-b33e92ea.entry.js → p-658d8b24.entry.js} +1 -1
  103. package/dist/ui-ai-kit/{p-3268aa48.entry.js → p-73cbb80b.entry.js} +1 -1
  104. package/dist/ui-ai-kit/p-77ef8015.entry.js +1 -0
  105. package/dist/ui-ai-kit/{p-999dd7c8.entry.js → p-78fb4ceb.entry.js} +1 -1
  106. package/dist/ui-ai-kit/p-849cd7e2.entry.js +1 -0
  107. package/dist/ui-ai-kit/p-8cb807f3.entry.js +1 -0
  108. package/dist/ui-ai-kit/p-BSQ0GkzI.js +2 -0
  109. package/dist/ui-ai-kit/p-DlD8m3rf.js +1 -0
  110. package/dist/ui-ai-kit/p-abd68089.entry.js +1 -0
  111. package/dist/ui-ai-kit/{p-27bf454d.entry.js → p-b88808a4.entry.js} +1 -1
  112. package/dist/ui-ai-kit/{p-6b9b1022.entry.js → p-c9dca99e.entry.js} +1 -1
  113. package/dist/ui-ai-kit/{p-2342431f.entry.js → p-dac67692.entry.js} +1 -1
  114. package/dist/ui-ai-kit/{p-9a4b8c7e.entry.js → p-eb40ffd0.entry.js} +2 -2
  115. package/dist/ui-ai-kit/ui-ai-kit.css +1 -1
  116. package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -1
  117. package/package.json +1 -1
  118. package/dist/cjs/icon-registry-BKb9-2Nt.js +0 -106
  119. package/dist/components/p-CAnlgwx0.js +0 -1
  120. package/dist/components/p-SJZ6Ujn9.js +0 -1
  121. package/dist/esm/icon-registry-SJZ6Ujn9.js +0 -104
  122. package/dist/ui-ai-kit/p-1cce63d4.entry.js +0 -1
  123. package/dist/ui-ai-kit/p-1e7608ee.entry.js +0 -1
  124. package/dist/ui-ai-kit/p-2a49ee93.entry.js +0 -1
  125. package/dist/ui-ai-kit/p-6b61d00f.entry.js +0 -1
  126. package/dist/ui-ai-kit/p-SJZ6Ujn9.js +0 -1
  127. package/dist/ui-ai-kit/p-a424e69b.entry.js +0 -1
  128. package/dist/ui-ai-kit/p-hxWjzqcH.js +0 -2
@@ -1,6 +1,7 @@
1
1
  import { Host, h } from "@stencil/core";
2
2
  import { iconRegistry } from "../../utils/icon-registry";
3
3
  export class AiChatHeader {
4
+ el;
4
5
  /** Layout variant */
5
6
  mode = 'agent';
6
7
  /** Agent mode: conversation title */
@@ -16,7 +17,20 @@ export class AiChatHeader {
16
17
  isDraggable = false;
17
18
  /** Human mode: status indicator variant */
18
19
  statusIndicator = 'online';
20
+ /** Browser mode: page title shown in the header */
21
+ pageTitle = '';
22
+ /** Browser mode: the external URL to link to */
23
+ pageUrl = '';
24
+ /** Conversation list: items to display in the dropdown panel */
25
+ conversationItems = [];
26
+ /** Conversation list: ID of the currently active conversation */
27
+ conversationActiveId = '';
28
+ /** Conversation list: show skeleton loading state */
29
+ conversationLoading = false;
30
+ /** Show a shimmer skeleton in place of the conversation title (e.g. while loading conversation) */
31
+ titleLoading = false;
19
32
  avatarError = false;
33
+ dropdownOpen = false;
20
34
  /** Cancel / close button */
21
35
  closeClick;
22
36
  /** Pencil-edit button (agent mode) */
@@ -32,6 +46,17 @@ export class AiChatHeader {
32
46
  * Composed + bubbling so ai-chat-container can receive it across shadow roots.
33
47
  */
34
48
  headerDragStart;
49
+ /** Open-external button (browser mode) */
50
+ openExternal;
51
+ /** Fired when a conversation is selected from the dropdown list */
52
+ conversationSelect;
53
+ /** Fired when a conversation delete button is clicked */
54
+ conversationDelete;
55
+ handleDocumentClick(event) {
56
+ if (this.dropdownOpen && !this.el.contains(event.target)) {
57
+ this.dropdownOpen = false;
58
+ }
59
+ }
35
60
  renderIcon(name, width, height) {
36
61
  const icon = iconRegistry[name];
37
62
  if (!icon)
@@ -44,18 +69,39 @@ export class AiChatHeader {
44
69
  if (!this.agentAvatar || this.avatarError) {
45
70
  return h("div", { class: "avatar-fallback" }, fallbackLetter);
46
71
  }
47
- return (h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName, onError: () => { this.avatarError = true; } }));
72
+ return (h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName, onError: () => {
73
+ this.avatarError = true;
74
+ } }));
48
75
  }
49
76
  renderDragBtn() {
50
- return this.isDraggable && (h("button", { class: "action-btn drag-btn", "aria-label": "\u0633\u062D\u0628 / Drag", onPointerDown: (e) => {
77
+ return (this.isDraggable && (h("button", { class: "action-btn drag-btn", "aria-label": "\u0633\u062D\u0628 / Drag", onPointerDown: (e) => {
51
78
  e.preventDefault();
52
79
  this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
53
- } }, this.renderIcon('drag', 11, 15)));
80
+ } }, this.renderIcon('drag', 11, 15))));
81
+ }
82
+ handleConversationSelect = (e) => {
83
+ e.stopPropagation();
84
+ this.conversationSelect.emit(e.detail);
85
+ this.dropdownOpen = false;
86
+ };
87
+ handleConversationDelete = (e) => {
88
+ e.stopPropagation();
89
+ this.conversationDelete.emit(e.detail);
90
+ };
91
+ renderConversationDropdown() {
92
+ if (!this.dropdownOpen || this.mode !== 'agent')
93
+ return null;
94
+ return (h("div", { class: "conversation-dropdown" }, h("ai-conversation-list", { items: this.conversationItems, activeId: this.conversationActiveId, loading: this.conversationLoading, onConversationSelect: this.handleConversationSelect, onConversationDelete: this.handleConversationDelete })));
54
95
  }
55
96
  renderAgentMode() {
56
97
  return [
57
98
  this.renderDragBtn(),
58
- h("div", { class: "content agent dropdown-trigger", role: "button", onClick: () => this.dropdownClick.emit(), "aria-haspopup": "listbox", "aria-expanded": false, "aria-label": `${this.conversation}, افتح قائمة المحادثات` }, h("span", { class: "title" }, this.conversation), h("span", { class: "dropdown-chevron" }, this.renderIcon('chevron-down', 24, 24))),
99
+ h("div", { class: "content agent dropdown-trigger", role: "button", onClick: () => {
100
+ if (this.titleLoading)
101
+ return;
102
+ this.dropdownOpen = !this.dropdownOpen;
103
+ this.dropdownClick.emit();
104
+ }, "aria-haspopup": "listbox", "aria-expanded": this.dropdownOpen, "aria-label": `${this.conversation}, افتح قائمة المحادثات` }, this.titleLoading ? (h("span", { class: "title-skeleton", "aria-busy": "true", "aria-label": "\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062D\u0645\u064A\u0644" })) : (h("span", { class: "title" }, this.conversation)), !this.titleLoading && (h("span", { class: `dropdown-chevron${this.dropdownOpen ? ' open' : ''}` }, this.renderIcon('chevron-down', 24, 24)))),
59
105
  h("div", { class: "actions" }, h("button", { class: "action-btn", "aria-label": "\u062A\u0639\u062F\u064A\u0644 / Edit", onClick: () => this.editClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
60
106
  ];
61
107
  }
@@ -66,8 +112,15 @@ export class AiChatHeader {
66
112
  h("div", { class: "actions" }, h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
67
113
  ];
68
114
  }
115
+ renderBrowserMode() {
116
+ return [
117
+ this.renderDragBtn(),
118
+ h("div", { class: "content browser" }, h("button", { class: "back-btn", "aria-label": "\u0631\u062C\u0648\u0639 / Back", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24)), h("span", { class: "browser-title" }, this.pageTitle), h("button", { class: "browser-link-btn", "aria-label": "\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629 / Open externally", onClick: () => this.openExternal.emit(this.pageUrl) }, this.renderIcon('link', 14, 14))),
119
+ h("div", { class: "actions" }, h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
120
+ ];
121
+ }
69
122
  render() {
70
- return (h(Host, { key: '66ad39b3b123aebf528b675e9b26a3004693a137' }, h("div", { key: '355be9c94e460c995a9fc58484c891c071ed9604', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.renderHumanMode())));
123
+ return (h(Host, { key: '8e1fe67030a0cb1eb94327f093327fb23d4faf01' }, h("div", { key: '14766bd663e5fe027f1a3320bd3f16d79e9feb45', class: "header-wrapper" }, h("div", { key: 'bef30f621ba3b148f4af055347eb707bc8f64b15', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.mode === 'human' ? this.renderHumanMode() : this.renderBrowserMode()), this.renderConversationDropdown())));
71
124
  }
72
125
  static get is() { return "ai-chat-header"; }
73
126
  static get encapsulation() { return "shadow"; }
@@ -87,8 +140,8 @@ export class AiChatHeader {
87
140
  "type": "string",
88
141
  "mutable": false,
89
142
  "complexType": {
90
- "original": "'agent' | 'human'",
91
- "resolved": "\"agent\" | \"human\"",
143
+ "original": "'agent' | 'human' | 'browser'",
144
+ "resolved": "\"agent\" | \"browser\" | \"human\"",
92
145
  "references": {}
93
146
  },
94
147
  "required": false,
@@ -242,12 +295,138 @@ export class AiChatHeader {
242
295
  "reflect": false,
243
296
  "attribute": "status-indicator",
244
297
  "defaultValue": "'online'"
298
+ },
299
+ "pageTitle": {
300
+ "type": "string",
301
+ "mutable": false,
302
+ "complexType": {
303
+ "original": "string",
304
+ "resolved": "string",
305
+ "references": {}
306
+ },
307
+ "required": false,
308
+ "optional": false,
309
+ "docs": {
310
+ "tags": [],
311
+ "text": "Browser mode: page title shown in the header"
312
+ },
313
+ "getter": false,
314
+ "setter": false,
315
+ "reflect": false,
316
+ "attribute": "page-title",
317
+ "defaultValue": "''"
318
+ },
319
+ "pageUrl": {
320
+ "type": "string",
321
+ "mutable": false,
322
+ "complexType": {
323
+ "original": "string",
324
+ "resolved": "string",
325
+ "references": {}
326
+ },
327
+ "required": false,
328
+ "optional": false,
329
+ "docs": {
330
+ "tags": [],
331
+ "text": "Browser mode: the external URL to link to"
332
+ },
333
+ "getter": false,
334
+ "setter": false,
335
+ "reflect": false,
336
+ "attribute": "page-url",
337
+ "defaultValue": "''"
338
+ },
339
+ "conversationItems": {
340
+ "type": "unknown",
341
+ "mutable": false,
342
+ "complexType": {
343
+ "original": "ConversationItem[]",
344
+ "resolved": "ConversationItem[]",
345
+ "references": {
346
+ "ConversationItem": {
347
+ "location": "import",
348
+ "path": "../ai-conversation-list/ai-conversation-list",
349
+ "id": "src/components/ai-conversation-list/ai-conversation-list.tsx::ConversationItem",
350
+ "referenceLocation": "ConversationItem"
351
+ }
352
+ }
353
+ },
354
+ "required": false,
355
+ "optional": false,
356
+ "docs": {
357
+ "tags": [],
358
+ "text": "Conversation list: items to display in the dropdown panel"
359
+ },
360
+ "getter": false,
361
+ "setter": false,
362
+ "defaultValue": "[]"
363
+ },
364
+ "conversationActiveId": {
365
+ "type": "string",
366
+ "mutable": false,
367
+ "complexType": {
368
+ "original": "string",
369
+ "resolved": "string",
370
+ "references": {}
371
+ },
372
+ "required": false,
373
+ "optional": false,
374
+ "docs": {
375
+ "tags": [],
376
+ "text": "Conversation list: ID of the currently active conversation"
377
+ },
378
+ "getter": false,
379
+ "setter": false,
380
+ "reflect": false,
381
+ "attribute": "conversation-active-id",
382
+ "defaultValue": "''"
383
+ },
384
+ "conversationLoading": {
385
+ "type": "boolean",
386
+ "mutable": false,
387
+ "complexType": {
388
+ "original": "boolean",
389
+ "resolved": "boolean",
390
+ "references": {}
391
+ },
392
+ "required": false,
393
+ "optional": false,
394
+ "docs": {
395
+ "tags": [],
396
+ "text": "Conversation list: show skeleton loading state"
397
+ },
398
+ "getter": false,
399
+ "setter": false,
400
+ "reflect": false,
401
+ "attribute": "conversation-loading",
402
+ "defaultValue": "false"
403
+ },
404
+ "titleLoading": {
405
+ "type": "boolean",
406
+ "mutable": false,
407
+ "complexType": {
408
+ "original": "boolean",
409
+ "resolved": "boolean",
410
+ "references": {}
411
+ },
412
+ "required": false,
413
+ "optional": false,
414
+ "docs": {
415
+ "tags": [],
416
+ "text": "Show a shimmer skeleton in place of the conversation title (e.g. while loading conversation)"
417
+ },
418
+ "getter": false,
419
+ "setter": false,
420
+ "reflect": false,
421
+ "attribute": "title-loading",
422
+ "defaultValue": "false"
245
423
  }
246
424
  };
247
425
  }
248
426
  static get states() {
249
427
  return {
250
- "avatarError": {}
428
+ "avatarError": {},
429
+ "dropdownOpen": {}
251
430
  };
252
431
  }
253
432
  static get events() {
@@ -341,6 +520,61 @@ export class AiChatHeader {
341
520
  "resolved": "{ clientX: number; clientY: number; }",
342
521
  "references": {}
343
522
  }
523
+ }, {
524
+ "method": "openExternal",
525
+ "name": "openExternal",
526
+ "bubbles": true,
527
+ "cancelable": true,
528
+ "composed": true,
529
+ "docs": {
530
+ "tags": [],
531
+ "text": "Open-external button (browser mode)"
532
+ },
533
+ "complexType": {
534
+ "original": "string",
535
+ "resolved": "string",
536
+ "references": {}
537
+ }
538
+ }, {
539
+ "method": "conversationSelect",
540
+ "name": "conversationSelect",
541
+ "bubbles": true,
542
+ "cancelable": true,
543
+ "composed": true,
544
+ "docs": {
545
+ "tags": [],
546
+ "text": "Fired when a conversation is selected from the dropdown list"
547
+ },
548
+ "complexType": {
549
+ "original": "string",
550
+ "resolved": "string",
551
+ "references": {}
552
+ }
553
+ }, {
554
+ "method": "conversationDelete",
555
+ "name": "conversationDelete",
556
+ "bubbles": true,
557
+ "cancelable": true,
558
+ "composed": true,
559
+ "docs": {
560
+ "tags": [],
561
+ "text": "Fired when a conversation delete button is clicked"
562
+ },
563
+ "complexType": {
564
+ "original": "string",
565
+ "resolved": "string",
566
+ "references": {}
567
+ }
568
+ }];
569
+ }
570
+ static get elementRef() { return "el"; }
571
+ static get listeners() {
572
+ return [{
573
+ "name": "click",
574
+ "method": "handleDocumentClick",
575
+ "target": "document",
576
+ "capture": false,
577
+ "passive": false
344
578
  }];
345
579
  }
346
580
  }
@@ -126,7 +126,13 @@ export class AiChatMessage {
126
126
  getRenderedContent() {
127
127
  if (!this.content)
128
128
  return '';
129
- return DOMPurify.sanitize(this.parseMarkdown(this.content), SANITIZE_CONFIG);
129
+ try {
130
+ return DOMPurify.sanitize(this.parseMarkdown(this.content), SANITIZE_CONFIG);
131
+ }
132
+ catch {
133
+ // Fallback: render raw text safely if markdown parsing fails
134
+ return DOMPurify.sanitize(`<p>${this.content.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>')}</p>`, SANITIZE_CONFIG);
135
+ }
130
136
  }
131
137
  getRelativeTime() {
132
138
  if (!this.timestamp)
@@ -195,7 +201,7 @@ export class AiChatMessage {
195
201
  } })), h("slot", null), showActions && this.renderActionsBar()), (this.agentName || this.timestamp) && (h("div", { class: "agent-info" }, this.agentName && h("span", { class: "agent-info-name" }, this.agentName), this.agentName && this.timestamp && this.renderIcon('eclipse', 10), this.timestamp && h("span", { class: "agent-info-time" }, this.getRelativeTime()))))));
196
202
  }
197
203
  render() {
198
- return h(Host, { key: 'ceb0df75b3fc5ba2bd7494e150e679960707b891' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
204
+ return h(Host, { key: 'b6fe466c9830e69c3ae6f405daa9e77ef3f75aca' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
199
205
  }
200
206
  static get is() { return "ai-chat-message"; }
201
207
  static get encapsulation() { return "shadow"; }
@@ -1,13 +1,17 @@
1
1
  :host {
2
- display: block;
2
+ display: flex;
3
+ flex-direction: column;
3
4
  height: 100%;
5
+ min-height: 0;
6
+ overflow: hidden;
4
7
  }
5
8
 
6
9
  .conversation-list {
7
10
  display: flex;
8
11
  flex-direction: column;
9
12
  gap: 8px;
10
- height: 100%;
13
+ flex: 1;
14
+ min-height: 0;
11
15
  background: var(--ai-bg-surface);
12
16
  }
13
17
 
@@ -15,23 +19,28 @@
15
19
 
16
20
  .list-scroll {
17
21
  flex: 1;
22
+ min-height: 0;
18
23
  overflow-y: auto;
19
24
  padding: 0 8px 12px;
20
25
  scrollbar-width: thin;
21
- scrollbar-color: var(--ai-scrollbar-thumb) var(--ai-scrollbar-track);
26
+ scrollbar-color: var(--ai-scrollbar-thumb) transparent;
22
27
  }
23
28
 
24
29
  .list-scroll::-webkit-scrollbar {
25
- width: 4px;
30
+ width: 3px;
26
31
  }
27
32
 
28
33
  .list-scroll::-webkit-scrollbar-track {
29
- background: var(--ai-scrollbar-track);
34
+ background: transparent;
30
35
  }
31
36
 
32
37
  .list-scroll::-webkit-scrollbar-thumb {
33
38
  background: var(--ai-scrollbar-thumb);
34
- border-radius: 4px;
39
+ border-radius: 99px;
40
+ }
41
+
42
+ .list-scroll::-webkit-scrollbar-thumb:hover {
43
+ background: var(--ai-scrollbar-thumb-hover);
35
44
  }
36
45
 
37
46
  /* ── Conversation item ─────────────────────────────────── */
@@ -152,6 +161,106 @@
152
161
  line-height: 0;
153
162
  }
154
163
 
164
+ /* ── Empty state ───────────────────────────────────────── */
165
+
166
+ .empty-state {
167
+ display: flex;
168
+ flex-direction: column;
169
+ align-items: center;
170
+ justify-content: center;
171
+ gap: 8px;
172
+ padding: 40px 16px;
173
+ text-align: center;
174
+ }
175
+
176
+ .empty-state__icon {
177
+ display: flex;
178
+ align-items: center;
179
+ justify-content: center;
180
+ width: 40px;
181
+ height: 40px;
182
+ border-radius: 10px;
183
+ background: var(--ai-bg-card);
184
+ color: var(--ai-text-muted);
185
+ line-height: 0;
186
+ }
187
+
188
+ .empty-state__icon .icon-wrap {
189
+ display: inline-flex;
190
+ align-items: center;
191
+ line-height: 0;
192
+ }
193
+
194
+ .empty-state__text {
195
+ margin: 0;
196
+ font-size: 13px;
197
+ color: var(--ai-text-muted);
198
+ line-height: 1.4;
199
+ }
200
+
201
+ /* ── Error state ───────────────────────────────────────── */
202
+
203
+ .error-state {
204
+ display: flex;
205
+ flex-direction: column;
206
+ align-items: center;
207
+ justify-content: center;
208
+ gap: 8px;
209
+ padding: 40px 16px;
210
+ text-align: center;
211
+ }
212
+
213
+ .error-state__icon {
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ width: 40px;
218
+ height: 40px;
219
+ border-radius: 10px;
220
+ background: var(--ai-status-danger-bg, rgba(239, 68, 68, 0.1));
221
+ color: var(--ai-status-danger, #ef4444);
222
+ line-height: 0;
223
+ }
224
+
225
+ .error-state__icon .icon-wrap {
226
+ display: inline-flex;
227
+ align-items: center;
228
+ line-height: 0;
229
+ }
230
+
231
+ .error-state__text {
232
+ margin: 0;
233
+ font-size: 13px;
234
+ color: var(--ai-text-muted);
235
+ line-height: 1.4;
236
+ }
237
+
238
+ .error-state__retry {
239
+ display: inline-flex;
240
+ align-items: center;
241
+ gap: 4px;
242
+ margin-top: 4px;
243
+ padding: 6px 14px;
244
+ font-size: 12px;
245
+ font-weight: 600;
246
+ color: var(--ai-text-primary);
247
+ background: var(--ai-bg-card);
248
+ border: 1px solid var(--ai-border-default);
249
+ border-radius: 8px;
250
+ cursor: pointer;
251
+ transition: background 0.15s, box-shadow 0.15s;
252
+ }
253
+
254
+ .error-state__retry:hover {
255
+ box-shadow: var(--ai-shadow-sm);
256
+ }
257
+
258
+ .error-state__retry .icon-wrap {
259
+ display: inline-flex;
260
+ align-items: center;
261
+ line-height: 0;
262
+ }
263
+
155
264
  /* ── Skeleton loading ──────────────────────────────────── */
156
265
 
157
266
  .skeleton-list {
@@ -170,7 +279,7 @@
170
279
 
171
280
  .skeleton-line {
172
281
  border-radius: 6px;
173
- background: var(--ai-shimmer-gradient);
282
+ background: var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(0, 0, 0, 0.06) 25%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0.06) 75%));
174
283
  background-size: 200% 100%;
175
284
  animation: shimmer 2s linear infinite;
176
285
  height: 12px;