@salla.sa/ui-ai-kit-core 2.1.1 → 2.2.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.
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 +89 -14
  4. package/dist/cjs/ai-chat-header.cjs.entry.js +114 -14
  5. package/dist/cjs/ai-chat-message.cjs.entry.js +10 -4
  6. package/dist/cjs/ai-conversation-list.cjs.entry.js +37 -12
  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 +50 -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-Cc05u4ND.js} +86 -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 +263 -16
  26. package/dist/collection/components/ai-chat-header/ai-chat-header.css +98 -0
  27. package/dist/collection/components/ai-chat-header/ai-chat-header.js +298 -26
  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 +128 -9
  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 +78 -0
  34. package/dist/collection/components/ai-in-chat-browser/ai-in-chat-browser.js +102 -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-BPkf7wZg.js +1 -0
  64. package/dist/components/p-Ba0urr6Q.js +1 -0
  65. package/dist/components/p-CJzVwMlS.js +1 -0
  66. package/dist/components/{p-Bbmjx9lq.js → p-DZuBxUde.js} +1 -1
  67. package/dist/components/p-DlD8m3rf.js +1 -0
  68. package/dist/components/{p-C5gkZloN.js → p-bGFmyIp1.js} +1 -1
  69. package/dist/esm/ai-agent-error.entry.js +3 -3
  70. package/dist/esm/ai-card.entry.js +3 -3
  71. package/dist/esm/ai-chat-container.entry.js +89 -14
  72. package/dist/esm/ai-chat-header.entry.js +114 -14
  73. package/dist/esm/ai-chat-message.entry.js +10 -4
  74. package/dist/esm/ai-conversation-list.entry.js +37 -12
  75. package/dist/esm/ai-conversation-summary.entry.js +3 -3
  76. package/dist/esm/ai-icon.entry.js +2 -2
  77. package/dist/esm/ai-in-chat-browser.entry.js +48 -0
  78. package/dist/esm/ai-link.entry.js +3 -3
  79. package/dist/esm/ai-loading.entry.js +3 -3
  80. package/dist/esm/ai-message-input.entry.js +12 -7
  81. package/dist/esm/ai-rating.entry.js +26 -18
  82. package/dist/esm/ai-route-decision.entry.js +3 -3
  83. package/dist/esm/ai-suggestion.entry.js +3 -3
  84. package/dist/esm/ai-voice-input.entry.js +2 -2
  85. package/dist/esm/icon-registry-DlD8m3rf.js +124 -0
  86. package/dist/esm/{index-hxWjzqcH.js → index-VMEwYfaX.js} +86 -1
  87. package/dist/esm/loader.js +3 -3
  88. package/dist/esm/ui-ai-kit.js +3 -3
  89. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +38 -2
  90. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +41 -4
  91. package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +11 -0
  92. package/dist/types/components/ai-in-chat-browser/ai-in-chat-browser.d.ts +13 -0
  93. package/dist/types/components/ai-rating/ai-rating.d.ts +4 -1
  94. package/dist/types/components.d.ts +275 -18
  95. package/dist/types/index.d.ts +1 -0
  96. package/dist/types/utils/icon-registry.d.ts +1 -1
  97. package/dist/ui-ai-kit/{p-889c6b00.entry.js → p-062cad02.entry.js} +1 -1
  98. package/dist/ui-ai-kit/{p-27bf454d.entry.js → p-187db371.entry.js} +1 -1
  99. package/dist/ui-ai-kit/p-1b247096.entry.js +1 -0
  100. package/dist/ui-ai-kit/p-338d55d3.entry.js +1 -0
  101. package/dist/ui-ai-kit/{p-210b11dc.entry.js → p-4359a116.entry.js} +1 -1
  102. package/dist/ui-ai-kit/{p-ccaec7b4.entry.js → p-5f005ec5.entry.js} +1 -1
  103. package/dist/ui-ai-kit/p-6a4b66ed.entry.js +1 -0
  104. package/dist/ui-ai-kit/{p-5ea933a4.entry.js → p-6b644d32.entry.js} +1 -1
  105. package/dist/ui-ai-kit/{p-b33e92ea.entry.js → p-6bd54e29.entry.js} +1 -1
  106. package/dist/ui-ai-kit/{p-0da537b1.entry.js → p-83f46030.entry.js} +2 -2
  107. package/dist/ui-ai-kit/p-8ac8febb.entry.js +1 -0
  108. package/dist/ui-ai-kit/{p-72c6e3d1.entry.js → p-8fabdbe8.entry.js} +1 -1
  109. package/dist/ui-ai-kit/p-953d4348.entry.js +1 -0
  110. package/dist/ui-ai-kit/p-DlD8m3rf.js +1 -0
  111. package/dist/ui-ai-kit/p-VMEwYfaX.js +2 -0
  112. package/dist/ui-ai-kit/{p-cf6caba5.entry.js → p-cae762e0.entry.js} +1 -1
  113. package/dist/ui-ai-kit/p-d02f2db5.entry.js +1 -0
  114. package/dist/ui-ai-kit/{p-999dd7c8.entry.js → p-e6236df2.entry.js} +1 -1
  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-70836960.entry.js +0 -1
  124. package/dist/ui-ai-kit/p-8f721843.entry.js +0 -1
  125. package/dist/ui-ai-kit/p-95b50b7b.entry.js +0 -1
  126. package/dist/ui-ai-kit/p-SJZ6Ujn9.js +0 -1
  127. package/dist/ui-ai-kit/p-c9ec615f.entry.js +0 -1
  128. package/dist/ui-ai-kit/p-hxWjzqcH.js +0 -2
@@ -4,7 +4,7 @@ export class ChatContainer {
4
4
  /** Controls visibility of the chat panel */
5
5
  isOpen = false;
6
6
  /** Position of the panel: 'left', 'right', or 'float' */
7
- position = 'right';
7
+ position = 'left';
8
8
  /** Width of the panel (CSS value, e.g., '400px', '30%', '28rem') */
9
9
  width = '28rem';
10
10
  /** Enable/disable auto-scroll to latest message */
@@ -15,6 +15,24 @@ export class ChatContainer {
15
15
  floatHeight = '600px';
16
16
  /** Color theme for the panel */
17
17
  theme = 'light';
18
+ /** Show skeleton loading state (e.g. while loading conversation history) */
19
+ loading = false;
20
+ /** Show error state (e.g. failed to load conversation) */
21
+ error = false;
22
+ /** Error message text */
23
+ errorText = 'تعذّر تحميل المحادثة';
24
+ /** Retry button label */
25
+ retryLabel = 'إعادة المحاولة';
26
+ /**
27
+ * Layout direction set by the host app.
28
+ * - `'rtl'` → valid docked position is `left`; cycle order: left ↔ float
29
+ * - `'ltr'` → valid docked position is `right`; cycle order: right ↔ float
30
+ */
31
+ direction = 'rtl';
32
+ /** Event emitted when the retry button is clicked */
33
+ retryClick;
34
+ /** Fired when the position changes (via cyclePosition or the header button) */
35
+ positionChange;
18
36
  isMobile = false;
19
37
  floatLeft = '24px';
20
38
  floatTop = '24px';
@@ -22,8 +40,11 @@ export class ChatContainer {
22
40
  messagesAreaRef;
23
41
  dragState = null;
24
42
  mutationObserver = null;
43
+ resizeObserver = null;
25
44
  // Named arrow so we can reliably add/remove it without leaking
26
45
  dragListener = (e) => {
46
+ if (typeof window === 'undefined')
47
+ return;
27
48
  const container = this.containerRef;
28
49
  if (!container)
29
50
  return;
@@ -62,19 +83,31 @@ export class ChatContainer {
62
83
  document.addEventListener('pointermove', onMove);
63
84
  document.addEventListener('pointerup', onUp);
64
85
  };
65
- constructor() {
66
- // Bind so window.removeEventListener can match the reference
67
- this.checkMobile = this.checkMobile.bind(this);
86
+ /**
87
+ * Listen for the composed headerPositionClick event fired by ai-chat-header.
88
+ * Automatically cycles the position so the host app doesn't need to wire it manually.
89
+ */
90
+ handleHeaderPositionClick() {
91
+ this.cyclePosition();
68
92
  }
69
93
  componentWillLoad() {
70
94
  this.checkMobile();
71
95
  }
72
96
  componentDidLoad() {
73
- if (typeof window !== 'undefined') {
74
- window.addEventListener('resize', this.checkMobile);
75
- if (this.position === 'float') {
76
- this.setupDrag();
77
- }
97
+ if (typeof window === 'undefined')
98
+ return;
99
+ // Use ResizeObserver for responsive mobile detection instead of window.resize
100
+ if (typeof ResizeObserver !== 'undefined') {
101
+ this.resizeObserver = new ResizeObserver(() => {
102
+ this.checkMobile();
103
+ this.clampFloatPosition();
104
+ });
105
+ this.resizeObserver.observe(this.el);
106
+ }
107
+ // Also listen to window resize for viewport changes (e.g. browser resize)
108
+ window.addEventListener('resize', this.handleWindowResize);
109
+ if (this.position === 'float') {
110
+ this.setupDrag();
78
111
  }
79
112
  this.mutationObserver = new MutationObserver(() => {
80
113
  if (this.autoScroll && this.messagesAreaRef) {
@@ -99,9 +132,12 @@ export class ChatContainer {
99
132
  }
100
133
  }
101
134
  disconnectedCallback() {
102
- window.removeEventListener('resize', this.checkMobile);
135
+ if (typeof window !== 'undefined') {
136
+ window.removeEventListener('resize', this.handleWindowResize);
137
+ }
103
138
  this.el.removeEventListener('headerDragStart', this.dragListener);
104
139
  this.mutationObserver?.disconnect();
140
+ this.resizeObserver?.disconnect();
105
141
  }
106
142
  /** Programmatically scroll the messages area to the bottom */
107
143
  async scrollToBottom() {
@@ -109,11 +145,40 @@ export class ChatContainer {
109
145
  this.messagesAreaRef.scrollTop = this.messagesAreaRef.scrollHeight;
110
146
  }
111
147
  }
148
+ /**
149
+ * Cycle to the next valid position based on the current direction.
150
+ * - RTL: left ↔ float
151
+ * - LTR: right ↔ float
152
+ */
153
+ async cyclePosition() {
154
+ const docked = this.direction === 'rtl' ? 'left' : 'right';
155
+ this.position = this.position === 'float' ? docked : 'float';
156
+ this.positionChange.emit(this.position);
157
+ }
158
+ handleWindowResize = () => {
159
+ this.checkMobile();
160
+ this.clampFloatPosition();
161
+ };
112
162
  checkMobile() {
113
163
  if (typeof window !== 'undefined') {
114
164
  this.isMobile = window.innerWidth < 768;
115
165
  }
116
166
  }
167
+ /** Re-clamp float position so the panel never ends up off-screen after resize */
168
+ clampFloatPosition() {
169
+ if (typeof window === 'undefined' || this.position !== 'float' || !this.containerRef)
170
+ return;
171
+ const vw = window.innerWidth;
172
+ const vh = window.innerHeight;
173
+ const w = this.containerRef.offsetWidth;
174
+ const h = this.containerRef.offsetHeight;
175
+ let left = parseFloat(this.floatLeft) || 0;
176
+ let top = parseFloat(this.floatTop) || 0;
177
+ left = Math.max(0, Math.min(left, vw - w));
178
+ top = Math.max(0, Math.min(top, vh - h));
179
+ this.floatLeft = `${left}px`;
180
+ this.floatTop = `${top}px`;
181
+ }
117
182
  setupDrag() {
118
183
  // Remove any existing listener before adding to prevent accumulation
119
184
  this.el.removeEventListener('headerDragStart', this.dragListener);
@@ -153,8 +218,14 @@ export class ChatContainer {
153
218
  }
154
219
  return false;
155
220
  }
221
+ renderSkeleton() {
222
+ return (h("div", { class: "skeleton-messages", "aria-busy": "true", "aria-label": "Loading conversation" }, h("div", { class: "skeleton-row agent" }, h("div", { class: "skeleton-bubble" }, h("div", { class: "skeleton-line", style: { width: '80%' } }), h("div", { class: "skeleton-line", style: { width: '60%' } }), h("div", { class: "skeleton-line", style: { width: '40%' } }))), h("div", { class: "skeleton-row user" }, h("div", { class: "skeleton-bubble" }, h("div", { class: "skeleton-line", style: { width: '70%' } }))), h("div", { class: "skeleton-row agent" }, h("div", { class: "skeleton-bubble" }, h("div", { class: "skeleton-line", style: { width: '90%' } }), h("div", { class: "skeleton-line", style: { width: '55%' } }))), h("div", { class: "skeleton-row user" }, h("div", { class: "skeleton-bubble" }, h("div", { class: "skeleton-line", style: { width: '50%' } }), h("div", { class: "skeleton-line", style: { width: '35%' } })))));
223
+ }
224
+ renderError() {
225
+ return (h("div", { class: "error-state", role: "alert" }, h("svg", { class: "error-icon", width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", "stroke-width": "1.5" }), h("path", { d: "M12 7v6", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" }), h("circle", { cx: "12", cy: "16.5", r: "0.75", fill: "currentColor" })), h("p", { class: "error-text" }, this.errorText), h("button", { class: "error-retry-btn", type: "button", onClick: () => this.retryClick.emit() }, this.retryLabel)));
226
+ }
156
227
  render() {
157
- return (h(Host, { key: 'fb25617bfba35681e5190cec602ad17f8a8e53ef', class: { dark: this.isDark() } }, h("div", { key: '463a07a473470a497212948fa601cd677d1f266b', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && (h("div", { key: '40c3fa4a496a848950dba73372acacd14b4c5dda', class: "watermark" }, h("ai-icon", { key: '7467301453bce43c8d3eaca7efe83800a9e4bc8b', name: "watermark", size: 133 }))), h("slot", { key: 'c082990d1e7829d5d879a1c176dd0b57a3b3a244', name: "header" }), h("div", { key: '13b9ccd90f1e1e26794c8e780a5e8e89a4de43d2', class: "messages-area", ref: el => (this.messagesAreaRef = el) }, h("slot", { key: '247cb11401e834b41d220515b88d5e202f40e8e8' })), h("slot", { key: '8115183cbe55bc3ba472fed0e368a811e5232b47', name: "footer" }))));
228
+ return (h(Host, { key: '6290736307488f10a4ed441e2a8e0b3a2e89af05', class: { dark: this.isDark() } }, h("div", { key: '6d6a731d9941457b786c71625243a7dd1e9f11f8', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && !this.loading && !this.error && (h("div", { key: '0c2ae5b52f8c30bdf356a3c356d52305451cb19e', class: "watermark" }, h("svg", { key: '36076d8dd514f5736050228d22b9a03d5d48ce28', class: "watermark-circle-svg", width: "133", height: "133", viewBox: "0 0 133 133", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("g", { key: '737a3f3d8b7a0f91120258c292d047f9dc90871c', filter: "url(#wm_circle_shadow)" }, h("circle", { key: 'a59549c879ddaa2a0007c4fd9645c4382b14e73f', cx: "66.415", cy: "66.415", r: "66.415", class: "watermark-circle" })), h("defs", { key: '58d5edc4e05f3dd8a60f7a829b70f154ba85bfc1' }, h("filter", { key: 'd2cb7cb5a84bdf1496b56ec5a0c0c79001040670', id: "wm_circle_shadow", x: "0", y: "0", width: "132.83", height: "135.83", filterUnits: "userSpaceOnUse", "color-interpolation-filters": "sRGB" }, h("feFlood", { key: 'e90404f557fba552a21bd3748ad728470172040f', "flood-opacity": "0", result: "BackgroundImageFix" }), h("feBlend", { key: 'ef5aee167a4973c35f8ffaa8ae4a0487de8266ee', mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), h("feColorMatrix", { key: 'e0869202bc43610b91abce92e85e8e5264cda999', in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), h("feOffset", { key: '7bef38d885b93711fce4c0efbb719a83417eeefb', dy: "3" }), h("feGaussianBlur", { key: '053de38388f049be8db7867b99b53d403de934ca', stdDeviation: "3" }), h("feComposite", { key: 'e5f68fbcf0923174a177545bf3364d066a122347', in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), h("feColorMatrix", { key: '62dc924cbdc92ce4adc0ec81be851c1d40e7a5b0', type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" }), h("feBlend", { key: '908299725f9e553c636bd18eab6541c6a7c69fe5', mode: "normal", in2: "shape", result: "effect1_innerShadow" })))), h("svg", { key: '2a6ce2364bfd667c4eba56d859a1326f70a82901', class: "watermark-star-svg", width: "78", height: "78", viewBox: "0 0 78 78", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("g", { key: 'e2c431ac6bee320c817a7283e6e356edc4667146', filter: "url(#wm_star_shadow)" }, h("path", { key: 'd87d0313e649527f5909ac1b08f7af2979760d79', d: "M38.7421 0C39.5691 0 40.2689 0.286272 40.8414 0.858815C41.414 1.43136 41.7002 2.13113 41.7002 2.95814C41.7002 8.87442 43.1952 14.3772 46.1851 19.4665C49.1115 24.4285 53.0557 28.3727 58.0177 31.299C63.107 34.289 68.6097 35.7839 74.526 35.7839C75.353 35.7839 76.0528 36.0702 76.6254 36.6428C77.1979 37.2153 77.4842 37.9151 77.4842 38.7421C77.4842 39.5691 77.1979 40.2689 76.6254 40.8414C76.0528 41.414 75.353 41.7002 74.526 41.7002C68.6097 41.7002 63.107 43.1952 58.0177 46.1851C53.0557 49.1115 49.1115 53.0557 46.1851 58.0177C43.1952 63.107 41.7002 68.6097 41.7002 74.526C41.7002 75.353 41.414 76.0528 40.8414 76.6254C40.2689 77.1979 39.5691 77.4842 38.7421 77.4842C37.9151 77.4842 37.2153 77.1979 36.6428 76.6254C36.0702 76.0528 35.7839 75.353 35.7839 74.526C35.7839 68.6097 34.289 63.107 31.299 58.0177C28.3727 53.0557 24.4285 49.1115 19.4665 46.1851C14.3772 43.1952 8.87442 41.7002 2.95814 41.7002C2.13113 41.7002 1.43136 41.414 0.858815 40.8414C0.286272 40.2689 0 39.5691 0 38.7421C0 37.9151 0.286272 37.2153 0.858815 36.6428C1.43136 36.0702 2.13113 35.7839 2.95814 35.7839C8.87442 35.7839 14.3772 34.289 19.4665 31.299C24.4285 28.3727 28.3727 24.4285 31.299 19.4665C34.289 14.3772 35.7839 8.87442 35.7839 2.95814C35.7839 2.13113 36.0702 1.43136 36.6428 0.858815C37.2153 0.286272 37.9151 0 38.7421 0Z", class: "watermark-star" })), h("defs", { key: '51e7ef185399e3a10d0b19eb399500be3e5384f8' }, h("filter", { key: '09f52cd1b7084a8af9488bbce05c277fe07012f9', id: "wm_star_shadow", x: "0", y: "0", width: "77.4844", height: "79.4841", filterUnits: "userSpaceOnUse", "color-interpolation-filters": "sRGB" }, h("feFlood", { key: '1b055616d714f824dd38a895a5c1a635fefc4a66', "flood-opacity": "0", result: "BackgroundImageFix" }), h("feBlend", { key: '044cba9d32d0a1d56fc39d318dfc1cdd0fdc0ae7', mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), h("feColorMatrix", { key: '4bf50b36bd6b1ae90d29a95290762ef52dbfff7a', in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), h("feOffset", { key: '0988514af2fda03cb2ff43e95c1423137351186f', dy: "2" }), h("feGaussianBlur", { key: 'c96fb451b890e9bda84043dcd699c2a3f59c195c', stdDeviation: "2" }), h("feComposite", { key: '77b2bb3e01eefb08cac5f60a494c2cd15e97db4a', in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), h("feColorMatrix", { key: 'aef785066c732cc5cbc16689f2e57a7df7d18bc5', type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" }), h("feBlend", { key: '292a1d370d268312514f1c8fcee2167159c2d4e9', mode: "normal", in2: "shape", result: "effect1_innerShadow" })))))), h("slot", { key: '009fd561884a5a70e559d865dc1b1d55937d923c', name: "header" }), h("div", { key: 'fde5090720cd70c2b5fe72bcaec95007e7792f4e', class: "messages-area", ref: el => (this.messagesAreaRef = el) }, this.loading ? this.renderSkeleton() : this.error ? this.renderError() : h("slot", null)), h("slot", { key: '838ea2de9f788af2af70568a7882a08645c6b2ac', name: "footer" }))));
158
229
  }
159
230
  static get is() { return "ai-chat-container"; }
160
231
  static get encapsulation() { return "shadow"; }
@@ -192,11 +263,17 @@ export class ChatContainer {
192
263
  },
193
264
  "position": {
194
265
  "type": "string",
195
- "mutable": false,
266
+ "mutable": true,
196
267
  "complexType": {
197
- "original": "'left' | 'right' | 'float'",
268
+ "original": "ChatPosition",
198
269
  "resolved": "\"float\" | \"left\" | \"right\"",
199
- "references": {}
270
+ "references": {
271
+ "ChatPosition": {
272
+ "location": "local",
273
+ "path": "/home/ahmed/Desktop/Salla/Dev/multi-agent/ui-ai-kit/packages/core/src/components/ai-chat-container/ai-chat-container.tsx",
274
+ "id": "src/components/ai-chat-container/ai-chat-container.tsx::ChatPosition"
275
+ }
276
+ }
200
277
  },
201
278
  "required": false,
202
279
  "optional": false,
@@ -206,9 +283,9 @@ export class ChatContainer {
206
283
  },
207
284
  "getter": false,
208
285
  "setter": false,
209
- "reflect": false,
286
+ "reflect": true,
210
287
  "attribute": "position",
211
- "defaultValue": "'right'"
288
+ "defaultValue": "'left'"
212
289
  },
213
290
  "width": {
214
291
  "type": "string",
@@ -309,6 +386,106 @@ export class ChatContainer {
309
386
  "reflect": false,
310
387
  "attribute": "theme",
311
388
  "defaultValue": "'light'"
389
+ },
390
+ "loading": {
391
+ "type": "boolean",
392
+ "mutable": false,
393
+ "complexType": {
394
+ "original": "boolean",
395
+ "resolved": "boolean",
396
+ "references": {}
397
+ },
398
+ "required": false,
399
+ "optional": false,
400
+ "docs": {
401
+ "tags": [],
402
+ "text": "Show skeleton loading state (e.g. while loading conversation history)"
403
+ },
404
+ "getter": false,
405
+ "setter": false,
406
+ "reflect": false,
407
+ "attribute": "loading",
408
+ "defaultValue": "false"
409
+ },
410
+ "error": {
411
+ "type": "boolean",
412
+ "mutable": false,
413
+ "complexType": {
414
+ "original": "boolean",
415
+ "resolved": "boolean",
416
+ "references": {}
417
+ },
418
+ "required": false,
419
+ "optional": false,
420
+ "docs": {
421
+ "tags": [],
422
+ "text": "Show error state (e.g. failed to load conversation)"
423
+ },
424
+ "getter": false,
425
+ "setter": false,
426
+ "reflect": false,
427
+ "attribute": "error",
428
+ "defaultValue": "false"
429
+ },
430
+ "errorText": {
431
+ "type": "string",
432
+ "mutable": false,
433
+ "complexType": {
434
+ "original": "string",
435
+ "resolved": "string",
436
+ "references": {}
437
+ },
438
+ "required": false,
439
+ "optional": false,
440
+ "docs": {
441
+ "tags": [],
442
+ "text": "Error message text"
443
+ },
444
+ "getter": false,
445
+ "setter": false,
446
+ "reflect": false,
447
+ "attribute": "error-text",
448
+ "defaultValue": "'\u062A\u0639\u0630\u0651\u0631 \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0645\u062D\u0627\u062F\u062B\u0629'"
449
+ },
450
+ "retryLabel": {
451
+ "type": "string",
452
+ "mutable": false,
453
+ "complexType": {
454
+ "original": "string",
455
+ "resolved": "string",
456
+ "references": {}
457
+ },
458
+ "required": false,
459
+ "optional": false,
460
+ "docs": {
461
+ "tags": [],
462
+ "text": "Retry button label"
463
+ },
464
+ "getter": false,
465
+ "setter": false,
466
+ "reflect": false,
467
+ "attribute": "retry-label",
468
+ "defaultValue": "'\u0625\u0639\u0627\u062F\u0629 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629'"
469
+ },
470
+ "direction": {
471
+ "type": "string",
472
+ "mutable": false,
473
+ "complexType": {
474
+ "original": "'rtl' | 'ltr'",
475
+ "resolved": "\"ltr\" | \"rtl\"",
476
+ "references": {}
477
+ },
478
+ "required": false,
479
+ "optional": false,
480
+ "docs": {
481
+ "tags": [],
482
+ "text": "Layout direction set by the host app.\n- `'rtl'` \u2192 valid docked position is `left`; cycle order: left \u2194 float\n- `'ltr'` \u2192 valid docked position is `right`; cycle order: right \u2194 float"
483
+ },
484
+ "getter": false,
485
+ "setter": false,
486
+ "reflect": true,
487
+ "attribute": "direction",
488
+ "defaultValue": "'rtl'"
312
489
  }
313
490
  };
314
491
  }
@@ -319,6 +496,45 @@ export class ChatContainer {
319
496
  "floatTop": {}
320
497
  };
321
498
  }
499
+ static get events() {
500
+ return [{
501
+ "method": "retryClick",
502
+ "name": "retryClick",
503
+ "bubbles": true,
504
+ "cancelable": true,
505
+ "composed": true,
506
+ "docs": {
507
+ "tags": [],
508
+ "text": "Event emitted when the retry button is clicked"
509
+ },
510
+ "complexType": {
511
+ "original": "void",
512
+ "resolved": "void",
513
+ "references": {}
514
+ }
515
+ }, {
516
+ "method": "positionChange",
517
+ "name": "positionChange",
518
+ "bubbles": true,
519
+ "cancelable": true,
520
+ "composed": true,
521
+ "docs": {
522
+ "tags": [],
523
+ "text": "Fired when the position changes (via cyclePosition or the header button)"
524
+ },
525
+ "complexType": {
526
+ "original": "ChatPosition",
527
+ "resolved": "\"float\" | \"left\" | \"right\"",
528
+ "references": {
529
+ "ChatPosition": {
530
+ "location": "local",
531
+ "path": "/home/ahmed/Desktop/Salla/Dev/multi-agent/ui-ai-kit/packages/core/src/components/ai-chat-container/ai-chat-container.tsx",
532
+ "id": "src/components/ai-chat-container/ai-chat-container.tsx::ChatPosition"
533
+ }
534
+ }
535
+ }
536
+ }];
537
+ }
322
538
  static get methods() {
323
539
  return {
324
540
  "scrollToBottom": {
@@ -337,6 +553,28 @@ export class ChatContainer {
337
553
  "text": "Programmatically scroll the messages area to the bottom",
338
554
  "tags": []
339
555
  }
556
+ },
557
+ "cyclePosition": {
558
+ "complexType": {
559
+ "signature": "() => Promise<void>",
560
+ "parameters": [],
561
+ "references": {
562
+ "Promise": {
563
+ "location": "global",
564
+ "id": "global::Promise"
565
+ },
566
+ "ChatPosition": {
567
+ "location": "local",
568
+ "path": "/home/ahmed/Desktop/Salla/Dev/multi-agent/ui-ai-kit/packages/core/src/components/ai-chat-container/ai-chat-container.tsx",
569
+ "id": "src/components/ai-chat-container/ai-chat-container.tsx::ChatPosition"
570
+ }
571
+ },
572
+ "return": "Promise<void>"
573
+ },
574
+ "docs": {
575
+ "text": "Cycle to the next valid position based on the current direction.\n- RTL: left \u2194 float\n- LTR: right \u2194 float",
576
+ "tags": []
577
+ }
340
578
  }
341
579
  };
342
580
  }
@@ -350,4 +588,13 @@ export class ChatContainer {
350
588
  "methodName": "positionChanged"
351
589
  }];
352
590
  }
591
+ static get listeners() {
592
+ return [{
593
+ "name": "headerPositionClick",
594
+ "method": "handleHeaderPositionClick",
595
+ "target": undefined,
596
+ "capture": false,
597
+ "passive": false
598
+ }];
599
+ }
353
600
  }
@@ -1,5 +1,14 @@
1
1
  :host {
2
2
  display: block;
3
+ position: relative;
4
+ z-index: 10;
5
+ }
6
+
7
+ /* ── Wrapper ────────────────────────────────────────────────────── */
8
+ .header-wrapper {
9
+ position: relative;
10
+ display: flex;
11
+ flex-direction: column;
3
12
  }
4
13
 
5
14
  /* ── Container ──────────────────────────────────────────────────── */
@@ -83,6 +92,10 @@
83
92
  gap: 8px;
84
93
  }
85
94
 
95
+ .content.browser {
96
+ gap: 8px;
97
+ }
98
+
86
99
  /* ── Dropdown Trigger (agent mode) ──────────────────────────────── */
87
100
  .dropdown-trigger {
88
101
  display: flex;
@@ -122,6 +135,55 @@
122
135
  text-overflow: ellipsis;
123
136
  }
124
137
 
138
+ /* ── Title Skeleton (loading state) ─────────────────────────────── */
139
+ @keyframes title-shimmer {
140
+ 0% { background-position: 200% 0; }
141
+ 100% { background-position: -200% 0; }
142
+ }
143
+
144
+ .title-skeleton {
145
+ display: inline-block;
146
+ width: 120px;
147
+ height: 16px;
148
+ border-radius: 8px;
149
+ 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%));
150
+ background-size: 200% 100%;
151
+ animation: title-shimmer 1.6s ease-in-out infinite;
152
+ }
153
+
154
+ /* ── Browser Title (browser mode) ───────────────────────────────── */
155
+ .browser-title {
156
+ font-size: 14px;
157
+ font-weight: 600;
158
+ color: var(--ai-text-primary);
159
+ white-space: nowrap;
160
+ overflow: hidden;
161
+ text-overflow: ellipsis;
162
+ min-width: 0;
163
+ line-height: 20px;
164
+ }
165
+
166
+ /* ── Browser Link Button (browser mode) ─────────────────────────── */
167
+ .browser-link-btn {
168
+ width: 28px;
169
+ height: 28px;
170
+ padding: 0;
171
+ display: inline-flex;
172
+ align-items: center;
173
+ justify-content: center;
174
+ background: none;
175
+ border: none;
176
+ border-radius: 8px;
177
+ cursor: pointer;
178
+ flex-shrink: 0;
179
+ color: var(--ai-text-secondary);
180
+ }
181
+
182
+ .browser-link-btn:focus-visible {
183
+ outline: 2px solid var(--ai-focus-ring);
184
+ outline-offset: 2px;
185
+ }
186
+
125
187
  /* ── Avatar & Online Dot (human mode) ──────────────────────────── */
126
188
  .avatar-wrapper {
127
189
  position: relative;
@@ -226,3 +288,39 @@
226
288
  :host([dir='ltr']) .back-btn .icon-wrap {
227
289
  transform: scaleX(-1);
228
290
  }
291
+
292
+ /* ── Conversation Dropdown Panel ────────────────────────────────── */
293
+ .conversation-dropdown {
294
+ position: absolute;
295
+ top: 100%;
296
+ left: 0;
297
+ right: 0;
298
+ z-index: 20;
299
+ height: 360px;
300
+ display: flex;
301
+ flex-direction: column;
302
+ background: var(--ai-bg-surface);
303
+ border-bottom: 1px solid var(--ai-border-light);
304
+ box-shadow: var(--ai-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08));
305
+ animation: slideDown 0.2s ease;
306
+ overflow: hidden;
307
+ }
308
+
309
+ .conversation-dropdown ai-conversation-list {
310
+ display: flex;
311
+ flex-direction: column;
312
+ flex: 1;
313
+ min-height: 0;
314
+ overflow: hidden;
315
+ }
316
+
317
+ @keyframes slideDown {
318
+ from {
319
+ opacity: 0;
320
+ transform: translateY(-8px);
321
+ }
322
+ to {
323
+ opacity: 1;
324
+ transform: translateY(0);
325
+ }
326
+ }