@a.izzuddin/ai-chat 0.2.25 → 0.2.27-beta.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.
@@ -987,6 +987,11 @@
987
987
  }
988
988
  ]
989
989
  },
990
+ {
991
+ "kind": "field",
992
+ "name": "_viewportResizeHandler",
993
+ "privacy": "private"
994
+ },
990
995
  {
991
996
  "kind": "method",
992
997
  "name": "scrollToBottom",
package/dist/index.d.mts CHANGED
@@ -25,6 +25,7 @@ interface Message {
25
25
  faqs?: FAQ[];
26
26
  suggestedQuestions?: SuggestedQuestion[];
27
27
  confidence?: Confidence;
28
+ language?: string;
28
29
  }
29
30
  /**
30
31
  * AI Chat Web Component
@@ -212,7 +213,9 @@ declare class AIChat extends LitElement {
212
213
  private loadMessagesFromStorage;
213
214
  private clearMessagesFromStorage;
214
215
  private formatMessageContent;
216
+ private _viewportResizeHandler;
215
217
  connectedCallback(): Promise<void>;
218
+ disconnectedCallback(): void;
216
219
  updated(changedProperties: PropertyValues): void;
217
220
  private scrollToBottom;
218
221
  /**
package/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ interface Message {
25
25
  faqs?: FAQ[];
26
26
  suggestedQuestions?: SuggestedQuestion[];
27
27
  confidence?: Confidence;
28
+ language?: string;
28
29
  }
29
30
  /**
30
31
  * AI Chat Web Component
@@ -212,7 +213,9 @@ declare class AIChat extends LitElement {
212
213
  private loadMessagesFromStorage;
213
214
  private clearMessagesFromStorage;
214
215
  private formatMessageContent;
216
+ private _viewportResizeHandler;
215
217
  connectedCallback(): Promise<void>;
218
+ disconnectedCallback(): void;
216
219
  updated(changedProperties: PropertyValues): void;
217
220
  private scrollToBottom;
218
221
  /**
package/dist/index.js CHANGED
@@ -5373,7 +5373,7 @@ MarkdownIt.prototype.renderInline = function(src, env) {
5373
5373
  var lib_default = MarkdownIt;
5374
5374
 
5375
5375
  // src/components/ai-chat.ts
5376
- console.log("Chatbot Ver = 0.2.24-beta.0");
5376
+ console.log("Chatbot Ver = 0.2.27-beta.1");
5377
5377
  var md = new lib_default({
5378
5378
  html: false,
5379
5379
  // Disable HTML tags in source for security
@@ -5385,6 +5385,13 @@ var md = new lib_default({
5385
5385
  exports.AIChat = class AIChat extends lit.LitElement {
5386
5386
  constructor() {
5387
5387
  super();
5388
+ this._viewportResizeHandler = () => {
5389
+ const vv = window.visualViewport;
5390
+ if (vv) {
5391
+ this.style.setProperty("--viewport-height", `${vv.height}px`);
5392
+ this.style.setProperty("--viewport-offset-top", `${vv.offsetTop}px`);
5393
+ }
5394
+ };
5388
5395
  this.apiUrl = "";
5389
5396
  this.sessionId = "default-session";
5390
5397
  this.chatTitle = "My AI Agent";
@@ -5528,6 +5535,11 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5528
5535
  }
5529
5536
  async connectedCallback() {
5530
5537
  super.connectedCallback();
5538
+ if (window.visualViewport) {
5539
+ window.visualViewport.addEventListener("resize", this._viewportResizeHandler);
5540
+ window.visualViewport.addEventListener("scroll", this._viewportResizeHandler);
5541
+ this._viewportResizeHandler();
5542
+ }
5531
5543
  const savedMessages = this.loadMessagesFromStorage();
5532
5544
  if (this.initialMessages && this.initialMessages.length > 0) {
5533
5545
  this.messages = [...this.initialMessages];
@@ -5598,6 +5610,13 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5598
5610
  }, 500);
5599
5611
  }
5600
5612
  }
5613
+ disconnectedCallback() {
5614
+ super.disconnectedCallback();
5615
+ if (window.visualViewport) {
5616
+ window.visualViewport.removeEventListener("resize", this._viewportResizeHandler);
5617
+ window.visualViewport.removeEventListener("scroll", this._viewportResizeHandler);
5618
+ }
5619
+ }
5601
5620
  updated(changedProperties) {
5602
5621
  super.updated(changedProperties);
5603
5622
  if (changedProperties.has("messages")) {
@@ -5791,7 +5810,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5791
5810
  id: (Date.now() + 1).toString(),
5792
5811
  role: "assistant",
5793
5812
  content: responseText,
5794
- suggestedQuestions
5813
+ suggestedQuestions,
5814
+ language: this.language
5795
5815
  };
5796
5816
  this.messages = [...this.messages, assistantMessage];
5797
5817
  this.clearPendingRequest();
@@ -5940,7 +5960,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5940
5960
  content: responseText,
5941
5961
  faqs,
5942
5962
  suggestedQuestions,
5943
- confidence
5963
+ confidence,
5964
+ language: this.language
5944
5965
  };
5945
5966
  this.messages = [...this.messages, assistantMessage];
5946
5967
  this.clearPendingRequest();
@@ -6027,7 +6048,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6027
6048
  id: (Date.now() + 1).toString(),
6028
6049
  role: "assistant",
6029
6050
  content: responseText,
6030
- suggestedQuestions
6051
+ suggestedQuestions,
6052
+ language: this.language
6031
6053
  };
6032
6054
  this.messages = [...this.messages, assistantMessage];
6033
6055
  this.clearPendingRequest();
@@ -6196,7 +6218,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6196
6218
  content: responseText,
6197
6219
  faqs,
6198
6220
  suggestedQuestions,
6199
- confidence
6221
+ confidence,
6222
+ language: this.language
6200
6223
  };
6201
6224
  this.messages = [...this.messages, assistantMessage];
6202
6225
  this.clearPendingRequest();
@@ -6228,6 +6251,13 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6228
6251
  <!-- Header -->
6229
6252
  <div class="header" style="--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};">
6230
6253
  <div class="header-content">
6254
+ ${this.mode === "widget" ? lit.html`
6255
+ <button class="header-back-button" @click=${this.toggleWidget} aria-label="Back">
6256
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
6257
+ <polyline points="15 18 9 12 15 6"></polyline>
6258
+ </svg>
6259
+ </button>
6260
+ ` : ""}
6231
6261
  <div class="header-avatar">
6232
6262
  ${this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="Bot" class="header-avatar-image" />` : lit.html`<svg viewBox="0 0 24 24" fill="none" stroke="${this.primaryColor}" stroke-width="2" style="width: 1.5rem; height: 1.5rem;">
6233
6263
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
@@ -6278,7 +6308,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6278
6308
  ` : ""}
6279
6309
  ${msg.role === "assistant" && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? lit.html`
6280
6310
  <div class="faq-section">
6281
- <p class="faq-title">${this.language === "ms" || this.language === "my" ? "Cadangan Soalan:" : "Suggested Questions:"}</p>
6311
+ <p class="faq-title">${msg.language === "ms" || msg.language === "my" ? "Cadangan Soalan:" : "Suggested Questions:"}</p>
6282
6312
  <ul class="faq-list">
6283
6313
  ${msg.suggestedQuestions.map((question) => lit.html`
6284
6314
  <li class="faq-item" @click=${(e) => this.handleFAQClick(question, e)}>
@@ -6370,14 +6400,18 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6370
6400
  <button
6371
6401
  class=${classMap_js.classMap({
6372
6402
  "widget-button": true,
6373
- "widget-button-no-bg": !!this.widgetIconUrl,
6374
- "widget-button-hidden": this.isOpen
6403
+ "widget-button-no-bg": !this.isOpen && !!this.widgetIconUrl,
6404
+ "widget-button-close": this.isOpen
6375
6405
  })}
6376
6406
  style="--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};"
6377
6407
  @click=${this.toggleWidget}
6378
6408
  aria-label=${this.isOpen ? "Close chat" : "Open chat"}
6379
6409
  >
6380
- ${this.widgetIconUrl ? lit.html`
6410
+ ${this.isOpen ? lit.html`
6411
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
6412
+ <polyline points="6 9 12 15 18 9"></polyline>
6413
+ </svg>
6414
+ ` : this.widgetIconUrl ? lit.html`
6381
6415
  <img src="${this.widgetIconUrl}" alt="Chat" class="widget-button-icon" />
6382
6416
  ` : lit.html`
6383
6417
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -6402,6 +6436,7 @@ exports.AIChat.styles = lit.css`
6402
6436
  display: flex;
6403
6437
  flex-direction: column;
6404
6438
  height: 100vh;
6439
+ height: var(--viewport-height, 100dvh);
6405
6440
  background: #ffffff;
6406
6441
  }
6407
6442
 
@@ -6453,8 +6488,19 @@ exports.AIChat.styles = lit.css`
6453
6488
  transform: scale(1.1);
6454
6489
  }
6455
6490
 
6456
- .widget-button-hidden {
6457
- display: none;
6491
+ .widget-button-close {
6492
+ background: var(--primary-color, #3681D3);
6493
+ box-shadow: 0 4px 16px rgba(54, 129, 211, 0.3);
6494
+ }
6495
+
6496
+ .widget-button-close:hover {
6497
+ background: var(--primary-color, #3681D3);
6498
+ box-shadow: 0 6px 20px rgba(54, 129, 211, 0.4);
6499
+ transform: scale(1.05);
6500
+ }
6501
+
6502
+ .widget-button-close svg {
6503
+ color: #ffffff;
6458
6504
  }
6459
6505
 
6460
6506
  .widget-speech-bubble {
@@ -6505,7 +6551,7 @@ exports.AIChat.styles = lit.css`
6505
6551
 
6506
6552
  .widget-window {
6507
6553
  position: absolute;
6508
- bottom: 0;
6554
+ bottom: 90px;
6509
6555
  right: 0;
6510
6556
  width: var(--widget-width, 380px);
6511
6557
  height: var(--widget-height, 600px);
@@ -6551,10 +6597,14 @@ exports.AIChat.styles = lit.css`
6551
6597
  /* Mobile portrait */
6552
6598
  @media (max-width: 480px) and (orientation: portrait) {
6553
6599
  .widget-window {
6554
- width: calc(100vw - 40px);
6555
- height: 70vh;
6556
- bottom: 0;
6600
+ position: fixed;
6601
+ top: var(--viewport-offset-top, 0px);
6602
+ left: 0;
6557
6603
  right: 0;
6604
+ width: 100vw;
6605
+ height: 100vh;
6606
+ height: var(--viewport-height, 100dvh);
6607
+ border-radius: 0;
6558
6608
  }
6559
6609
 
6560
6610
  .widget-button {
@@ -6571,10 +6621,14 @@ exports.AIChat.styles = lit.css`
6571
6621
  /* Mobile landscape */
6572
6622
  @media (max-width: 900px) and (orientation: landscape) {
6573
6623
  .widget-window {
6574
- width: var(--widget-width, 500px);
6575
- height: calc(100vh - 100px);
6576
- bottom: 0;
6624
+ position: fixed;
6625
+ top: var(--viewport-offset-top, 0px);
6626
+ left: 0;
6577
6627
  right: 0;
6628
+ width: 100vw;
6629
+ height: 100vh;
6630
+ height: var(--viewport-height, 100dvh);
6631
+ border-radius: 0;
6578
6632
  }
6579
6633
 
6580
6634
  .widget-button {
@@ -6835,6 +6889,41 @@ exports.AIChat.styles = lit.css`
6835
6889
  height: 1.25rem;
6836
6890
  }
6837
6891
 
6892
+ .header-back-button {
6893
+ display: none;
6894
+ background: none;
6895
+ border: none;
6896
+ cursor: pointer;
6897
+ color: #fff;
6898
+ padding: 0.3rem;
6899
+ align-items: center;
6900
+ justify-content: center;
6901
+ border-radius: 50%;
6902
+ transition: background 0.2s;
6903
+ flex-shrink: 0;
6904
+ }
6905
+
6906
+ .header-back-button:hover {
6907
+ background: rgba(255, 255, 255, 0.2);
6908
+ }
6909
+
6910
+ .header-back-button svg {
6911
+ width: 1.25rem;
6912
+ height: 1.25rem;
6913
+ }
6914
+
6915
+ @media (max-width: 480px) {
6916
+ .header-back-button {
6917
+ display: flex;
6918
+ }
6919
+ }
6920
+
6921
+ @media (max-width: 900px) and (orientation: landscape) {
6922
+ .header-back-button {
6923
+ display: flex;
6924
+ }
6925
+ }
6926
+
6838
6927
  .messages-area {
6839
6928
  flex: 1;
6840
6929
  overflow-y: auto;