@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.
- package/LICENSE +21 -0
- package/dist/cjs/ai-card.cjs.entry.js +25 -0
- package/dist/cjs/ai-chat-container.cjs.entry.js +138 -0
- package/dist/cjs/ai-chat-header.cjs.entry.js +79 -0
- package/dist/cjs/ai-chat-message.cjs.entry.js +164 -0
- package/dist/cjs/ai-icon.cjs.entry.js +25 -0
- package/dist/cjs/ai-link.cjs.entry.js +34 -0
- package/dist/cjs/ai-loading.cjs.entry.js +77 -0
- package/dist/cjs/ai-message-input.cjs.entry.js +65 -0
- package/dist/cjs/ai-rating.cjs.entry.js +57 -0
- package/dist/cjs/ai-suggestion.cjs.entry.js +31 -0
- package/dist/cjs/ai-voice-input.cjs.entry.js +233 -0
- package/dist/cjs/icon-registry-dmfLA-Dj.js +82 -0
- package/dist/cjs/index-DLJcLHFH.js +1622 -0
- package/dist/cjs/index.cjs.js +7 -0
- package/dist/cjs/loader.cjs.js +12 -0
- package/dist/cjs/ui-ai-kit.cjs.js +24 -0
- package/dist/collection/collection-manifest.json +23 -0
- package/dist/collection/components/ai-card/ai-card.css +40 -0
- package/dist/collection/components/ai-card/ai-card.js +70 -0
- package/dist/collection/components/ai-card/ai-card.stories.js +52 -0
- package/dist/collection/components/ai-chat-container/ai-chat-container.css +137 -0
- package/dist/collection/components/ai-chat-container/ai-chat-container.js +270 -0
- package/dist/collection/components/ai-chat-container/ai-chat-container.stories.js +160 -0
- package/dist/collection/components/ai-chat-header/ai-chat-header.css +186 -0
- package/dist/collection/components/ai-chat-header/ai-chat-header.js +311 -0
- package/dist/collection/components/ai-chat-header/ai-chat-header.stories.js +138 -0
- package/dist/collection/components/ai-chat-message/ai-chat-message.css +304 -0
- package/dist/collection/components/ai-chat-message/ai-chat-message.js +379 -0
- package/dist/collection/components/ai-chat-message/ai-chat-message.stories.js +164 -0
- package/dist/collection/components/ai-icon/ai-icon.css +9 -0
- package/dist/collection/components/ai-icon/ai-icon.js +76 -0
- package/dist/collection/components/ai-link/ai-link.css +62 -0
- package/dist/collection/components/ai-link/ai-link.js +119 -0
- package/dist/collection/components/ai-link/ai-link.stories.js +79 -0
- package/dist/collection/components/ai-loading/ai-loading.css +202 -0
- package/dist/collection/components/ai-loading/ai-loading.js +244 -0
- package/dist/collection/components/ai-loading/ai-loading.stories.js +145 -0
- package/dist/collection/components/ai-message-input/ai-message-input.css +175 -0
- package/dist/collection/components/ai-message-input/ai-message-input.js +192 -0
- package/dist/collection/components/ai-message-input/ai-message-input.stories.js +125 -0
- package/dist/collection/components/ai-rating/ai-rating.css +145 -0
- package/dist/collection/components/ai-rating/ai-rating.js +176 -0
- package/dist/collection/components/ai-rating/ai-rating.stories.js +78 -0
- package/dist/collection/components/ai-suggestion/ai-suggestion.css +69 -0
- package/dist/collection/components/ai-suggestion/ai-suggestion.js +93 -0
- package/dist/collection/components/ai-suggestion/ai-suggestion.stories.js +62 -0
- package/dist/collection/components/ai-voice-input/ai-voice-input.css +136 -0
- package/dist/collection/components/ai-voice-input/ai-voice-input.js +341 -0
- package/dist/collection/components/ai-voice-input/ai-voice-input.stories.js +118 -0
- package/dist/collection/index.js +10 -0
- package/dist/collection/utils/icon-registry.js +78 -0
- package/dist/collection/utils/utils.js +3 -0
- package/dist/components/ai-card.d.ts +11 -0
- package/dist/components/ai-card.js +1 -0
- package/dist/components/ai-chat-container.d.ts +11 -0
- package/dist/components/ai-chat-container.js +1 -0
- package/dist/components/ai-chat-header.d.ts +11 -0
- package/dist/components/ai-chat-header.js +1 -0
- package/dist/components/ai-chat-message.d.ts +11 -0
- package/dist/components/ai-chat-message.js +1 -0
- package/dist/components/ai-icon.d.ts +11 -0
- package/dist/components/ai-icon.js +1 -0
- package/dist/components/ai-link.d.ts +11 -0
- package/dist/components/ai-link.js +1 -0
- package/dist/components/ai-loading.d.ts +11 -0
- package/dist/components/ai-loading.js +1 -0
- package/dist/components/ai-message-input.d.ts +11 -0
- package/dist/components/ai-message-input.js +1 -0
- package/dist/components/ai-rating.d.ts +11 -0
- package/dist/components/ai-rating.js +1 -0
- package/dist/components/ai-suggestion.d.ts +11 -0
- package/dist/components/ai-suggestion.js +1 -0
- package/dist/components/ai-voice-input.d.ts +11 -0
- package/dist/components/ai-voice-input.js +1 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/p-CWjXxYJI.js +1 -0
- package/dist/components/p-CY6emva2.js +1 -0
- package/dist/components/p-DYv5ef4M.js +1 -0
- package/dist/esm/ai-card.entry.js +23 -0
- package/dist/esm/ai-chat-container.entry.js +136 -0
- package/dist/esm/ai-chat-header.entry.js +77 -0
- package/dist/esm/ai-chat-message.entry.js +162 -0
- package/dist/esm/ai-icon.entry.js +23 -0
- package/dist/esm/ai-link.entry.js +32 -0
- package/dist/esm/ai-loading.entry.js +75 -0
- package/dist/esm/ai-message-input.entry.js +63 -0
- package/dist/esm/ai-rating.entry.js +55 -0
- package/dist/esm/ai-suggestion.entry.js +29 -0
- package/dist/esm/ai-voice-input.entry.js +231 -0
- package/dist/esm/icon-registry-DYv5ef4M.js +80 -0
- package/dist/esm/index-7hrZ8FOQ.js +1612 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/loader.js +10 -0
- package/dist/esm/ui-ai-kit.js +20 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types/components/ai-card/ai-card.d.ts +7 -0
- package/dist/types/components/ai-card/ai-card.stories.d.ts +7 -0
- package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +28 -0
- package/dist/types/components/ai-chat-container/ai-chat-container.stories.d.ts +7 -0
- package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +38 -0
- package/dist/types/components/ai-chat-header/ai-chat-header.stories.d.ts +8 -0
- package/dist/types/components/ai-chat-message/ai-chat-message.d.ts +27 -0
- package/dist/types/components/ai-chat-message/ai-chat-message.stories.d.ts +10 -0
- package/dist/types/components/ai-icon/ai-icon.d.ts +8 -0
- package/dist/types/components/ai-link/ai-link.d.ts +12 -0
- package/dist/types/components/ai-link/ai-link.stories.d.ts +8 -0
- package/dist/types/components/ai-loading/ai-loading.d.ts +33 -0
- package/dist/types/components/ai-loading/ai-loading.stories.d.ts +10 -0
- package/dist/types/components/ai-message-input/ai-message-input.d.ts +22 -0
- package/dist/types/components/ai-message-input/ai-message-input.stories.d.ts +13 -0
- package/dist/types/components/ai-rating/ai-rating.d.ts +17 -0
- package/dist/types/components/ai-rating/ai-rating.stories.d.ts +8 -0
- package/dist/types/components/ai-suggestion/ai-suggestion.d.ts +10 -0
- package/dist/types/components/ai-suggestion/ai-suggestion.stories.d.ts +8 -0
- package/dist/types/components/ai-voice-input/ai-voice-input.d.ts +43 -0
- package/dist/types/components/ai-voice-input/ai-voice-input.stories.d.ts +9 -0
- package/dist/types/components.d.ts +860 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/stencil-public-runtime.d.ts +1860 -0
- package/dist/types/utils/icon-registry.d.ts +5 -0
- package/dist/types/utils/utils.d.ts +1 -0
- package/dist/ui-ai-kit/index.esm.js +1 -0
- package/dist/ui-ai-kit/p-11facfad.entry.js +1 -0
- package/dist/ui-ai-kit/p-128a2ed4.entry.js +1 -0
- package/dist/ui-ai-kit/p-227bdb8f.entry.js +1 -0
- package/dist/ui-ai-kit/p-455daa17.entry.js +1 -0
- package/dist/ui-ai-kit/p-56163e8c.entry.js +1 -0
- package/dist/ui-ai-kit/p-6d21d0fd.entry.js +1 -0
- package/dist/ui-ai-kit/p-6ddcd77b.entry.js +1 -0
- package/dist/ui-ai-kit/p-7hrZ8FOQ.js +2 -0
- package/dist/ui-ai-kit/p-8e90143e.entry.js +1 -0
- package/dist/ui-ai-kit/p-9938c277.entry.js +1 -0
- package/dist/ui-ai-kit/p-DYv5ef4M.js +1 -0
- package/dist/ui-ai-kit/p-dc5b4a7f.entry.js +1 -0
- package/dist/ui-ai-kit/p-fb1702de.entry.js +1 -0
- package/dist/ui-ai-kit/ui-ai-kit.css +1 -0
- package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +77 -0
- package/readme.md +111 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
|
|
5
|
+
const aiCardCss = () => `:host{--ai-card-bg:var(--ai-bg-card, #ffffff);--ai-card-border:1px solid var(--ai-border-default, #eeeeee);--ai-card-radius:16px;--ai-card-padding:16px;--ai-card-gap:12px;--ai-card-shadow:0px 1px 2px 0px rgba(18, 18, 23, 0.05);--ai-text-color:var(--ai-text-primary, #333333);display:block;direction:rtl}.card{background:var(--ai-card-bg);border:var(--ai-card-border);border-radius:var(--ai-card-radius);padding:var(--ai-card-padding);box-shadow:var(--ai-card-shadow);box-sizing:border-box;overflow:hidden;color:var(--ai-text-color);width:100%;display:flex;flex-direction:column;gap:var(--ai-card-gap);text-align:right;font-size:14px;line-height:20px}.card--no-padding{padding:0}.card--no-shadow{box-shadow:none}`;
|
|
6
|
+
|
|
7
|
+
const AiCard = class {
|
|
8
|
+
constructor(hostRef) {
|
|
9
|
+
index.registerInstance(this, hostRef);
|
|
10
|
+
}
|
|
11
|
+
/** Remove the default padding */
|
|
12
|
+
noPadding = false;
|
|
13
|
+
/** Remove the shadow */
|
|
14
|
+
noShadow = false;
|
|
15
|
+
render() {
|
|
16
|
+
return (index.h(index.Host, { key: '4805b02b4eee8e01d0233de788a58770a85db2aa' }, index.h("div", { key: '75576f8a791fc49c3a750d491b0e835d0e5ce8cb', class: {
|
|
17
|
+
card: true,
|
|
18
|
+
'card--no-padding': this.noPadding,
|
|
19
|
+
'card--no-shadow': this.noShadow,
|
|
20
|
+
} }, index.h("slot", { key: 'e16cdb10e803451fdd47006a98656168fe2495f4' }))));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
AiCard.style = aiCardCss();
|
|
24
|
+
|
|
25
|
+
exports.ai_card = AiCard;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
|
|
5
|
+
const aiChatContainerCss = () => `:host{display:contents}.chat-container{font-family:var(--ai-font-family, 'PingARLT', sans-serif);display:flex;flex-direction:column;overflow:hidden;position:relative;background-color:var(--ai-container-bg, var(--ai-bg-card, white));border:1px solid var(--border-default, var(--ai-border-default, #eee));z-index:50;box-sizing:border-box}.messages-area{flex:1;overflow-y:auto;min-height:0;scrollbar-width:thin;scrollbar-color:var(--ai-scrollbar-thumb, rgba(0, 0, 0, 0.15)) transparent}.messages-area::-webkit-scrollbar{width:3px}.messages-area::-webkit-scrollbar-track{background:transparent}.messages-area::-webkit-scrollbar-thumb{background:var(--ai-scrollbar-thumb, rgba(0, 0, 0, 0.15));border-radius:99px}.messages-area::-webkit-scrollbar-thumb:hover{background:var(--ai-scrollbar-thumb, rgba(0, 0, 0, 0.28))}.chat-container.left,.chat-container.right{position:fixed;top:0;bottom:0;transition:transform 300ms cubic-bezier(0.4, 0, 0.2, 1)}.chat-container.left{left:0;transform:translateX(-100%)}.chat-container.right{right:0;transform:translateX(100%)}.chat-container.left.open,.chat-container.right.open{transform:translateX(0)}.chat-container.float{position:fixed;top:24px;left:24px;border-radius:16px;box-shadow:0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);display:none}.chat-container.float.open{display:flex}.watermark{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);pointer-events:none}.watermark ai-icon{opacity:0.8;filter:drop-shadow(0 4px 6px rgba(0, 0, 0, 0.05))}.chat-container.mobile{width:100% !important}.chat-container.float.mobile{left:0 !important;right:0 !important;top:0 !important;bottom:0 !important;height:100% !important;border-radius:0 !important}@media (max-width: 767px){.chat-container{width:100% !important}.chat-container.float{left:0 !important;right:0 !important;top:0 !important;bottom:0 !important;height:100% !important;border-radius:0 !important}}:host(.dark) .watermark ai-icon{opacity:0.6}`;
|
|
6
|
+
|
|
7
|
+
const ChatContainer = class {
|
|
8
|
+
constructor(hostRef) {
|
|
9
|
+
index.registerInstance(this, hostRef);
|
|
10
|
+
}
|
|
11
|
+
get el() { return index.getElement(this); }
|
|
12
|
+
/** Controls visibility of the chat panel */
|
|
13
|
+
isOpen = false;
|
|
14
|
+
/** Position of the panel: 'left', 'right', or 'float' */
|
|
15
|
+
position = 'right';
|
|
16
|
+
/** Width of the panel (CSS value, e.g., '400px', '30%', '28rem') */
|
|
17
|
+
width = '28rem';
|
|
18
|
+
/** Enable/disable auto-scroll to latest message */
|
|
19
|
+
autoScroll = true;
|
|
20
|
+
/** Show AI watermark in the top half of the container */
|
|
21
|
+
showWatermark = false;
|
|
22
|
+
/** Height of the panel when position='float' */
|
|
23
|
+
floatHeight = '600px';
|
|
24
|
+
isMobile = false;
|
|
25
|
+
containerRef;
|
|
26
|
+
dragState = null;
|
|
27
|
+
resizeObserver;
|
|
28
|
+
componentWillLoad() {
|
|
29
|
+
this.checkMobile();
|
|
30
|
+
}
|
|
31
|
+
componentDidLoad() {
|
|
32
|
+
if (typeof window !== 'undefined') {
|
|
33
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
34
|
+
this.checkMobile();
|
|
35
|
+
});
|
|
36
|
+
this.resizeObserver.observe(document.body);
|
|
37
|
+
if (this.position === 'float') {
|
|
38
|
+
this.setupDrag();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
positionChanged(newVal) {
|
|
43
|
+
if (newVal === 'float') {
|
|
44
|
+
this.setupDrag();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
disconnectedCallback() {
|
|
48
|
+
if (this.resizeObserver) {
|
|
49
|
+
this.resizeObserver.disconnect();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
checkMobile() {
|
|
53
|
+
if (typeof window !== 'undefined') {
|
|
54
|
+
this.isMobile = window.innerWidth < 768;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
setupDrag() {
|
|
58
|
+
const container = this.containerRef;
|
|
59
|
+
if (!container)
|
|
60
|
+
return;
|
|
61
|
+
// Listen on the host element so composed events from ai-chat-header's shadow DOM
|
|
62
|
+
// are received. (composedPath() hides cross-shadow-root elements from shadow listeners.)
|
|
63
|
+
this.el.addEventListener('headerDragStart', (e) => {
|
|
64
|
+
const { clientX, clientY } = e.detail;
|
|
65
|
+
const rect = container.getBoundingClientRect();
|
|
66
|
+
this.dragState = {
|
|
67
|
+
startX: clientX,
|
|
68
|
+
startY: clientY,
|
|
69
|
+
initLeft: rect.left,
|
|
70
|
+
initTop: rect.top,
|
|
71
|
+
};
|
|
72
|
+
// Switch from bottom/right anchoring to top/left so we can move freely
|
|
73
|
+
container.style.right = 'auto';
|
|
74
|
+
container.style.bottom = 'auto';
|
|
75
|
+
container.style.left = `${rect.left}px`;
|
|
76
|
+
container.style.top = `${rect.top}px`;
|
|
77
|
+
const onMove = (me) => {
|
|
78
|
+
if (!this.dragState)
|
|
79
|
+
return;
|
|
80
|
+
const dx = me.clientX - this.dragState.startX;
|
|
81
|
+
const dy = me.clientY - this.dragState.startY;
|
|
82
|
+
let newLeft = this.dragState.initLeft + dx;
|
|
83
|
+
let newTop = this.dragState.initTop + dy;
|
|
84
|
+
// Clamp to viewport edges
|
|
85
|
+
const vw = window.innerWidth;
|
|
86
|
+
const vh = window.innerHeight;
|
|
87
|
+
const w = container.offsetWidth;
|
|
88
|
+
const h = container.offsetHeight;
|
|
89
|
+
newLeft = Math.max(0, Math.min(newLeft, vw - w));
|
|
90
|
+
newTop = Math.max(0, Math.min(newTop, vh - h));
|
|
91
|
+
container.style.left = `${newLeft}px`;
|
|
92
|
+
container.style.top = `${newTop}px`;
|
|
93
|
+
};
|
|
94
|
+
const onUp = () => {
|
|
95
|
+
this.dragState = null;
|
|
96
|
+
document.removeEventListener('pointermove', onMove);
|
|
97
|
+
document.removeEventListener('pointerup', onUp);
|
|
98
|
+
};
|
|
99
|
+
document.addEventListener('pointermove', onMove);
|
|
100
|
+
document.addEventListener('pointerup', onUp);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
getContainerClasses() {
|
|
104
|
+
const classes = ['chat-container', this.position];
|
|
105
|
+
if (this.isOpen) {
|
|
106
|
+
classes.push('open');
|
|
107
|
+
}
|
|
108
|
+
if (this.isMobile) {
|
|
109
|
+
classes.push('mobile');
|
|
110
|
+
}
|
|
111
|
+
return classes.join(' ');
|
|
112
|
+
}
|
|
113
|
+
getContainerStyle() {
|
|
114
|
+
const style = {};
|
|
115
|
+
if (this.isMobile) {
|
|
116
|
+
return style;
|
|
117
|
+
}
|
|
118
|
+
if (this.position === 'float') {
|
|
119
|
+
style.width = this.width;
|
|
120
|
+
style.height = this.floatHeight;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
style.width = this.width;
|
|
124
|
+
}
|
|
125
|
+
return style;
|
|
126
|
+
}
|
|
127
|
+
render() {
|
|
128
|
+
return (index.h(index.Host, { key: '5048010bf45a26985c92bfb9a6caf01d8aa938c0' }, index.h("div", { key: '08491cff2361071bc0635914cc665281b80321ac', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && (index.h("div", { key: '366140a61929689fc522dddfb1485bbd4d2cbef9', class: "watermark" }, index.h("ai-icon", { key: '5e210929feeb519889344385fa2fb75373ff8fed', name: "watermark", size: 133 }))), index.h("slot", { key: '57eef4d0c273009feeeb4f03400e05352acdf6cd', name: "header" }), index.h("div", { key: '15b14f49819f886ce1d56de87c770bb7241dcd77', class: "messages-area" }, index.h("slot", { key: '050cd0fde5bc3de75df0747031dc84214c125d5d' })), index.h("slot", { key: '195ab33291da775299e0d7c0c53df92fcf46a4ca', name: "footer" }))));
|
|
129
|
+
}
|
|
130
|
+
static get watchers() { return {
|
|
131
|
+
"position": [{
|
|
132
|
+
"positionChanged": 0
|
|
133
|
+
}]
|
|
134
|
+
}; }
|
|
135
|
+
};
|
|
136
|
+
ChatContainer.style = aiChatContainerCss();
|
|
137
|
+
|
|
138
|
+
exports.ai_chat_container = ChatContainer;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
var iconRegistry = require('./icon-registry-dmfLA-Dj.js');
|
|
5
|
+
|
|
6
|
+
const aiChatHeaderCss = () => `:host{display:block;font-family:var(--ai-font-family, "PingARLT", sans-serif)}.header-container{display:flex;align-items:center;gap:8px;padding:16px;background:var(--ai-bg-card, white);border-bottom:1px solid var(--ai-border-light, #f4f4f4);width:100%;box-sizing:border-box}.header-container{direction:rtl}.drag-btn{cursor:grab;color:var(--ai-text-muted)}.drag-btn:active{cursor:grabbing}.action-btn,.back-btn{width:40px;height:40px;padding:4px;display:flex;align-items:center;justify-content:center;background:var(--ai-bg-card, white);border:none;border-radius:8px;cursor:pointer;flex-shrink:0;color:var(--ai-text-primary);transition:background 0.15s ease}.action-btn:hover,.back-btn:hover{background:var(--ai-bg-surface, #f9fafb)}.action-btn:focus-visible,.back-btn:focus-visible{outline:2px solid var(--ai-focus-ring);outline-offset:2px}.action-btn:active,.back-btn:active{background:var(--ai-bg-surface, #f3f4f6)}.actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.content{flex:1 0 0;display:flex;align-items:center;justify-content:flex-start;min-width:0}.content.agent{gap:4px;height:40px}.content.human{gap:8px}.dropdown-trigger{display:flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;padding:0;flex-shrink:0;color:var(--ai-text-primary)}.dropdown-trigger:focus-visible{outline:2px solid var(--ai-focus-ring);outline-offset:2px}.title{font-size:16px;font-weight:700;color:var(--ai-text-primary, #444444);white-space:nowrap;line-height:normal;min-width:0;overflow:hidden;text-overflow:ellipsis}.avatar-wrapper{position:relative;width:40px;height:40px;flex-shrink:0}.avatar{width:40px;height:40px;border-radius:9999px;border:1px solid var(--ai-border-default, #eeeeee);object-fit:cover;display:block}.online-dot{position:absolute;bottom:0;left:0;width:10px;height:10px;display:inline-flex;align-items:center;justify-content:center;color:var(--ai-bg-card);}.text-block{display:flex;flex-direction:column;align-items:flex-end;gap:0;flex-shrink:0}.agent-name{font-size:14px;font-weight:500;color:var(--ai-text-primary, #333333);line-height:20px;white-space:nowrap}.agent-status{font-size:14px;font-weight:400;color:var(--ai-text-secondary, #737373);line-height:20px;white-space:nowrap}.icon-wrap{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.icon-wrap svg{display:block}`;
|
|
7
|
+
|
|
8
|
+
const AiChatHeader = class {
|
|
9
|
+
constructor(hostRef) {
|
|
10
|
+
index.registerInstance(this, hostRef);
|
|
11
|
+
this.closeClick = index.createEvent(this, "closeClick");
|
|
12
|
+
this.editClick = index.createEvent(this, "editClick");
|
|
13
|
+
this.dropdownClick = index.createEvent(this, "dropdownClick");
|
|
14
|
+
this.moreClick = index.createEvent(this, "moreClick");
|
|
15
|
+
this.backClick = index.createEvent(this, "backClick");
|
|
16
|
+
this.headerDragStart = index.createEvent(this, "headerDragStart");
|
|
17
|
+
}
|
|
18
|
+
/** Layout variant */
|
|
19
|
+
mode = 'agent';
|
|
20
|
+
/** Agent mode: conversation title */
|
|
21
|
+
conversation = 'محادثة جديدة';
|
|
22
|
+
/** Human mode: agent's display name */
|
|
23
|
+
agentName = '';
|
|
24
|
+
/** Human mode: status label (e.g. "Active") */
|
|
25
|
+
agentStatus = '';
|
|
26
|
+
/** Human mode: avatar image URL */
|
|
27
|
+
agentAvatar = '';
|
|
28
|
+
/** Human mode: show the back button */
|
|
29
|
+
showBack = true;
|
|
30
|
+
isDraggable = false;
|
|
31
|
+
/** Cancel / close button */
|
|
32
|
+
closeClick;
|
|
33
|
+
/** Pencil-edit button (agent mode) */
|
|
34
|
+
editClick;
|
|
35
|
+
/** Title / chevron click → open conversation list (agent mode) */
|
|
36
|
+
dropdownClick;
|
|
37
|
+
/** Chevron-down button (human mode) */
|
|
38
|
+
moreClick;
|
|
39
|
+
/** Back-arrow button (human mode) */
|
|
40
|
+
backClick;
|
|
41
|
+
/**
|
|
42
|
+
* Fired on pointerdown of the drag handle.
|
|
43
|
+
* Composed + bubbling so ai-chat-container can receive it across shadow roots.
|
|
44
|
+
*/
|
|
45
|
+
headerDragStart;
|
|
46
|
+
renderIcon(name, width, height) {
|
|
47
|
+
const icon = iconRegistry.iconRegistry[name];
|
|
48
|
+
if (!icon)
|
|
49
|
+
return null;
|
|
50
|
+
const svg = `<svg width="${width}" height="${height}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
|
|
51
|
+
return index.h("span", { class: "icon-wrap", innerHTML: svg });
|
|
52
|
+
}
|
|
53
|
+
renderAgentMode() {
|
|
54
|
+
return [
|
|
55
|
+
this.isDraggable && (index.h("button", { class: "action-btn drag-btn", onPointerDown: (e) => {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
|
|
58
|
+
} }, this.renderIcon('drag', 11, 15))),
|
|
59
|
+
index.h("div", { class: "content agent" }, index.h("span", { class: "title" }, this.conversation), index.h("button", { class: "dropdown-trigger", onClick: () => this.dropdownClick.emit() }, this.renderIcon('chevron-down', 24, 24))),
|
|
60
|
+
index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", onClick: () => this.editClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), index.h("button", { class: "action-btn", onClick: () => this.moreClick.emit() }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
renderHumanMode() {
|
|
64
|
+
return [
|
|
65
|
+
this.isDraggable && (index.h("button", { class: "action-btn drag-btn", onPointerDown: (e) => {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
|
|
68
|
+
} }, this.renderIcon('drag', 11, 15))),
|
|
69
|
+
index.h("div", { class: "content human" }, this.showBack && (index.h("button", { class: "back-btn", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24))), index.h("div", { class: "avatar-wrapper" }, index.h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName }), index.h("span", { class: "online-dot" }, this.renderIcon('online-dot', 10, 10))), index.h("div", { class: "text-block" }, index.h("span", { class: "agent-name" }, this.agentName), index.h("span", { class: "agent-status" }, this.agentStatus))),
|
|
70
|
+
index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", onClick: () => this.moreClick.emit() }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
render() {
|
|
74
|
+
return (index.h(index.Host, { key: '93fe332abe1339f7235aa18717d63aa65d9aac13' }, index.h("div", { key: 'b496695911f7d1f959c4f98506b0d230e77a86c3', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.renderHumanMode())));
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
AiChatHeader.style = aiChatHeaderCss();
|
|
78
|
+
|
|
79
|
+
exports.ai_chat_header = AiChatHeader;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
var iconRegistry = require('./icon-registry-dmfLA-Dj.js');
|
|
5
|
+
|
|
6
|
+
const aiChatMessageCss = () => `:host{--ai-msg-user-bg:var(--ai-user-bubble-bg, #F4F4F4);--ai-msg-user-color:var(--ai-text-primary, #333333);--ai-msg-user-border:1px solid var(--ai-border-default, #eee);--ai-msg-agent-bg:var(--ai-agent-bubble-bg, #ffffff);--ai-msg-agent-color:var(--ai-text-primary, #333333);--ai-msg-agent-border:1px solid var(--ai-border-default, #eee);--ai-msg-border-radius:16px;--ai-msg-padding:16px;--ai-msg-font-size:14px;--ai-msg-action-active-bg:var(--ai-accent, #a4ffe5);--ai-msg-timestamp-color:var(--ai-text-secondary, #737373);--ai-user-msg-max-width:80%;--ai-agent-msg-max-width:80%;display:block;direction:rtl;font-family:var(--ai-font-family, "PingARLT", sans-serif)}.message-row{display:flex}.user-row{flex-direction:column;align-items:flex-end}.user-bubble{background:var(--ai-msg-user-bg);color:var(--ai-msg-user-color);border:var(--ai-msg-user-border);border-radius:var(--ai-msg-border-radius);padding:var(--ai-msg-padding);font-size:var(--ai-msg-font-size);max-width:var(--ai-user-msg-max-width);line-height:1.5;word-break:break-word;box-shadow:0px 1px 2px 0px rgba(18, 18, 23, 0.05)}.user-row .timestamp{font-size:12px;color:var(--ai-msg-timestamp-color);margin-top:4px}.agent-row{flex-direction:row;justify-content:flex-start}.agent-bubble-wrapper{display:flex;flex-direction:column;gap:6px;width:100%;max-width:var(--ai-msg-agent-max-width);min-width:0}.agent-bubble{background:var(--ai-msg-agent-bg);color:var(--ai-msg-agent-color);border:var(--ai-msg-agent-border);border-radius:var(--ai-msg-border-radius);padding:var(--ai-msg-padding);font-size:var(--ai-msg-font-size);line-height:1.6;word-break:break-word;box-shadow:0px 1px 2px 0px rgba(18, 18, 23, 0.05);display:flex;flex-direction:column;gap:12px}.message-content{white-space:pre-wrap}.message-content p{margin:0 0 8px 0}.message-content p:last-child{margin-bottom:0}.message-content h2{font-size:16px;font-weight:700;margin:0 0 8px 0}.message-content h3{font-size:15px;font-weight:600;margin:0 0 6px 0}.message-content strong{font-weight:700}.message-content em{font-style:italic}.message-content code{background:var(--ai-bg-surface, #f3f4f6);border-radius:4px;padding:1px 5px;font-family:monospace;font-size:13px;color:var(--ai-text-primary, #374151)}.message-content pre{background:var(--ai-bg-surface, #f3f4f6);border-radius:8px;padding:10px 12px;overflow-x:auto;margin:8px 0}.message-content pre code{background:none;padding:0;font-size:13px}.message-content ul,.message-content ol{padding-inline-start:20px;margin:4px 0 8px 0}.message-content li{margin-bottom:3px}.actions-bar{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:6px;height:0;overflow:hidden;opacity:0;pointer-events:none;transition:height 0.15s ease, opacity 0.15s ease}.agent-bubble:hover .actions-bar{height:32px;opacity:1;pointer-events:auto}.action-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:8px;background:var(--ai-bg-card, #ffffff);border:1px solid var(--ai-border-default, #eee);cursor:pointer;color:var(--ai-text-primary, #333333);transition:background 0.15s, color 0.15s;padding:0;flex-shrink:0}.action-btn:hover{background:var(--ai-bg-surface, #f3f4f6)}.action-btn.copy-success{background:var(--ai-msg-action-active-bg);color:var(--ai-accent-text);border-color:var(--ai-accent)}.feedback-group{display:flex;align-items:center;border:1px solid var(--ai-border-default, #eee);border-radius:8px;overflow:hidden;background:var(--ai-bg-card, #ffffff)}.feedback-btn{display:flex;align-items:center;justify-content:center;height:32px;padding:0 8px;background:var(--ai-bg-card, #ffffff);border:none;border-inline-start:1px solid var(--ai-border-default, #eee);cursor:pointer;color:var(--ai-text-primary, #333333);transition:background 0.15s, color 0.15s}.feedback-btn:first-child{border-inline-start:none}.feedback-btn:hover{background:var(--ai-bg-surface, #f3f4f6)}.feedback-btn.active{background:var(--ai-msg-action-active-bg);color:var(--ai-accent-text)}.icon-wrap{display:flex;align-items:center;justify-content:center;line-height:0}.agent-info{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:6px;color:var(--ai-text-muted, #9ca3af)}.agent-info-name,.agent-info-time{font-size:12px;color:inherit;line-height:16px;white-space:nowrap}.agent-info .icon-wrap{display:flex;align-items:center;color:inherit;opacity:0.6;flex-shrink:0}.typing-indicator{display:flex;align-items:center;gap:5px;padding:4px 2px}.typing-dot{width:8px;height:8px;border-radius:50%;background:var(--ai-text-muted, #9ca3af);animation:typingBounce 1.2s ease-in-out infinite}.typing-dot:nth-child(2){animation-delay:0.2s}.typing-dot:nth-child(3){animation-delay:0.4s}@keyframes typingBounce{0%,60%,100%{transform:translateY(0)}30%{transform:translateY(-6px)}}.streaming-cursor{display:inline-block;width:2px;height:1em;background:currentColor;vertical-align:text-bottom;margin-inline-start:2px;animation:cursorBlink 0.8s step-start infinite}@keyframes cursorBlink{0%,100%{opacity:1}50%{opacity:0}}`;
|
|
7
|
+
|
|
8
|
+
const AiChatMessage = class {
|
|
9
|
+
constructor(hostRef) {
|
|
10
|
+
index.registerInstance(this, hostRef);
|
|
11
|
+
this.messageCopy = index.createEvent(this, "messageCopy");
|
|
12
|
+
this.messageFeedback = index.createEvent(this, "messageFeedback");
|
|
13
|
+
this.messageRegenerate = index.createEvent(this, "messageRegenerate");
|
|
14
|
+
}
|
|
15
|
+
role = 'user';
|
|
16
|
+
content = '';
|
|
17
|
+
format = 'text';
|
|
18
|
+
agentName = '';
|
|
19
|
+
timestamp = '';
|
|
20
|
+
showActions = true;
|
|
21
|
+
enableRegenerate = false;
|
|
22
|
+
feedbackValue = null;
|
|
23
|
+
messageCopy;
|
|
24
|
+
messageFeedback;
|
|
25
|
+
messageRegenerate;
|
|
26
|
+
copySuccess = false;
|
|
27
|
+
copyTimeout;
|
|
28
|
+
disconnectedCallback() {
|
|
29
|
+
if (this.copyTimeout)
|
|
30
|
+
clearTimeout(this.copyTimeout);
|
|
31
|
+
}
|
|
32
|
+
renderIcon(name, size = 16) {
|
|
33
|
+
const icon = iconRegistry.iconRegistry[name];
|
|
34
|
+
if (!icon)
|
|
35
|
+
return null;
|
|
36
|
+
const svg = `<svg width="${size}" height="${size}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
|
|
37
|
+
return index.h("span", { class: "icon-wrap", innerHTML: svg });
|
|
38
|
+
}
|
|
39
|
+
parseMarkdown(text) {
|
|
40
|
+
let html = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
41
|
+
const blocks = [];
|
|
42
|
+
html = html.replace(/```(?:\w+)?\n?([\s\S]*?)```/g, (_, code) => {
|
|
43
|
+
const idx = blocks.length;
|
|
44
|
+
blocks.push(`<pre><code>${code}</code></pre>`);
|
|
45
|
+
return `\x00BLOCK${idx}\x00`;
|
|
46
|
+
});
|
|
47
|
+
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
48
|
+
html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
|
|
49
|
+
html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
|
|
50
|
+
html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
|
|
51
|
+
html = html.replace(/\*([^*\n]+)\*/g, '<em>$1</em>');
|
|
52
|
+
html = html.replace(/((?:^[ \t]*[-*] .+\n?)+)/gm, match => {
|
|
53
|
+
const items = match
|
|
54
|
+
.trim()
|
|
55
|
+
.split('\n')
|
|
56
|
+
.filter(l => l.trim())
|
|
57
|
+
.map(l => `<li>${l.replace(/^[ \t]*[-*] /, '')}</li>`)
|
|
58
|
+
.join('');
|
|
59
|
+
return `\x00BLOCK${blocks.length}\x00${(() => {
|
|
60
|
+
blocks.push(`<ul>${items}</ul>`);
|
|
61
|
+
return '';
|
|
62
|
+
})()}`;
|
|
63
|
+
});
|
|
64
|
+
html = html.replace(/((?:^[ \t]*\d+\. .+\n?)+)/gm, match => {
|
|
65
|
+
const items = match
|
|
66
|
+
.trim()
|
|
67
|
+
.split('\n')
|
|
68
|
+
.filter(l => l.trim())
|
|
69
|
+
.map(l => `<li>${l.replace(/^[ \t]*\d+\. /, '')}</li>`)
|
|
70
|
+
.join('');
|
|
71
|
+
return `\x00BLOCK${blocks.length}\x00${(() => {
|
|
72
|
+
blocks.push(`<ol>${items}</ol>`);
|
|
73
|
+
return '';
|
|
74
|
+
})()}`;
|
|
75
|
+
});
|
|
76
|
+
html = html
|
|
77
|
+
.split(/\n{2,}/)
|
|
78
|
+
.map(chunk => {
|
|
79
|
+
const trimmed = chunk.trim();
|
|
80
|
+
if (!trimmed)
|
|
81
|
+
return '';
|
|
82
|
+
if (/^\x00BLOCK\d+\x00$/.test(trimmed))
|
|
83
|
+
return trimmed;
|
|
84
|
+
return `<p>${trimmed.replace(/\n/g, '<br>')}</p>`;
|
|
85
|
+
})
|
|
86
|
+
.join('');
|
|
87
|
+
html = html.replace(/\x00BLOCK(\d+)\x00/g, (_, i) => blocks[parseInt(i, 10)] || '');
|
|
88
|
+
return html;
|
|
89
|
+
}
|
|
90
|
+
getRenderedContent() {
|
|
91
|
+
if (!this.content)
|
|
92
|
+
return '';
|
|
93
|
+
let html = this.parseMarkdown(this.content);
|
|
94
|
+
return html;
|
|
95
|
+
}
|
|
96
|
+
getRelativeTime() {
|
|
97
|
+
if (!this.timestamp)
|
|
98
|
+
return '';
|
|
99
|
+
try {
|
|
100
|
+
const date = new Date(this.timestamp);
|
|
101
|
+
if (isNaN(date.getTime()))
|
|
102
|
+
return this.timestamp;
|
|
103
|
+
const diffMin = Math.floor((Date.now() - date.getTime()) / 60000);
|
|
104
|
+
if (diffMin < 1)
|
|
105
|
+
return 'الآن';
|
|
106
|
+
if (diffMin < 60)
|
|
107
|
+
return `منذ ${diffMin} دقيقة`;
|
|
108
|
+
const hours = Math.floor(diffMin / 60);
|
|
109
|
+
if (hours < 24)
|
|
110
|
+
return `منذ ${hours} ساعة`;
|
|
111
|
+
return `منذ ${Math.floor(hours / 24)} يوم`;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return this.timestamp;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async handleCopy() {
|
|
118
|
+
try {
|
|
119
|
+
await navigator.clipboard.writeText(this.content);
|
|
120
|
+
}
|
|
121
|
+
catch (_) { }
|
|
122
|
+
this.copySuccess = true;
|
|
123
|
+
this.messageCopy.emit();
|
|
124
|
+
this.copyTimeout = setTimeout(() => (this.copySuccess = false), 1500);
|
|
125
|
+
}
|
|
126
|
+
handleFeedback(val) {
|
|
127
|
+
this.feedbackValue = this.feedbackValue === val ? null : val;
|
|
128
|
+
this.messageFeedback.emit(val);
|
|
129
|
+
}
|
|
130
|
+
renderActionsBar() {
|
|
131
|
+
return (index.h("div", { class: "actions-bar" }, this.enableRegenerate && index.h("button", { class: 'action-btn', onClick: () => this.messageRegenerate.emit(), title: "\u0625\u0639\u0627\u062F\u0629 \u062A\u062D\u0645\u064A\u0644" }, this.renderIcon('reload', 16)), index.h("button", { class: `action-btn copy-btn${this.copySuccess ? ' copy-success' : ''}`, onClick: () => this.handleCopy(), title: "\u0646\u0633\u062E" }, this.renderIcon('copy', 16)), index.h("div", { class: "feedback-group" }, index.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)), index.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)))));
|
|
132
|
+
}
|
|
133
|
+
renderUserMessage() {
|
|
134
|
+
return (index.h("div", { class: "message-row user-row" }, index.h("div", { class: "bubble user-bubble" }, index.h("div", { class: "message-content", ref: el => {
|
|
135
|
+
if (!el)
|
|
136
|
+
return;
|
|
137
|
+
if (this.format === 'markdown') {
|
|
138
|
+
el.innerHTML = this.getRenderedContent();
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
el.textContent = this.content;
|
|
142
|
+
}
|
|
143
|
+
} }))));
|
|
144
|
+
}
|
|
145
|
+
renderAgentMessage() {
|
|
146
|
+
const showActions = this.showActions;
|
|
147
|
+
return (index.h("div", { class: "message-row agent-row" }, index.h("div", { class: "agent-bubble-wrapper" }, index.h("div", { class: "bubble agent-bubble" }, this.content && (index.h("div", { class: "message-content", ref: el => {
|
|
148
|
+
if (!el)
|
|
149
|
+
return;
|
|
150
|
+
if (this.format === 'markdown') {
|
|
151
|
+
el.innerHTML = this.getRenderedContent();
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
el.textContent = this.content;
|
|
155
|
+
}
|
|
156
|
+
} })), index.h("slot", null), showActions && this.renderActionsBar()), (this.agentName || this.timestamp) && (index.h("div", { class: "agent-info" }, this.agentName && index.h("span", { class: "agent-info-name" }, this.agentName), this.agentName && this.timestamp && this.renderIcon('eclipse', 10), this.timestamp && index.h("span", { class: "agent-info-time" }, this.getRelativeTime()))))));
|
|
157
|
+
}
|
|
158
|
+
render() {
|
|
159
|
+
return index.h(index.Host, { key: '77dd0c46a676c211fdfba283d51bd0e0d2594b24' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
AiChatMessage.style = aiChatMessageCss();
|
|
163
|
+
|
|
164
|
+
exports.ai_chat_message = AiChatMessage;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
var iconRegistry = require('./icon-registry-dmfLA-Dj.js');
|
|
5
|
+
|
|
6
|
+
const aiIconCss = () => `:host{display:inline-flex;align-items:center;justify-content:center}svg{display:block}`;
|
|
7
|
+
|
|
8
|
+
const AiIcon = class {
|
|
9
|
+
constructor(hostRef) {
|
|
10
|
+
index.registerInstance(this, hostRef);
|
|
11
|
+
}
|
|
12
|
+
/** Icon name from the registry */
|
|
13
|
+
name;
|
|
14
|
+
/** Size in pixels for width and height */
|
|
15
|
+
size = 16;
|
|
16
|
+
render() {
|
|
17
|
+
const icon = iconRegistry.iconRegistry[this.name];
|
|
18
|
+
if (!icon)
|
|
19
|
+
return null;
|
|
20
|
+
return (index.h(index.Host, null, index.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" })));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
AiIcon.style = aiIconCss();
|
|
24
|
+
|
|
25
|
+
exports.ai_icon = AiIcon;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
var iconRegistry = require('./icon-registry-dmfLA-Dj.js');
|
|
5
|
+
|
|
6
|
+
const aiLinkCss = () => `:host{--ai-link-color:var(--ai-accent-dark);--ai-link-color-hover:var(--ai-accent-dark);--ai-link-font-size:14px;--ai-link-font-weight:700;--ai-link-line-height:20px;--ai-link-gap:4px;--ai-link-icon-size:16px;display:flex;align-items:center;gap:var(--ai-link-gap);direction:rtl;font-family:var(--ai-font-family, 'PingARLT', sans-serif)}.link{display:inline-flex;align-items:center;justify-content:flex-end;gap:var(--ai-link-gap);color:var(--ai-link-color);font-size:var(--ai-link-font-size);font-weight:var(--ai-link-font-weight);font-family:inherit;line-height:var(--ai-link-line-height);text-decoration:none;white-space:nowrap;cursor:pointer;transition:color 0.15s ease;outline:none}.link:hover{color:var(--ai-link-color-hover);text-decoration:underline}.link:focus-visible{outline:2px solid var(--ai-accent);outline-offset:2px;border-radius:4px}.link__icon{display:inline-flex;align-items:center;justify-content:center;width:var(--ai-link-icon-size);height:var(--ai-link-icon-size);flex-shrink:0;line-height:0}.link__label{color:var(--ai-link-color);font-weight:bold}`;
|
|
7
|
+
|
|
8
|
+
const AiLink = class {
|
|
9
|
+
constructor(hostRef) {
|
|
10
|
+
index.registerInstance(this, hostRef);
|
|
11
|
+
}
|
|
12
|
+
/** Link display label */
|
|
13
|
+
label = '';
|
|
14
|
+
/** Href URL */
|
|
15
|
+
href = '#';
|
|
16
|
+
/** Link target */
|
|
17
|
+
target = '_blank';
|
|
18
|
+
/** Rel attribute — defaults to noopener noreferrer for _blank */
|
|
19
|
+
rel = '';
|
|
20
|
+
renderShareIcon() {
|
|
21
|
+
const icon = iconRegistry.iconRegistry['share'];
|
|
22
|
+
if (!icon)
|
|
23
|
+
return null;
|
|
24
|
+
const svg = `<svg width="16" height="16" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
|
|
25
|
+
return index.h("span", { class: "link__icon", innerHTML: svg });
|
|
26
|
+
}
|
|
27
|
+
render() {
|
|
28
|
+
const rel = this.rel || (this.target === '_blank' ? 'noopener noreferrer' : undefined);
|
|
29
|
+
return (index.h(index.Host, { key: '58a742b11ef7dcc1094031e804be6032311cea9d' }, index.h("span", { key: 'bf45468deb328c2d8ed70ac299d36968c16ababe', class: "link__label" }, this.label, index.h("slot", { key: 'bd43bc12d120ab806c895922ede0a08d4ec2f882' })), index.h("a", { key: 'b7c75a59bf18b1f1dc2e713b9e78c045afaa82e2', class: "link", href: this.href, target: this.target, rel: rel }, this.renderShareIcon())));
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
AiLink.style = aiLinkCss();
|
|
33
|
+
|
|
34
|
+
exports.ai_link = AiLink;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-DLJcLHFH.js');
|
|
4
|
+
var iconRegistry = require('./icon-registry-dmfLA-Dj.js');
|
|
5
|
+
|
|
6
|
+
const aiLoadingCss = () => `:host{display:block;direction:rtl}.icon-wrap{display:inline-flex;align-items:center;justify-content:center;line-height:0}.sparkle-avatar{width:24px;height:24px;border-radius:9999px;background:var(--ai-bg-card, #FCFCFC);box-shadow:inset 0px 0px 3px 1px rgba(18, 18, 23, 0.06);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--ai-amber)}.thinking-row{display:inline-flex;align-items:center;gap:8px;flex-direction:row}@keyframes shimmer{0%{background-position:200% center}100%{background-position:-200% center}}.shimmer-text{font-size:14px;font-weight:400;line-height:1.5;background:var(--ai-glow-gradient, linear-gradient(90deg, #737373 0%, #c5c5c5 50%, #737373 100%));background-size:200% auto;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;animation:shimmer 2s linear infinite}.steps-card{background:var(--ai-bg-card, #ffffff);border:1px solid var(--ai-border-default, #eeeeee);border-radius:16px;box-shadow:0px 1px 2px 0px rgba(18, 18, 23, 0.05);overflow:hidden}.steps-header{padding:16px;display:flex;align-items:center;gap:8px;border-bottom:1px solid var(--ai-border-default, #eeeeee)}.steps-header.collapsible{cursor:pointer;user-select:none}.steps-header-center{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.steps-title{font-size:16px;font-weight:500;color:var(--ai-text-primary, #333333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.progress-badge{font-size:12px;font-weight:500;color:var(--ai-accent-dark);background:var(--ai-accent-bg);padding:2px 8px;border-radius:9999px;white-space:nowrap;flex-shrink:0}.collapse-btn{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;padding:0;cursor:pointer;color:var(--ai-text-secondary, #737373);flex-shrink:0;transition:transform 0.2s ease;transform:rotate(180deg)}.collapse-btn.expanded{transform:rotate(0deg)}.steps-body{padding:12px 16px;display:flex;flex-direction:column}.step-row{display:flex;align-items:flex-start;gap:12px;cursor:pointer;padding:4px 0}.step-row:hover .step-text{color:var(--ai-text-primary, #333333)}.step-text{flex:1;font-size:14px;font-weight:400;color:var(--ai-text-secondary, #737373);line-height:1.5;padding-top:4px}.step-badge-col{display:flex;flex-direction:column;align-items:center;flex-shrink:0}.step-separator{width:1px;height:16px;background:var(--ai-border-default, #eeeeee);margin:2px 0}.step-badge-outer{padding:2px;border-radius:9999px;background:var(--ai-bg-surface, #f4f4f4);display:inline-flex;align-items:center;justify-content:center}.step-badge-inner{width:26px;height:26px;border-radius:9999px;background:var(--ai-bg-card, #ffffff);box-shadow:0px 0px 2px 1px rgba(18, 18, 23, 0.08);display:flex;align-items:center;justify-content:center;color:var(--ai-text-secondary, #737373)}.step-badge-inner.completed{background:var(--ai-success-bg);color:var(--ai-success-text)}.step-number{font-size:14px;font-weight:500;color:var(--ai-text-secondary, #737373);line-height:1}`;
|
|
7
|
+
|
|
8
|
+
const AiLoading = class {
|
|
9
|
+
constructor(hostRef) {
|
|
10
|
+
index.registerInstance(this, hostRef);
|
|
11
|
+
this.toggleExpand = index.createEvent(this, "toggleExpand");
|
|
12
|
+
this.stepClick = index.createEvent(this, "stepClick");
|
|
13
|
+
}
|
|
14
|
+
/** Main mode switch */
|
|
15
|
+
mode = 'thinking';
|
|
16
|
+
/** Thinking mode status text */
|
|
17
|
+
statusText = 'جاري التفكير...';
|
|
18
|
+
/** Steps as JSON string array of LoadingStep */
|
|
19
|
+
steps = '[]';
|
|
20
|
+
/** Steps mode title */
|
|
21
|
+
headerTitle = 'خطة التنفيذ';
|
|
22
|
+
/** Steps mode expand state */
|
|
23
|
+
expanded = true;
|
|
24
|
+
/** Whether steps card is collapsible */
|
|
25
|
+
collapsible = true;
|
|
26
|
+
toggleExpand;
|
|
27
|
+
stepClick;
|
|
28
|
+
_expanded = true;
|
|
29
|
+
componentWillLoad() {
|
|
30
|
+
this._expanded = this.expanded;
|
|
31
|
+
}
|
|
32
|
+
renderIcon(name, width, height) {
|
|
33
|
+
const icon = iconRegistry.iconRegistry[name];
|
|
34
|
+
if (!icon)
|
|
35
|
+
return null;
|
|
36
|
+
const svg = `<svg width="${width}" height="${height}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
|
|
37
|
+
return index.h("span", { class: "icon-wrap", innerHTML: svg });
|
|
38
|
+
}
|
|
39
|
+
renderSparkleAvatar() {
|
|
40
|
+
return index.h("div", { class: "sparkle-avatar" }, this.renderIcon('sparkle', 14, 14));
|
|
41
|
+
}
|
|
42
|
+
renderStepBadge(step, index$1) {
|
|
43
|
+
const isCompleted = step.status === 'completed';
|
|
44
|
+
return (index.h("div", { class: "step-badge-outer" }, index.h("div", { class: `step-badge-inner ${isCompleted ? 'completed' : ''}` }, isCompleted ? this.renderIcon('check', 14, 14) : index.h("span", { class: "step-number" }, index$1 + 1))));
|
|
45
|
+
}
|
|
46
|
+
getStepsList() {
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(this.steps) || [];
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
handleToggle() {
|
|
55
|
+
if (!this.collapsible)
|
|
56
|
+
return;
|
|
57
|
+
this._expanded = !this._expanded;
|
|
58
|
+
this.expanded = this._expanded;
|
|
59
|
+
this.toggleExpand.emit(this._expanded);
|
|
60
|
+
}
|
|
61
|
+
renderThinkingMode() {
|
|
62
|
+
return (index.h("div", { class: "thinking-row" }, this.renderSparkleAvatar(), index.h("span", { class: "shimmer-text" }, this.statusText)));
|
|
63
|
+
}
|
|
64
|
+
renderStepsMode() {
|
|
65
|
+
const stepsList = this.getStepsList();
|
|
66
|
+
const completedCount = stepsList.filter(s => s.status === 'completed').length;
|
|
67
|
+
const total = stepsList.length;
|
|
68
|
+
const allDone = total > 0 && completedCount === total;
|
|
69
|
+
return (index.h("div", { class: "steps-card" }, index.h("div", { class: `steps-header ${this.collapsible ? 'collapsible' : ''}`, onClick: () => this.handleToggle() }, this.renderSparkleAvatar(), index.h("div", { class: "steps-header-center" }, index.h("span", { class: "steps-title" }, this.headerTitle), total > 0 && index.h("span", { class: "progress-badge" }, allDone ? 'مكتمل' : `${completedCount}/${total}`)), this.collapsible && index.h("button", { class: `collapse-btn ${this._expanded ? 'expanded' : ''}` }, this.renderIcon('chevron-down', 20, 20))), this._expanded && stepsList.length > 0 && (index.h("div", { class: "steps-body" }, stepsList.map((step, i) => (index.h("div", { class: "step-row", onClick: () => this.stepClick.emit(step) }, index.h("div", { class: "step-badge-col" }, this.renderStepBadge(step, i), i < stepsList.length - 1 && index.h("div", { class: "step-separator" })), index.h("span", { class: "step-text" }, step.title))))))));
|
|
70
|
+
}
|
|
71
|
+
render() {
|
|
72
|
+
return index.h(index.Host, { key: '8a994758abe21c8a333088eeda498d158631bae6' }, this.mode === 'thinking' ? this.renderThinkingMode() : this.renderStepsMode());
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
AiLoading.style = aiLoadingCss();
|
|
76
|
+
|
|
77
|
+
exports.ai_loading = AiLoading;
|