@salla.sa/ui-ai-kit-core 2.1.1 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/cjs/ai-agent-error.cjs.entry.js +3 -3
  2. package/dist/cjs/ai-card.cjs.entry.js +3 -3
  3. package/dist/cjs/ai-chat-container.cjs.entry.js +89 -14
  4. package/dist/cjs/ai-chat-header.cjs.entry.js +114 -14
  5. package/dist/cjs/ai-chat-message.cjs.entry.js +10 -4
  6. package/dist/cjs/ai-conversation-list.cjs.entry.js +37 -12
  7. package/dist/cjs/ai-conversation-summary.cjs.entry.js +3 -3
  8. package/dist/cjs/ai-icon.cjs.entry.js +2 -2
  9. package/dist/cjs/ai-in-chat-browser.cjs.entry.js +50 -0
  10. package/dist/cjs/ai-link.cjs.entry.js +3 -3
  11. package/dist/cjs/ai-loading.cjs.entry.js +3 -3
  12. package/dist/cjs/ai-message-input.cjs.entry.js +12 -7
  13. package/dist/cjs/ai-rating.cjs.entry.js +26 -18
  14. package/dist/cjs/ai-route-decision.cjs.entry.js +3 -3
  15. package/dist/cjs/ai-suggestion.cjs.entry.js +3 -3
  16. package/dist/cjs/ai-voice-input.cjs.entry.js +2 -2
  17. package/dist/cjs/icon-registry-D-m8GW4D.js +126 -0
  18. package/dist/cjs/{index-Bs23yVuF.js → index-Cc05u4ND.js} +86 -1
  19. package/dist/cjs/loader.cjs.js +2 -2
  20. package/dist/cjs/ui-ai-kit.cjs.js +2 -2
  21. package/dist/collection/collection-manifest.json +2 -1
  22. package/dist/collection/components/ai-agent-error/ai-agent-error.js +1 -1
  23. package/dist/collection/components/ai-card/ai-card.js +2 -2
  24. package/dist/collection/components/ai-chat-container/ai-chat-container.css +175 -3
  25. package/dist/collection/components/ai-chat-container/ai-chat-container.js +263 -16
  26. package/dist/collection/components/ai-chat-header/ai-chat-header.css +98 -0
  27. package/dist/collection/components/ai-chat-header/ai-chat-header.js +298 -26
  28. package/dist/collection/components/ai-chat-message/ai-chat-message.js +8 -2
  29. package/dist/collection/components/ai-conversation-list/ai-conversation-list.css +116 -7
  30. package/dist/collection/components/ai-conversation-list/ai-conversation-list.js +128 -9
  31. package/dist/collection/components/ai-conversation-summary/ai-conversation-summary.js +1 -1
  32. package/dist/collection/components/ai-icon/ai-icon.js +1 -1
  33. package/dist/collection/components/ai-in-chat-browser/ai-in-chat-browser.css +78 -0
  34. package/dist/collection/components/ai-in-chat-browser/ai-in-chat-browser.js +102 -0
  35. package/dist/collection/components/ai-link/ai-link.js +1 -1
  36. package/dist/collection/components/ai-loading/ai-loading.js +1 -1
  37. package/dist/collection/components/ai-message-input/ai-message-input.css +46 -5
  38. package/dist/collection/components/ai-message-input/ai-message-input.js +10 -5
  39. package/dist/collection/components/ai-rating/ai-rating.css +22 -2
  40. package/dist/collection/components/ai-rating/ai-rating.js +46 -17
  41. package/dist/collection/components/ai-route-decision/ai-route-decision.js +1 -1
  42. package/dist/collection/components/ai-suggestion/ai-suggestion.js +2 -2
  43. package/dist/collection/components/ai-voice-input/ai-voice-input.js +1 -1
  44. package/dist/collection/utils/icon-registry.js +27 -7
  45. package/dist/components/ai-agent-error.js +1 -1
  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 -2
  50. package/dist/components/ai-conversation-list.js +1 -1
  51. package/dist/components/ai-conversation-summary.js +1 -1
  52. package/dist/components/ai-icon.js +1 -1
  53. package/dist/components/ai-in-chat-browser.d.ts +11 -0
  54. package/dist/components/ai-in-chat-browser.js +1 -0
  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.js +1 -1
  60. package/dist/components/ai-suggestion.js +1 -1
  61. package/dist/components/ai-voice-input.js +1 -1
  62. package/dist/components/index.js +1 -1
  63. package/dist/components/p-BPkf7wZg.js +1 -0
  64. package/dist/components/p-Ba0urr6Q.js +1 -0
  65. package/dist/components/p-CJzVwMlS.js +1 -0
  66. package/dist/components/{p-Bbmjx9lq.js → p-DZuBxUde.js} +1 -1
  67. package/dist/components/p-DlD8m3rf.js +1 -0
  68. package/dist/components/{p-C5gkZloN.js → p-bGFmyIp1.js} +1 -1
  69. package/dist/esm/ai-agent-error.entry.js +3 -3
  70. package/dist/esm/ai-card.entry.js +3 -3
  71. package/dist/esm/ai-chat-container.entry.js +89 -14
  72. package/dist/esm/ai-chat-header.entry.js +114 -14
  73. package/dist/esm/ai-chat-message.entry.js +10 -4
  74. package/dist/esm/ai-conversation-list.entry.js +37 -12
  75. package/dist/esm/ai-conversation-summary.entry.js +3 -3
  76. package/dist/esm/ai-icon.entry.js +2 -2
  77. package/dist/esm/ai-in-chat-browser.entry.js +48 -0
  78. package/dist/esm/ai-link.entry.js +3 -3
  79. package/dist/esm/ai-loading.entry.js +3 -3
  80. package/dist/esm/ai-message-input.entry.js +12 -7
  81. package/dist/esm/ai-rating.entry.js +26 -18
  82. package/dist/esm/ai-route-decision.entry.js +3 -3
  83. package/dist/esm/ai-suggestion.entry.js +3 -3
  84. package/dist/esm/ai-voice-input.entry.js +2 -2
  85. package/dist/esm/icon-registry-DlD8m3rf.js +124 -0
  86. package/dist/esm/{index-hxWjzqcH.js → index-VMEwYfaX.js} +86 -1
  87. package/dist/esm/loader.js +3 -3
  88. package/dist/esm/ui-ai-kit.js +3 -3
  89. package/dist/types/components/ai-chat-container/ai-chat-container.d.ts +38 -2
  90. package/dist/types/components/ai-chat-header/ai-chat-header.d.ts +41 -4
  91. package/dist/types/components/ai-conversation-list/ai-conversation-list.d.ts +11 -0
  92. package/dist/types/components/ai-in-chat-browser/ai-in-chat-browser.d.ts +13 -0
  93. package/dist/types/components/ai-rating/ai-rating.d.ts +4 -1
  94. package/dist/types/components.d.ts +275 -18
  95. package/dist/types/index.d.ts +1 -0
  96. package/dist/types/utils/icon-registry.d.ts +1 -1
  97. package/dist/ui-ai-kit/{p-889c6b00.entry.js → p-062cad02.entry.js} +1 -1
  98. package/dist/ui-ai-kit/{p-27bf454d.entry.js → p-187db371.entry.js} +1 -1
  99. package/dist/ui-ai-kit/p-1b247096.entry.js +1 -0
  100. package/dist/ui-ai-kit/p-338d55d3.entry.js +1 -0
  101. package/dist/ui-ai-kit/{p-210b11dc.entry.js → p-4359a116.entry.js} +1 -1
  102. package/dist/ui-ai-kit/{p-ccaec7b4.entry.js → p-5f005ec5.entry.js} +1 -1
  103. package/dist/ui-ai-kit/p-6a4b66ed.entry.js +1 -0
  104. package/dist/ui-ai-kit/{p-5ea933a4.entry.js → p-6b644d32.entry.js} +1 -1
  105. package/dist/ui-ai-kit/{p-b33e92ea.entry.js → p-6bd54e29.entry.js} +1 -1
  106. package/dist/ui-ai-kit/{p-0da537b1.entry.js → p-83f46030.entry.js} +2 -2
  107. package/dist/ui-ai-kit/p-8ac8febb.entry.js +1 -0
  108. package/dist/ui-ai-kit/{p-72c6e3d1.entry.js → p-8fabdbe8.entry.js} +1 -1
  109. package/dist/ui-ai-kit/p-953d4348.entry.js +1 -0
  110. package/dist/ui-ai-kit/p-DlD8m3rf.js +1 -0
  111. package/dist/ui-ai-kit/p-VMEwYfaX.js +2 -0
  112. package/dist/ui-ai-kit/{p-cf6caba5.entry.js → p-cae762e0.entry.js} +1 -1
  113. package/dist/ui-ai-kit/p-d02f2db5.entry.js +1 -0
  114. package/dist/ui-ai-kit/{p-999dd7c8.entry.js → p-e6236df2.entry.js} +1 -1
  115. package/dist/ui-ai-kit/ui-ai-kit.css +1 -1
  116. package/dist/ui-ai-kit/ui-ai-kit.esm.js +1 -1
  117. package/package.json +1 -1
  118. package/dist/cjs/icon-registry-BKb9-2Nt.js +0 -106
  119. package/dist/components/p-CAnlgwx0.js +0 -1
  120. package/dist/components/p-SJZ6Ujn9.js +0 -1
  121. package/dist/esm/icon-registry-SJZ6Ujn9.js +0 -104
  122. package/dist/ui-ai-kit/p-1cce63d4.entry.js +0 -1
  123. package/dist/ui-ai-kit/p-70836960.entry.js +0 -1
  124. package/dist/ui-ai-kit/p-8f721843.entry.js +0 -1
  125. package/dist/ui-ai-kit/p-95b50b7b.entry.js +0 -1
  126. package/dist/ui-ai-kit/p-SJZ6Ujn9.js +0 -1
  127. package/dist/ui-ai-kit/p-c9ec615f.entry.js +0 -1
  128. package/dist/ui-ai-kit/p-hxWjzqcH.js +0 -2
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
4
- var iconRegistry = require('./icon-registry-BKb9-2Nt.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
+ var iconRegistry = require('./icon-registry-D-m8GW4D.js');
5
5
 
6
6
  const aiAgentErrorCss = () => `:host{display:block}.icon-wrap{display:inline-flex;align-items:center;justify-content:center;line-height:0}@keyframes fade-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.error-card{background:var(--ai-danger-bg);border:1px solid var(--ai-danger-border);border-radius:16px;box-shadow:var(--ai-shadow-error);overflow:hidden;animation:fade-in 0.3s ease}.error-body{display:flex;align-items:flex-start;gap:12px;padding:16px}.error-icon-wrap{width:36px;height:36px;border-radius:9999px;background:var(--ai-bg-card);border:1px solid var(--ai-danger-border);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--ai-danger-text)}.error-content{flex:1;display:flex;flex-direction:column;gap:6px;min-width:0}.error-headline-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.error-headline{font-size:14px;font-weight:600;color:var(--ai-danger-text);line-height:1.4}.error-code-badge{font-size:11px;font-weight:500;color:var(--ai-danger-text);background:var(--ai-bg-card);border:1px solid var(--ai-danger-border);padding:1px 7px;border-radius:9999px;white-space:nowrap;flex-shrink:0;opacity:0.85}.error-message{margin:0;font-size:13px;font-weight:400;color:var(--ai-text-secondary);line-height:1.5}.dismiss-btn{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;padding:4px;cursor:pointer;color:var(--ai-danger-text);opacity:0.6;flex-shrink:0;border-radius:6px;transition:opacity 0.15s ease, background 0.15s ease}.dismiss-btn:hover{opacity:1;background:var(--ai-hover-overlay)}.error-footer{padding:0 16px 14px}.retry-btn{display:inline-flex;align-items:center;gap:6px;background:var(--ai-bg-card);border:1px solid var(--ai-danger-border);border-radius:9999px;padding:6px 14px;font-size:13px;font-weight:500;color:var(--ai-danger-text);cursor:pointer;transition:box-shadow 0.15s ease, opacity 0.15s ease;font-family:inherit}.retry-btn:hover{box-shadow:var(--ai-shadow-active);opacity:0.9}.retry-btn:active{opacity:0.75}`;
7
7
 
@@ -33,7 +33,7 @@ const AiAgentError = class {
33
33
  return index.h("span", { class: "icon-wrap", innerHTML: svg });
34
34
  }
35
35
  render() {
36
- return (index.h(index.Host, { key: '0376a351dfcff6612ddbbf9ec38afd90b51e4a42' }, index.h("div", { key: '4085f93755a8cd3b74ec182ebe510bb8a6626133', class: "error-card" }, index.h("div", { key: '61d42da5ed3d8bbc69cd9604e600437fc241edb0', class: "error-body" }, index.h("div", { key: '0d98c6ad7bfc320164ba5308b8f1f8f5557eccf2', class: "error-icon-wrap" }, this.renderIcon('warning', 20, 20)), index.h("div", { key: '7b75d807a6227d335b26965cd959471c7ae8f20b', class: "error-content" }, index.h("div", { key: 'd46f618bb685bb3ce20ba11fb59f524e4ffe6238', class: "error-headline-row" }, index.h("span", { key: '6ee0b1d651d6a037073e6ad8917b2fe5495d0ee0', class: "error-headline" }, this.headline), this.errorCode && (index.h("span", { key: 'b541eee2462ff33791e3975102841845297335d4', class: "error-code-badge" }, this.errorCode))), this.message && (index.h("p", { key: '34d133731a7512ebe16a873bf52eb97120463335', class: "error-message" }, this.message))), this.dismissible && (index.h("button", { key: '0e3bc48998e3e7e2379557e2c6c7503d5c021a42', class: "dismiss-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642", onClick: () => this.dismissClick.emit() }, this.renderIcon('cancel', 16, 16)))), this.retryable && (index.h("div", { key: 'f1865b3e69d946be9833943b66e1b8de046d343d', class: "error-footer" }, index.h("button", { key: '11c72fbbfbaabf60e5da178ac07177185c0046b8', class: "retry-btn", onClick: () => this.retryClick.emit() }, this.renderIcon('reload', 16, 16), index.h("span", { key: 'fafdec1b9bc0aa727ada94d011bd1e66da53df0e' }, this.retryLabel)))))));
36
+ return (index.h(index.Host, { key: '5cab52b708c10b0cfec5fdd0dfdc85046a7426a2' }, index.h("div", { key: 'b4691b7dfd9cbb98e522af9ed5ad2d2b912471fb', class: "error-card" }, index.h("div", { key: 'e8f5fb9ca5fda7f4cedf09bb4dc9848303d4a339', class: "error-body" }, index.h("div", { key: 'b1f2e61a60fa4a3fba6a98dc67f3531f9164b662', class: "error-icon-wrap" }, this.renderIcon('warning', 20, 20)), index.h("div", { key: 'a1e2e6f6096ed6e593e60eadfd792b11b7b117cd', class: "error-content" }, index.h("div", { key: '5eea71440e7b817732c3aab465f2710a2b198b1a', class: "error-headline-row" }, index.h("span", { key: '61b90ef0186837770ce10642257ee2ea5f1f6c9d', class: "error-headline" }, this.headline), this.errorCode && (index.h("span", { key: '12305a917ae3b479340533335203455c48d1bb24', class: "error-code-badge" }, this.errorCode))), this.message && (index.h("p", { key: 'f400a76fbd2caac0b64799914b9938de3e9eb78c', class: "error-message" }, this.message))), this.dismissible && (index.h("button", { key: 'f2fa1b1fb86fad249404e5b66ba72f2937c4eb67', class: "dismiss-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642", onClick: () => this.dismissClick.emit() }, this.renderIcon('cancel', 16, 16)))), this.retryable && (index.h("div", { key: 'd2c1f2190383345c6101e70b1499e05d59092653', class: "error-footer" }, index.h("button", { key: '7f8b52b0ac1e2dd4dd4244949e0da9874077f284', class: "retry-btn", onClick: () => this.retryClick.emit() }, this.renderIcon('reload', 16, 16), index.h("span", { key: '321d51fd3b36f23b7e49b05af3ab85346f87f44f' }, this.retryLabel)))))));
37
37
  }
38
38
  };
39
39
  AiAgentError.style = aiAgentErrorCss();
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
4
 
5
5
  const aiCardCss = () => `:host{--ai-card-border:1px solid var(--ai-border-default);--ai-card-radius:16px;--ai-card-padding:16px;--ai-card-gap:12px;--ai-card-shadow:var(--ai-shadow-sm);display:block}.card{background:var(--ai-bg-card);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-primary);width:100%;display:flex;flex-direction:column;gap:var(--ai-card-gap);text-align:start;font-size:14px;line-height:20px}.card--no-padding{padding:0}.card--no-shadow{box-shadow:none}`;
6
6
 
@@ -13,11 +13,11 @@ const AiCard = class {
13
13
  /** Remove the shadow */
14
14
  noShadow = false;
15
15
  render() {
16
- return (index.h(index.Host, { key: 'b9af2e825faa2dc3ba5a0c145a9c9399a75e048a' }, index.h("div", { key: 'f698c538583908fc84f4987e574c9f6740047791', class: {
16
+ return (index.h(index.Host, { key: '849dbf8d8eac913c76e71a10cb9b30f9fda3c320' }, index.h("div", { key: '5d9f75428e6d94cf2c3729698e87fd3185c20129', class: {
17
17
  card: true,
18
18
  'card--no-padding': this.noPadding,
19
19
  'card--no-shadow': this.noShadow,
20
- } }, index.h("slot", { key: '8012eba0a43945d4354f51f97badf87df072e0ea' }))));
20
+ } }, index.h("slot", { key: 'f604568228c02514ff0f569cfa4fd706c247652e' }))));
21
21
  }
22
22
  };
23
23
  AiCard.style = aiCardCss();
@@ -1,15 +1,20 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
4
 
5
- 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:var(--ai-watermark-opacity, 0.8);filter:var(--ai-watermark-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}}`;
5
+ 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;width:133px;height:133px}.watermark .watermark-circle-svg{position:absolute;top:0;left:0}.watermark .watermark-star-svg{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%)}.watermark .watermark-circle{fill:var(--ai-watermark-circle, #FCFCFC)}.watermark .watermark-star{fill:var(--ai-watermark-star, #FAFAFA)}:host(.dark) .watermark .watermark-circle{fill:var(--ai-watermark-circle, #222222)}:host(.dark) .watermark .watermark-star{fill:var(--ai-watermark-star, #292B2C)}.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}}@keyframes skeleton-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}.skeleton-messages{display:flex;flex-direction:column;gap:20px;padding:8px 0}.skeleton-row{display:flex;align-items:flex-start;gap:10px}.skeleton-row.agent{flex-direction:row}.skeleton-row.user{flex-direction:row-reverse}.skeleton-avatar{width:32px;height:32px;min-width:32px;border-radius:50%;background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(0,0,0,0.06) 25%, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.06) 75%));background-size:200% 100%;animation:skeleton-shimmer 1.6s ease-in-out infinite}.skeleton-bubble{display:flex;flex-direction:column;gap:8px;padding:14px 16px;border-radius:16px;background-color:var(--ai-bg-surface, #f9fafb);max-width:75%;min-width:120px}.skeleton-row.user .skeleton-bubble{background-color:var(--ai-user-bubble-bg, var(--ai-accent, #004956));border-radius:16px}.skeleton-line{height:12px;border-radius:6px;background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(0,0,0,0.06) 25%, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.06) 75%));background-size:200% 100%;animation:skeleton-shimmer 1.6s ease-in-out infinite}.skeleton-row.user .skeleton-line{background:linear-gradient(90deg, rgba(255,255,255,0.08) 25%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.08) 75%);background-size:200% 100%;animation:skeleton-shimmer 1.6s ease-in-out infinite}:host(.dark) .skeleton-avatar{background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(255,255,255,0.06) 25%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.06) 75%));background-size:200% 100%;animation:skeleton-shimmer 1.6s ease-in-out infinite}:host(.dark) .skeleton-bubble{background-color:var(--ai-bg-surface, #1f2937)}:host(.dark) .skeleton-line{background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(255,255,255,0.06) 25%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.06) 75%));background-size:200% 100%;animation:skeleton-shimmer 1.6s ease-in-out infinite}.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:12px;padding:48px 24px;flex:1}.error-icon{color:var(--ai-text-muted, #9ca3af);opacity:0.7}.error-text{margin:0;font-size:14px;line-height:1.5;color:var(--ai-text-secondary, #6b7280)}.error-retry-btn{display:inline-flex;align-items:center;justify-content:center;padding:8px 20px;border-radius:9999px;border:1px solid var(--ai-border-default);background-color:var(--ai-bg-surface, #f9fafb);color:var(--ai-text-primary);font-size:13px;font-weight:500;font-family:inherit;cursor:pointer;transition:background-color 0.15s ease, border-color 0.15s ease}.error-retry-btn:hover{background-color:var(--ai-hover-overlay, rgba(0, 0, 0, 0.04));border-color:var(--ai-accent, #004956)}.error-retry-btn:focus-visible{outline:2px solid var(--ai-focus-ring-color, var(--ai-focus-ring));outline-offset:2px}:host(.dark) .error-retry-btn{background-color:var(--ai-bg-surface, #1f2937);color:var(--ai-text-primary, #f9fafb)}:host(.dark) .error-retry-btn:hover{background-color:var(--ai-hover-overlay, rgba(255, 255, 255, 0.06))}`;
6
6
 
7
7
  const ChatContainer = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.retryClick = index.createEvent(this, "retryClick");
11
+ this.positionChange = index.createEvent(this, "positionChange");
12
+ }
8
13
  get el() { return index.getElement(this); }
9
14
  /** Controls visibility of the chat panel */
10
15
  isOpen = false;
11
16
  /** Position of the panel: 'left', 'right', or 'float' */
12
- position = 'right';
17
+ position = 'left';
13
18
  /** Width of the panel (CSS value, e.g., '400px', '30%', '28rem') */
14
19
  width = '28rem';
15
20
  /** Enable/disable auto-scroll to latest message */
@@ -20,6 +25,24 @@ const ChatContainer = class {
20
25
  floatHeight = '600px';
21
26
  /** Color theme for the panel */
22
27
  theme = 'light';
28
+ /** Show skeleton loading state (e.g. while loading conversation history) */
29
+ loading = false;
30
+ /** Show error state (e.g. failed to load conversation) */
31
+ error = false;
32
+ /** Error message text */
33
+ errorText = 'تعذّر تحميل المحادثة';
34
+ /** Retry button label */
35
+ retryLabel = 'إعادة المحاولة';
36
+ /**
37
+ * Layout direction set by the host app.
38
+ * - `'rtl'` → valid docked position is `left`; cycle order: left ↔ float
39
+ * - `'ltr'` → valid docked position is `right`; cycle order: right ↔ float
40
+ */
41
+ direction = 'rtl';
42
+ /** Event emitted when the retry button is clicked */
43
+ retryClick;
44
+ /** Fired when the position changes (via cyclePosition or the header button) */
45
+ positionChange;
23
46
  isMobile = false;
24
47
  floatLeft = '24px';
25
48
  floatTop = '24px';
@@ -27,8 +50,11 @@ const ChatContainer = class {
27
50
  messagesAreaRef;
28
51
  dragState = null;
29
52
  mutationObserver = null;
53
+ resizeObserver = null;
30
54
  // Named arrow so we can reliably add/remove it without leaking
31
55
  dragListener = (e) => {
56
+ if (typeof window === 'undefined')
57
+ return;
32
58
  const container = this.containerRef;
33
59
  if (!container)
34
60
  return;
@@ -67,20 +93,31 @@ const ChatContainer = class {
67
93
  document.addEventListener('pointermove', onMove);
68
94
  document.addEventListener('pointerup', onUp);
69
95
  };
70
- constructor(hostRef) {
71
- index.registerInstance(this, hostRef);
72
- // Bind so window.removeEventListener can match the reference
73
- this.checkMobile = this.checkMobile.bind(this);
96
+ /**
97
+ * Listen for the composed headerPositionClick event fired by ai-chat-header.
98
+ * Automatically cycles the position so the host app doesn't need to wire it manually.
99
+ */
100
+ handleHeaderPositionClick() {
101
+ this.cyclePosition();
74
102
  }
75
103
  componentWillLoad() {
76
104
  this.checkMobile();
77
105
  }
78
106
  componentDidLoad() {
79
- if (typeof window !== 'undefined') {
80
- window.addEventListener('resize', this.checkMobile);
81
- if (this.position === 'float') {
82
- this.setupDrag();
83
- }
107
+ if (typeof window === 'undefined')
108
+ return;
109
+ // Use ResizeObserver for responsive mobile detection instead of window.resize
110
+ if (typeof ResizeObserver !== 'undefined') {
111
+ this.resizeObserver = new ResizeObserver(() => {
112
+ this.checkMobile();
113
+ this.clampFloatPosition();
114
+ });
115
+ this.resizeObserver.observe(this.el);
116
+ }
117
+ // Also listen to window resize for viewport changes (e.g. browser resize)
118
+ window.addEventListener('resize', this.handleWindowResize);
119
+ if (this.position === 'float') {
120
+ this.setupDrag();
84
121
  }
85
122
  this.mutationObserver = new MutationObserver(() => {
86
123
  if (this.autoScroll && this.messagesAreaRef) {
@@ -105,9 +142,12 @@ const ChatContainer = class {
105
142
  }
106
143
  }
107
144
  disconnectedCallback() {
108
- window.removeEventListener('resize', this.checkMobile);
145
+ if (typeof window !== 'undefined') {
146
+ window.removeEventListener('resize', this.handleWindowResize);
147
+ }
109
148
  this.el.removeEventListener('headerDragStart', this.dragListener);
110
149
  this.mutationObserver?.disconnect();
150
+ this.resizeObserver?.disconnect();
111
151
  }
112
152
  /** Programmatically scroll the messages area to the bottom */
113
153
  async scrollToBottom() {
@@ -115,11 +155,40 @@ const ChatContainer = class {
115
155
  this.messagesAreaRef.scrollTop = this.messagesAreaRef.scrollHeight;
116
156
  }
117
157
  }
158
+ /**
159
+ * Cycle to the next valid position based on the current direction.
160
+ * - RTL: left ↔ float
161
+ * - LTR: right ↔ float
162
+ */
163
+ async cyclePosition() {
164
+ const docked = this.direction === 'rtl' ? 'left' : 'right';
165
+ this.position = this.position === 'float' ? docked : 'float';
166
+ this.positionChange.emit(this.position);
167
+ }
168
+ handleWindowResize = () => {
169
+ this.checkMobile();
170
+ this.clampFloatPosition();
171
+ };
118
172
  checkMobile() {
119
173
  if (typeof window !== 'undefined') {
120
174
  this.isMobile = window.innerWidth < 768;
121
175
  }
122
176
  }
177
+ /** Re-clamp float position so the panel never ends up off-screen after resize */
178
+ clampFloatPosition() {
179
+ if (typeof window === 'undefined' || this.position !== 'float' || !this.containerRef)
180
+ return;
181
+ const vw = window.innerWidth;
182
+ const vh = window.innerHeight;
183
+ const w = this.containerRef.offsetWidth;
184
+ const h = this.containerRef.offsetHeight;
185
+ let left = parseFloat(this.floatLeft) || 0;
186
+ let top = parseFloat(this.floatTop) || 0;
187
+ left = Math.max(0, Math.min(left, vw - w));
188
+ top = Math.max(0, Math.min(top, vh - h));
189
+ this.floatLeft = `${left}px`;
190
+ this.floatTop = `${top}px`;
191
+ }
123
192
  setupDrag() {
124
193
  // Remove any existing listener before adding to prevent accumulation
125
194
  this.el.removeEventListener('headerDragStart', this.dragListener);
@@ -159,8 +228,14 @@ const ChatContainer = class {
159
228
  }
160
229
  return false;
161
230
  }
231
+ renderSkeleton() {
232
+ return (index.h("div", { class: "skeleton-messages", "aria-busy": "true", "aria-label": "Loading conversation" }, index.h("div", { class: "skeleton-row agent" }, index.h("div", { class: "skeleton-bubble" }, index.h("div", { class: "skeleton-line", style: { width: '80%' } }), index.h("div", { class: "skeleton-line", style: { width: '60%' } }), index.h("div", { class: "skeleton-line", style: { width: '40%' } }))), index.h("div", { class: "skeleton-row user" }, index.h("div", { class: "skeleton-bubble" }, index.h("div", { class: "skeleton-line", style: { width: '70%' } }))), index.h("div", { class: "skeleton-row agent" }, index.h("div", { class: "skeleton-bubble" }, index.h("div", { class: "skeleton-line", style: { width: '90%' } }), index.h("div", { class: "skeleton-line", style: { width: '55%' } }))), index.h("div", { class: "skeleton-row user" }, index.h("div", { class: "skeleton-bubble" }, index.h("div", { class: "skeleton-line", style: { width: '50%' } }), index.h("div", { class: "skeleton-line", style: { width: '35%' } })))));
233
+ }
234
+ renderError() {
235
+ return (index.h("div", { class: "error-state", role: "alert" }, index.h("svg", { class: "error-icon", width: "48", height: "48", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", "stroke-width": "1.5" }), index.h("path", { d: "M12 7v6", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" }), index.h("circle", { cx: "12", cy: "16.5", r: "0.75", fill: "currentColor" })), index.h("p", { class: "error-text" }, this.errorText), index.h("button", { class: "error-retry-btn", type: "button", onClick: () => this.retryClick.emit() }, this.retryLabel)));
236
+ }
162
237
  render() {
163
- return (index.h(index.Host, { key: 'fb25617bfba35681e5190cec602ad17f8a8e53ef', class: { dark: this.isDark() } }, index.h("div", { key: '463a07a473470a497212948fa601cd677d1f266b', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && (index.h("div", { key: '40c3fa4a496a848950dba73372acacd14b4c5dda', class: "watermark" }, index.h("ai-icon", { key: '7467301453bce43c8d3eaca7efe83800a9e4bc8b', name: "watermark", size: 133 }))), index.h("slot", { key: 'c082990d1e7829d5d879a1c176dd0b57a3b3a244', name: "header" }), index.h("div", { key: '13b9ccd90f1e1e26794c8e780a5e8e89a4de43d2', class: "messages-area", ref: el => (this.messagesAreaRef = el) }, index.h("slot", { key: '247cb11401e834b41d220515b88d5e202f40e8e8' })), index.h("slot", { key: '8115183cbe55bc3ba472fed0e368a811e5232b47', name: "footer" }))));
238
+ return (index.h(index.Host, { key: '6290736307488f10a4ed441e2a8e0b3a2e89af05', class: { dark: this.isDark() } }, index.h("div", { key: '6d6a731d9941457b786c71625243a7dd1e9f11f8', class: this.getContainerClasses(), style: this.getContainerStyle(), ref: el => (this.containerRef = el) }, this.showWatermark && !this.loading && !this.error && (index.h("div", { key: '0c2ae5b52f8c30bdf356a3c356d52305451cb19e', class: "watermark" }, index.h("svg", { key: '36076d8dd514f5736050228d22b9a03d5d48ce28', class: "watermark-circle-svg", width: "133", height: "133", viewBox: "0 0 133 133", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("g", { key: '737a3f3d8b7a0f91120258c292d047f9dc90871c', filter: "url(#wm_circle_shadow)" }, index.h("circle", { key: 'a59549c879ddaa2a0007c4fd9645c4382b14e73f', cx: "66.415", cy: "66.415", r: "66.415", class: "watermark-circle" })), index.h("defs", { key: '58d5edc4e05f3dd8a60f7a829b70f154ba85bfc1' }, index.h("filter", { key: 'd2cb7cb5a84bdf1496b56ec5a0c0c79001040670', id: "wm_circle_shadow", x: "0", y: "0", width: "132.83", height: "135.83", filterUnits: "userSpaceOnUse", "color-interpolation-filters": "sRGB" }, index.h("feFlood", { key: 'e90404f557fba552a21bd3748ad728470172040f', "flood-opacity": "0", result: "BackgroundImageFix" }), index.h("feBlend", { key: 'ef5aee167a4973c35f8ffaa8ae4a0487de8266ee', mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), index.h("feColorMatrix", { key: 'e0869202bc43610b91abce92e85e8e5264cda999', in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), index.h("feOffset", { key: '7bef38d885b93711fce4c0efbb719a83417eeefb', dy: "3" }), index.h("feGaussianBlur", { key: '053de38388f049be8db7867b99b53d403de934ca', stdDeviation: "3" }), index.h("feComposite", { key: 'e5f68fbcf0923174a177545bf3364d066a122347', in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), index.h("feColorMatrix", { key: '62dc924cbdc92ce4adc0ec81be851c1d40e7a5b0', type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" }), index.h("feBlend", { key: '908299725f9e553c636bd18eab6541c6a7c69fe5', mode: "normal", in2: "shape", result: "effect1_innerShadow" })))), index.h("svg", { key: '2a6ce2364bfd667c4eba56d859a1326f70a82901', class: "watermark-star-svg", width: "78", height: "78", viewBox: "0 0 78 78", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, index.h("g", { key: 'e2c431ac6bee320c817a7283e6e356edc4667146', filter: "url(#wm_star_shadow)" }, index.h("path", { key: 'd87d0313e649527f5909ac1b08f7af2979760d79', d: "M38.7421 0C39.5691 0 40.2689 0.286272 40.8414 0.858815C41.414 1.43136 41.7002 2.13113 41.7002 2.95814C41.7002 8.87442 43.1952 14.3772 46.1851 19.4665C49.1115 24.4285 53.0557 28.3727 58.0177 31.299C63.107 34.289 68.6097 35.7839 74.526 35.7839C75.353 35.7839 76.0528 36.0702 76.6254 36.6428C77.1979 37.2153 77.4842 37.9151 77.4842 38.7421C77.4842 39.5691 77.1979 40.2689 76.6254 40.8414C76.0528 41.414 75.353 41.7002 74.526 41.7002C68.6097 41.7002 63.107 43.1952 58.0177 46.1851C53.0557 49.1115 49.1115 53.0557 46.1851 58.0177C43.1952 63.107 41.7002 68.6097 41.7002 74.526C41.7002 75.353 41.414 76.0528 40.8414 76.6254C40.2689 77.1979 39.5691 77.4842 38.7421 77.4842C37.9151 77.4842 37.2153 77.1979 36.6428 76.6254C36.0702 76.0528 35.7839 75.353 35.7839 74.526C35.7839 68.6097 34.289 63.107 31.299 58.0177C28.3727 53.0557 24.4285 49.1115 19.4665 46.1851C14.3772 43.1952 8.87442 41.7002 2.95814 41.7002C2.13113 41.7002 1.43136 41.414 0.858815 40.8414C0.286272 40.2689 0 39.5691 0 38.7421C0 37.9151 0.286272 37.2153 0.858815 36.6428C1.43136 36.0702 2.13113 35.7839 2.95814 35.7839C8.87442 35.7839 14.3772 34.289 19.4665 31.299C24.4285 28.3727 28.3727 24.4285 31.299 19.4665C34.289 14.3772 35.7839 8.87442 35.7839 2.95814C35.7839 2.13113 36.0702 1.43136 36.6428 0.858815C37.2153 0.286272 37.9151 0 38.7421 0Z", class: "watermark-star" })), index.h("defs", { key: '51e7ef185399e3a10d0b19eb399500be3e5384f8' }, index.h("filter", { key: '09f52cd1b7084a8af9488bbce05c277fe07012f9', id: "wm_star_shadow", x: "0", y: "0", width: "77.4844", height: "79.4841", filterUnits: "userSpaceOnUse", "color-interpolation-filters": "sRGB" }, index.h("feFlood", { key: '1b055616d714f824dd38a895a5c1a635fefc4a66', "flood-opacity": "0", result: "BackgroundImageFix" }), index.h("feBlend", { key: '044cba9d32d0a1d56fc39d318dfc1cdd0fdc0ae7', mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), index.h("feColorMatrix", { key: '4bf50b36bd6b1ae90d29a95290762ef52dbfff7a', in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), index.h("feOffset", { key: '0988514af2fda03cb2ff43e95c1423137351186f', dy: "2" }), index.h("feGaussianBlur", { key: 'c96fb451b890e9bda84043dcd699c2a3f59c195c', stdDeviation: "2" }), index.h("feComposite", { key: '77b2bb3e01eefb08cac5f60a494c2cd15e97db4a', in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), index.h("feColorMatrix", { key: 'aef785066c732cc5cbc16689f2e57a7df7d18bc5', type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" }), index.h("feBlend", { key: '292a1d370d268312514f1c8fcee2167159c2d4e9', mode: "normal", in2: "shape", result: "effect1_innerShadow" })))))), index.h("slot", { key: '009fd561884a5a70e559d865dc1b1d55937d923c', name: "header" }), index.h("div", { key: 'fde5090720cd70c2b5fe72bcaec95007e7792f4e', class: "messages-area", ref: el => (this.messagesAreaRef = el) }, this.loading ? this.renderSkeleton() : this.error ? this.renderError() : index.h("slot", null)), index.h("slot", { key: '838ea2de9f788af2af70568a7882a08645c6b2ac', name: "footer" }))));
164
239
  }
165
240
  static get watchers() { return {
166
241
  "isOpen": [{
@@ -1,20 +1,25 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
4
- var iconRegistry = require('./icon-registry-BKb9-2Nt.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
+ var iconRegistry = require('./icon-registry-D-m8GW4D.js');
5
5
 
6
- 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-chevron{display:inline-flex;transition:transform 0.2s ease}.dropdown-chevron.open{transform:rotate(180deg)}.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)}`;
6
+ const aiChatHeaderCss = () => `:host{display:block;position:relative;z-index:10}.header-wrapper{position:relative;display:flex;flex-direction:column}.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}.content.browser{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-chevron{display:inline-flex;transition:transform 0.2s ease}.dropdown-chevron.open{transform:rotate(180deg)}.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}@keyframes title-shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}.title-skeleton{display:inline-block;width:120px;height:16px;border-radius:8px;background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(0,0,0,0.06) 25%, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.06) 75%));background-size:200% 100%;animation:title-shimmer 1.6s ease-in-out infinite}.browser-title{font-size:14px;font-weight:600;color:var(--ai-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;line-height:20px}.browser-link-btn{width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;border-radius:8px;cursor:pointer;flex-shrink:0;color:var(--ai-text-secondary)}.browser-link-btn:focus-visible{outline:2px solid var(--ai-focus-ring);outline-offset:2px}.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)}.conversation-dropdown{position:absolute;top:100%;left:0;right:0;z-index:20;height:360px;display:flex;flex-direction:column;background:var(--ai-bg-surface);border-bottom:1px solid var(--ai-border-light);box-shadow:var(--ai-shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08));animation:slideDown 0.2s ease;overflow:hidden}.conversation-dropdown ai-conversation-list{display:flex;flex-direction:column;flex:1;min-height:0;overflow:hidden}@keyframes slideDown{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}`;
7
7
 
8
8
  const AiChatHeader = class {
9
9
  constructor(hostRef) {
10
10
  index.registerInstance(this, hostRef);
11
11
  this.closeClick = index.createEvent(this, "closeClick");
12
- this.editClick = index.createEvent(this, "editClick");
12
+ this.newChatClick = index.createEvent(this, "newChatClick");
13
13
  this.dropdownClick = index.createEvent(this, "dropdownClick");
14
14
  this.positionClick = index.createEvent(this, "positionClick");
15
+ this.headerPositionClick = index.createEvent(this, "headerPositionClick");
15
16
  this.backClick = index.createEvent(this, "backClick");
16
17
  this.headerDragStart = index.createEvent(this, "headerDragStart");
18
+ this.openExternal = index.createEvent(this, "openExternal");
19
+ this.conversationSelect = index.createEvent(this, "conversationSelect");
20
+ this.conversationDelete = index.createEvent(this, "conversationDelete");
17
21
  }
22
+ get el() { return index.getElement(this); }
18
23
  /** Layout variant */
19
24
  mode = 'agent';
20
25
  /** Agent mode: conversation title */
@@ -27,19 +32,38 @@ const AiChatHeader = class {
27
32
  agentAvatar = '';
28
33
  /** Human mode: show the back button */
29
34
  showBack = true;
30
- isDraggable = false;
31
35
  /** Human mode: status indicator variant */
32
36
  statusIndicator = 'online';
37
+ /** Browser mode: page title shown in the header */
38
+ pageTitle = '';
39
+ /** Browser mode: the external URL to link to */
40
+ pageUrl = '';
41
+ /** Conversation list: items to display in the dropdown panel */
42
+ conversationItems = [];
43
+ /** Conversation list: ID of the currently active conversation */
44
+ conversationActiveId = '';
45
+ /** Conversation list: show skeleton loading state */
46
+ conversationLoading = false;
47
+ /** Show a shimmer skeleton in place of the conversation title (e.g. while loading conversation) */
48
+ titleLoading = false;
33
49
  avatarError = false;
34
50
  dropdownOpen = false;
51
+ /** Internally managed — true when the parent ai-chat-container has position="float" */
52
+ isFloating = false;
53
+ parentPositionObserver = null;
35
54
  /** Cancel / close button */
36
55
  closeClick;
37
56
  /** Pencil-edit button (agent mode) */
38
- editClick;
57
+ newChatClick;
39
58
  /** Title / chevron click → open conversation list (agent mode) */
40
59
  dropdownClick;
41
- /** More options button */
60
+ /** More options button — also fires a composed event so ai-chat-container can auto-cycle position */
42
61
  positionClick;
62
+ /**
63
+ * Composed + bubbling event that ai-chat-container listens to internally
64
+ * to automatically cycle its position. Fires alongside positionClick.
65
+ */
66
+ headerPositionClick;
43
67
  /** Back-arrow button (human mode) */
44
68
  backClick;
45
69
  /**
@@ -47,6 +71,54 @@ const AiChatHeader = class {
47
71
  * Composed + bubbling so ai-chat-container can receive it across shadow roots.
48
72
  */
49
73
  headerDragStart;
74
+ /** Open-external button (browser mode) */
75
+ openExternal;
76
+ /** Fired when a conversation is selected from the dropdown list */
77
+ conversationSelect;
78
+ /** Fired when a conversation delete button is clicked */
79
+ conversationDelete;
80
+ handleDocumentClick(event) {
81
+ if (this.dropdownOpen && !this.el.contains(event.target)) {
82
+ this.dropdownOpen = false;
83
+ }
84
+ }
85
+ connectedCallback() {
86
+ // Initial sync will happen in componentDidLoad
87
+ }
88
+ componentDidLoad() {
89
+ // By this point, the element is fully in the DOM and parent relationships are established
90
+ // Small delay to ensure parent custom elements are fully upgraded
91
+ requestAnimationFrame(() => {
92
+ this.syncFloatingState();
93
+ this.observeParentPosition();
94
+ });
95
+ }
96
+ disconnectedCallback() {
97
+ this.parentPositionObserver?.disconnect();
98
+ this.parentPositionObserver = null;
99
+ }
100
+ observeParentPosition() {
101
+ if (this.parentPositionObserver)
102
+ return; // Already observing
103
+ const container = this.el.closest('ai-chat-container');
104
+ if (container) {
105
+ this.parentPositionObserver = new MutationObserver(() => this.syncFloatingState());
106
+ this.parentPositionObserver.observe(container, { attributes: true, attributeFilter: ['position'] });
107
+ }
108
+ }
109
+ syncFloatingState() {
110
+ const container = this.el.closest('ai-chat-container');
111
+ if (container) {
112
+ const newState = container.getAttribute('position') === 'float';
113
+ if (this.isFloating !== newState) {
114
+ this.isFloating = newState;
115
+ }
116
+ return;
117
+ }
118
+ if (this.isFloating !== false) {
119
+ this.isFloating = false;
120
+ }
121
+ }
50
122
  renderIcon(name, width, height) {
51
123
  const icon = iconRegistry.iconRegistry[name];
52
124
  if (!icon)
@@ -59,30 +131,58 @@ const AiChatHeader = class {
59
131
  if (!this.agentAvatar || this.avatarError) {
60
132
  return index.h("div", { class: "avatar-fallback" }, fallbackLetter);
61
133
  }
62
- return (index.h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName, onError: () => { this.avatarError = true; } }));
134
+ return (index.h("img", { class: "avatar", src: this.agentAvatar, alt: this.agentName, onError: () => {
135
+ this.avatarError = true;
136
+ } }));
63
137
  }
64
138
  renderDragBtn() {
65
- return this.isDraggable && (index.h("button", { class: "action-btn drag-btn", "aria-label": "\u0633\u062D\u0628 / Drag", onPointerDown: (e) => {
139
+ return (this.isFloating && (index.h("button", { class: "action-btn drag-btn", "aria-label": "\u0633\u062D\u0628 / Drag", onPointerDown: (e) => {
66
140
  e.preventDefault();
67
141
  this.headerDragStart.emit({ clientX: e.clientX, clientY: e.clientY });
68
- } }, this.renderIcon('drag', 11, 15)));
142
+ } }, this.renderIcon('drag', 11, 15))));
143
+ }
144
+ handleConversationSelect = (e) => {
145
+ e.stopPropagation();
146
+ this.conversationSelect.emit(e.detail);
147
+ this.dropdownOpen = false;
148
+ };
149
+ handleConversationDelete = (e) => {
150
+ e.stopPropagation();
151
+ this.conversationDelete.emit(e.detail);
152
+ };
153
+ renderConversationDropdown() {
154
+ if (!this.dropdownOpen || this.mode !== 'agent')
155
+ return null;
156
+ return (index.h("div", { class: "conversation-dropdown" }, index.h("ai-conversation-list", { items: this.conversationItems, activeId: this.conversationActiveId, loading: this.conversationLoading, onConversationSelect: this.handleConversationSelect, onConversationDelete: this.handleConversationDelete })));
69
157
  }
70
158
  renderAgentMode() {
71
159
  return [
72
160
  this.renderDragBtn(),
73
- index.h("div", { class: "content agent dropdown-trigger", role: "button", onClick: () => { this.dropdownOpen = !this.dropdownOpen; this.dropdownClick.emit(); }, "aria-haspopup": "listbox", "aria-expanded": this.dropdownOpen, "aria-label": `${this.conversation}, افتح قائمة المحادثات` }, index.h("span", { class: "title" }, this.conversation), index.h("span", { class: `dropdown-chevron${this.dropdownOpen ? ' open' : ''}` }, this.renderIcon('chevron-down', 24, 24))),
74
- index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", "aria-label": "\u062A\u0639\u062F\u064A\u0644 / Edit", onClick: () => this.editClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
161
+ index.h("div", { class: "content agent dropdown-trigger", role: "button", onClick: () => {
162
+ if (this.titleLoading)
163
+ return;
164
+ this.dropdownOpen = !this.dropdownOpen;
165
+ this.dropdownClick.emit();
166
+ }, "aria-haspopup": "listbox", "aria-expanded": this.dropdownOpen, "aria-label": `${this.conversation}, افتح قائمة المحادثات` }, this.titleLoading ? (index.h("span", { class: "title-skeleton", "aria-busy": "true", "aria-label": "\u062C\u0627\u0631\u064A \u0627\u0644\u062A\u062D\u0645\u064A\u0644" })) : (index.h("span", { class: "title" }, this.conversation)), !this.titleLoading && (index.h("span", { class: `dropdown-chevron${this.dropdownOpen ? ' open' : ''}` }, this.renderIcon('chevron-down', 24, 24)))),
167
+ index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", "aria-label": "\u0645\u062D\u0627\u062F\u062B\u0629 \u062C\u062F\u064A\u062F\u0629 / New Chat", onClick: () => this.newChatClick.emit() }, this.renderIcon('pencil-edit', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => { this.positionClick.emit(); this.headerPositionClick.emit(); } }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
75
168
  ];
76
169
  }
77
170
  renderHumanMode() {
78
171
  return [
79
172
  this.renderDragBtn(),
80
173
  index.h("div", { class: "content human" }, this.showBack && (index.h("button", { class: "back-btn", "aria-label": "\u0631\u062C\u0648\u0639 / Back", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24))), index.h("div", { class: "avatar-wrapper" }, this.renderAvatar(), index.h("span", { class: `online-dot status-${this.statusIndicator}` }, this.renderIcon('online-dot', 10, 10))), index.h("div", { class: "text-block" }, index.h("span", { class: "agent-name" }, this.agentName), this.agentStatus && index.h("span", { class: "agent-status" }, this.agentStatus))),
81
- index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => this.positionClick.emit() }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
174
+ index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => { this.positionClick.emit(); this.headerPositionClick.emit(); } }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
175
+ ];
176
+ }
177
+ renderBrowserMode() {
178
+ return [
179
+ this.renderDragBtn(),
180
+ index.h("div", { class: "content browser" }, index.h("button", { class: "back-btn", "aria-label": "\u0631\u062C\u0648\u0639 / Back", onClick: () => this.backClick.emit() }, this.renderIcon('arrow-right', 24, 24)), index.h("span", { class: "browser-title" }, this.pageTitle), index.h("button", { class: "browser-link-btn", "aria-label": "\u0641\u062A\u062D \u0641\u064A \u0646\u0627\u0641\u0630\u0629 \u062C\u062F\u064A\u062F\u0629 / Open externally", onClick: () => this.openExternal.emit(this.pageUrl) }, this.renderIcon('link', 14, 14))),
181
+ index.h("div", { class: "actions" }, index.h("button", { class: "action-btn", "aria-label": "\u0627\u0644\u0639\u0631\u0636 / Position", onClick: () => { this.positionClick.emit(); this.headerPositionClick.emit(); } }, this.renderIcon('hand', 22, 22)), index.h("button", { class: "action-btn", "aria-label": "\u0625\u063A\u0644\u0627\u0642 / Close", onClick: () => this.closeClick.emit() }, this.renderIcon('cancel', 22, 22))),
82
182
  ];
83
183
  }
84
184
  render() {
85
- return (index.h(index.Host, { key: 'e7384f8737db6d63472fb458ebb0e1090438c03e' }, index.h("div", { key: 'b1b5fcc22aeca94649cc972042c3e9de75ddbdb7', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.renderHumanMode())));
185
+ return (index.h(index.Host, { key: 'b11b4d03d7f1980ec91b0fdba7db314971b7e7d3' }, index.h("div", { key: '47f40b54a6861b69adee00bea45ab8a6691c13f2', class: "header-wrapper" }, index.h("div", { key: 'dcc18d4cb88457c2eb959bfccb2c8d72655d610a', class: "header-container" }, this.mode === 'agent' ? this.renderAgentMode() : this.mode === 'human' ? this.renderHumanMode() : this.renderBrowserMode()), this.renderConversationDropdown())));
86
186
  }
87
187
  };
88
188
  AiChatHeader.style = aiChatHeaderCss();
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
4
- var iconRegistry = require('./icon-registry-BKb9-2Nt.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
+ var iconRegistry = require('./icon-registry-D-m8GW4D.js');
5
5
 
6
6
  /*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */
7
7
 
@@ -1522,7 +1522,13 @@ const AiChatMessage = class {
1522
1522
  getRenderedContent() {
1523
1523
  if (!this.content)
1524
1524
  return '';
1525
- return purify.sanitize(this.parseMarkdown(this.content), SANITIZE_CONFIG);
1525
+ try {
1526
+ return purify.sanitize(this.parseMarkdown(this.content), SANITIZE_CONFIG);
1527
+ }
1528
+ catch {
1529
+ // Fallback: render raw text safely if markdown parsing fails
1530
+ return purify.sanitize(`<p>${this.content.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br>')}</p>`, SANITIZE_CONFIG);
1531
+ }
1526
1532
  }
1527
1533
  getRelativeTime() {
1528
1534
  if (!this.timestamp)
@@ -1591,7 +1597,7 @@ const AiChatMessage = class {
1591
1597
  } })), 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()))))));
1592
1598
  }
1593
1599
  render() {
1594
- return index.h(index.Host, { key: '004ac6918ec7ec7e960ca6fd3f75edb13529bf71' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
1600
+ return index.h(index.Host, { key: 'b6fe466c9830e69c3ae6f405daa9e77ef3f75aca' }, this.role === 'user' ? this.renderUserMessage() : this.renderAgentMessage());
1595
1601
  }
1596
1602
  };
1597
1603
  AiChatMessage.style = aiChatMessageCss();
@@ -1,15 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Bs23yVuF.js');
4
- var iconRegistry = require('./icon-registry-BKb9-2Nt.js');
3
+ var index = require('./index-Cc05u4ND.js');
4
+ var iconRegistry = require('./icon-registry-D-m8GW4D.js');
5
5
 
6
- const aiConversationListCss = () => `:host{display:block;height:100%}.conversation-list{display:flex;flex-direction:column;gap:8px;height:100%;background:var(--ai-bg-surface)}.list-scroll{flex:1;overflow-y:auto;padding:0 8px 12px;scrollbar-width:thin;scrollbar-color:var(--ai-scrollbar-thumb) var(--ai-scrollbar-track)}.list-scroll::-webkit-scrollbar{width:4px}.list-scroll::-webkit-scrollbar-track{background:var(--ai-scrollbar-track)}.list-scroll::-webkit-scrollbar-thumb{background:var(--ai-scrollbar-thumb);border-radius:4px}.conv-item{display:flex;align-items:flex-start;gap:6px;margin-top:6px;padding:10px 10px 10px 6px;border-radius:10px;cursor:pointer;transition:background 0.15s;position:relative}.conv-item:hover{background:var(--ai-bg-card)}.conv-item--active{background:var(--ai-bg-card);box-shadow:var(--ai-shadow-sm)}.conv-item__body{flex:1;min-width:0}.conv-item__title{margin:0 0 3px;font-size:13px;font-weight:600;color:var(--ai-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.conv-item__preview{margin:0 0 5px;font-size:12px;color:var(--ai-text-muted);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.conv-item__meta{display:flex;align-items:center;gap:8px}.conv-item__time{font-size:11px;color:var(--ai-text-muted);flex-shrink:0}.rating-dots{display:flex;align-items:center;gap:3px}.rating-dot{width:6px;height:6px;border-radius:50%;background:var(--ai-border-default);transition:background 0.15s}.rating-dot--filled{background:var(--ai-accent-warning, #ffaf44)}.delete-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:6px;cursor:pointer;color:var(--ai-text-muted);opacity:0;transition:opacity 0.15s, background 0.15s, color 0.15s;margin-block-start:2px}.conv-item:hover .delete-btn,.conv-item--active .delete-btn{opacity:1}.delete-btn:hover{background:var(--ai-status-danger-bg, rgba(239, 68, 68, 0.1));color:var(--ai-status-danger, #ef4444)}.delete-btn .icon-wrap{display:inline-flex;align-items:center;line-height:0}.skeleton-list{display:flex;flex-direction:column;gap:4px}.skeleton-item{padding:10px;border-radius:10px;display:flex;flex-direction:column;gap:6px}.skeleton-line{border-radius:6px;background:var(--ai-shimmer-gradient);background-size:200% 100%;animation:shimmer 2s linear infinite;height:12px}.skeleton-line--title{width:65%;height:13px}.skeleton-line--preview{width:100%}.skeleton-line--meta{width:35%;height:10px}@keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}`;
6
+ const aiConversationListCss = () => `:host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}.conversation-list{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0;background:var(--ai-bg-surface)}.list-scroll{flex:1;min-height:0;overflow-y:auto;padding:0 8px 12px;scrollbar-width:thin;scrollbar-color:var(--ai-scrollbar-thumb) transparent}.list-scroll::-webkit-scrollbar{width:3px}.list-scroll::-webkit-scrollbar-track{background:transparent}.list-scroll::-webkit-scrollbar-thumb{background:var(--ai-scrollbar-thumb);border-radius:99px}.list-scroll::-webkit-scrollbar-thumb:hover{background:var(--ai-scrollbar-thumb-hover)}.conv-item{display:flex;align-items:flex-start;gap:6px;margin-top:6px;padding:10px 10px 10px 6px;border-radius:10px;cursor:pointer;transition:background 0.15s;position:relative}.conv-item:hover{background:var(--ai-bg-card)}.conv-item--active{background:var(--ai-bg-card);box-shadow:var(--ai-shadow-sm)}.conv-item__body{flex:1;min-width:0}.conv-item__title{margin:0 0 3px;font-size:13px;font-weight:600;color:var(--ai-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.conv-item__preview{margin:0 0 5px;font-size:12px;color:var(--ai-text-muted);line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.conv-item__meta{display:flex;align-items:center;gap:8px}.conv-item__time{font-size:11px;color:var(--ai-text-muted);flex-shrink:0}.rating-dots{display:flex;align-items:center;gap:3px}.rating-dot{width:6px;height:6px;border-radius:50%;background:var(--ai-border-default);transition:background 0.15s}.rating-dot--filled{background:var(--ai-accent-warning, #ffaf44)}.delete-btn{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:6px;cursor:pointer;color:var(--ai-text-muted);opacity:0;transition:opacity 0.15s, background 0.15s, color 0.15s;margin-block-start:2px}.conv-item:hover .delete-btn,.conv-item--active .delete-btn{opacity:1}.delete-btn:hover{background:var(--ai-status-danger-bg, rgba(239, 68, 68, 0.1));color:var(--ai-status-danger, #ef4444)}.delete-btn .icon-wrap{display:inline-flex;align-items:center;line-height:0}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 16px;text-align:center}.empty-state__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:10px;background:var(--ai-bg-card);color:var(--ai-text-muted);line-height:0}.empty-state__icon .icon-wrap{display:inline-flex;align-items:center;line-height:0}.empty-state__text{margin:0;font-size:13px;color:var(--ai-text-muted);line-height:1.4}.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 16px;text-align:center}.error-state__icon{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:10px;background:var(--ai-status-danger-bg, rgba(239, 68, 68, 0.1));color:var(--ai-status-danger, #ef4444);line-height:0}.error-state__icon .icon-wrap{display:inline-flex;align-items:center;line-height:0}.error-state__text{margin:0;font-size:13px;color:var(--ai-text-muted);line-height:1.4}.error-state__retry{display:inline-flex;align-items:center;gap:4px;margin-top:4px;padding:6px 14px;font-size:12px;font-weight:600;color:var(--ai-text-primary);background:var(--ai-bg-card);border:1px solid var(--ai-border-default);border-radius:8px;cursor:pointer;transition:background 0.15s, box-shadow 0.15s}.error-state__retry:hover{box-shadow:var(--ai-shadow-sm)}.error-state__retry .icon-wrap{display:inline-flex;align-items:center;line-height:0}.skeleton-list{display:flex;flex-direction:column;gap:4px}.skeleton-item{padding:10px;border-radius:10px;display:flex;flex-direction:column;gap:6px}.skeleton-line{border-radius:6px;background:var(--ai-shimmer-gradient, linear-gradient(90deg, rgba(0, 0, 0, 0.06) 25%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0.06) 75%));background-size:200% 100%;animation:shimmer 2s linear infinite;height:12px}.skeleton-line--title{width:65%;height:13px}.skeleton-line--preview{width:100%}.skeleton-line--meta{width:35%;height:10px}@keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}`;
7
7
 
8
8
  const AiConversationList = class {
9
9
  constructor(hostRef) {
10
10
  index.registerInstance(this, hostRef);
11
11
  this.conversationSelect = index.createEvent(this, "conversationSelect");
12
12
  this.conversationDelete = index.createEvent(this, "conversationDelete");
13
+ this.retryClick = index.createEvent(this, "retryClick");
13
14
  }
14
15
  /** JSON array of ConversationItem */
15
16
  items = [];
@@ -17,8 +18,17 @@ const AiConversationList = class {
17
18
  activeId = '';
18
19
  /** Show skeleton loading state */
19
20
  loading = false;
21
+ /** Text shown when the list is empty */
22
+ emptyText = 'لا توجد محادثات';
23
+ /** Show error state when fetching conversations fails */
24
+ error = false;
25
+ /** Error message text */
26
+ errorText = 'تعذّر تحميل المحادثات';
27
+ /** Retry button label for error state */
28
+ retryLabel = 'إعادة المحاولة';
20
29
  conversationSelect;
21
30
  conversationDelete;
31
+ retryClick;
22
32
  renderIcon(name, width, height) {
23
33
  const icon = iconRegistry.iconRegistry[name];
24
34
  if (!icon)
@@ -27,8 +37,12 @@ const AiConversationList = class {
27
37
  return index.h("span", { class: "icon-wrap", innerHTML: svg });
28
38
  }
29
39
  formatRelativeTime(timestamp) {
40
+ if (!timestamp)
41
+ return '';
30
42
  try {
31
43
  const date = new Date(timestamp);
44
+ if (isNaN(date.getTime()))
45
+ return timestamp;
32
46
  const diffMs = Date.now() - date.getTime();
33
47
  const diffMin = Math.floor(diffMs / 60000);
34
48
  const diffHour = Math.floor(diffMin / 60);
@@ -44,7 +58,7 @@ const AiConversationList = class {
44
58
  return rtf.format(-diffDay, 'day');
45
59
  }
46
60
  catch {
47
- return '';
61
+ return timestamp;
48
62
  }
49
63
  }
50
64
  renderRatingDots(rating) {
@@ -54,16 +68,27 @@ const AiConversationList = class {
54
68
  renderSkeleton() {
55
69
  return (index.h("div", { class: "skeleton-list" }, [1, 2, 3, 4].map(i => (index.h("div", { key: i, class: "skeleton-item" }, index.h("div", { class: "skeleton-line skeleton-line--title" }), index.h("div", { class: "skeleton-line skeleton-line--preview" }), index.h("div", { class: "skeleton-line skeleton-line--meta" }))))));
56
70
  }
71
+ renderEmpty() {
72
+ return (index.h("div", { class: "empty-state" }, index.h("div", { class: "empty-state__icon" }, this.renderIcon('list', 24, 24)), index.h("p", { class: "empty-state__text" }, this.emptyText)));
73
+ }
74
+ renderError() {
75
+ return (index.h("div", { class: "error-state" }, index.h("div", { class: "error-state__icon" }, this.renderIcon('wifi-off', 24, 24)), index.h("p", { class: "error-state__text" }, this.errorText), index.h("button", { class: "error-state__retry", onClick: () => this.retryClick.emit() }, this.renderIcon('reload', 14, 14), index.h("span", null, this.retryLabel))));
76
+ }
57
77
  render() {
58
- return (index.h(index.Host, { key: 'b67df60c8d758fdf42afec98e4322b3560abc212' }, index.h("div", { key: '13a7d396f253ba185edb3ad3cc97a7468d5209dc', class: "conversation-list" }, index.h("div", { key: 'efacc2632ca9ae8b5b3b68f3751b390879517e06', class: "list-scroll", role: "list" }, this.loading
78
+ const showEmpty = !this.loading && !this.error && this.items.length === 0;
79
+ return (index.h(index.Host, { key: '9be146c657629a6f7ac7f4325e1fbfdbea27f4de' }, index.h("div", { key: '2e7f5daebdde0c69c5e22d581f9f31fc9f232308', class: "conversation-list" }, index.h("div", { key: 'f87e9462d0cac6e5d601528ada588aa18385b252', class: "list-scroll", role: "list" }, this.loading
59
80
  ? this.renderSkeleton()
60
- : this.items.map(item => {
61
- const isActive = item.id === this.activeId;
62
- return (index.h("div", { key: item.id, class: { 'conv-item': true, 'conv-item--active': isActive }, role: "listitem", "aria-current": isActive ? 'true' : undefined, onClick: () => this.conversationSelect.emit(item.id) }, index.h("div", { class: "conv-item__body" }, index.h("p", { class: "conv-item__title" }, item.title), index.h("p", { class: "conv-item__preview" }, item.preview), index.h("div", { class: "conv-item__meta" }, index.h("span", { class: "conv-item__time" }, this.formatRelativeTime(item.timestamp)), item.rating != null && this.renderRatingDots(item.rating))), index.h("button", { class: "delete-btn", "aria-label": "\u062D\u0630\u0641 \u0627\u0644\u0645\u062D\u0627\u062F\u062B\u0629", onClick: e => {
63
- e.stopPropagation();
64
- this.conversationDelete.emit(item.id);
65
- } }, this.renderIcon('cancel', 14, 14))));
66
- })))));
81
+ : this.error
82
+ ? this.renderError()
83
+ : showEmpty
84
+ ? this.renderEmpty()
85
+ : this.items.map(item => {
86
+ const isActive = item.id === this.activeId;
87
+ return (index.h("div", { key: item.id, class: { 'conv-item': true, 'conv-item--active': isActive }, role: "listitem", "aria-current": isActive ? 'true' : undefined, onClick: () => this.conversationSelect.emit(item.id) }, index.h("div", { class: "conv-item__body" }, index.h("p", { class: "conv-item__title" }, item.title), index.h("p", { class: "conv-item__preview" }, item.preview), index.h("div", { class: "conv-item__meta" }, index.h("span", { class: "conv-item__time" }, this.formatRelativeTime(item.timestamp)), item.rating != null && this.renderRatingDots(item.rating))), index.h("button", { class: "delete-btn", "aria-label": "\u062D\u0630\u0641 \u0627\u0644\u0645\u062D\u0627\u062F\u062B\u0629", onClick: e => {
88
+ e.stopPropagation();
89
+ this.conversationDelete.emit(item.id);
90
+ } }, this.renderIcon('cancel', 14, 14))));
91
+ })))));
67
92
  }
68
93
  };
69
94
  AiConversationList.style = aiConversationListCss();