@salla.sa/ui-ai-kit-core 1.1.0 → 2.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/dist/cjs/ai-card.cjs.entry.js +2 -2
  2. package/dist/cjs/ai-chat-container.cjs.entry.js +84 -57
  3. package/dist/cjs/ai-chat-header.cjs.entry.js +29 -19
  4. package/dist/cjs/ai-chat-message.cjs.entry.js +1456 -21
  5. package/dist/cjs/ai-conversation-list.cjs.entry.js +80 -0
  6. package/dist/cjs/ai-conversation-summary.cjs.entry.js +33 -0
  7. package/dist/cjs/ai-icon.cjs.entry.js +2 -2
  8. package/dist/cjs/ai-link.cjs.entry.js +4 -4
  9. package/dist/cjs/ai-loading.cjs.entry.js +35 -22
  10. package/dist/cjs/ai-message-input.cjs.entry.js +48 -15
  11. package/dist/cjs/ai-rating.cjs.entry.js +2 -2
  12. package/dist/cjs/ai-route-decision.cjs.entry.js +48 -0
  13. package/dist/cjs/ai-suggestion.cjs.entry.js +4 -4
  14. package/dist/cjs/ai-voice-input.cjs.entry.js +75 -21
  15. package/dist/cjs/{icon-registry-dmfLA-Dj.js → icon-registry-BKb9-2Nt.js} +24 -0
  16. package/dist/cjs/{index-DLJcLHFH.js → index-BkNg07SW.js} +1 -1
  17. package/dist/cjs/loader.cjs.js +2 -2
  18. package/dist/cjs/ui-ai-kit.cjs.js +2 -2
  19. package/dist/collection/collection-manifest.json +3 -0
  20. package/dist/collection/components/ai-card/ai-card.css +5 -8
  21. package/dist/collection/components/ai-chat-container/ai-chat-container.css +17 -14
  22. package/dist/collection/components/ai-chat-container/ai-chat-container.js +125 -53
  23. package/dist/collection/components/ai-chat-header/ai-chat-header.css +50 -17
  24. package/dist/collection/components/ai-chat-header/ai-chat-header.js +53 -18
  25. package/dist/collection/components/ai-chat-message/ai-chat-message.css +47 -38
  26. package/dist/collection/components/ai-chat-message/ai-chat-message.js +68 -18
  27. package/dist/collection/components/ai-conversation-list/ai-conversation-list.css +196 -0
  28. package/dist/collection/components/ai-conversation-list/ai-conversation-list.js +176 -0
  29. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.css +103 -0
  30. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.js +118 -0
  31. package/dist/collection/components/ai-icon/ai-icon.js +1 -1
  32. package/dist/collection/components/ai-link/ai-link.css +3 -7
  33. package/dist/collection/components/ai-link/ai-link.js +1 -1
  34. package/dist/collection/components/ai-loading/ai-loading.css +149 -20
  35. package/dist/collection/components/ai-loading/ai-loading.js +100 -23
  36. package/dist/collection/components/ai-message-input/ai-message-input.css +41 -37
  37. package/dist/collection/components/ai-message-input/ai-message-input.js +100 -19
  38. package/dist/collection/components/ai-rating/ai-rating.css +8 -14
  39. package/dist/collection/components/ai-route-decision/ai-route-decision.css +132 -0
  40. package/dist/collection/components/ai-route-decision/ai-route-decision.js +195 -0
  41. package/dist/collection/components/ai-suggestion/ai-suggestion.css +5 -11
  42. package/dist/collection/components/ai-suggestion/ai-suggestion.js +2 -2
  43. package/dist/collection/components/ai-voice-input/ai-voice-input.css +27 -22
  44. package/dist/collection/components/ai-voice-input/ai-voice-input.js +116 -20
  45. package/dist/collection/utils/icon-registry.js +24 -0
  46. package/dist/components/ai-card.js +1 -1
  47. package/dist/components/ai-chat-container.js +1 -1
  48. package/dist/components/ai-chat-header.js +1 -1
  49. package/dist/components/ai-chat-message.js +2 -1
  50. package/dist/components/ai-conversation-list.d.ts +11 -0
  51. package/dist/components/ai-conversation-list.js +1 -0
  52. package/dist/components/ai-conversation-summary.d.ts +11 -0
  53. package/dist/components/ai-conversation-summary.js +1 -0
  54. package/dist/components/ai-icon.js +1 -1
  55. package/dist/components/ai-link.js +1 -1
  56. package/dist/components/ai-loading.js +1 -1
  57. package/dist/components/ai-message-input.js +1 -1
  58. package/dist/components/ai-rating.js +1 -1
  59. package/dist/components/ai-route-decision.d.ts +11 -0
  60. package/dist/components/ai-route-decision.js +1 -0
  61. package/dist/components/ai-suggestion.js +1 -1
  62. package/dist/components/ai-voice-input.js +1 -1
  63. package/dist/components/index.js +1 -1
  64. package/dist/components/p-CX1Yp79q.js +1 -0
  65. package/dist/components/p-DnO4dikr.js +1 -0
  66. package/dist/components/{p-CY6emva2.js → p-Dr2tAPV7.js} +1 -1
  67. package/dist/{ui-ai-kit/p-DYv5ef4M.js → components/p-SJZ6Ujn9.js} +1 -1
  68. package/dist/esm/ai-card.entry.js +2 -2
  69. package/dist/esm/ai-chat-container.entry.js +84 -57
  70. package/dist/esm/ai-chat-header.entry.js +29 -19
  71. package/dist/esm/ai-chat-message.entry.js +1456 -21
  72. package/dist/esm/ai-conversation-list.entry.js +78 -0
  73. package/dist/esm/ai-conversation-summary.entry.js +31 -0
  74. package/dist/esm/ai-icon.entry.js +2 -2
  75. package/dist/esm/ai-link.entry.js +4 -4
  76. package/dist/esm/ai-loading.entry.js +35 -22
  77. package/dist/esm/ai-message-input.entry.js +48 -15
  78. package/dist/esm/ai-rating.entry.js +2 -2
  79. package/dist/esm/ai-route-decision.entry.js +46 -0
  80. package/dist/esm/ai-suggestion.entry.js +4 -4
  81. package/dist/esm/ai-voice-input.entry.js +75 -21
  82. package/dist/esm/{icon-registry-DYv5ef4M.js → icon-registry-SJZ6Ujn9.js} +24 -0
  83. package/dist/esm/{index-7hrZ8FOQ.js → index-B0yIzgh4.js} +1 -1
  84. package/dist/esm/loader.js +3 -3
  85. package/dist/esm/ui-ai-kit.js +3 -3
  86. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +11 -1
  87. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +7 -2
  88. package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +24 -0
  89. package/dist/types/components/ai-conversation-summary/ai-conversation-summary.d.ts +12 -0
  90. package/dist/types/components/ai-loading/ai-loading.d.ts +12 -6
  91. package/dist/types/components/ai-message-input/ai-message-input.d.ts +17 -3
  92. package/dist/types/components/ai-route-decision/ai-route-decision.d.ts +21 -0
  93. package/dist/types/components/ai-voice-input/ai-voice-input.d.ts +7 -0
  94. package/dist/types/components.d.ts +335 -11
  95. package/dist/types/index.d.ts +2 -0
  96. package/dist/types/utils/icon-registry.d.ts +1 -1
  97. package/dist/ui-ai-kit/p-2955439f.entry.js +1 -0
  98. package/dist/ui-ai-kit/p-5c9e9822.entry.js +1 -0
  99. package/dist/ui-ai-kit/p-5caf1c38.entry.js +1 -0
  100. package/dist/ui-ai-kit/p-74c5c83f.entry.js +1 -0
  101. package/dist/ui-ai-kit/p-76195745.entry.js +1 -0
  102. package/dist/ui-ai-kit/p-79c78d8e.entry.js +1 -0
  103. package/dist/ui-ai-kit/p-87e9739b.entry.js +1 -0
  104. package/dist/ui-ai-kit/p-9c4c6c01.entry.js +1 -0
  105. package/dist/ui-ai-kit/p-B0yIzgh4.js +2 -0
  106. package/dist/{components/p-DYv5ef4M.js → ui-ai-kit/p-SJZ6Ujn9.js} +1 -1
  107. package/dist/ui-ai-kit/p-a099fcfb.entry.js +1 -0
  108. package/dist/ui-ai-kit/p-b28af13a.entry.js +1 -0
  109. package/dist/ui-ai-kit/p-d1bb1ad0.entry.js +1 -0
  110. package/dist/ui-ai-kit/p-eb0c7e7a.entry.js +1 -0
  111. package/dist/ui-ai-kit/{p-455daa17.entry.js → p-eec6f083.entry.js} +1 -1
  112. package/dist/ui-ai-kit/p-ef07638f.entry.js +2 -0
  113. package/dist/ui-ai-kit/ui-ai-kit.css +1 -1
  114. package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -1
  115. package/package.json +5 -13
  116. package/dist/collection/components/ai-card/ai-card.stories.js +0 -52
  117. package/dist/collection/components/ai-chat-container/ai-chat-container.stories.js +0 -160
  118. package/dist/collection/components/ai-chat-header/ai-chat-header.stories.js +0 -138
  119. package/dist/collection/components/ai-chat-message/ai-chat-message.stories.js +0 -164
  120. package/dist/collection/components/ai-link/ai-link.stories.js +0 -79
  121. package/dist/collection/components/ai-loading/ai-loading.stories.js +0 -145
  122. package/dist/collection/components/ai-message-input/ai-message-input.stories.js +0 -125
  123. package/dist/collection/components/ai-rating/ai-rating.stories.js +0 -78
  124. package/dist/collection/components/ai-suggestion/ai-suggestion.stories.js +0 -62
  125. package/dist/collection/components/ai-voice-input/ai-voice-input.stories.js +0 -118
  126. package/dist/components/p-CWjXxYJI.js +0 -1
  127. package/dist/types/components/ai-card/ai-card.stories.d.ts +0 -7
  128. package/dist/types/components/ai-chat-container/ai-chat-container.stories.d.ts +0 -7
  129. package/dist/types/components/ai-chat-header/ai-chat-header.stories.d.ts +0 -8
  130. package/dist/types/components/ai-chat-message/ai-chat-message.stories.d.ts +0 -10
  131. package/dist/types/components/ai-link/ai-link.stories.d.ts +0 -8
  132. package/dist/types/components/ai-loading/ai-loading.stories.d.ts +0 -10
  133. package/dist/types/components/ai-message-input/ai-message-input.stories.d.ts +0 -13
  134. package/dist/types/components/ai-rating/ai-rating.stories.d.ts +0 -8
  135. package/dist/types/components/ai-suggestion/ai-suggestion.stories.d.ts +0 -8
  136. package/dist/types/components/ai-voice-input/ai-voice-input.stories.d.ts +0 -9
  137. package/dist/ui-ai-kit/p-11facfad.entry.js +0 -1
  138. package/dist/ui-ai-kit/p-128a2ed4.entry.js +0 -1
  139. package/dist/ui-ai-kit/p-227bdb8f.entry.js +0 -1
  140. package/dist/ui-ai-kit/p-56163e8c.entry.js +0 -1
  141. package/dist/ui-ai-kit/p-6d21d0fd.entry.js +0 -1
  142. package/dist/ui-ai-kit/p-6ddcd77b.entry.js +0 -1
  143. package/dist/ui-ai-kit/p-7hrZ8FOQ.js +0 -2
  144. package/dist/ui-ai-kit/p-8e90143e.entry.js +0 -1
  145. package/dist/ui-ai-kit/p-9938c277.entry.js +0 -1
  146. package/dist/ui-ai-kit/p-dc5b4a7f.entry.js +0 -1
  147. package/dist/ui-ai-kit/p-fb1702de.entry.js +0 -1
@@ -1,11 +1,8 @@
1
- import { r as registerInstance, a as getElement, h, H as Host } from './index-7hrZ8FOQ.js';
1
+ import { a as getElement, r as registerInstance, h, H as Host } from './index-B0yIzgh4.js';
2
2
 
3
- 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}`;
3
+ const aiChatContainerCss = () => `:host{display:contents}.chat-container{font-family:var(--ai-font-family);display:flex;flex-direction:column;overflow:hidden;position:relative;background-color:var(--ai-container-bg, var(--ai-bg-card));border:1px solid var(--ai-border-default);z-index:50;box-sizing:border-box}.messages-area{flex:1;overflow-y:auto;min-height:0;scrollbar-width:thin;padding:var(--ai-spacing-2xl, 16px);scrollbar-color:var(--ai-scrollbar-thumb) transparent}.messages-area::-webkit-scrollbar{width:3px}.messages-area::-webkit-scrollbar-track{background:transparent}.messages-area::-webkit-scrollbar-thumb{background:var(--ai-scrollbar-thumb);border-radius:99px}.messages-area::-webkit-scrollbar-thumb:hover{background:var(--ai-scrollbar-thumb-hover)}.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;border-radius:16px;box-shadow:var(--ai-shadow-float);opacity:0;pointer-events:none;transform:scale(0.95);transform-origin:bottom left;transition:opacity 200ms ease, transform 200ms ease}.chat-container.float.open{opacity:1;pointer-events:auto;transform:scale(1)}.watermark{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);pointer-events:none}.watermark ai-icon{opacity:0.8;filter:var(--ai-shadow-watermark)}.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}`;
4
4
 
5
5
  const ChatContainer = class {
6
- constructor(hostRef) {
7
- registerInstance(this, hostRef);
8
- }
9
6
  get el() { return getElement(this); }
10
7
  /** Controls visibility of the chat panel */
11
8
  isOpen = false;
@@ -19,32 +16,90 @@ const ChatContainer = class {
19
16
  showWatermark = false;
20
17
  /** Height of the panel when position='float' */
21
18
  floatHeight = '600px';
19
+ /** Color theme for the panel */
20
+ theme = 'light';
22
21
  isMobile = false;
22
+ floatLeft = '24px';
23
+ floatTop = '24px';
23
24
  containerRef;
25
+ messagesAreaRef;
24
26
  dragState = null;
25
- resizeObserver;
27
+ // Named arrow so we can reliably add/remove it without leaking
28
+ dragListener = (e) => {
29
+ const container = this.containerRef;
30
+ if (!container)
31
+ return;
32
+ const { clientX, clientY } = e.detail;
33
+ const rect = container.getBoundingClientRect();
34
+ this.dragState = {
35
+ startX: clientX,
36
+ startY: clientY,
37
+ initLeft: rect.left,
38
+ initTop: rect.top,
39
+ };
40
+ // Capture current rendered position into state so subsequent re-renders don't jump
41
+ this.floatLeft = `${rect.left}px`;
42
+ this.floatTop = `${rect.top}px`;
43
+ const onMove = (me) => {
44
+ if (!this.dragState)
45
+ return;
46
+ const dx = me.clientX - this.dragState.startX;
47
+ const dy = me.clientY - this.dragState.startY;
48
+ let newLeft = this.dragState.initLeft + dx;
49
+ let newTop = this.dragState.initTop + dy;
50
+ const vw = window.innerWidth;
51
+ const vh = window.innerHeight;
52
+ const w = container.offsetWidth;
53
+ const h = container.offsetHeight;
54
+ newLeft = Math.max(0, Math.min(newLeft, vw - w));
55
+ newTop = Math.max(0, Math.min(newTop, vh - h));
56
+ this.floatLeft = `${newLeft}px`;
57
+ this.floatTop = `${newTop}px`;
58
+ };
59
+ const onUp = () => {
60
+ this.dragState = null;
61
+ document.removeEventListener('pointermove', onMove);
62
+ document.removeEventListener('pointerup', onUp);
63
+ };
64
+ document.addEventListener('pointermove', onMove);
65
+ document.addEventListener('pointerup', onUp);
66
+ };
67
+ constructor(hostRef) {
68
+ registerInstance(this, hostRef);
69
+ // Bind so window.removeEventListener can match the reference
70
+ this.checkMobile = this.checkMobile.bind(this);
71
+ }
26
72
  componentWillLoad() {
27
73
  this.checkMobile();
28
74
  }
29
75
  componentDidLoad() {
30
76
  if (typeof window !== 'undefined') {
31
- this.resizeObserver = new ResizeObserver(() => {
32
- this.checkMobile();
33
- });
34
- this.resizeObserver.observe(document.body);
77
+ window.addEventListener('resize', this.checkMobile);
35
78
  if (this.position === 'float') {
36
79
  this.setupDrag();
37
80
  }
38
81
  }
39
82
  }
83
+ isOpenChanged(newVal) {
84
+ if (newVal && this.autoScroll && this.messagesAreaRef) {
85
+ requestAnimationFrame(() => {
86
+ this.messagesAreaRef.scrollTop = this.messagesAreaRef.scrollHeight;
87
+ });
88
+ }
89
+ }
40
90
  positionChanged(newVal) {
41
91
  if (newVal === 'float') {
42
92
  this.setupDrag();
43
93
  }
44
94
  }
45
95
  disconnectedCallback() {
46
- if (this.resizeObserver) {
47
- this.resizeObserver.disconnect();
96
+ window.removeEventListener('resize', this.checkMobile);
97
+ this.el.removeEventListener('headerDragStart', this.dragListener);
98
+ }
99
+ /** Programmatically scroll the messages area to the bottom */
100
+ async scrollToBottom() {
101
+ if (this.messagesAreaRef) {
102
+ this.messagesAreaRef.scrollTop = this.messagesAreaRef.scrollHeight;
48
103
  }
49
104
  }
50
105
  checkMobile() {
@@ -53,50 +108,9 @@ const ChatContainer = class {
53
108
  }
54
109
  }
55
110
  setupDrag() {
56
- const container = this.containerRef;
57
- if (!container)
58
- return;
59
- // Listen on the host element so composed events from ai-chat-header's shadow DOM
60
- // are received. (composedPath() hides cross-shadow-root elements from shadow listeners.)
61
- this.el.addEventListener('headerDragStart', (e) => {
62
- const { clientX, clientY } = e.detail;
63
- const rect = container.getBoundingClientRect();
64
- this.dragState = {
65
- startX: clientX,
66
- startY: clientY,
67
- initLeft: rect.left,
68
- initTop: rect.top,
69
- };
70
- // Switch from bottom/right anchoring to top/left so we can move freely
71
- container.style.right = 'auto';
72
- container.style.bottom = 'auto';
73
- container.style.left = `${rect.left}px`;
74
- container.style.top = `${rect.top}px`;
75
- const onMove = (me) => {
76
- if (!this.dragState)
77
- return;
78
- const dx = me.clientX - this.dragState.startX;
79
- const dy = me.clientY - this.dragState.startY;
80
- let newLeft = this.dragState.initLeft + dx;
81
- let newTop = this.dragState.initTop + dy;
82
- // Clamp to viewport edges
83
- const vw = window.innerWidth;
84
- const vh = window.innerHeight;
85
- const w = container.offsetWidth;
86
- const h = container.offsetHeight;
87
- newLeft = Math.max(0, Math.min(newLeft, vw - w));
88
- newTop = Math.max(0, Math.min(newTop, vh - h));
89
- container.style.left = `${newLeft}px`;
90
- container.style.top = `${newTop}px`;
91
- };
92
- const onUp = () => {
93
- this.dragState = null;
94
- document.removeEventListener('pointermove', onMove);
95
- document.removeEventListener('pointerup', onUp);
96
- };
97
- document.addEventListener('pointermove', onMove);
98
- document.addEventListener('pointerup', onUp);
99
- });
111
+ // Remove any existing listener before adding to prevent accumulation
112
+ this.el.removeEventListener('headerDragStart', this.dragListener);
113
+ this.el.addEventListener('headerDragStart', this.dragListener);
100
114
  }
101
115
  getContainerClasses() {
102
116
  const classes = ['chat-container', this.position];
@@ -116,16 +130,29 @@ const ChatContainer = class {
116
130
  if (this.position === 'float') {
117
131
  style.width = this.width;
118
132
  style.height = this.floatHeight;
133
+ style.left = this.floatLeft;
134
+ style.top = this.floatTop;
119
135
  }
120
136
  else {
121
137
  style.width = this.width;
122
138
  }
123
139
  return style;
124
140
  }
141
+ isDark() {
142
+ if (this.theme === 'dark')
143
+ return true;
144
+ if (this.theme === 'auto' && typeof window !== 'undefined') {
145
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
146
+ }
147
+ return false;
148
+ }
125
149
  render() {
126
- return (h(Host, { key: '5048010bf45a26985c92bfb9a6caf01d8aa938c0' }, h("div", { key: '08491cff2361071bc0635914cc665281b80321ac', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && (h("div", { key: '366140a61929689fc522dddfb1485bbd4d2cbef9', class: "watermark" }, h("ai-icon", { key: '5e210929feeb519889344385fa2fb75373ff8fed', name: "watermark", size: 133 }))), h("slot", { key: '57eef4d0c273009feeeb4f03400e05352acdf6cd', name: "header" }), h("div", { key: '15b14f49819f886ce1d56de87c770bb7241dcd77', class: "messages-area" }, h("slot", { key: '050cd0fde5bc3de75df0747031dc84214c125d5d' })), h("slot", { key: '195ab33291da775299e0d7c0c53df92fcf46a4ca', name: "footer" }))));
150
+ return (h(Host, { key: 'dd656127f6974b6eef12f64c78c072f2c1f92a6a', class: { dark: this.isDark() } }, h("div", { key: '0eb43bc5c8b80e5576146f01998e5279eb860162', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && (h("div", { key: '363046f0e73ab7aa0209d5f41562031fb34d6c2d', class: "watermark" }, h("ai-icon", { key: '1f3c26ba6a145f8532f6e1a40ea344249e8e5b43', name: "watermark", size: 133 }))), h("slot", { key: '3ec10548660ff721c094be36a15a152fdf6dac78', name: "header" }), h("div", { key: '9babb87041287ac400322b910aa64f7a7b1743a5', class: "messages-area", ref: el => (this.messagesAreaRef = el) }, h("slot", { key: '937c0c0bd675e5a619d46883e7c1f890754aae4b' })), h("slot", { key: '0982b8bc96537c6cecca757926d5849ba386bd69', name: "footer" }))));
127
151
  }
128
152
  static get watchers() { return {
153
+ "isOpen": [{
154
+ "isOpenChanged": 0
155
+ }],
129
156
  "position": [{
130
157
  "positionChanged": 0
131
158
  }]
@@ -1,7 +1,7 @@
1
- import { r as registerInstance, c as createEvent, h, H as Host } from './index-7hrZ8FOQ.js';
2
- import { i as iconRegistry } from './icon-registry-DYv5ef4M.js';
1
+ import { r as registerInstance, c as createEvent, h, H as Host } from './index-B0yIzgh4.js';
2
+ import { i as iconRegistry } from './icon-registry-SJZ6Ujn9.js';
3
3
 
4
- 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}`;
4
+ const aiChatHeaderCss = () => `:host{display:block}.header-container{display:flex;align-items:center;gap:8px;padding:16px;background:var(--ai-bg-card);border-bottom:1px solid var(--ai-border-light);width:100%;box-sizing:border-box}.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);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)}.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)}.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);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);object-fit:cover;display:block}.avatar-fallback{width:40px;height:40px;border-radius:9999px;border:1px solid var(--ai-border-default);background:var(--ai-bg-surface);color:var(--ai-text-primary);font-size:16px;font-weight:600;display:flex;align-items:center;justify-content:center;flex-shrink:0}.online-dot{position:absolute;bottom:0;inset-inline-end:0;width:10px;height:10px;display:inline-flex;align-items:center;justify-content:center;color:var(--ai-bg-card);}.online-dot.status-online{color:#22c55e;}.online-dot.status-offline{color:#9ca3af;}.online-dot.status-busy{color:#ef4444;}.online-dot.status-away{color:#f59e0b;}.text-block{display:flex;flex-direction:column;align-items:flex-start;gap:0;flex-shrink:0}.agent-name{font-size:14px;font-weight:500;color:var(--ai-text-primary);line-height:20px;white-space:nowrap}.agent-status{font-size:14px;font-weight:400;color:var(--ai-text-secondary);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}:host-context([dir='ltr']) .back-btn .icon-wrap,:host([dir='ltr']) .back-btn .icon-wrap{transform:scaleX(-1)}`;
5
5
 
6
6
  const AiChatHeader = class {
7
7
  constructor(hostRef) {
@@ -9,7 +9,7 @@ const AiChatHeader = class {
9
9
  this.closeClick = createEvent(this, "closeClick");
10
10
  this.editClick = createEvent(this, "editClick");
11
11
  this.dropdownClick = createEvent(this, "dropdownClick");
12
- this.moreClick = createEvent(this, "moreClick");
12
+ this.positionClick = createEvent(this, "positionClick");
13
13
  this.backClick = createEvent(this, "backClick");
14
14
  this.headerDragStart = createEvent(this, "headerDragStart");
15
15
  }
@@ -26,14 +26,17 @@ const AiChatHeader = class {
26
26
  /** Human mode: show the back button */
27
27
  showBack = true;
28
28
  isDraggable = false;
29
+ /** Human mode: status indicator variant */
30
+ statusIndicator = 'online';
31
+ avatarError = false;
29
32
  /** Cancel / close button */
30
33
  closeClick;
31
34
  /** Pencil-edit button (agent mode) */
32
35
  editClick;
33
36
  /** Title / chevron click → open conversation list (agent mode) */
34
37
  dropdownClick;
35
- /** Chevron-down button (human mode) */
36
- moreClick;
38
+ /** More options button */
39
+ positionClick;
37
40
  /** Back-arrow button (human mode) */
38
41
  backClick;
39
42
  /**
@@ -48,28 +51,35 @@ const AiChatHeader = class {
48
51
  const svg = `<svg width="${width}" height="${height}" viewBox="${icon.viewBox}" fill="none" xmlns="http://www.w3.org/2000/svg">${icon.content}</svg>`;
49
52
  return h("span", { class: "icon-wrap", innerHTML: svg });
50
53
  }
54
+ renderAvatar() {
55
+ const fallbackLetter = this.agentName ? this.agentName.charAt(0) : '?';
56
+ if (!this.agentAvatar || this.avatarError) {
57
+ return h("div", { class: "avatar-fallback" }, fallbackLetter);
58
+ }
59
+ return (h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName, onError: () => { this.avatarError = true; } }));
60
+ }
61
+ renderDragBtn() {
62
+ return this.isDraggable && (h("button", { class: "action-btn drag-btn", "aria-label": "\u0633\u062D\u0628 / Drag", onPointerDown: (e) => {
63
+ e.preventDefault();
64
+ this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
65
+ } }, this.renderIcon('drag', 11, 15)));
66
+ }
51
67
  renderAgentMode() {
52
68
  return [
53
- this.isDraggable && (h("button", { class: "action-btn drag-btn", onPointerDown: (e) => {
54
- e.preventDefault();
55
- this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
56
- } }, this.renderIcon('drag', 11, 15))),
57
- h("div", { class: "content agent" }, h("span", { class: "title" }, this.conversation), h("button", { class: "dropdown-trigger", onClick: () => this.dropdownClick.emit() }, this.renderIcon('chevron-down', 24, 24))),
58
- h("div", { class: "actions" }, h("button", { class: "action-btn", onClick: () => this.editClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), h("button", { class: "action-btn", onClick: () => this.moreClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
69
+ this.renderDragBtn(),
70
+ h("div", { class: "content agent dropdown-trigger", role: "button", onClick: () => this.dropdownClick.emit(), "aria-haspopup": "listbox", "aria-expanded": false, "aria-label": `${this.conversation}, افتح قائمة المحادثات` }, h("span", { class: "title" }, this.conversation), h("span", { class: "dropdown-chevron" }, this.renderIcon('chevron-down', 24, 24))),
71
+ h("div", { class: "actions" }, h("button", { class: "action-btn", "aria-label": "\u062A\u0639\u062F\u064A\u0644 / Edit", onClick: () => this.editClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
59
72
  ];
60
73
  }
61
74
  renderHumanMode() {
62
75
  return [
63
- this.isDraggable && (h("button", { class: "action-btn drag-btn", onPointerDown: (e) => {
64
- e.preventDefault();
65
- this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
66
- } }, this.renderIcon('drag', 11, 15))),
67
- h("div", { class: "content human" }, this.showBack && (h("button", { class: "back-btn", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24))), h("div", { class: "avatar-wrapper" }, h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName }), h("span", { class: "online-dot" }, this.renderIcon('online-dot', 10, 10))), h("div", { class: "text-block" }, h("span", { class: "agent-name" }, this.agentName), h("span", { class: "agent-status" }, this.agentStatus))),
68
- h("div", { class: "actions" }, h("button", { class: "action-btn", onClick: () => this.moreClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
76
+ this.renderDragBtn(),
77
+ h("div", { class: "content human" }, this.showBack && (h("button", { class: "back-btn", "aria-label": "\u0631\u062C\u0648\u0639 / Back", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24))), h("div", { class: "avatar-wrapper" }, this.renderAvatar(), h("span", { class: `online-dot status-${this.statusIndicator}` }, this.renderIcon('online-dot', 10, 10))), h("div", { class: "text-block" }, h("span", { class: "agent-name" }, this.agentName), this.agentStatus && h("span", { class: "agent-status" }, this.agentStatus))),
78
+ h("div", { class: "actions" }, h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
69
79
  ];
70
80
  }
71
81
  render() {
72
- return (h(Host, { key: '93fe332abe1339f7235aa18717d63aa65d9aac13' }, h("div", { key: 'b496695911f7d1f959c4f98506b0d230e77a86c3', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.renderHumanMode())));
82
+ return (h(Host, { key: 'f96f4d5c533747b2843706c165866769b834fb98' }, h("div", { key: '8643a8cb214cbe40f0ee1a0b64c483829b5de6c9', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.renderHumanMode())));
73
83
  }
74
84
  };
75
85
  AiChatHeader.style = aiChatHeaderCss();