@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.
- package/dist/cjs/ai-card.cjs.entry.js +2 -2
- package/dist/cjs/ai-chat-container.cjs.entry.js +84 -57
- package/dist/cjs/ai-chat-header.cjs.entry.js +27 -17
- package/dist/cjs/ai-chat-message.cjs.entry.js +1456 -21
- package/dist/cjs/ai-conversation-list.cjs.entry.js +80 -0
- package/dist/cjs/ai-conversation-summary.cjs.entry.js +33 -0
- package/dist/cjs/ai-icon.cjs.entry.js +2 -2
- package/dist/cjs/ai-link.cjs.entry.js +4 -4
- package/dist/cjs/ai-loading.cjs.entry.js +35 -22
- package/dist/cjs/ai-message-input.cjs.entry.js +48 -15
- package/dist/cjs/ai-rating.cjs.entry.js +2 -2
- package/dist/cjs/ai-route-decision.cjs.entry.js +48 -0
- package/dist/cjs/ai-suggestion.cjs.entry.js +4 -4
- package/dist/cjs/ai-voice-input.cjs.entry.js +62 -14
- package/dist/cjs/{icon-registry-dmfLA-Dj.js → icon-registry-BKb9-2Nt.js} +24 -0
- package/dist/cjs/{index-DLJcLHFH.js → index-BkNg07SW.js} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/ui-ai-kit.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +3 -0
- package/dist/collection/components/ai-card/ai-card.css +5 -8
- package/dist/collection/components/ai-chat-container/ai-chat-container.css +17 -14
- package/dist/collection/components/ai-chat-container/ai-chat-container.js +125 -53
- package/dist/collection/components/ai-chat-header/ai-chat-header.css +50 -17
- package/dist/collection/components/ai-chat-header/ai-chat-header.js +50 -15
- package/dist/collection/components/ai-chat-message/ai-chat-message.css +47 -38
- package/dist/collection/components/ai-chat-message/ai-chat-message.js +68 -18
- package/dist/collection/components/ai-conversation-list/ai-conversation-list.css +196 -0
- package/dist/collection/components/ai-conversation-list/ai-conversation-list.js +176 -0
- package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.css +103 -0
- package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.js +118 -0
- package/dist/collection/components/ai-icon/ai-icon.js +1 -1
- package/dist/collection/components/ai-link/ai-link.css +3 -7
- package/dist/collection/components/ai-link/ai-link.js +1 -1
- package/dist/collection/components/ai-loading/ai-loading.css +149 -20
- package/dist/collection/components/ai-loading/ai-loading.js +100 -23
- package/dist/collection/components/ai-message-input/ai-message-input.css +41 -37
- package/dist/collection/components/ai-message-input/ai-message-input.js +100 -19
- package/dist/collection/components/ai-rating/ai-rating.css +8 -14
- package/dist/collection/components/ai-route-decision/ai-route-decision.css +132 -0
- package/dist/collection/components/ai-route-decision/ai-route-decision.js +195 -0
- package/dist/collection/components/ai-suggestion/ai-suggestion.css +5 -11
- package/dist/collection/components/ai-suggestion/ai-suggestion.js +2 -2
- package/dist/collection/components/ai-voice-input/ai-voice-input.css +26 -21
- package/dist/collection/components/ai-voice-input/ai-voice-input.js +103 -13
- package/dist/collection/utils/icon-registry.js +24 -0
- package/dist/components/ai-card.js +1 -1
- package/dist/components/ai-chat-container.js +1 -1
- package/dist/components/ai-chat-header.js +1 -1
- package/dist/components/ai-chat-message.js +2 -1
- package/dist/components/ai-conversation-list.d.ts +11 -0
- package/dist/components/ai-conversation-list.js +1 -0
- package/dist/components/ai-conversation-summary.d.ts +11 -0
- package/dist/components/ai-conversation-summary.js +1 -0
- package/dist/components/ai-icon.js +1 -1
- package/dist/components/ai-link.js +1 -1
- package/dist/components/ai-loading.js +1 -1
- package/dist/components/ai-message-input.js +1 -1
- package/dist/components/ai-rating.js +1 -1
- package/dist/components/ai-route-decision.d.ts +11 -0
- package/dist/components/ai-route-decision.js +1 -0
- package/dist/components/ai-suggestion.js +1 -1
- package/dist/components/ai-voice-input.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/p-DCr8F_XV.js +1 -0
- package/dist/components/p-DnO4dikr.js +1 -0
- package/dist/components/{p-CY6emva2.js → p-Dr2tAPV7.js} +1 -1
- package/dist/{ui-ai-kit/p-DYv5ef4M.js → components/p-SJZ6Ujn9.js} +1 -1
- package/dist/esm/ai-card.entry.js +2 -2
- package/dist/esm/ai-chat-container.entry.js +84 -57
- package/dist/esm/ai-chat-header.entry.js +27 -17
- package/dist/esm/ai-chat-message.entry.js +1456 -21
- package/dist/esm/ai-conversation-list.entry.js +78 -0
- package/dist/esm/ai-conversation-summary.entry.js +31 -0
- package/dist/esm/ai-icon.entry.js +2 -2
- package/dist/esm/ai-link.entry.js +4 -4
- package/dist/esm/ai-loading.entry.js +35 -22
- package/dist/esm/ai-message-input.entry.js +48 -15
- package/dist/esm/ai-rating.entry.js +2 -2
- package/dist/esm/ai-route-decision.entry.js +46 -0
- package/dist/esm/ai-suggestion.entry.js +4 -4
- package/dist/esm/ai-voice-input.entry.js +62 -14
- package/dist/esm/{icon-registry-DYv5ef4M.js → icon-registry-SJZ6Ujn9.js} +24 -0
- package/dist/esm/{index-7hrZ8FOQ.js → index-B0yIzgh4.js} +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/ui-ai-kit.js +3 -3
- package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +11 -1
- package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +6 -1
- package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +24 -0
- package/dist/types/components/ai-conversation-summary/ai-conversation-summary.d.ts +12 -0
- package/dist/types/components/ai-loading/ai-loading.d.ts +12 -6
- package/dist/types/components/ai-message-input/ai-message-input.d.ts +17 -3
- package/dist/types/components/ai-route-decision/ai-route-decision.d.ts +21 -0
- package/dist/types/components/ai-voice-input/ai-voice-input.d.ts +7 -0
- package/dist/types/components.d.ts +333 -9
- package/dist/types/index.d.ts +2 -0
- package/dist/types/utils/icon-registry.d.ts +1 -1
- package/dist/ui-ai-kit/p-21c4fc1f.entry.js +1 -0
- package/dist/ui-ai-kit/p-2955439f.entry.js +1 -0
- package/dist/ui-ai-kit/p-5c9e9822.entry.js +1 -0
- package/dist/ui-ai-kit/p-5caf1c38.entry.js +1 -0
- package/dist/ui-ai-kit/p-6d3505e9.entry.js +1 -0
- package/dist/ui-ai-kit/p-74c5c83f.entry.js +1 -0
- package/dist/ui-ai-kit/p-87e9739b.entry.js +1 -0
- package/dist/ui-ai-kit/p-B0yIzgh4.js +2 -0
- package/dist/{components/p-DYv5ef4M.js → ui-ai-kit/p-SJZ6Ujn9.js} +1 -1
- package/dist/ui-ai-kit/p-a099fcfb.entry.js +1 -0
- package/dist/ui-ai-kit/p-a9e4eaef.entry.js +1 -0
- package/dist/ui-ai-kit/p-b28af13a.entry.js +1 -0
- package/dist/ui-ai-kit/p-d1bb1ad0.entry.js +1 -0
- package/dist/ui-ai-kit/p-eb0c7e7a.entry.js +1 -0
- package/dist/ui-ai-kit/{p-455daa17.entry.js → p-eec6f083.entry.js} +1 -1
- package/dist/ui-ai-kit/p-ef07638f.entry.js +2 -0
- package/dist/ui-ai-kit/ui-ai-kit.css +1 -1
- package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -1
- package/package.json +5 -14
- package/dist/collection/components/ai-card/ai-card.stories.js +0 -52
- package/dist/collection/components/ai-chat-container/ai-chat-container.stories.js +0 -160
- package/dist/collection/components/ai-chat-header/ai-chat-header.stories.js +0 -138
- package/dist/collection/components/ai-chat-message/ai-chat-message.stories.js +0 -164
- package/dist/collection/components/ai-link/ai-link.stories.js +0 -79
- package/dist/collection/components/ai-loading/ai-loading.stories.js +0 -145
- package/dist/collection/components/ai-message-input/ai-message-input.stories.js +0 -125
- package/dist/collection/components/ai-rating/ai-rating.stories.js +0 -78
- package/dist/collection/components/ai-suggestion/ai-suggestion.stories.js +0 -62
- package/dist/collection/components/ai-voice-input/ai-voice-input.stories.js +0 -118
- package/dist/components/p-CWjXxYJI.js +0 -1
- package/dist/types/components/ai-card/ai-card.stories.d.ts +0 -7
- package/dist/types/components/ai-chat-container/ai-chat-container.stories.d.ts +0 -7
- package/dist/types/components/ai-chat-header/ai-chat-header.stories.d.ts +0 -8
- package/dist/types/components/ai-chat-message/ai-chat-message.stories.d.ts +0 -10
- package/dist/types/components/ai-link/ai-link.stories.d.ts +0 -8
- package/dist/types/components/ai-loading/ai-loading.stories.d.ts +0 -10
- package/dist/types/components/ai-message-input/ai-message-input.stories.d.ts +0 -13
- package/dist/types/components/ai-rating/ai-rating.stories.d.ts +0 -8
- package/dist/types/components/ai-suggestion/ai-suggestion.stories.d.ts +0 -8
- package/dist/types/components/ai-voice-input/ai-voice-input.stories.d.ts +0 -9
- package/dist/ui-ai-kit/p-11facfad.entry.js +0 -1
- package/dist/ui-ai-kit/p-128a2ed4.entry.js +0 -1
- package/dist/ui-ai-kit/p-227bdb8f.entry.js +0 -1
- package/dist/ui-ai-kit/p-56163e8c.entry.js +0 -1
- package/dist/ui-ai-kit/p-6d21d0fd.entry.js +0 -1
- package/dist/ui-ai-kit/p-6ddcd77b.entry.js +0 -1
- package/dist/ui-ai-kit/p-7hrZ8FOQ.js +0 -2
- package/dist/ui-ai-kit/p-8e90143e.entry.js +0 -1
- package/dist/ui-ai-kit/p-9938c277.entry.js +0 -1
- package/dist/ui-ai-kit/p-dc5b4a7f.entry.js +0 -1
- package/dist/ui-ai-kit/p-fb1702de.entry.js +0 -1
- package/readme.md +0 -111
|
@@ -7,21 +7,38 @@ export class MessageInput {
|
|
|
7
7
|
disabled = false;
|
|
8
8
|
/** Whether to show the voice recording button */
|
|
9
9
|
showVoiceButton = true;
|
|
10
|
+
/** Maximum characters allowed */
|
|
11
|
+
maxLength = 4000;
|
|
12
|
+
/** External prop to show/hide the inline voice recorder */
|
|
13
|
+
isRecording = false;
|
|
10
14
|
inputValue = '';
|
|
15
|
+
showVoiceRecorder = false;
|
|
16
|
+
isMultiline = false;
|
|
11
17
|
textareaRef;
|
|
12
18
|
/** Event emitted when a message is sent */
|
|
13
19
|
sendMessage;
|
|
14
|
-
/** Event emitted when
|
|
15
|
-
|
|
20
|
+
/** Event emitted when voice recording is complete and audio is ready */
|
|
21
|
+
voiceAudioReady;
|
|
22
|
+
onIsRecordingChange(newVal) {
|
|
23
|
+
this.showVoiceRecorder = newVal;
|
|
24
|
+
}
|
|
16
25
|
/** Set the textarea value programmatically (e.g. after speech-to-text transcription) */
|
|
17
26
|
async setInputValue(value) {
|
|
18
27
|
this.inputValue = value;
|
|
19
28
|
if (this.textareaRef) {
|
|
20
|
-
|
|
21
|
-
this.textareaRef.
|
|
29
|
+
// Set value imperatively before measuring to avoid stale scrollHeight from async render queue
|
|
30
|
+
this.textareaRef.value = value;
|
|
31
|
+
this.updateHeight();
|
|
22
32
|
this.textareaRef.focus();
|
|
23
33
|
}
|
|
24
34
|
}
|
|
35
|
+
updateHeight = () => {
|
|
36
|
+
if (!this.textareaRef)
|
|
37
|
+
return;
|
|
38
|
+
this.textareaRef.style.height = 'auto';
|
|
39
|
+
this.textareaRef.style.height = `${this.textareaRef.scrollHeight}px`;
|
|
40
|
+
this.isMultiline = this.textareaRef.scrollHeight > 28;
|
|
41
|
+
};
|
|
25
42
|
handleSendMessage = () => {
|
|
26
43
|
if (!this.inputValue.trim() || this.disabled)
|
|
27
44
|
return;
|
|
@@ -29,25 +46,36 @@ export class MessageInput {
|
|
|
29
46
|
this.inputValue = '';
|
|
30
47
|
if (this.textareaRef) {
|
|
31
48
|
this.textareaRef.style.height = 'auto';
|
|
49
|
+
this.isMultiline = false;
|
|
32
50
|
}
|
|
33
51
|
};
|
|
34
|
-
|
|
52
|
+
handleKeyDown = (e) => {
|
|
35
53
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
36
54
|
e.preventDefault();
|
|
37
55
|
this.handleSendMessage();
|
|
38
56
|
}
|
|
39
57
|
};
|
|
58
|
+
handleVoiceClick = () => {
|
|
59
|
+
this.showVoiceRecorder = true;
|
|
60
|
+
};
|
|
61
|
+
handleAudioRecorded = (e) => {
|
|
62
|
+
this.showVoiceRecorder = false;
|
|
63
|
+
this.voiceAudioReady.emit(e.detail);
|
|
64
|
+
};
|
|
65
|
+
handleRecordingCancel = () => {
|
|
66
|
+
this.showVoiceRecorder = false;
|
|
67
|
+
};
|
|
40
68
|
handleInputChange = (e) => {
|
|
41
|
-
|
|
42
|
-
this.
|
|
43
|
-
if (this.textareaRef) {
|
|
44
|
-
this.textareaRef.style.height = 'auto';
|
|
45
|
-
this.textareaRef.style.height = `${this.textareaRef.scrollHeight}px`;
|
|
46
|
-
}
|
|
69
|
+
this.inputValue = e.target.value;
|
|
70
|
+
this.updateHeight();
|
|
47
71
|
};
|
|
48
72
|
render() {
|
|
73
|
+
if (this.showVoiceRecorder) {
|
|
74
|
+
return (h(Host, null, h("ai-voice-input", { autoStart: true, onAudioRecorded: this.handleAudioRecorded, onRecordingCancel: this.handleRecordingCancel })));
|
|
75
|
+
}
|
|
49
76
|
const canSend = !!this.inputValue.trim() && !this.disabled;
|
|
50
|
-
|
|
77
|
+
const remaining = this.maxLength - this.inputValue.length;
|
|
78
|
+
return (h(Host, null, h("div", { part: "wrapper", class: "wrapper" }, h("div", { part: "glow", class: "glow", "aria-hidden": "true" }), h("div", { part: "container", class: `input-container${this.isMultiline ? ' multiline' : ''}` }, h("div", { class: "input-row" }, h("textarea", { part: "textarea", ref: el => (this.textareaRef = el), value: this.inputValue, onInput: this.handleInputChange, onKeyDown: this.handleKeyDown, disabled: this.disabled, placeholder: this.placeholder, rows: 1, class: "textarea", maxLength: this.maxLength }), remaining < 200 && (h("span", { class: `char-counter${remaining < 50 ? ' warning' : ''}`, "aria-live": "polite" }, remaining)), h("div", { class: "actions" }, this.showVoiceButton && !this.inputValue && (h("button", { part: "voice-button", class: "voice-button", onClick: this.handleVoiceClick, disabled: this.disabled, type: "button", "aria-label": "Record voice" }, h("ai-icon", { name: "mic", size: 16 }))), h("button", { part: "send-button", class: `send-button${canSend ? ' active' : ''}`, onClick: this.handleSendMessage, disabled: !canSend, type: "button", "aria-label": "Send message" }, h("ai-icon", { name: "send", size: 16 }))))))));
|
|
51
79
|
}
|
|
52
80
|
static get is() { return "ai-message-input"; }
|
|
53
81
|
static get encapsulation() { return "shadow"; }
|
|
@@ -122,12 +150,54 @@ export class MessageInput {
|
|
|
122
150
|
"reflect": false,
|
|
123
151
|
"attribute": "show-voice-button",
|
|
124
152
|
"defaultValue": "true"
|
|
153
|
+
},
|
|
154
|
+
"maxLength": {
|
|
155
|
+
"type": "number",
|
|
156
|
+
"mutable": false,
|
|
157
|
+
"complexType": {
|
|
158
|
+
"original": "number",
|
|
159
|
+
"resolved": "number",
|
|
160
|
+
"references": {}
|
|
161
|
+
},
|
|
162
|
+
"required": false,
|
|
163
|
+
"optional": false,
|
|
164
|
+
"docs": {
|
|
165
|
+
"tags": [],
|
|
166
|
+
"text": "Maximum characters allowed"
|
|
167
|
+
},
|
|
168
|
+
"getter": false,
|
|
169
|
+
"setter": false,
|
|
170
|
+
"reflect": false,
|
|
171
|
+
"attribute": "max-length",
|
|
172
|
+
"defaultValue": "4000"
|
|
173
|
+
},
|
|
174
|
+
"isRecording": {
|
|
175
|
+
"type": "boolean",
|
|
176
|
+
"mutable": false,
|
|
177
|
+
"complexType": {
|
|
178
|
+
"original": "boolean",
|
|
179
|
+
"resolved": "boolean",
|
|
180
|
+
"references": {}
|
|
181
|
+
},
|
|
182
|
+
"required": false,
|
|
183
|
+
"optional": false,
|
|
184
|
+
"docs": {
|
|
185
|
+
"tags": [],
|
|
186
|
+
"text": "External prop to show/hide the inline voice recorder"
|
|
187
|
+
},
|
|
188
|
+
"getter": false,
|
|
189
|
+
"setter": false,
|
|
190
|
+
"reflect": false,
|
|
191
|
+
"attribute": "is-recording",
|
|
192
|
+
"defaultValue": "false"
|
|
125
193
|
}
|
|
126
194
|
};
|
|
127
195
|
}
|
|
128
196
|
static get states() {
|
|
129
197
|
return {
|
|
130
|
-
"inputValue": {}
|
|
198
|
+
"inputValue": {},
|
|
199
|
+
"showVoiceRecorder": {},
|
|
200
|
+
"isMultiline": {}
|
|
131
201
|
};
|
|
132
202
|
}
|
|
133
203
|
static get events() {
|
|
@@ -147,19 +217,24 @@ export class MessageInput {
|
|
|
147
217
|
"references": {}
|
|
148
218
|
}
|
|
149
219
|
}, {
|
|
150
|
-
"method": "
|
|
151
|
-
"name": "
|
|
220
|
+
"method": "voiceAudioReady",
|
|
221
|
+
"name": "voiceAudioReady",
|
|
152
222
|
"bubbles": true,
|
|
153
223
|
"cancelable": true,
|
|
154
224
|
"composed": true,
|
|
155
225
|
"docs": {
|
|
156
226
|
"tags": [],
|
|
157
|
-
"text": "Event emitted when
|
|
227
|
+
"text": "Event emitted when voice recording is complete and audio is ready"
|
|
158
228
|
},
|
|
159
229
|
"complexType": {
|
|
160
|
-
"original": "
|
|
161
|
-
"resolved": "
|
|
162
|
-
"references": {
|
|
230
|
+
"original": "{ blob: Blob; duration: number }",
|
|
231
|
+
"resolved": "{ blob: Blob; duration: number; }",
|
|
232
|
+
"references": {
|
|
233
|
+
"Blob": {
|
|
234
|
+
"location": "global",
|
|
235
|
+
"id": "global::Blob"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
163
238
|
}
|
|
164
239
|
}];
|
|
165
240
|
}
|
|
@@ -189,4 +264,10 @@ export class MessageInput {
|
|
|
189
264
|
};
|
|
190
265
|
}
|
|
191
266
|
static get elementRef() { return "el"; }
|
|
267
|
+
static get watchers() {
|
|
268
|
+
return [{
|
|
269
|
+
"propName": "isRecording",
|
|
270
|
+
"methodName": "onIsRecordingChange"
|
|
271
|
+
}];
|
|
272
|
+
}
|
|
192
273
|
}
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
/* ─── Custom Properties ──────────────────────────────────────────────────── */
|
|
2
2
|
:host {
|
|
3
|
-
--ai-rating-question-color: var(--ai-text-primary, #333333);
|
|
4
|
-
--ai-rating-subtitle-color: var(--ai-text-secondary, #737373);
|
|
5
3
|
--ai-rating-question-size: 16px;
|
|
6
4
|
--ai-rating-subtitle-size: 14px;
|
|
7
5
|
--ai-rating-gap: 8px;
|
|
8
6
|
--ai-rating-emoji-size: 24px;
|
|
9
7
|
--ai-rating-btn-padding: 6px;
|
|
10
|
-
--ai-rating-btn-border: 1px solid var(--ai-border-light
|
|
8
|
+
--ai-rating-btn-border: 1px solid var(--ai-border-light);
|
|
11
9
|
--ai-rating-btn-radius: 9999px;
|
|
12
10
|
|
|
13
11
|
/* hover */
|
|
14
|
-
--ai-rating-btn-bg-hover: var(--ai-bg-surface
|
|
12
|
+
--ai-rating-btn-bg-hover: var(--ai-bg-surface);
|
|
15
13
|
--ai-rating-btn-border-hover: 1px solid var(--ai-border-default);
|
|
16
14
|
|
|
17
15
|
/* selected — matches Figma warning palette */
|
|
18
|
-
--ai-rating-btn-bg-active: var(--ai-warning-bg
|
|
19
|
-
--ai-rating-btn-border-active: 1px solid var(--ai-warning-border
|
|
20
|
-
--ai-rating-btn-shadow-active:
|
|
21
|
-
0px 2px 4px -1px rgba(18, 18, 23, 0.06);
|
|
16
|
+
--ai-rating-btn-bg-active: var(--ai-warning-bg);
|
|
17
|
+
--ai-rating-btn-border-active: 1px solid var(--ai-warning-border);
|
|
18
|
+
--ai-rating-btn-shadow-active: var(--ai-shadow-active);
|
|
22
19
|
|
|
23
20
|
/* selected label */
|
|
24
|
-
--ai-rating-label-color: var(--ai-text-primary, #333333);
|
|
25
21
|
--ai-rating-label-size: 16px;
|
|
26
22
|
|
|
27
23
|
display: block;
|
|
28
|
-
direction: rtl;
|
|
29
|
-
font-family: var(--ai-font-family, "PingARLT", sans-serif);
|
|
30
24
|
}
|
|
31
25
|
|
|
32
26
|
/* ─── Wrapper ────────────────────────────────────────────────────────────── */
|
|
@@ -53,7 +47,7 @@
|
|
|
53
47
|
font-size: var(--ai-rating-question-size);
|
|
54
48
|
font-weight: 500;
|
|
55
49
|
line-height: 24px;
|
|
56
|
-
color: var(--ai-
|
|
50
|
+
color: var(--ai-text-primary);
|
|
57
51
|
}
|
|
58
52
|
|
|
59
53
|
.rating__subtitle {
|
|
@@ -61,7 +55,7 @@
|
|
|
61
55
|
font-size: var(--ai-rating-subtitle-size);
|
|
62
56
|
font-weight: 400;
|
|
63
57
|
line-height: 20px;
|
|
64
|
-
color: var(--ai-
|
|
58
|
+
color: var(--ai-text-secondary);
|
|
65
59
|
}
|
|
66
60
|
|
|
67
61
|
/* ─── Emoji row ──────────────────────────────────────────────────────────── */
|
|
@@ -133,7 +127,7 @@
|
|
|
133
127
|
font-size: var(--ai-rating-label-size);
|
|
134
128
|
font-weight: 500;
|
|
135
129
|
line-height: 24px;
|
|
136
|
-
color: var(--ai-
|
|
130
|
+
color: var(--ai-text-primary);
|
|
137
131
|
text-align: center;
|
|
138
132
|
width: 100%;
|
|
139
133
|
animation: fadeIn 0.15s ease;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/* ── Icon wrapper ───────────────────────────────────────── */
|
|
6
|
+
.icon-wrap {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
line-height: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* ── Pill shell ─────────────────────────────────────────── */
|
|
14
|
+
.route-pill {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
background: var(--ai-bg-card);
|
|
18
|
+
border: 1px solid var(--ai-border-default);
|
|
19
|
+
border-radius: 9999px;
|
|
20
|
+
box-shadow: var(--ai-shadow-sm);
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
transition: border-radius 0.2s ease;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.route-pill.expanded {
|
|
26
|
+
border-radius: 12px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* ── Pill header row ────────────────────────────────────── */
|
|
30
|
+
.route-pill-main {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: 6px;
|
|
34
|
+
padding: 6px 12px;
|
|
35
|
+
background: none;
|
|
36
|
+
border: none;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
color: var(--ai-text-primary);
|
|
39
|
+
font-size: 13px;
|
|
40
|
+
font-weight: 500;
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
width: 100%;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.route-icon {
|
|
46
|
+
color: var(--ai-accent-dark);
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
flex-shrink: 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.agent-label {
|
|
52
|
+
display: inline-flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 4px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.agent-emoji {
|
|
58
|
+
font-size: 14px;
|
|
59
|
+
line-height: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.confidence-badge {
|
|
63
|
+
font-size: 11px;
|
|
64
|
+
font-weight: 600;
|
|
65
|
+
color: var(--ai-accent-dark);
|
|
66
|
+
background: var(--ai-accent-bg);
|
|
67
|
+
padding: 1px 6px;
|
|
68
|
+
border-radius: 9999px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ── Expand arrow ───────────────────────────────────────── */
|
|
72
|
+
.expand-icon {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
margin-inline-start: auto;
|
|
75
|
+
color: var(--ai-text-secondary);
|
|
76
|
+
transition: transform 0.2s ease;
|
|
77
|
+
transform: rotate(0deg);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.expand-icon.expanded {
|
|
81
|
+
transform: rotate(90deg);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ── Expanded details ───────────────────────────────────── */
|
|
85
|
+
.route-details {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: 8px;
|
|
89
|
+
padding: 8px 12px 12px;
|
|
90
|
+
border-top: 1px solid var(--ai-border-default);
|
|
91
|
+
animation: fade-in 0.2s ease;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@keyframes fade-in {
|
|
95
|
+
from { opacity: 0; transform: translateY(-4px); }
|
|
96
|
+
to { opacity: 1; transform: translateY(0); }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.reason-text {
|
|
100
|
+
margin: 0;
|
|
101
|
+
font-size: 12px;
|
|
102
|
+
color: var(--ai-text-secondary);
|
|
103
|
+
line-height: 1.5;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* ── Confidence bar ─────────────────────────────────────── */
|
|
107
|
+
.confidence-bar-wrap {
|
|
108
|
+
height: 4px;
|
|
109
|
+
border-radius: 9999px;
|
|
110
|
+
background: var(--ai-border-default);
|
|
111
|
+
overflow: hidden;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.confidence-bar {
|
|
115
|
+
height: 100%;
|
|
116
|
+
border-radius: 9999px;
|
|
117
|
+
background: var(--ai-accent-dark);
|
|
118
|
+
transition: width 0.4s ease;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* ── Meta row (language, etc.) ──────────────────────────── */
|
|
122
|
+
.meta-row {
|
|
123
|
+
display: inline-flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
gap: 4px;
|
|
126
|
+
color: var(--ai-text-secondary);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.lang-chip {
|
|
130
|
+
font-size: 11px;
|
|
131
|
+
color: var(--ai-text-secondary);
|
|
132
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { Host, h } from "@stencil/core";
|
|
2
|
+
import { iconRegistry } from "../../utils/icon-registry";
|
|
3
|
+
export class AiRouteDecision {
|
|
4
|
+
/** Selected agent name */
|
|
5
|
+
selectedAgent = '';
|
|
6
|
+
/** Agent icon — emoji or short text displayed before the agent name */
|
|
7
|
+
agentIcon = '';
|
|
8
|
+
/** Reason for routing decision (shown when expanded) */
|
|
9
|
+
reason = '';
|
|
10
|
+
/** Routing confidence percentage 0–100 */
|
|
11
|
+
confidence = 0;
|
|
12
|
+
/** Detected language label (shown when expanded) */
|
|
13
|
+
detectedLanguage = '';
|
|
14
|
+
/** Initial expanded state */
|
|
15
|
+
expanded = false;
|
|
16
|
+
_expanded = false;
|
|
17
|
+
routeExpand;
|
|
18
|
+
componentWillLoad() {
|
|
19
|
+
this._expanded = this.expanded;
|
|
20
|
+
}
|
|
21
|
+
renderIcon(name, width, height) {
|
|
22
|
+
const icon = iconRegistry[name];
|
|
23
|
+
if (!icon)
|
|
24
|
+
return null;
|
|
25
|
+
const svg = `<svg width="${width}" height="${height}" 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
|
+
handleToggle() {
|
|
29
|
+
this._expanded = !this._expanded;
|
|
30
|
+
this.expanded = this._expanded;
|
|
31
|
+
this.routeExpand.emit(this._expanded);
|
|
32
|
+
}
|
|
33
|
+
render() {
|
|
34
|
+
return (h(Host, { key: 'a22239e1db9982a860bbd6242e5848c3cdfe57ce' }, h("div", { key: '21c447b12e737e77d67b33b10f82f727f10ef4e5', class: `route-pill ${this._expanded ? 'expanded' : ''}` }, h("button", { key: 'fe5c0f167cad2b2fa2549a03a87a32c848efc4c6', class: "route-pill-main", onClick: () => this.handleToggle() }, h("span", { key: 'a1a07c6f8f108e637a43424fa9cdb918e882db3a', class: "route-icon" }, this.renderIcon('route', 14, 14)), h("span", { key: '005662e7b00f47edf185a7806ca268c2b0e9e62a', class: "agent-label" }, this.agentIcon && h("span", { key: '9fbadba81754d515e156bfcfa4821f7e2cefc88b', class: "agent-emoji", "aria-hidden": "true" }, this.agentIcon), this.selectedAgent), this.confidence > 0 && (h("span", { key: 'c2acf259644e0c74264b535b5d34ea5a3b519797', class: "confidence-badge" }, this.confidence, "%")), h("span", { key: 'ac5d1ee27417d85c50a88adb297b493c83aa85bc', class: `expand-icon ${this._expanded ? 'expanded' : ''}` }, this.renderIcon('arrow-right', 12, 12))), this._expanded && (h("div", { key: 'dc1f297cdeede44b4e6b8a4888204eef2200bc72', class: "route-details" }, this.reason && h("p", { key: '7e819d2a6dceeb81d88282e7fcc927b9fe4219c2', class: "reason-text" }, this.reason), this.confidence > 0 && (h("div", { key: 'ec6cbaf221e0679241fc1f13066d542d5b64b9ef', class: "confidence-bar-wrap" }, h("div", { key: '84b3c99aa734308db8d9abd7674eb9f5ee22b17c', class: "confidence-bar", style: { width: `${this.confidence}%` } }))), this.detectedLanguage && (h("div", { key: 'e83127633ec30ea79446a3622f31428ed50ede4d', class: "meta-row" }, this.renderIcon('list', 12, 12), h("span", { key: '1547936eaa529d999b9d0b9dc3421bff2e20937a', class: "lang-chip" }, this.detectedLanguage))))))));
|
|
35
|
+
}
|
|
36
|
+
static get is() { return "ai-route-decision"; }
|
|
37
|
+
static get encapsulation() { return "shadow"; }
|
|
38
|
+
static get originalStyleUrls() {
|
|
39
|
+
return {
|
|
40
|
+
"$": ["ai-route-decision.css"]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
static get styleUrls() {
|
|
44
|
+
return {
|
|
45
|
+
"$": ["ai-route-decision.css"]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static get properties() {
|
|
49
|
+
return {
|
|
50
|
+
"selectedAgent": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"mutable": false,
|
|
53
|
+
"complexType": {
|
|
54
|
+
"original": "string",
|
|
55
|
+
"resolved": "string",
|
|
56
|
+
"references": {}
|
|
57
|
+
},
|
|
58
|
+
"required": false,
|
|
59
|
+
"optional": false,
|
|
60
|
+
"docs": {
|
|
61
|
+
"tags": [],
|
|
62
|
+
"text": "Selected agent name"
|
|
63
|
+
},
|
|
64
|
+
"getter": false,
|
|
65
|
+
"setter": false,
|
|
66
|
+
"reflect": false,
|
|
67
|
+
"attribute": "selected-agent",
|
|
68
|
+
"defaultValue": "''"
|
|
69
|
+
},
|
|
70
|
+
"agentIcon": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"mutable": false,
|
|
73
|
+
"complexType": {
|
|
74
|
+
"original": "string",
|
|
75
|
+
"resolved": "string",
|
|
76
|
+
"references": {}
|
|
77
|
+
},
|
|
78
|
+
"required": false,
|
|
79
|
+
"optional": false,
|
|
80
|
+
"docs": {
|
|
81
|
+
"tags": [],
|
|
82
|
+
"text": "Agent icon \u2014 emoji or short text displayed before the agent name"
|
|
83
|
+
},
|
|
84
|
+
"getter": false,
|
|
85
|
+
"setter": false,
|
|
86
|
+
"reflect": false,
|
|
87
|
+
"attribute": "agent-icon",
|
|
88
|
+
"defaultValue": "''"
|
|
89
|
+
},
|
|
90
|
+
"reason": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"mutable": false,
|
|
93
|
+
"complexType": {
|
|
94
|
+
"original": "string",
|
|
95
|
+
"resolved": "string",
|
|
96
|
+
"references": {}
|
|
97
|
+
},
|
|
98
|
+
"required": false,
|
|
99
|
+
"optional": false,
|
|
100
|
+
"docs": {
|
|
101
|
+
"tags": [],
|
|
102
|
+
"text": "Reason for routing decision (shown when expanded)"
|
|
103
|
+
},
|
|
104
|
+
"getter": false,
|
|
105
|
+
"setter": false,
|
|
106
|
+
"reflect": false,
|
|
107
|
+
"attribute": "reason",
|
|
108
|
+
"defaultValue": "''"
|
|
109
|
+
},
|
|
110
|
+
"confidence": {
|
|
111
|
+
"type": "number",
|
|
112
|
+
"mutable": false,
|
|
113
|
+
"complexType": {
|
|
114
|
+
"original": "number",
|
|
115
|
+
"resolved": "number",
|
|
116
|
+
"references": {}
|
|
117
|
+
},
|
|
118
|
+
"required": false,
|
|
119
|
+
"optional": false,
|
|
120
|
+
"docs": {
|
|
121
|
+
"tags": [],
|
|
122
|
+
"text": "Routing confidence percentage 0\u2013100"
|
|
123
|
+
},
|
|
124
|
+
"getter": false,
|
|
125
|
+
"setter": false,
|
|
126
|
+
"reflect": false,
|
|
127
|
+
"attribute": "confidence",
|
|
128
|
+
"defaultValue": "0"
|
|
129
|
+
},
|
|
130
|
+
"detectedLanguage": {
|
|
131
|
+
"type": "string",
|
|
132
|
+
"mutable": false,
|
|
133
|
+
"complexType": {
|
|
134
|
+
"original": "string",
|
|
135
|
+
"resolved": "string",
|
|
136
|
+
"references": {}
|
|
137
|
+
},
|
|
138
|
+
"required": false,
|
|
139
|
+
"optional": false,
|
|
140
|
+
"docs": {
|
|
141
|
+
"tags": [],
|
|
142
|
+
"text": "Detected language label (shown when expanded)"
|
|
143
|
+
},
|
|
144
|
+
"getter": false,
|
|
145
|
+
"setter": false,
|
|
146
|
+
"reflect": false,
|
|
147
|
+
"attribute": "detected-language",
|
|
148
|
+
"defaultValue": "''"
|
|
149
|
+
},
|
|
150
|
+
"expanded": {
|
|
151
|
+
"type": "boolean",
|
|
152
|
+
"mutable": true,
|
|
153
|
+
"complexType": {
|
|
154
|
+
"original": "boolean",
|
|
155
|
+
"resolved": "boolean",
|
|
156
|
+
"references": {}
|
|
157
|
+
},
|
|
158
|
+
"required": false,
|
|
159
|
+
"optional": false,
|
|
160
|
+
"docs": {
|
|
161
|
+
"tags": [],
|
|
162
|
+
"text": "Initial expanded state"
|
|
163
|
+
},
|
|
164
|
+
"getter": false,
|
|
165
|
+
"setter": false,
|
|
166
|
+
"reflect": false,
|
|
167
|
+
"attribute": "expanded",
|
|
168
|
+
"defaultValue": "false"
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
static get states() {
|
|
173
|
+
return {
|
|
174
|
+
"_expanded": {}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
static get events() {
|
|
178
|
+
return [{
|
|
179
|
+
"method": "routeExpand",
|
|
180
|
+
"name": "routeExpand",
|
|
181
|
+
"bubbles": true,
|
|
182
|
+
"cancelable": true,
|
|
183
|
+
"composed": true,
|
|
184
|
+
"docs": {
|
|
185
|
+
"tags": [],
|
|
186
|
+
"text": ""
|
|
187
|
+
},
|
|
188
|
+
"complexType": {
|
|
189
|
+
"original": "boolean",
|
|
190
|
+
"resolved": "boolean",
|
|
191
|
+
"references": {}
|
|
192
|
+
}
|
|
193
|
+
}];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
/* ─── Custom Properties ──────────────────────────────────────────────────── */
|
|
2
2
|
:host {
|
|
3
|
-
--ai-suggestion-bg: var(--ai-bg-card);
|
|
4
|
-
--ai-suggestion-bg-hover: var(--ai-accent-bg);
|
|
5
|
-
--ai-suggestion-bg-active: var(--ai-accent-bg);
|
|
6
3
|
--ai-suggestion-border: 1px solid var(--ai-accent);
|
|
7
4
|
--ai-suggestion-border-hover: 1px solid var(--ai-accent);
|
|
8
5
|
--ai-suggestion-radius: 9999px;
|
|
9
6
|
--ai-suggestion-padding: 8px 12px;
|
|
10
7
|
--ai-suggestion-gap: 4px;
|
|
11
|
-
--ai-suggestion-color: var(--ai-accent-dark);
|
|
12
8
|
--ai-suggestion-font-size: 14px;
|
|
13
9
|
--ai-suggestion-line-height: 20px;
|
|
14
10
|
|
|
15
11
|
display: inline-block;
|
|
16
|
-
direction: rtl;
|
|
17
|
-
font-family: var(--ai-font-family, "PingARLT", sans-serif);
|
|
18
12
|
}
|
|
19
13
|
|
|
20
14
|
/* ─── Chip button ────────────────────────────────────────────────────────── */
|
|
@@ -23,11 +17,11 @@
|
|
|
23
17
|
align-items: center;
|
|
24
18
|
justify-content: center;
|
|
25
19
|
gap: var(--ai-suggestion-gap);
|
|
26
|
-
background: var(--ai-
|
|
20
|
+
background: var(--ai-bg-card);
|
|
27
21
|
border: var(--ai-suggestion-border);
|
|
28
22
|
border-radius: var(--ai-suggestion-radius);
|
|
29
23
|
padding: var(--ai-suggestion-padding);
|
|
30
|
-
color: var(--ai-
|
|
24
|
+
color: var(--ai-accent-dark);
|
|
31
25
|
font-size: var(--ai-suggestion-font-size);
|
|
32
26
|
font-weight: 400;
|
|
33
27
|
line-height: var(--ai-suggestion-line-height);
|
|
@@ -36,16 +30,16 @@
|
|
|
36
30
|
cursor: pointer;
|
|
37
31
|
transition: background 0.15s ease, border-color 0.15s ease;
|
|
38
32
|
outline: none;
|
|
39
|
-
text-align:
|
|
33
|
+
text-align: start;
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
.chip:hover:not(:disabled) {
|
|
43
|
-
background: var(--ai-
|
|
37
|
+
background: var(--ai-accent-bg);
|
|
44
38
|
border: var(--ai-suggestion-border-hover);
|
|
45
39
|
}
|
|
46
40
|
|
|
47
41
|
.chip:active:not(:disabled) {
|
|
48
|
-
background: var(--ai-
|
|
42
|
+
background: var(--ai-accent-bg);
|
|
49
43
|
}
|
|
50
44
|
|
|
51
45
|
.chip:focus-visible {
|
|
@@ -11,10 +11,10 @@ export class AiSuggestion {
|
|
|
11
11
|
this.suggestionClick.emit(this.label);
|
|
12
12
|
}
|
|
13
13
|
render() {
|
|
14
|
-
return (h(Host, { key: '
|
|
14
|
+
return (h(Host, { key: 'd8a9ff7279fce63faebd187cb69f0173239518ca' }, h("button", { key: '42bc023c9c48bafc11b388bb80e130255ea830b8', class: {
|
|
15
15
|
chip: true,
|
|
16
16
|
'chip--disabled': this.disabled,
|
|
17
|
-
}, disabled: this.disabled, onClick: () => this.handleClick() }, h("span", { key: '
|
|
17
|
+
}, disabled: this.disabled, onClick: () => this.handleClick() }, h("span", { key: '06f0324b97d9f7fb77fb2d4b9dbf0be9b5c4c3f1', class: "chip__label" }, this.label, h("slot", { key: 'ccd0d639f0b2c001088561b029b08691395e9198' })))));
|
|
18
18
|
}
|
|
19
19
|
static get is() { return "ai-suggestion"; }
|
|
20
20
|
static get encapsulation() { return "shadow"; }
|