@salla.sa/ui-ai-kit-core 1.0.0 → 1.1.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 (148) hide show
  1. package/dist/cjs/ai-card.cjs.entry.js +2 -2
  2. package/dist/cjs/ai-chat-container.cjs.entry.js +84 -57
  3. package/dist/cjs/ai-chat-header.cjs.entry.js +27 -17
  4. package/dist/cjs/ai-chat-message.cjs.entry.js +1456 -21
  5. package/dist/cjs/ai-conversation-list.cjs.entry.js +80 -0
  6. package/dist/cjs/ai-conversation-summary.cjs.entry.js +33 -0
  7. package/dist/cjs/ai-icon.cjs.entry.js +2 -2
  8. package/dist/cjs/ai-link.cjs.entry.js +4 -4
  9. package/dist/cjs/ai-loading.cjs.entry.js +35 -22
  10. package/dist/cjs/ai-message-input.cjs.entry.js +48 -15
  11. package/dist/cjs/ai-rating.cjs.entry.js +2 -2
  12. package/dist/cjs/ai-route-decision.cjs.entry.js +48 -0
  13. package/dist/cjs/ai-suggestion.cjs.entry.js +4 -4
  14. package/dist/cjs/ai-voice-input.cjs.entry.js +62 -14
  15. package/dist/cjs/{icon-registry-dmfLA-Dj.js → icon-registry-BKb9-2Nt.js} +24 -0
  16. package/dist/cjs/{index-DLJcLHFH.js → index-BkNg07SW.js} +1 -1
  17. package/dist/cjs/loader.cjs.js +2 -2
  18. package/dist/cjs/ui-ai-kit.cjs.js +2 -2
  19. package/dist/collection/collection-manifest.json +3 -0
  20. package/dist/collection/components/ai-card/ai-card.css +5 -8
  21. package/dist/collection/components/ai-chat-container/ai-chat-container.css +17 -14
  22. package/dist/collection/components/ai-chat-container/ai-chat-container.js +125 -53
  23. package/dist/collection/components/ai-chat-header/ai-chat-header.css +50 -17
  24. package/dist/collection/components/ai-chat-header/ai-chat-header.js +50 -15
  25. package/dist/collection/components/ai-chat-message/ai-chat-message.css +47 -38
  26. package/dist/collection/components/ai-chat-message/ai-chat-message.js +68 -18
  27. package/dist/collection/components/ai-conversation-list/ai-conversation-list.css +196 -0
  28. package/dist/collection/components/ai-conversation-list/ai-conversation-list.js +176 -0
  29. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.css +103 -0
  30. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.js +118 -0
  31. package/dist/collection/components/ai-icon/ai-icon.js +1 -1
  32. package/dist/collection/components/ai-link/ai-link.css +3 -7
  33. package/dist/collection/components/ai-link/ai-link.js +1 -1
  34. package/dist/collection/components/ai-loading/ai-loading.css +149 -20
  35. package/dist/collection/components/ai-loading/ai-loading.js +100 -23
  36. package/dist/collection/components/ai-message-input/ai-message-input.css +41 -37
  37. package/dist/collection/components/ai-message-input/ai-message-input.js +100 -19
  38. package/dist/collection/components/ai-rating/ai-rating.css +8 -14
  39. package/dist/collection/components/ai-route-decision/ai-route-decision.css +132 -0
  40. package/dist/collection/components/ai-route-decision/ai-route-decision.js +195 -0
  41. package/dist/collection/components/ai-suggestion/ai-suggestion.css +5 -11
  42. package/dist/collection/components/ai-suggestion/ai-suggestion.js +2 -2
  43. package/dist/collection/components/ai-voice-input/ai-voice-input.css +26 -21
  44. package/dist/collection/components/ai-voice-input/ai-voice-input.js +103 -13
  45. package/dist/collection/utils/icon-registry.js +24 -0
  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 -1
  50. package/dist/components/ai-conversation-list.d.ts +11 -0
  51. package/dist/components/ai-conversation-list.js +1 -0
  52. package/dist/components/ai-conversation-summary.d.ts +11 -0
  53. package/dist/components/ai-conversation-summary.js +1 -0
  54. package/dist/components/ai-icon.js +1 -1
  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.d.ts +11 -0
  60. package/dist/components/ai-route-decision.js +1 -0
  61. package/dist/components/ai-suggestion.js +1 -1
  62. package/dist/components/ai-voice-input.js +1 -1
  63. package/dist/components/index.js +1 -1
  64. package/dist/components/p-DCr8F_XV.js +1 -0
  65. package/dist/components/p-DnO4dikr.js +1 -0
  66. package/dist/components/{p-CY6emva2.js → p-Dr2tAPV7.js} +1 -1
  67. package/dist/{ui-ai-kit/p-DYv5ef4M.js → components/p-SJZ6Ujn9.js} +1 -1
  68. package/dist/esm/ai-card.entry.js +2 -2
  69. package/dist/esm/ai-chat-container.entry.js +84 -57
  70. package/dist/esm/ai-chat-header.entry.js +27 -17
  71. package/dist/esm/ai-chat-message.entry.js +1456 -21
  72. package/dist/esm/ai-conversation-list.entry.js +78 -0
  73. package/dist/esm/ai-conversation-summary.entry.js +31 -0
  74. package/dist/esm/ai-icon.entry.js +2 -2
  75. package/dist/esm/ai-link.entry.js +4 -4
  76. package/dist/esm/ai-loading.entry.js +35 -22
  77. package/dist/esm/ai-message-input.entry.js +48 -15
  78. package/dist/esm/ai-rating.entry.js +2 -2
  79. package/dist/esm/ai-route-decision.entry.js +46 -0
  80. package/dist/esm/ai-suggestion.entry.js +4 -4
  81. package/dist/esm/ai-voice-input.entry.js +62 -14
  82. package/dist/esm/{icon-registry-DYv5ef4M.js → icon-registry-SJZ6Ujn9.js} +24 -0
  83. package/dist/esm/{index-7hrZ8FOQ.js → index-B0yIzgh4.js} +1 -1
  84. package/dist/esm/loader.js +3 -3
  85. package/dist/esm/ui-ai-kit.js +3 -3
  86. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +11 -1
  87. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +6 -1
  88. package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +24 -0
  89. package/dist/types/components/ai-conversation-summary/ai-conversation-summary.d.ts +12 -0
  90. package/dist/types/components/ai-loading/ai-loading.d.ts +12 -6
  91. package/dist/types/components/ai-message-input/ai-message-input.d.ts +17 -3
  92. package/dist/types/components/ai-route-decision/ai-route-decision.d.ts +21 -0
  93. package/dist/types/components/ai-voice-input/ai-voice-input.d.ts +7 -0
  94. package/dist/types/components.d.ts +333 -9
  95. package/dist/types/index.d.ts +2 -0
  96. package/dist/types/utils/icon-registry.d.ts +1 -1
  97. package/dist/ui-ai-kit/p-21c4fc1f.entry.js +1 -0
  98. package/dist/ui-ai-kit/p-2955439f.entry.js +1 -0
  99. package/dist/ui-ai-kit/p-5c9e9822.entry.js +1 -0
  100. package/dist/ui-ai-kit/p-5caf1c38.entry.js +1 -0
  101. package/dist/ui-ai-kit/p-6d3505e9.entry.js +1 -0
  102. package/dist/ui-ai-kit/p-74c5c83f.entry.js +1 -0
  103. package/dist/ui-ai-kit/p-87e9739b.entry.js +1 -0
  104. package/dist/ui-ai-kit/p-B0yIzgh4.js +2 -0
  105. package/dist/{components/p-DYv5ef4M.js → ui-ai-kit/p-SJZ6Ujn9.js} +1 -1
  106. package/dist/ui-ai-kit/p-a099fcfb.entry.js +1 -0
  107. package/dist/ui-ai-kit/p-a9e4eaef.entry.js +1 -0
  108. package/dist/ui-ai-kit/p-b28af13a.entry.js +1 -0
  109. package/dist/ui-ai-kit/p-d1bb1ad0.entry.js +1 -0
  110. package/dist/ui-ai-kit/p-eb0c7e7a.entry.js +1 -0
  111. package/dist/ui-ai-kit/{p-455daa17.entry.js → p-eec6f083.entry.js} +1 -1
  112. package/dist/ui-ai-kit/p-ef07638f.entry.js +2 -0
  113. package/dist/ui-ai-kit/ui-ai-kit.css +1 -1
  114. package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -1
  115. package/package.json +5 -14
  116. package/dist/collection/components/ai-card/ai-card.stories.js +0 -52
  117. package/dist/collection/components/ai-chat-container/ai-chat-container.stories.js +0 -160
  118. package/dist/collection/components/ai-chat-header/ai-chat-header.stories.js +0 -138
  119. package/dist/collection/components/ai-chat-message/ai-chat-message.stories.js +0 -164
  120. package/dist/collection/components/ai-link/ai-link.stories.js +0 -79
  121. package/dist/collection/components/ai-loading/ai-loading.stories.js +0 -145
  122. package/dist/collection/components/ai-message-input/ai-message-input.stories.js +0 -125
  123. package/dist/collection/components/ai-rating/ai-rating.stories.js +0 -78
  124. package/dist/collection/components/ai-suggestion/ai-suggestion.stories.js +0 -62
  125. package/dist/collection/components/ai-voice-input/ai-voice-input.stories.js +0 -118
  126. package/dist/components/p-CWjXxYJI.js +0 -1
  127. package/dist/types/components/ai-card/ai-card.stories.d.ts +0 -7
  128. package/dist/types/components/ai-chat-container/ai-chat-container.stories.d.ts +0 -7
  129. package/dist/types/components/ai-chat-header/ai-chat-header.stories.d.ts +0 -8
  130. package/dist/types/components/ai-chat-message/ai-chat-message.stories.d.ts +0 -10
  131. package/dist/types/components/ai-link/ai-link.stories.d.ts +0 -8
  132. package/dist/types/components/ai-loading/ai-loading.stories.d.ts +0 -10
  133. package/dist/types/components/ai-message-input/ai-message-input.stories.d.ts +0 -13
  134. package/dist/types/components/ai-rating/ai-rating.stories.d.ts +0 -8
  135. package/dist/types/components/ai-suggestion/ai-suggestion.stories.d.ts +0 -8
  136. package/dist/types/components/ai-voice-input/ai-voice-input.stories.d.ts +0 -9
  137. package/dist/ui-ai-kit/p-11facfad.entry.js +0 -1
  138. package/dist/ui-ai-kit/p-128a2ed4.entry.js +0 -1
  139. package/dist/ui-ai-kit/p-227bdb8f.entry.js +0 -1
  140. package/dist/ui-ai-kit/p-56163e8c.entry.js +0 -1
  141. package/dist/ui-ai-kit/p-6d21d0fd.entry.js +0 -1
  142. package/dist/ui-ai-kit/p-6ddcd77b.entry.js +0 -1
  143. package/dist/ui-ai-kit/p-7hrZ8FOQ.js +0 -2
  144. package/dist/ui-ai-kit/p-8e90143e.entry.js +0 -1
  145. package/dist/ui-ai-kit/p-9938c277.entry.js +0 -1
  146. package/dist/ui-ai-kit/p-dc5b4a7f.entry.js +0 -1
  147. package/dist/ui-ai-kit/p-fb1702de.entry.js +0 -1
  148. package/readme.md +0 -111
@@ -1,6 +1,5 @@
1
1
  :host {
2
2
  display: block;
3
- direction: rtl;
4
3
  }
5
4
 
6
5
  /* ── Icon wrapper ───────────────────────────────────────── */
@@ -12,12 +11,27 @@
12
11
  }
13
12
 
14
13
  /* ── Sparkle avatar ─────────────────────────────────────── */
14
+ .sparkle-avatar-wrap {
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: 6px;
18
+ flex-shrink: 0;
19
+ }
20
+
21
+ @keyframes sparkle-twinkle {
22
+ 0%, 100% { transform: scale(1); opacity: 1; filter: brightness(1); }
23
+ 15% { transform: scale(1.4); opacity: 0.4; filter: brightness(2); }
24
+ 30% { transform: scale(0.85); opacity: 0.9; filter: brightness(0.9); }
25
+ 50% { transform: scale(1.3); opacity: 0.5; filter: brightness(1.8); }
26
+ 70% { transform: scale(0.9); opacity: 1; filter: brightness(1); }
27
+ }
28
+
15
29
  .sparkle-avatar {
16
30
  width: 24px;
17
31
  height: 24px;
18
32
  border-radius: 9999px;
19
- background: var(--ai-bg-card, #FCFCFC);
20
- box-shadow: inset 0px 0px 3px 1px rgba(18, 18, 23, 0.06);
33
+ background: var(--ai-bg-card);
34
+ box-shadow: var(--ai-shadow-inner);
21
35
  display: flex;
22
36
  align-items: center;
23
37
  justify-content: center;
@@ -25,6 +39,17 @@
25
39
  color: var(--ai-amber);
26
40
  }
27
41
 
42
+ .sparkle-avatar .icon-wrap {
43
+ animation: sparkle-twinkle 2.4s ease-in-out infinite;
44
+ transform-origin: center;
45
+ }
46
+
47
+ .header-agent {
48
+ font-size: 12px;
49
+ color: var(--ai-text-secondary);
50
+ white-space: nowrap;
51
+ }
52
+
28
53
  /* ── Thinking mode ──────────────────────────────────────── */
29
54
  .thinking-row {
30
55
  display: inline-flex;
@@ -33,6 +58,12 @@
33
58
  flex-direction: row;
34
59
  }
35
60
 
61
+ .thinking-col {
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 2px;
65
+ }
66
+
36
67
  @keyframes shimmer {
37
68
  0% {
38
69
  background-position: 200% center;
@@ -46,7 +77,7 @@
46
77
  font-size: 14px;
47
78
  font-weight: 400;
48
79
  line-height: 1.5;
49
- background: var(--ai-glow-gradient, linear-gradient(90deg, #737373 0%, #c5c5c5 50%, #737373 100%));
80
+ background: var(--ai-glow-gradient);
50
81
  background-size: 200% auto;
51
82
  -webkit-background-clip: text;
52
83
  -webkit-text-fill-color: transparent;
@@ -54,13 +85,30 @@
54
85
  animation: shimmer 2s linear infinite;
55
86
  }
56
87
 
88
+ .shimmer-text.subtext {
89
+ font-size: 12px;
90
+ opacity: 0.75;
91
+ }
92
+
57
93
  /* ── Steps card ─────────────────────────────────────────── */
94
+ @keyframes fade-in {
95
+ from {
96
+ opacity: 0;
97
+ transform: translateY(4px);
98
+ }
99
+ to {
100
+ opacity: 1;
101
+ transform: translateY(0);
102
+ }
103
+ }
104
+
58
105
  .steps-card {
59
- background: var(--ai-bg-card, #ffffff);
60
- border: 1px solid var(--ai-border-default, #eeeeee);
106
+ background: var(--ai-bg-card);
107
+ border: 1px solid var(--ai-border-default);
61
108
  border-radius: 16px;
62
- box-shadow: 0px 1px 2px 0px rgba(18, 18, 23, 0.05);
109
+ box-shadow: var(--ai-shadow-sm);
63
110
  overflow: hidden;
111
+ animation: fade-in 0.3s ease;
64
112
  }
65
113
 
66
114
  /* ── Steps header ───────────────────────────────────────── */
@@ -69,7 +117,7 @@
69
117
  display: flex;
70
118
  align-items: center;
71
119
  gap: 8px;
72
- border-bottom: 1px solid var(--ai-border-default, #eeeeee);
120
+ border-bottom: 1px solid var(--ai-border-default);
73
121
  }
74
122
 
75
123
  .steps-header.collapsible {
@@ -88,7 +136,7 @@
88
136
  .steps-title {
89
137
  font-size: 16px;
90
138
  font-weight: 500;
91
- color: var(--ai-text-primary, #333333);
139
+ color: var(--ai-text-primary);
92
140
  white-space: nowrap;
93
141
  overflow: hidden;
94
142
  text-overflow: ellipsis;
@@ -105,6 +153,12 @@
105
153
  flex-shrink: 0;
106
154
  }
107
155
 
156
+ .progress-badge.executing-title {
157
+ max-width: 180px;
158
+ overflow: hidden;
159
+ text-overflow: ellipsis;
160
+ }
161
+
108
162
  /* ── Collapse button ────────────────────────────────────── */
109
163
  .collapse-btn {
110
164
  display: inline-flex;
@@ -114,7 +168,7 @@
114
168
  border: none;
115
169
  padding: 0;
116
170
  cursor: pointer;
117
- color: var(--ai-text-secondary, #737373);
171
+ color: var(--ai-text-secondary);
118
172
  flex-shrink: 0;
119
173
  transition: transform 0.2s ease;
120
174
  transform: rotate(180deg);
@@ -131,6 +185,10 @@
131
185
  flex-direction: column;
132
186
  }
133
187
 
188
+ .planning-shimmer {
189
+ padding: 4px 0;
190
+ }
191
+
134
192
  .step-row {
135
193
  display: flex;
136
194
  align-items: flex-start;
@@ -140,16 +198,57 @@
140
198
  }
141
199
 
142
200
  .step-row:hover .step-text {
143
- color: var(--ai-text-primary, #333333);
201
+ color: var(--ai-text-primary);
144
202
  }
145
203
 
146
- .step-text {
204
+ .step-row.pending {
205
+ opacity: 0.5;
206
+ }
207
+
208
+ .step-row.executing .step-text {
209
+ color: var(--ai-text-primary);
210
+ }
211
+
212
+ .step-row.failed .step-text {
213
+ color: var(--ai-error-text, #dc2626);
214
+ }
215
+
216
+ /* ── Step content ───────────────────────────────────────── */
217
+ .step-content {
147
218
  flex: 1;
219
+ display: flex;
220
+ flex-direction: column;
221
+ gap: 2px;
222
+ padding-top: 4px;
223
+ }
224
+
225
+ .step-text {
148
226
  font-size: 14px;
149
227
  font-weight: 400;
150
- color: var(--ai-text-secondary, #737373);
228
+ color: var(--ai-text-secondary);
151
229
  line-height: 1.5;
152
- padding-top: 4px;
230
+ }
231
+
232
+ .step-description {
233
+ font-size: 12px;
234
+ color: var(--ai-text-secondary);
235
+ line-height: 1.4;
236
+ }
237
+
238
+ .step-duration {
239
+ font-size: 11px;
240
+ color: var(--ai-text-secondary);
241
+ opacity: 0.7;
242
+ }
243
+
244
+ .agent-chip {
245
+ display: inline-flex;
246
+ align-self: flex-start;
247
+ font-size: 11px;
248
+ padding: 1px 6px;
249
+ border-radius: 9999px;
250
+ border: 1px solid var(--ai-border-default);
251
+ color: var(--ai-text-secondary);
153
252
  }
154
253
 
155
254
  /* ── Step badge column (badge + separator) ──────────────── */
@@ -163,30 +262,51 @@
163
262
  .step-separator {
164
263
  width: 1px;
165
264
  height: 16px;
166
- background: var(--ai-border-default, #eeeeee);
265
+ background: var(--ai-border-default);
167
266
  margin: 2px 0;
168
267
  }
169
268
 
170
269
  /* ── Step badge ─────────────────────────────────────────── */
270
+ @keyframes pulse-ring {
271
+ 0% {
272
+ transform: scale(1);
273
+ opacity: 0.6;
274
+ }
275
+ 100% {
276
+ transform: scale(2);
277
+ opacity: 0;
278
+ }
279
+ }
280
+
171
281
  .step-badge-outer {
172
282
  padding: 2px;
173
283
  border-radius: 9999px;
174
- background: var(--ai-bg-surface, #f4f4f4);
284
+ background: var(--ai-bg-surface);
175
285
  display: inline-flex;
176
286
  align-items: center;
177
287
  justify-content: center;
288
+ position: relative;
289
+ }
290
+
291
+ .step-badge-outer.pulse-ring::after {
292
+ content: '';
293
+ position: absolute;
294
+ inset: 0;
295
+ border-radius: 9999px;
296
+ border: 2px solid var(--ai-amber);
297
+ animation: pulse-ring 1.2s ease-out infinite;
178
298
  }
179
299
 
180
300
  .step-badge-inner {
181
301
  width: 26px;
182
302
  height: 26px;
183
303
  border-radius: 9999px;
184
- background: var(--ai-bg-card, #ffffff);
185
- box-shadow: 0px 0px 2px 1px rgba(18, 18, 23, 0.08);
304
+ background: var(--ai-bg-card);
305
+ box-shadow: var(--ai-shadow-badge);
186
306
  display: flex;
187
307
  align-items: center;
188
308
  justify-content: center;
189
- color: var(--ai-text-secondary, #737373);
309
+ color: var(--ai-text-secondary);
190
310
  }
191
311
 
192
312
  .step-badge-inner.completed {
@@ -194,9 +314,18 @@
194
314
  color: var(--ai-success-text);
195
315
  }
196
316
 
317
+ .step-badge-inner.executing {
318
+ color: var(--ai-amber);
319
+ }
320
+
321
+ .step-badge-inner.failed {
322
+ background: var(--ai-error-bg, #fee2e2);
323
+ color: var(--ai-error-text, #dc2626);
324
+ }
325
+
197
326
  .step-number {
198
327
  font-size: 14px;
199
328
  font-weight: 500;
200
- color: var(--ai-text-secondary, #737373);
329
+ color: var(--ai-text-secondary);
201
330
  line-height: 1;
202
331
  }
@@ -5,10 +5,16 @@ export class AiLoading {
5
5
  mode = 'thinking';
6
6
  /** Thinking mode status text */
7
7
  statusText = 'جاري التفكير...';
8
+ /** Secondary shimmer line in thinking mode (e.g. live node name) */
9
+ thinkingSubtext = '';
8
10
  /** Steps as JSON string array of LoadingStep */
9
- steps = '[]';
11
+ steps = [];
10
12
  /** Steps mode title */
11
13
  headerTitle = 'خطة التنفيذ';
14
+ /** Agent name shown in header alongside sparkle */
15
+ currentAgent = '';
16
+ /** Show per-step agent chips */
17
+ showAgentBadges = false;
12
18
  /** Steps mode expand state */
13
19
  expanded = true;
14
20
  /** Whether steps card is collapsible */
@@ -26,20 +32,16 @@ export class AiLoading {
26
32
  const svg = `<svg width="${width}" height="${height}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
27
33
  return h("span", { class: "icon-wrap", innerHTML: svg });
28
34
  }
29
- renderSparkleAvatar() {
30
- return h("div", { class: "sparkle-avatar" }, this.renderIcon('sparkle', 14, 14));
35
+ renderSparkleAvatar(agentName) {
36
+ return (h("div", { class: "sparkle-avatar-wrap" }, h("div", { class: "sparkle-avatar" }, this.renderIcon('sparkle', 14, 14)), agentName && h("span", { class: "header-agent" }, agentName)));
31
37
  }
32
38
  renderStepBadge(step, index) {
33
- const isCompleted = step.status === 'completed';
34
- return (h("div", { class: "step-badge-outer" }, h("div", { class: `step-badge-inner ${isCompleted ? 'completed' : ''}` }, isCompleted ? this.renderIcon('check', 14, 14) : h("span", { class: "step-number" }, index + 1))));
35
- }
36
- getStepsList() {
37
- try {
38
- return JSON.parse(this.steps) || [];
39
- }
40
- catch {
41
- return [];
42
- }
39
+ const { status } = step;
40
+ const isCompleted = status === 'completed';
41
+ const isExecuting = status === 'executing';
42
+ const isFailed = status === 'failed';
43
+ const inner = (h("div", { class: `step-badge-inner ${isCompleted ? 'completed' : ''} ${isExecuting ? 'executing' : ''} ${isFailed ? 'failed' : ''}` }, isCompleted && this.renderIcon('check', 14, 14), isFailed && this.renderIcon('cancel', 14, 14), isExecuting && this.renderIcon('list', 14, 14), !isCompleted && !isFailed && !isExecuting && h("span", { class: "step-number" }, index + 1)));
44
+ return h("div", { class: `step-badge-outer ${isExecuting ? 'pulse-ring' : ''}` }, inner);
43
45
  }
44
46
  handleToggle() {
45
47
  if (!this.collapsible)
@@ -49,17 +51,28 @@ export class AiLoading {
49
51
  this.toggleExpand.emit(this._expanded);
50
52
  }
51
53
  renderThinkingMode() {
52
- return (h("div", { class: "thinking-row" }, this.renderSparkleAvatar(), h("span", { class: "shimmer-text" }, this.statusText)));
54
+ return (h("div", { class: "thinking-row" }, this.renderSparkleAvatar(), h("div", { class: "thinking-col" }, h("span", { class: "shimmer-text" }, this.statusText), this.thinkingSubtext && h("span", { class: "shimmer-text subtext" }, this.thinkingSubtext))));
55
+ }
56
+ renderPlanningShimmer() {
57
+ return (h("div", { class: "steps-body" }, h("div", { class: "thinking-row planning-shimmer" }, h("div", { class: "sparkle-avatar" }, this.renderIcon('sparkle', 14, 14)), h("span", { class: "shimmer-text" }, "\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062E\u0637\u064A\u0637..."))));
53
58
  }
54
59
  renderStepsMode() {
55
- const stepsList = this.getStepsList();
56
- const completedCount = stepsList.filter(s => s.status === 'completed').length;
57
- const total = stepsList.length;
60
+ const completedCount = this.steps.filter(s => s.status === 'completed').length;
61
+ const total = this.steps.length;
58
62
  const allDone = total > 0 && completedCount === total;
59
- return (h("div", { class: "steps-card" }, h("div", { class: `steps-header ${this.collapsible ? 'collapsible' : ''}`, onClick: () => this.handleToggle() }, this.renderSparkleAvatar(), h("div", { class: "steps-header-center" }, h("span", { class: "steps-title" }, this.headerTitle), total > 0 && h("span", { class: "progress-badge" }, allDone ? 'مكتمل' : `${completedCount}/${total}`)), this.collapsible && h("button", { class: `collapse-btn ${this._expanded ? 'expanded' : ''}` }, this.renderIcon('chevron-down', 20, 20))), this._expanded && stepsList.length > 0 && (h("div", { class: "steps-body" }, stepsList.map((step, i) => (h("div", { class: "step-row", onClick: () => this.stepClick.emit(step) }, h("div", { class: "step-badge-col" }, this.renderStepBadge(step, i), i < stepsList.length - 1 && h("div", { class: "step-separator" })), h("span", { class: "step-text" }, step.title))))))));
63
+ const executingStep = this.steps.find(s => s.status === 'executing');
64
+ const headerBadge = () => {
65
+ if (total === 0)
66
+ return null;
67
+ if (!this._expanded && executingStep) {
68
+ return h("span", { class: "progress-badge executing-title" }, executingStep.action);
69
+ }
70
+ return h("span", { class: "progress-badge" }, allDone ? 'مكتمل' : `${completedCount}/${total}`);
71
+ };
72
+ return (h("div", { class: "steps-card" }, h("div", { class: `steps-header ${this.collapsible ? 'collapsible' : ''}`, onClick: () => this.handleToggle() }, this.renderSparkleAvatar(this.currentAgent || undefined), h("div", { class: "steps-header-center" }, h("span", { class: "steps-title" }, this.headerTitle), headerBadge()), this.collapsible && h("button", { class: `collapse-btn ${this._expanded ? 'expanded' : ''}` }, this.renderIcon('chevron-down', 20, 20))), this._expanded && total === 0 && this.renderPlanningShimmer(), this._expanded && total > 0 && (h("div", { class: "steps-body" }, this.steps.map((step, i) => (h("div", { class: `step-row ${step.status}`, onClick: () => this.stepClick.emit(step) }, h("div", { class: "step-badge-col" }, this.renderStepBadge(step, i), i < this.steps.length - 1 && h("div", { class: "step-separator" })), h("div", { class: "step-content" }, h("span", { class: "step-text" }, step.action), step.reason && h("span", { class: "step-description" }, step.reason)))))))));
60
73
  }
61
74
  render() {
62
- return h(Host, { key: '8a994758abe21c8a333088eeda498d158631bae6' }, this.mode === 'thinking' ? this.renderThinkingMode() : this.renderStepsMode());
75
+ return h(Host, { key: 'da2c7fad8bbf4e572972a9b8308204cecb91dd63' }, this.mode === 'thinking' ? this.renderThinkingMode() : this.renderStepsMode());
63
76
  }
64
77
  static get is() { return "ai-loading"; }
65
78
  static get encapsulation() { return "shadow"; }
@@ -115,7 +128,7 @@ export class AiLoading {
115
128
  "attribute": "status-text",
116
129
  "defaultValue": "'\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u0641\u0643\u064A\u0631...'"
117
130
  },
118
- "steps": {
131
+ "thinkingSubtext": {
119
132
  "type": "string",
120
133
  "mutable": false,
121
134
  "complexType": {
@@ -127,13 +140,37 @@ export class AiLoading {
127
140
  "optional": false,
128
141
  "docs": {
129
142
  "tags": [],
130
- "text": "Steps as JSON string array of LoadingStep"
143
+ "text": "Secondary shimmer line in thinking mode (e.g. live node name)"
131
144
  },
132
145
  "getter": false,
133
146
  "setter": false,
134
147
  "reflect": false,
135
- "attribute": "steps",
136
- "defaultValue": "'[]'"
148
+ "attribute": "thinking-subtext",
149
+ "defaultValue": "''"
150
+ },
151
+ "steps": {
152
+ "type": "unknown",
153
+ "mutable": false,
154
+ "complexType": {
155
+ "original": "LoadingStep[]",
156
+ "resolved": "LoadingStep[]",
157
+ "references": {
158
+ "LoadingStep": {
159
+ "location": "local",
160
+ "path": "/home/ahmed/Desktop/Salla/Dev/multi-agent/ui-ai-kit/packages/core/src/components/ai-loading/ai-loading.tsx",
161
+ "id": "src/components/ai-loading/ai-loading.tsx::LoadingStep"
162
+ }
163
+ }
164
+ },
165
+ "required": false,
166
+ "optional": false,
167
+ "docs": {
168
+ "tags": [],
169
+ "text": "Steps as JSON string array of LoadingStep"
170
+ },
171
+ "getter": false,
172
+ "setter": false,
173
+ "defaultValue": "[]"
137
174
  },
138
175
  "headerTitle": {
139
176
  "type": "string",
@@ -155,6 +192,46 @@ export class AiLoading {
155
192
  "attribute": "header-title",
156
193
  "defaultValue": "'\u062E\u0637\u0629 \u0627\u0644\u062A\u0646\u0641\u064A\u0630'"
157
194
  },
195
+ "currentAgent": {
196
+ "type": "string",
197
+ "mutable": false,
198
+ "complexType": {
199
+ "original": "string",
200
+ "resolved": "string",
201
+ "references": {}
202
+ },
203
+ "required": false,
204
+ "optional": false,
205
+ "docs": {
206
+ "tags": [],
207
+ "text": "Agent name shown in header alongside sparkle"
208
+ },
209
+ "getter": false,
210
+ "setter": false,
211
+ "reflect": false,
212
+ "attribute": "current-agent",
213
+ "defaultValue": "''"
214
+ },
215
+ "showAgentBadges": {
216
+ "type": "boolean",
217
+ "mutable": false,
218
+ "complexType": {
219
+ "original": "boolean",
220
+ "resolved": "boolean",
221
+ "references": {}
222
+ },
223
+ "required": false,
224
+ "optional": false,
225
+ "docs": {
226
+ "tags": [],
227
+ "text": "Show per-step agent chips"
228
+ },
229
+ "getter": false,
230
+ "setter": false,
231
+ "reflect": false,
232
+ "attribute": "show-agent-badges",
233
+ "defaultValue": "false"
234
+ },
158
235
  "expanded": {
159
236
  "type": "boolean",
160
237
  "mutable": true,
@@ -1,23 +1,12 @@
1
1
  :host {
2
2
  display: block;
3
- font-family: var(--ai-font-family, "PingARLT", sans-serif);
4
3
  width: 100%;
5
-
6
- --ai-input-bg: var(--ai-bg-input, #ffffff);
7
- --ai-input-border-color: var(--ai-border-default, #eeeeee);
8
- --ai-input-text-color: var(--ai-text-primary, #333333);
9
- --ai-input-placeholder-color: var(--ai-text-secondary, #737373);
10
- --ai-voice-button-color: var(--ai-text-secondary, #737373);
11
- --ai-send-button-bg: var(--ai-border-default, #eeeeee);
12
- --ai-send-button-border: var(--ai-border-default, #eeeeee);
13
- --ai-send-button-color: var(--ai-text-secondary, #737373);
14
- --ai-send-button-active-color: var(--ai-text-primary, #333333);
15
4
  }
16
5
 
17
6
  /* Wrapper holds glow + container */
18
7
  .wrapper {
19
8
  position: relative;
20
- padding: var(--ai-input-wrapper-padding, 16px);
9
+ padding: var(--Spacing-Sizes-lg, 12px);
21
10
  }
22
11
 
23
12
  /* Decorative gradient glow below the input */
@@ -37,12 +26,17 @@
37
26
  /* Main container — pill shaped */
38
27
  .input-container {
39
28
  position: relative;
40
- background-color: var(--ai-input-bg, #ffffff);
29
+ background-color: var(--ai-bg-input);
41
30
  border-radius: var(--ai-input-border-radius, 9999px);
42
- border: 1px solid var(--ai-input-border-color, #eeeeee);
43
- box-shadow: 0 1px 2px 0 var(--ai-input-shadow-color, rgba(18, 18, 23, 0.05));
31
+ border: 1px solid var(--ai-border-default);
32
+ box-shadow: var(--ai-shadow-sm);
44
33
  padding: var(--ai-input-padding, 12px);
45
34
  overflow: hidden;
35
+ transition: border-radius 0.15s ease;
36
+ }
37
+
38
+ .input-container.multiline {
39
+ border-radius: var(--ai-input-border-radius-multiline, 20px);
46
40
  }
47
41
 
48
42
  .input-row {
@@ -51,6 +45,10 @@
51
45
  gap: var(--ai-input-gap, 12px);
52
46
  }
53
47
 
48
+ .input-container.multiline .input-row {
49
+ align-items: flex-end;
50
+ }
51
+
54
52
  /* Action buttons (send + optional voice) */
55
53
  .actions {
56
54
  display: flex;
@@ -69,14 +67,11 @@
69
67
  max-height: 32px;
70
68
  padding: 4px 8px;
71
69
  border-radius: 32px;
72
- border: 2px solid var(--ai-send-button-border, #eeeeee);
73
- background-color: var(--ai-send-button-bg, #eeeeee);
74
- color: var(--ai-send-button-color, #737373);
70
+ border: 2px solid var(--ai-border-default);
71
+ background-color: var(--ai-border-default);
72
+ color: var(--ai-text-secondary);
75
73
  cursor: not-allowed;
76
- transition:
77
- background-color 0.2s ease,
78
- border-color 0.2s ease,
79
- color 0.2s ease;
74
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
80
75
  flex-shrink: 0;
81
76
  }
82
77
 
@@ -94,6 +89,7 @@
94
89
 
95
90
  .send-button:focus {
96
91
  outline: none;
92
+ box-shadow: 0 0 0 2px var(--ai-focus-ring-color, var(--ai-focus-ring));
97
93
  }
98
94
 
99
95
  /* Voice Button */
@@ -106,16 +102,14 @@
106
102
  border-radius: 32px;
107
103
  border: none;
108
104
  background-color: transparent;
109
- color: var(--ai-voice-button-color, #737373);
105
+ color: var(--ai-text-secondary);
110
106
  cursor: pointer;
111
- transition:
112
- background-color 0.2s ease,
113
- color 0.2s ease;
107
+ transition: background-color 0.2s ease, color 0.2s ease;
114
108
  flex-shrink: 0;
115
109
  }
116
110
 
117
111
  .voice-button:hover:not(:disabled) {
118
- background-color: var(--ai-voice-button-hover-bg, rgba(0, 0, 0, 0.06));
112
+ background-color: var(--ai-hover-overlay);
119
113
  color: var(--ai-voice-button-hover-color, var(--ai-text-secondary));
120
114
  }
121
115
 
@@ -138,17 +132,17 @@
138
132
  background: transparent;
139
133
  font-size: var(--ai-input-font-size, 14px);
140
134
  line-height: var(--ai-input-line-height, 20px);
141
- color: var(--ai-input-text-color, #333333);
135
+ color: var(--ai-text-primary);
142
136
  font-family: inherit;
143
137
  min-height: 20px;
144
- text-align: right;
145
- direction: rtl;
138
+ max-height: var(--ai-input-max-height, 120px);
139
+ overflow-y: hidden;
140
+ text-align: start;
146
141
  padding: 0;
147
- overflow: hidden;
148
142
  }
149
143
 
150
144
  .textarea::placeholder {
151
- color: var(--ai-input-placeholder-color, #737373);
145
+ color: var(--ai-text-secondary);
152
146
  }
153
147
 
154
148
  .textarea:disabled {
@@ -159,7 +153,7 @@
159
153
  /* Active / focus state for container — matches Figma active state */
160
154
  .input-container:focus-within {
161
155
  border-color: var(--ai-input-focus-border-color, var(--ai-accent));
162
- box-shadow: 0 0 10px 4px rgba(227, 255, 247, 0.4);
156
+ box-shadow: var(--ai-input-focus-glow);
163
157
  }
164
158
 
165
159
  /* Disabled state */
@@ -168,8 +162,18 @@
168
162
  pointer-events: none;
169
163
  }
170
164
 
171
- /* RTL Support */
172
- :host([dir='ltr']) .textarea {
173
- text-align: left;
174
- direction: ltr;
165
+ :host([disabled]) .glow {
166
+ display: none;
167
+ }
168
+
169
+ /* Character counter */
170
+ .char-counter {
171
+ font-size: 11px;
172
+ color: var(--ai-text-secondary);
173
+ flex-shrink: 0;
174
+ transition: color 0.2s ease;
175
+ }
176
+
177
+ .char-counter.warning {
178
+ color: var(--ai-voice-timer-warning-color, var(--ai-danger-text));
175
179
  }