@salla.sa/ui-ai-kit-core 1.0.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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/ai-card.cjs.entry.js +25 -0
  3. package/dist/cjs/ai-chat-container.cjs.entry.js +138 -0
  4. package/dist/cjs/ai-chat-header.cjs.entry.js +79 -0
  5. package/dist/cjs/ai-chat-message.cjs.entry.js +164 -0
  6. package/dist/cjs/ai-icon.cjs.entry.js +25 -0
  7. package/dist/cjs/ai-link.cjs.entry.js +34 -0
  8. package/dist/cjs/ai-loading.cjs.entry.js +77 -0
  9. package/dist/cjs/ai-message-input.cjs.entry.js +65 -0
  10. package/dist/cjs/ai-rating.cjs.entry.js +57 -0
  11. package/dist/cjs/ai-suggestion.cjs.entry.js +31 -0
  12. package/dist/cjs/ai-voice-input.cjs.entry.js +233 -0
  13. package/dist/cjs/icon-registry-dmfLA-Dj.js +82 -0
  14. package/dist/cjs/index-DLJcLHFH.js +1622 -0
  15. package/dist/cjs/index.cjs.js +7 -0
  16. package/dist/cjs/loader.cjs.js +12 -0
  17. package/dist/cjs/ui-ai-kit.cjs.js +24 -0
  18. package/dist/collection/collection-manifest.json +23 -0
  19. package/dist/collection/components/ai-card/ai-card.css +40 -0
  20. package/dist/collection/components/ai-card/ai-card.js +70 -0
  21. package/dist/collection/components/ai-card/ai-card.stories.js +52 -0
  22. package/dist/collection/components/ai-chat-container/ai-chat-container.css +137 -0
  23. package/dist/collection/components/ai-chat-container/ai-chat-container.js +270 -0
  24. package/dist/collection/components/ai-chat-container/ai-chat-container.stories.js +160 -0
  25. package/dist/collection/components/ai-chat-header/ai-chat-header.css +186 -0
  26. package/dist/collection/components/ai-chat-header/ai-chat-header.js +311 -0
  27. package/dist/collection/components/ai-chat-header/ai-chat-header.stories.js +138 -0
  28. package/dist/collection/components/ai-chat-message/ai-chat-message.css +304 -0
  29. package/dist/collection/components/ai-chat-message/ai-chat-message.js +379 -0
  30. package/dist/collection/components/ai-chat-message/ai-chat-message.stories.js +164 -0
  31. package/dist/collection/components/ai-icon/ai-icon.css +9 -0
  32. package/dist/collection/components/ai-icon/ai-icon.js +76 -0
  33. package/dist/collection/components/ai-link/ai-link.css +62 -0
  34. package/dist/collection/components/ai-link/ai-link.js +119 -0
  35. package/dist/collection/components/ai-link/ai-link.stories.js +79 -0
  36. package/dist/collection/components/ai-loading/ai-loading.css +202 -0
  37. package/dist/collection/components/ai-loading/ai-loading.js +244 -0
  38. package/dist/collection/components/ai-loading/ai-loading.stories.js +145 -0
  39. package/dist/collection/components/ai-message-input/ai-message-input.css +175 -0
  40. package/dist/collection/components/ai-message-input/ai-message-input.js +192 -0
  41. package/dist/collection/components/ai-message-input/ai-message-input.stories.js +125 -0
  42. package/dist/collection/components/ai-rating/ai-rating.css +145 -0
  43. package/dist/collection/components/ai-rating/ai-rating.js +176 -0
  44. package/dist/collection/components/ai-rating/ai-rating.stories.js +78 -0
  45. package/dist/collection/components/ai-suggestion/ai-suggestion.css +69 -0
  46. package/dist/collection/components/ai-suggestion/ai-suggestion.js +93 -0
  47. package/dist/collection/components/ai-suggestion/ai-suggestion.stories.js +62 -0
  48. package/dist/collection/components/ai-voice-input/ai-voice-input.css +136 -0
  49. package/dist/collection/components/ai-voice-input/ai-voice-input.js +341 -0
  50. package/dist/collection/components/ai-voice-input/ai-voice-input.stories.js +118 -0
  51. package/dist/collection/index.js +10 -0
  52. package/dist/collection/utils/icon-registry.js +78 -0
  53. package/dist/collection/utils/utils.js +3 -0
  54. package/dist/components/ai-card.d.ts +11 -0
  55. package/dist/components/ai-card.js +1 -0
  56. package/dist/components/ai-chat-container.d.ts +11 -0
  57. package/dist/components/ai-chat-container.js +1 -0
  58. package/dist/components/ai-chat-header.d.ts +11 -0
  59. package/dist/components/ai-chat-header.js +1 -0
  60. package/dist/components/ai-chat-message.d.ts +11 -0
  61. package/dist/components/ai-chat-message.js +1 -0
  62. package/dist/components/ai-icon.d.ts +11 -0
  63. package/dist/components/ai-icon.js +1 -0
  64. package/dist/components/ai-link.d.ts +11 -0
  65. package/dist/components/ai-link.js +1 -0
  66. package/dist/components/ai-loading.d.ts +11 -0
  67. package/dist/components/ai-loading.js +1 -0
  68. package/dist/components/ai-message-input.d.ts +11 -0
  69. package/dist/components/ai-message-input.js +1 -0
  70. package/dist/components/ai-rating.d.ts +11 -0
  71. package/dist/components/ai-rating.js +1 -0
  72. package/dist/components/ai-suggestion.d.ts +11 -0
  73. package/dist/components/ai-suggestion.js +1 -0
  74. package/dist/components/ai-voice-input.d.ts +11 -0
  75. package/dist/components/ai-voice-input.js +1 -0
  76. package/dist/components/index.d.ts +35 -0
  77. package/dist/components/index.js +1 -0
  78. package/dist/components/p-CWjXxYJI.js +1 -0
  79. package/dist/components/p-CY6emva2.js +1 -0
  80. package/dist/components/p-DYv5ef4M.js +1 -0
  81. package/dist/esm/ai-card.entry.js +23 -0
  82. package/dist/esm/ai-chat-container.entry.js +136 -0
  83. package/dist/esm/ai-chat-header.entry.js +77 -0
  84. package/dist/esm/ai-chat-message.entry.js +162 -0
  85. package/dist/esm/ai-icon.entry.js +23 -0
  86. package/dist/esm/ai-link.entry.js +32 -0
  87. package/dist/esm/ai-loading.entry.js +75 -0
  88. package/dist/esm/ai-message-input.entry.js +63 -0
  89. package/dist/esm/ai-rating.entry.js +55 -0
  90. package/dist/esm/ai-suggestion.entry.js +29 -0
  91. package/dist/esm/ai-voice-input.entry.js +231 -0
  92. package/dist/esm/icon-registry-DYv5ef4M.js +80 -0
  93. package/dist/esm/index-7hrZ8FOQ.js +1612 -0
  94. package/dist/esm/index.js +5 -0
  95. package/dist/esm/loader.js +10 -0
  96. package/dist/esm/ui-ai-kit.js +20 -0
  97. package/dist/index.cjs.js +1 -0
  98. package/dist/index.js +1 -0
  99. package/dist/types/components/ai-card/ai-card.d.ts +7 -0
  100. package/dist/types/components/ai-card/ai-card.stories.d.ts +7 -0
  101. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +28 -0
  102. package/dist/types/components/ai-chat-container/ai-chat-container.stories.d.ts +7 -0
  103. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +38 -0
  104. package/dist/types/components/ai-chat-header/ai-chat-header.stories.d.ts +8 -0
  105. package/dist/types/components/ai-chat-message/ai-chat-message.d.ts +27 -0
  106. package/dist/types/components/ai-chat-message/ai-chat-message.stories.d.ts +10 -0
  107. package/dist/types/components/ai-icon/ai-icon.d.ts +8 -0
  108. package/dist/types/components/ai-link/ai-link.d.ts +12 -0
  109. package/dist/types/components/ai-link/ai-link.stories.d.ts +8 -0
  110. package/dist/types/components/ai-loading/ai-loading.d.ts +33 -0
  111. package/dist/types/components/ai-loading/ai-loading.stories.d.ts +10 -0
  112. package/dist/types/components/ai-message-input/ai-message-input.d.ts +22 -0
  113. package/dist/types/components/ai-message-input/ai-message-input.stories.d.ts +13 -0
  114. package/dist/types/components/ai-rating/ai-rating.d.ts +17 -0
  115. package/dist/types/components/ai-rating/ai-rating.stories.d.ts +8 -0
  116. package/dist/types/components/ai-suggestion/ai-suggestion.d.ts +10 -0
  117. package/dist/types/components/ai-suggestion/ai-suggestion.stories.d.ts +8 -0
  118. package/dist/types/components/ai-voice-input/ai-voice-input.d.ts +43 -0
  119. package/dist/types/components/ai-voice-input/ai-voice-input.stories.d.ts +9 -0
  120. package/dist/types/components.d.ts +860 -0
  121. package/dist/types/index.d.ts +11 -0
  122. package/dist/types/stencil-public-runtime.d.ts +1860 -0
  123. package/dist/types/utils/icon-registry.d.ts +5 -0
  124. package/dist/types/utils/utils.d.ts +1 -0
  125. package/dist/ui-ai-kit/index.esm.js +1 -0
  126. package/dist/ui-ai-kit/p-11facfad.entry.js +1 -0
  127. package/dist/ui-ai-kit/p-128a2ed4.entry.js +1 -0
  128. package/dist/ui-ai-kit/p-227bdb8f.entry.js +1 -0
  129. package/dist/ui-ai-kit/p-455daa17.entry.js +1 -0
  130. package/dist/ui-ai-kit/p-56163e8c.entry.js +1 -0
  131. package/dist/ui-ai-kit/p-6d21d0fd.entry.js +1 -0
  132. package/dist/ui-ai-kit/p-6ddcd77b.entry.js +1 -0
  133. package/dist/ui-ai-kit/p-7hrZ8FOQ.js +2 -0
  134. package/dist/ui-ai-kit/p-8e90143e.entry.js +1 -0
  135. package/dist/ui-ai-kit/p-9938c277.entry.js +1 -0
  136. package/dist/ui-ai-kit/p-DYv5ef4M.js +1 -0
  137. package/dist/ui-ai-kit/p-dc5b4a7f.entry.js +1 -0
  138. package/dist/ui-ai-kit/p-fb1702de.entry.js +1 -0
  139. package/dist/ui-ai-kit/ui-ai-kit.css +1 -0
  140. package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -0
  141. package/loader/cdn.js +1 -0
  142. package/loader/index.cjs.js +1 -0
  143. package/loader/index.d.ts +24 -0
  144. package/loader/index.es2017.js +1 -0
  145. package/loader/index.js +2 -0
  146. package/package.json +77 -0
  147. package/readme.md +111 -0
@@ -0,0 +1,379 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import { iconRegistry } from "../../utils/icon-registry";
3
+ export class AiChatMessage {
4
+ role = 'user';
5
+ content = '';
6
+ format = 'text';
7
+ agentName = '';
8
+ timestamp = '';
9
+ showActions = true;
10
+ enableRegenerate = false;
11
+ feedbackValue = null;
12
+ messageCopy;
13
+ messageFeedback;
14
+ messageRegenerate;
15
+ copySuccess = false;
16
+ copyTimeout;
17
+ disconnectedCallback() {
18
+ if (this.copyTimeout)
19
+ clearTimeout(this.copyTimeout);
20
+ }
21
+ renderIcon(name, size = 16) {
22
+ const icon = iconRegistry[name];
23
+ if (!icon)
24
+ return null;
25
+ const svg = `<svg width="${size}" height="${size}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
26
+ return h("span", { class: "icon-wrap", innerHTML: svg });
27
+ }
28
+ parseMarkdown(text) {
29
+ let html = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
30
+ const blocks = [];
31
+ html = html.replace(/```(?:\w+)?\n?([\s\S]*?)```/g, (_, code) => {
32
+ const idx = blocks.length;
33
+ blocks.push(`<pre><code>${code}</code></pre>`);
34
+ return `\x00BLOCK${idx}\x00`;
35
+ });
36
+ html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
37
+ html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
38
+ html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
39
+ html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
40
+ html = html.replace(/\*([^*\n]+)\*/g, '<em>$1</em>');
41
+ html = html.replace(/((?:^[ \t]*[-*] .+\n?)+)/gm, match => {
42
+ const items = match
43
+ .trim()
44
+ .split('\n')
45
+ .filter(l => l.trim())
46
+ .map(l => `<li>${l.replace(/^[ \t]*[-*] /, '')}</li>`)
47
+ .join('');
48
+ return `\x00BLOCK${blocks.length}\x00${(() => {
49
+ blocks.push(`<ul>${items}</ul>`);
50
+ return '';
51
+ })()}`;
52
+ });
53
+ html = html.replace(/((?:^[ \t]*\d+\. .+\n?)+)/gm, match => {
54
+ const items = match
55
+ .trim()
56
+ .split('\n')
57
+ .filter(l => l.trim())
58
+ .map(l => `<li>${l.replace(/^[ \t]*\d+\. /, '')}</li>`)
59
+ .join('');
60
+ return `\x00BLOCK${blocks.length}\x00${(() => {
61
+ blocks.push(`<ol>${items}</ol>`);
62
+ return '';
63
+ })()}`;
64
+ });
65
+ html = html
66
+ .split(/\n{2,}/)
67
+ .map(chunk => {
68
+ const trimmed = chunk.trim();
69
+ if (!trimmed)
70
+ return '';
71
+ if (/^\x00BLOCK\d+\x00$/.test(trimmed))
72
+ return trimmed;
73
+ return `<p>${trimmed.replace(/\n/g, '<br>')}</p>`;
74
+ })
75
+ .join('');
76
+ html = html.replace(/\x00BLOCK(\d+)\x00/g, (_, i) => blocks[parseInt(i, 10)] || '');
77
+ return html;
78
+ }
79
+ getRenderedContent() {
80
+ if (!this.content)
81
+ return '';
82
+ let html = this.parseMarkdown(this.content);
83
+ return html;
84
+ }
85
+ getRelativeTime() {
86
+ if (!this.timestamp)
87
+ return '';
88
+ try {
89
+ const date = new Date(this.timestamp);
90
+ if (isNaN(date.getTime()))
91
+ return this.timestamp;
92
+ const diffMin = Math.floor((Date.now() - date.getTime()) / 60000);
93
+ if (diffMin < 1)
94
+ return 'الآن';
95
+ if (diffMin < 60)
96
+ return `منذ ${diffMin} دقيقة`;
97
+ const hours = Math.floor(diffMin / 60);
98
+ if (hours < 24)
99
+ return `منذ ${hours} ساعة`;
100
+ return `منذ ${Math.floor(hours / 24)} يوم`;
101
+ }
102
+ catch {
103
+ return this.timestamp;
104
+ }
105
+ }
106
+ async handleCopy() {
107
+ try {
108
+ await navigator.clipboard.writeText(this.content);
109
+ }
110
+ catch (_) { }
111
+ this.copySuccess = true;
112
+ this.messageCopy.emit();
113
+ this.copyTimeout = setTimeout(() => (this.copySuccess = false), 1500);
114
+ }
115
+ handleFeedback(val) {
116
+ this.feedbackValue = this.feedbackValue === val ? null : val;
117
+ this.messageFeedback.emit(val);
118
+ }
119
+ renderActionsBar() {
120
+ return (h("div", { class: "actions-bar" }, this.enableRegenerate && h("button", { class: 'action-btn', onClick: () => this.messageRegenerate.emit(), title: "\u0625\u0639\u0627\u062F\u0629 \u062A\u062D\u0645\u064A\u0644" }, this.renderIcon('reload', 16)), h("button", { class: `action-btn copy-btn${this.copySuccess ? ' copy-success' : ''}`, onClick: () => this.handleCopy(), title: "\u0646\u0633\u062E" }, this.renderIcon('copy', 16)), h("div", { class: "feedback-group" }, h("button", { class: `feedback-btn thumbs-down-btn${this.feedbackValue === 'down' ? ' active' : ''}`, onClick: () => this.handleFeedback('down'), title: "\u063A\u064A\u0631 \u0645\u0641\u064A\u062F" }, this.renderIcon('thumbs-down', 16)), h("button", { class: `feedback-btn thumbs-up-btn${this.feedbackValue === 'up' ? ' active' : ''}`, onClick: () => this.handleFeedback('up'), title: "\u0645\u0641\u064A\u062F" }, this.renderIcon('thumbs-up', 16)))));
121
+ }
122
+ renderUserMessage() {
123
+ return (h("div", { class: "message-row user-row" }, h("div", { class: "bubble user-bubble" }, h("div", { class: "message-content", ref: el => {
124
+ if (!el)
125
+ return;
126
+ if (this.format === 'markdown') {
127
+ el.innerHTML = this.getRenderedContent();
128
+ }
129
+ else {
130
+ el.textContent = this.content;
131
+ }
132
+ } }))));
133
+ }
134
+ renderAgentMessage() {
135
+ const showActions = this.showActions;
136
+ return (h("div", { class: "message-row agent-row" }, h("div", { class: "agent-bubble-wrapper" }, h("div", { class: "bubble agent-bubble" }, this.content && (h("div", { class: "message-content", ref: el => {
137
+ if (!el)
138
+ return;
139
+ if (this.format === 'markdown') {
140
+ el.innerHTML = this.getRenderedContent();
141
+ }
142
+ else {
143
+ el.textContent = this.content;
144
+ }
145
+ } })), 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()))))));
146
+ }
147
+ render() {
148
+ return h(Host, { key: '77dd0c46a676c211fdfba283d51bd0e0d2594b24' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
149
+ }
150
+ static get is() { return "ai-chat-message"; }
151
+ static get encapsulation() { return "shadow"; }
152
+ static get originalStyleUrls() {
153
+ return {
154
+ "$": ["ai-chat-message.css"]
155
+ };
156
+ }
157
+ static get styleUrls() {
158
+ return {
159
+ "$": ["ai-chat-message.css"]
160
+ };
161
+ }
162
+ static get properties() {
163
+ return {
164
+ "role": {
165
+ "type": "string",
166
+ "mutable": false,
167
+ "complexType": {
168
+ "original": "'user' | 'agent'",
169
+ "resolved": "\"agent\" | \"user\"",
170
+ "references": {}
171
+ },
172
+ "required": false,
173
+ "optional": false,
174
+ "docs": {
175
+ "tags": [],
176
+ "text": ""
177
+ },
178
+ "getter": false,
179
+ "setter": false,
180
+ "reflect": false,
181
+ "attribute": "role",
182
+ "defaultValue": "'user'"
183
+ },
184
+ "content": {
185
+ "type": "string",
186
+ "mutable": false,
187
+ "complexType": {
188
+ "original": "string",
189
+ "resolved": "string",
190
+ "references": {}
191
+ },
192
+ "required": false,
193
+ "optional": false,
194
+ "docs": {
195
+ "tags": [],
196
+ "text": ""
197
+ },
198
+ "getter": false,
199
+ "setter": false,
200
+ "reflect": false,
201
+ "attribute": "content",
202
+ "defaultValue": "''"
203
+ },
204
+ "format": {
205
+ "type": "string",
206
+ "mutable": false,
207
+ "complexType": {
208
+ "original": "'text' | 'markdown'",
209
+ "resolved": "\"markdown\" | \"text\"",
210
+ "references": {}
211
+ },
212
+ "required": false,
213
+ "optional": false,
214
+ "docs": {
215
+ "tags": [],
216
+ "text": ""
217
+ },
218
+ "getter": false,
219
+ "setter": false,
220
+ "reflect": false,
221
+ "attribute": "format",
222
+ "defaultValue": "'text'"
223
+ },
224
+ "agentName": {
225
+ "type": "string",
226
+ "mutable": false,
227
+ "complexType": {
228
+ "original": "string",
229
+ "resolved": "string",
230
+ "references": {}
231
+ },
232
+ "required": false,
233
+ "optional": false,
234
+ "docs": {
235
+ "tags": [],
236
+ "text": ""
237
+ },
238
+ "getter": false,
239
+ "setter": false,
240
+ "reflect": false,
241
+ "attribute": "agent-name",
242
+ "defaultValue": "''"
243
+ },
244
+ "timestamp": {
245
+ "type": "string",
246
+ "mutable": false,
247
+ "complexType": {
248
+ "original": "string",
249
+ "resolved": "string",
250
+ "references": {}
251
+ },
252
+ "required": false,
253
+ "optional": false,
254
+ "docs": {
255
+ "tags": [],
256
+ "text": ""
257
+ },
258
+ "getter": false,
259
+ "setter": false,
260
+ "reflect": false,
261
+ "attribute": "timestamp",
262
+ "defaultValue": "''"
263
+ },
264
+ "showActions": {
265
+ "type": "boolean",
266
+ "mutable": false,
267
+ "complexType": {
268
+ "original": "boolean",
269
+ "resolved": "boolean",
270
+ "references": {}
271
+ },
272
+ "required": false,
273
+ "optional": false,
274
+ "docs": {
275
+ "tags": [],
276
+ "text": ""
277
+ },
278
+ "getter": false,
279
+ "setter": false,
280
+ "reflect": false,
281
+ "attribute": "show-actions",
282
+ "defaultValue": "true"
283
+ },
284
+ "enableRegenerate": {
285
+ "type": "boolean",
286
+ "mutable": false,
287
+ "complexType": {
288
+ "original": "boolean",
289
+ "resolved": "boolean",
290
+ "references": {}
291
+ },
292
+ "required": false,
293
+ "optional": false,
294
+ "docs": {
295
+ "tags": [],
296
+ "text": ""
297
+ },
298
+ "getter": false,
299
+ "setter": false,
300
+ "reflect": false,
301
+ "attribute": "enable-regenerate",
302
+ "defaultValue": "false"
303
+ },
304
+ "feedbackValue": {
305
+ "type": "string",
306
+ "mutable": true,
307
+ "complexType": {
308
+ "original": "'up' | 'down' | null",
309
+ "resolved": "\"down\" | \"up\"",
310
+ "references": {}
311
+ },
312
+ "required": false,
313
+ "optional": false,
314
+ "docs": {
315
+ "tags": [],
316
+ "text": ""
317
+ },
318
+ "getter": false,
319
+ "setter": false,
320
+ "reflect": false,
321
+ "attribute": "feedback-value",
322
+ "defaultValue": "null"
323
+ }
324
+ };
325
+ }
326
+ static get states() {
327
+ return {
328
+ "copySuccess": {}
329
+ };
330
+ }
331
+ static get events() {
332
+ return [{
333
+ "method": "messageCopy",
334
+ "name": "messageCopy",
335
+ "bubbles": true,
336
+ "cancelable": true,
337
+ "composed": true,
338
+ "docs": {
339
+ "tags": [],
340
+ "text": ""
341
+ },
342
+ "complexType": {
343
+ "original": "void",
344
+ "resolved": "void",
345
+ "references": {}
346
+ }
347
+ }, {
348
+ "method": "messageFeedback",
349
+ "name": "messageFeedback",
350
+ "bubbles": true,
351
+ "cancelable": true,
352
+ "composed": true,
353
+ "docs": {
354
+ "tags": [],
355
+ "text": ""
356
+ },
357
+ "complexType": {
358
+ "original": "'up' | 'down'",
359
+ "resolved": "\"down\" | \"up\"",
360
+ "references": {}
361
+ }
362
+ }, {
363
+ "method": "messageRegenerate",
364
+ "name": "messageRegenerate",
365
+ "bubbles": true,
366
+ "cancelable": true,
367
+ "composed": true,
368
+ "docs": {
369
+ "tags": [],
370
+ "text": ""
371
+ },
372
+ "complexType": {
373
+ "original": "void",
374
+ "resolved": "void",
375
+ "references": {}
376
+ }
377
+ }];
378
+ }
379
+ }
@@ -0,0 +1,164 @@
1
+ import { html } from "lit";
2
+ const meta = {
3
+ title: 'Chat/Chat Message',
4
+ component: 'ai-chat-message',
5
+ tags: ['autodocs'],
6
+ argTypes: {
7
+ role: {
8
+ control: { type: 'select' },
9
+ options: ['user', 'agent'],
10
+ },
11
+ content: { control: 'text' },
12
+ format: {
13
+ control: { type: 'select' },
14
+ options: ['text', 'markdown'],
15
+ },
16
+ agentName: { control: 'text' },
17
+ timestamp: { control: 'text' },
18
+ isLoading: { control: 'boolean' },
19
+ showActions: { control: 'boolean' },
20
+ enableRegenerate: { control: 'boolean' },
21
+ feedbackValue: {
22
+ control: { type: 'select' },
23
+ options: [null, 'up', 'down'],
24
+ },
25
+ },
26
+ };
27
+ export default meta;
28
+ const wrapStyle = 'padding: 24px; background: #f3f4f6; direction: rtl;';
29
+ const threadStyle = `${wrapStyle} display: flex; flex-direction: column; gap: 12px; max-width: 480px;`;
30
+ export const UserMessage = {
31
+ render: args => html `
32
+ <div style="${wrapStyle}">
33
+ <ai-chat-message
34
+ role="${args.role}"
35
+ content="${args.content}"
36
+ timestamp="${args.timestamp}"
37
+ ></ai-chat-message>
38
+ </div>
39
+ `,
40
+ args: {
41
+ role: 'user',
42
+ content: 'مرحباً، كيف يمكنني تتبع طلبي؟',
43
+ timestamp: new Date(Date.now() - 120000).toISOString(),
44
+ },
45
+ };
46
+ export const AgentMessageSimple = {
47
+ render: args => html `
48
+ <div style="${wrapStyle}">
49
+ <ai-chat-message
50
+ role="${args.role}"
51
+ content="${args.content}"
52
+ agent-name="${args.agentName}"
53
+ timestamp="${args.timestamp}"
54
+ ?show-actions="${args.showActions}"
55
+ ></ai-chat-message>
56
+ </div>
57
+ `,
58
+ args: {
59
+ role: 'agent',
60
+ content: 'مرحباً بك! يسعدني مساعدتك في تتبع طلبك. هل يمكنك تزويدي برقم الطلب؟',
61
+ agentName: 'الرد الآلي | Salla AI',
62
+ timestamp: new Date().toISOString(),
63
+ showActions: true,
64
+ },
65
+ };
66
+ export const AgentMessageMarkdown = {
67
+ render: args => html `
68
+ <div style="${wrapStyle}">
69
+ <ai-chat-message
70
+ role="${args.role}"
71
+ content="${args.content}"
72
+ format="${args.format}"
73
+ agent-name="${args.agentName}"
74
+ timestamp="${args.timestamp}"
75
+ ?show-actions="${args.showActions}"
76
+ ?enable-regenerate="${args.enableRegenerate}"
77
+ ></ai-chat-message>
78
+ </div>
79
+ `,
80
+ args: {
81
+ role: 'agent',
82
+ content: `## تفاصيل طلبك\n\nوجدت طلبك **#ORD-2024-78945**. إليك الملخص:\n\n- **الحالة**: قيد الشحن\n- **التاريخ**: 10 مارس 2026\n- **المنتجات**: 3 عناصر\n\n### الخطوات التالية\n\nسيصلك *رمز التتبع* خلال ساعة.`,
83
+ format: 'markdown',
84
+ agentName: 'الرد الآلي | Salla AI',
85
+ timestamp: new Date().toISOString(),
86
+ showActions: true,
87
+ },
88
+ };
89
+ export const FeedbackSelected = {
90
+ render: args => html `
91
+ <div style="${wrapStyle}">
92
+ <ai-chat-message
93
+ role="${args.role}"
94
+ content="${args.content}"
95
+ agent-name="${args.agentName}"
96
+ timestamp="${args.timestamp}"
97
+ feedback-value="${args.feedbackValue}"
98
+ ?show-actions="${args.showActions}"
99
+ ></ai-chat-message>
100
+ </div>
101
+ `,
102
+ args: {
103
+ role: 'agent',
104
+ content: 'تم شحن طلبك وسيصلك خلال يومين.',
105
+ agentName: 'الرد الآلي | Salla AI',
106
+ timestamp: new Date().toISOString(),
107
+ feedbackValue: 'up',
108
+ showActions: true,
109
+ },
110
+ };
111
+ export const WithSlottedContent = {
112
+ render: () => html `
113
+ <div style="${wrapStyle} max-width: 480px;">
114
+ <ai-chat-message
115
+ role="agent"
116
+ content="جاري معالجة طلبك..."
117
+ agent-name="الرد الآلي | Salla AI"
118
+ timestamp="${new Date().toISOString()}"
119
+ ?show-actions="${false}"
120
+ >
121
+ <ai-execution-steps
122
+ steps='[{"id":"1","title":"البحث عن الطلب","status":"completed","agent":"الطلبات"},{"id":"2","title":"التحقق من حالة الشحن","status":"executing","agent":"الشحن"},{"id":"3","title":"إعداد رابط التتبع","status":"pending","agent":"التجميع"}]'
123
+ language="ar"
124
+ variant="compact"
125
+ title="خطة التنفيذ"
126
+ ></ai-execution-steps>
127
+ </ai-chat-message>
128
+ </div>
129
+ `,
130
+ };
131
+ export const ConversationThread = {
132
+ render: () => html `
133
+ <div style="${threadStyle}">
134
+ <ai-chat-message
135
+ role="user"
136
+ content="مرحباً، أحتاج مساعدة في تتبع طلبي"
137
+ timestamp="${new Date(Date.now() - 300000).toISOString()}"
138
+ ></ai-chat-message>
139
+
140
+ <ai-chat-message
141
+ role="agent"
142
+ content="مرحباً! يسعدني مساعدتك. هل يمكنك تزويدي برقم الطلب؟"
143
+ agent-name="الرد الآلي | Salla AI"
144
+ timestamp="${new Date(Date.now() - 240000).toISOString()}"
145
+ show-actions
146
+ ></ai-chat-message>
147
+
148
+ <ai-chat-message
149
+ role="user"
150
+ content="بالتأكيد، رقمه #ORD-2024-78945"
151
+ timestamp="${new Date(Date.now() - 180000).toISOString()}"
152
+ ></ai-chat-message>
153
+
154
+ <ai-chat-message
155
+ role="agent"
156
+ content="**وجدت طلبك!** حالته الآن *قيد الشحن* وسيصلك خلال يومين عمل.\n\n- رقم التتبع: **TRK-9876543**\n- شركة الشحن: أرامكس"
157
+ format="markdown"
158
+ agent-name="الرد الآلي | Salla AI"
159
+ timestamp="${new Date().toISOString()}"
160
+ show-actions
161
+ ></ai-chat-message>
162
+ </div>
163
+ `,
164
+ };
@@ -0,0 +1,9 @@
1
+ :host {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ }
6
+
7
+ svg {
8
+ display: block;
9
+ }
@@ -0,0 +1,76 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import { iconRegistry } from "../../utils/icon-registry";
3
+ export class AiIcon {
4
+ /** Icon name from the registry */
5
+ name;
6
+ /** Size in pixels for width and height */
7
+ size = 16;
8
+ render() {
9
+ const icon = iconRegistry[this.name];
10
+ if (!icon)
11
+ return null;
12
+ return (h(Host, null, h("svg", { width: this.size, height: this.size, viewBox: icon.viewBox, xmlns: "http://www.w3.org/2000/svg", ref: (el) => el && (el.innerHTML = icon.content), "aria-hidden": "true" })));
13
+ }
14
+ static get is() { return "ai-icon"; }
15
+ static get encapsulation() { return "shadow"; }
16
+ static get originalStyleUrls() {
17
+ return {
18
+ "$": ["ai-icon.css"]
19
+ };
20
+ }
21
+ static get styleUrls() {
22
+ return {
23
+ "$": ["ai-icon.css"]
24
+ };
25
+ }
26
+ static get properties() {
27
+ return {
28
+ "name": {
29
+ "type": "string",
30
+ "mutable": false,
31
+ "complexType": {
32
+ "original": "IconName",
33
+ "resolved": "\"arrow-right\" | \"arrow-up\" | \"cancel\" | \"check\" | \"chevron-down\" | \"copy\" | \"drag\" | \"eclipse\" | \"hand\" | \"mic\" | \"online-dot\" | \"pencil-edit\" | \"reload\" | \"send\" | \"share\" | \"sparkle\" | \"thumbs-down\" | \"thumbs-up\" | \"watermark\"",
34
+ "references": {
35
+ "IconName": {
36
+ "location": "import",
37
+ "path": "../../utils/icon-registry",
38
+ "id": "src/utils/icon-registry.ts::IconName",
39
+ "referenceLocation": "IconName"
40
+ }
41
+ }
42
+ },
43
+ "required": false,
44
+ "optional": false,
45
+ "docs": {
46
+ "tags": [],
47
+ "text": "Icon name from the registry"
48
+ },
49
+ "getter": false,
50
+ "setter": false,
51
+ "reflect": false,
52
+ "attribute": "name"
53
+ },
54
+ "size": {
55
+ "type": "number",
56
+ "mutable": false,
57
+ "complexType": {
58
+ "original": "number",
59
+ "resolved": "number",
60
+ "references": {}
61
+ },
62
+ "required": false,
63
+ "optional": false,
64
+ "docs": {
65
+ "tags": [],
66
+ "text": "Size in pixels for width and height"
67
+ },
68
+ "getter": false,
69
+ "setter": false,
70
+ "reflect": false,
71
+ "attribute": "size",
72
+ "defaultValue": "16"
73
+ }
74
+ };
75
+ }
76
+ }