@a.izzuddin/ai-chat 0.2.4 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ var lit = require('lit');
4
4
  var decorators_js = require('lit/decorators.js');
5
5
  var repeat_js = require('lit/directives/repeat.js');
6
6
  var classMap_js = require('lit/directives/class-map.js');
7
+ var unsafeHtml_js = require('lit/directives/unsafe-html.js');
7
8
 
8
9
  var __defProp = Object.defineProperty;
9
10
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -15,7 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
15
16
  if (kind && result) __defProp(target, key, result);
16
17
  return result;
17
18
  };
18
- var VERSION = "0.2.4";
19
+ var VERSION = "0.2.7";
19
20
  exports.AIChat = class AIChat extends lit.LitElement {
20
21
  constructor() {
21
22
  super();
@@ -27,6 +28,14 @@ exports.AIChat = class AIChat extends lit.LitElement {
27
28
  this.initialMessages = [];
28
29
  this.botAvatarUrl = "";
29
30
  this.backgroundImageUrl = "";
31
+ this.widgetWidth = "380px";
32
+ this.widgetHeight = "600px";
33
+ this.primaryColor = "#3681D3";
34
+ this.primaryColorHover = "#3457C7";
35
+ this.userMessageBg = "#D6E4FF";
36
+ this.botMessageBg = "#F5F5F5";
37
+ this.welcomeMessage = "How can I help you today?";
38
+ this.welcomeSubtitle = "";
30
39
  this.messages = [];
31
40
  this.input = "";
32
41
  this.isLoading = false;
@@ -35,6 +44,67 @@ exports.AIChat = class AIChat extends lit.LitElement {
35
44
  toggleWidget() {
36
45
  this.isOpen = !this.isOpen;
37
46
  }
47
+ lightenColor(hex, percent = 15) {
48
+ hex = hex.replace("#", "");
49
+ const r = parseInt(hex.substring(0, 2), 16);
50
+ const g = parseInt(hex.substring(2, 4), 16);
51
+ const b = parseInt(hex.substring(4, 6), 16);
52
+ const newR = Math.min(255, Math.round(r + (255 - r) * (percent / 100)));
53
+ const newG = Math.min(255, Math.round(g + (255 - g) * (percent / 100)));
54
+ const newB = Math.min(255, Math.round(b + (255 - b) * (percent / 100)));
55
+ return `#${newR.toString(16).padStart(2, "0")}${newG.toString(16).padStart(2, "0")}${newB.toString(16).padStart(2, "0")}`;
56
+ }
57
+ formatMessageContent(content) {
58
+ const escapeHtml = (text) => {
59
+ const div = document.createElement("div");
60
+ div.textContent = text;
61
+ return div.innerHTML;
62
+ };
63
+ let processedContent = content.replace(/(\d+\.\s+[^0-9]+?)(?=\s+\d+\.\s+|\s*$)/g, "$1\n");
64
+ processedContent = processedContent.replace(/(-\s+[^-]+?)(?=\s+-\s+|\s*$)/g, "$1\n");
65
+ const lines = processedContent.split("\n");
66
+ let formattedContent = "";
67
+ let inList = false;
68
+ let listType = null;
69
+ for (let i = 0; i < lines.length; i++) {
70
+ const line = lines[i];
71
+ const trimmedLine = line.trim();
72
+ const unorderedMatch = trimmedLine.match(/^[-*•]\s+(.+)$/);
73
+ const orderedMatch = trimmedLine.match(/^\d+\.\s+(.+)$/);
74
+ if (unorderedMatch) {
75
+ if (!inList || listType !== "ul") {
76
+ if (inList) formattedContent += listType === "ol" ? "</ol>" : "</ul>";
77
+ formattedContent += "<ul>";
78
+ inList = true;
79
+ listType = "ul";
80
+ }
81
+ formattedContent += `<li>${escapeHtml(unorderedMatch[1])}</li>`;
82
+ } else if (orderedMatch) {
83
+ if (!inList || listType !== "ol") {
84
+ if (inList) formattedContent += listType === "ol" ? "</ol>" : "</ul>";
85
+ formattedContent += "<ol>";
86
+ inList = true;
87
+ listType = "ol";
88
+ }
89
+ formattedContent += `<li>${escapeHtml(orderedMatch[1])}</li>`;
90
+ } else {
91
+ if (inList) {
92
+ formattedContent += listType === "ol" ? "</ol>" : "</ul>";
93
+ inList = false;
94
+ listType = null;
95
+ }
96
+ if (trimmedLine === "") {
97
+ formattedContent += "<br>";
98
+ } else {
99
+ formattedContent += escapeHtml(line) + "\n";
100
+ }
101
+ }
102
+ }
103
+ if (inList) {
104
+ formattedContent += listType === "ol" ? "</ol>" : "</ul>";
105
+ }
106
+ return formattedContent;
107
+ }
38
108
  connectedCallback() {
39
109
  super.connectedCallback();
40
110
  if (this.initialMessages && this.initialMessages.length > 0) {
@@ -95,6 +165,7 @@ exports.AIChat = class AIChat extends lit.LitElement {
95
165
  console.log("\u{1F50D} Raw API response:", data);
96
166
  let responseText = "No response from agent";
97
167
  let faqs = void 0;
168
+ let suggestedQuestions = void 0;
98
169
  if (data && typeof data === "object" && data.response && typeof data.response === "string") {
99
170
  console.log("\u{1F4DD} data.response type:", typeof data.response);
100
171
  console.log("\u{1F4DD} data.response preview:", data.response.substring(0, 100));
@@ -106,12 +177,15 @@ exports.AIChat = class AIChat extends lit.LitElement {
106
177
  console.log("\u2705 Parsed inner data with JSON.parse");
107
178
  if (innerData && innerData.response && typeof innerData.response === "string") {
108
179
  responseText = innerData.response;
109
- faqs = innerData.faqs_used || void 0;
180
+ faqs = innerData.faq_used || innerData.faqs_used || void 0;
181
+ suggestedQuestions = innerData.suggested_follow_ups || innerData.suggested_questions || void 0;
110
182
  console.log("\u2705 Extracted text length:", responseText.length);
111
183
  console.log("\u2705 Extracted FAQs count:", faqs?.length || 0);
184
+ console.log("\u2705 Extracted suggested questions count:", suggestedQuestions?.length || 0);
112
185
  } else {
113
186
  responseText = data.response;
114
- faqs = data.faqs_used || void 0;
187
+ faqs = data.faq_used || data.faqs_used || void 0;
188
+ suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
115
189
  }
116
190
  } catch (parseError) {
117
191
  console.warn("\u26A0\uFE0F JSON.parse failed, using regex extraction...", parseError);
@@ -124,7 +198,7 @@ exports.AIChat = class AIChat extends lit.LitElement {
124
198
  console.error("\u274C Could not extract response");
125
199
  responseText = "Error: Could not parse response";
126
200
  }
127
- const faqsPattern = /"faqs_used"\s*:\s*(\[[^\]]*\])/s;
201
+ const faqsPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[^\]]*\])/s;
128
202
  const faqsMatch = data.response.match(faqsPattern);
129
203
  if (faqsMatch) {
130
204
  try {
@@ -132,7 +206,7 @@ exports.AIChat = class AIChat extends lit.LitElement {
132
206
  console.log("\u2705 Extracted FAQs, count:", faqs?.length || 0);
133
207
  } catch {
134
208
  console.log("\u26A0\uFE0F Could not parse FAQs, trying multiline...");
135
- const faqsMultiPattern = /"faqs_used"\s*:\s*(\[[\s\S]*?\n\s*\])/;
209
+ const faqsMultiPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
136
210
  const faqsMultiMatch = data.response.match(faqsMultiPattern);
137
211
  if (faqsMultiMatch) {
138
212
  try {
@@ -144,11 +218,32 @@ exports.AIChat = class AIChat extends lit.LitElement {
144
218
  }
145
219
  }
146
220
  }
221
+ const suggestedPattern = /"(?:suggested_follow_ups|suggested_questions)"\s*:\s*(\[[^\]]*\])/s;
222
+ const suggestedMatch = data.response.match(suggestedPattern);
223
+ if (suggestedMatch) {
224
+ try {
225
+ suggestedQuestions = JSON.parse(suggestedMatch[1]);
226
+ console.log("\u2705 Extracted suggested questions, count:", suggestedQuestions?.length || 0);
227
+ } catch {
228
+ console.log("\u26A0\uFE0F Could not parse suggested questions, trying multiline...");
229
+ const suggestedMultiPattern = /"(?:suggested_follow_ups|suggested_questions)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
230
+ const suggestedMultiMatch = data.response.match(suggestedMultiPattern);
231
+ if (suggestedMultiMatch) {
232
+ try {
233
+ suggestedQuestions = JSON.parse(suggestedMultiMatch[1]);
234
+ console.log("\u2705 Extracted multi-line suggested questions, count:", suggestedQuestions?.length || 0);
235
+ } catch {
236
+ suggestedQuestions = void 0;
237
+ }
238
+ }
239
+ }
240
+ }
147
241
  }
148
242
  } else {
149
243
  console.log("\u{1F4C4} Direct text response (not JSON)");
150
244
  responseText = data.response;
151
- faqs = data.faqs_used || void 0;
245
+ faqs = data.faq_used || data.faqs_used || void 0;
246
+ suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
152
247
  }
153
248
  } else if (typeof data === "string") {
154
249
  console.log("\u{1F4C4} Response is a plain string");
@@ -156,15 +251,19 @@ exports.AIChat = class AIChat extends lit.LitElement {
156
251
  } else if (data && typeof data === "object") {
157
252
  console.warn("\u26A0\uFE0F Unexpected format, using fallback");
158
253
  responseText = data.message || data.answer || "Error: Unexpected response format";
254
+ faqs = data.faq_used || data.faqs_used || void 0;
255
+ suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
159
256
  }
160
257
  console.log("\u{1F3AF} Final responseText length:", responseText.length);
161
258
  console.log("\u{1F3AF} Final responseText preview:", responseText.substring(0, 100));
162
259
  console.log("\u{1F3AF} Final FAQs:", faqs);
260
+ console.log("\u{1F3AF} Final suggested questions:", suggestedQuestions);
163
261
  const assistantMessage = {
164
262
  id: (Date.now() + 1).toString(),
165
263
  role: "assistant",
166
264
  content: responseText,
167
- faqs
265
+ faqs,
266
+ suggestedQuestions
168
267
  };
169
268
  this.messages = [...this.messages, assistantMessage];
170
269
  this.dispatchEvent(new CustomEvent("response-received", {
@@ -192,20 +291,34 @@ Please check your API endpoint configuration.`
192
291
  }
193
292
  }
194
293
  renderChatUI() {
294
+ const primaryColorLight = this.lightenColor(this.primaryColor, 15);
195
295
  return lit.html`
196
296
  <!-- Header -->
197
- <div class="header">
297
+ <div class="header" style="--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover};">
198
298
  <div class="header-content">
299
+ <div class="header-avatar">
300
+ ${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;">
301
+ <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>
302
+ </svg>`}
303
+ </div>
199
304
  <h1 class="title">${this.chatTitle}</h1>
200
305
  </div>
201
306
  </div>
202
307
 
203
308
  <!-- Messages Area -->
204
- <div class="messages-area" style="${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}')` : ""}">
309
+ <div class="messages-area" style="--user-message-bg: ${this.userMessageBg}; --bot-message-bg: ${this.botMessageBg}; --primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight}; --primary-color-hover: ${this.primaryColorHover}; ${this.backgroundImageUrl ? `--background-image-url: url('${this.backgroundImageUrl}');` : ""}">
205
310
  <div class="messages-container">
206
311
  ${this.messages.length === 0 ? lit.html`
207
312
  <div class="empty-state">
208
- <p>How can I help you today?</p>
313
+ <div class="empty-state-avatar">
314
+ ${this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="Bot" class="empty-state-avatar-image" />` : lit.html`<svg viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2">
315
+ <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>
316
+ </svg>`}
317
+ </div>
318
+ <div class="empty-state-content">
319
+ <p class="empty-state-message">${this.welcomeMessage}</p>
320
+ ${this.welcomeSubtitle ? lit.html`<p class="empty-state-subtitle">${this.welcomeSubtitle}</p>` : ""}
321
+ </div>
209
322
  </div>
210
323
  ` : ""}
211
324
 
@@ -219,19 +332,31 @@ Please check your API endpoint configuration.`
219
332
  ${msg.role === "user" ? "U" : this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
220
333
  </div>
221
334
  <div class="message-content">
222
- <p class="message-text">${msg.content}</p>
335
+ <div class="message-text">${unsafeHtml_js.unsafeHTML(this.formatMessageContent(msg.content))}</div>
223
336
  ${msg.role === "assistant" && msg.faqs && msg.faqs.length > 0 ? lit.html`
224
337
  <div class="faq-section">
225
338
  <p class="faq-title">Related FAQs:</p>
226
339
  <ul class="faq-list">
227
340
  ${msg.faqs.map((faq) => lit.html`
228
- <li class="faq-item" @click=${() => this.handleFAQClick(faq.question)}>
341
+ <li class="faq-item-static">
229
342
  ${faq.question}
230
343
  </li>
231
344
  `)}
232
345
  </ul>
233
346
  </div>
234
347
  ` : ""}
348
+ ${msg.role === "assistant" && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? lit.html`
349
+ <div class="faq-section">
350
+ <p class="faq-title">Suggested Questions:</p>
351
+ <ul class="faq-list">
352
+ ${msg.suggestedQuestions.map((question) => lit.html`
353
+ <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
354
+ ${question}
355
+ </li>
356
+ `)}
357
+ </ul>
358
+ </div>
359
+ ` : ""}
235
360
  </div>
236
361
  </div>
237
362
  `)}
@@ -252,7 +377,7 @@ Please check your API endpoint configuration.`
252
377
  </div>
253
378
 
254
379
  <!-- Input Area -->
255
- <div class="input-area">
380
+ <div class="input-area" style="--primary-color: ${this.primaryColor}; --primary-color-hover: ${this.primaryColorHover};">
256
381
  <form class="input-form" @submit=${this.handleSubmit}>
257
382
  <input
258
383
  type="text"
@@ -285,17 +410,22 @@ Please check your API endpoint configuration.`
285
410
  `;
286
411
  }
287
412
  render() {
413
+ const primaryColorLight = this.lightenColor(this.primaryColor, 15);
288
414
  if (this.mode === "widget") {
289
415
  return lit.html`
290
416
  <div class="widget-container">
291
417
  <!-- Chat Window -->
292
- <div class=${classMap_js.classMap({ "widget-window": true, "open": this.isOpen })}>
418
+ <div
419
+ class=${classMap_js.classMap({ "widget-window": true, "open": this.isOpen })}
420
+ style="--widget-width: ${this.widgetWidth}; --widget-height: ${this.widgetHeight};"
421
+ >
293
422
  ${this.renderChatUI()}
294
423
  </div>
295
424
 
296
425
  <!-- Toggle Button -->
297
426
  <button
298
427
  class="widget-button"
428
+ style="--primary-color: ${this.primaryColor}; --primary-color-light: ${primaryColorLight};"
299
429
  @click=${this.toggleWidget}
300
430
  aria-label=${this.isOpen ? "Close chat" : "Open chat"}
301
431
  >
@@ -327,7 +457,7 @@ exports.AIChat.styles = lit.css`
327
457
  display: flex;
328
458
  flex-direction: column;
329
459
  height: 100vh;
330
- background: #fafafa;
460
+ background: #ffffff;
331
461
  }
332
462
 
333
463
  :host([mode="fullscreen"][theme="dark"]) {
@@ -351,19 +481,19 @@ exports.AIChat.styles = lit.css`
351
481
  width: 60px;
352
482
  height: 60px;
353
483
  border-radius: 50%;
354
- background: #2563eb;
484
+ background: #3681D3;
355
485
  border: none;
356
486
  cursor: pointer;
357
487
  display: flex;
358
488
  align-items: center;
359
489
  justify-content: center;
360
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
490
+ box-shadow: 0 4px 16px rgba(65, 105, 225, 0.3);
361
491
  transition: transform 0.2s, box-shadow 0.2s;
362
492
  }
363
493
 
364
494
  .widget-button:hover {
365
495
  transform: scale(1.05);
366
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
496
+ box-shadow: 0 6px 20px rgba(65, 105, 225, 0.4);
367
497
  }
368
498
 
369
499
  .widget-button svg {
@@ -376,11 +506,11 @@ exports.AIChat.styles = lit.css`
376
506
  position: absolute;
377
507
  bottom: 80px;
378
508
  right: 0;
379
- width: 380px;
380
- height: 600px;
509
+ width: var(--widget-width, 380px);
510
+ height: var(--widget-height, 600px);
381
511
  background: #fff;
382
- border-radius: 12px;
383
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
512
+ border-radius: 16px;
513
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.05);
384
514
  display: flex;
385
515
  flex-direction: column;
386
516
  overflow: hidden;
@@ -401,35 +531,251 @@ exports.AIChat.styles = lit.css`
401
531
  color: #fafafa;
402
532
  }
403
533
 
404
- @media (max-width: 480px) {
534
+ /* Tablet breakpoint */
535
+ @media (max-width: 1024px) and (min-width: 769px) {
536
+ .widget-window {
537
+ width: var(--widget-width, 400px);
538
+ height: var(--widget-height, 650px);
539
+ }
540
+ }
541
+
542
+ /* Small tablet breakpoint */
543
+ @media (max-width: 768px) and (min-width: 481px) {
544
+ .widget-window {
545
+ width: var(--widget-width, 360px);
546
+ height: var(--widget-height, 550px);
547
+ }
548
+ }
549
+
550
+ /* Mobile portrait */
551
+ @media (max-width: 480px) and (orientation: portrait) {
405
552
  .widget-window {
406
553
  width: calc(100vw - 40px);
554
+ height: 70vh;
555
+ bottom: 80px;
556
+ right: 0;
557
+ }
558
+
559
+ .widget-button {
560
+ width: 56px;
561
+ height: 56px;
562
+ }
563
+
564
+ .widget-button svg {
565
+ width: 24px;
566
+ height: 24px;
567
+ }
568
+ }
569
+
570
+ /* Mobile landscape */
571
+ @media (max-width: 900px) and (orientation: landscape) {
572
+ .widget-window {
573
+ width: var(--widget-width, 500px);
407
574
  height: calc(100vh - 100px);
408
575
  bottom: 80px;
409
576
  right: 0;
410
577
  }
578
+
579
+ .widget-button {
580
+ width: 56px;
581
+ height: 56px;
582
+ }
583
+
584
+ .widget-button svg {
585
+ width: 24px;
586
+ height: 24px;
587
+ }
588
+ }
589
+
590
+ /* Mobile responsive styles for all modes */
591
+ @media (max-width: 768px) {
592
+ .header {
593
+ padding: 0.875rem 1rem;
594
+ }
595
+
596
+ .header-avatar {
597
+ width: 2.25rem;
598
+ height: 2.25rem;
599
+ }
600
+
601
+ .title {
602
+ font-size: 1.125rem;
603
+ }
604
+
605
+ .messages-area {
606
+ padding: 1rem 0.75rem;
607
+ }
608
+
609
+ .message {
610
+ gap: 0.75rem;
611
+ }
612
+
613
+ .avatar {
614
+ width: 2rem;
615
+ height: 2rem;
616
+ font-size: 0.75rem;
617
+ }
618
+
619
+ .message-content {
620
+ max-width: 100%;
621
+ padding: 0.625rem 0.875rem;
622
+ font-size: 0.9375rem;
623
+ }
624
+
625
+ .empty-state {
626
+ margin-top: 3rem;
627
+ }
628
+
629
+ .empty-state p {
630
+ font-size: 1.25rem;
631
+ padding: 0 1rem;
632
+ }
633
+
634
+ .faq-section {
635
+ margin-top: 0.75rem;
636
+ padding-top: 0.75rem;
637
+ }
638
+
639
+ .faq-item {
640
+ font-size: 0.8125rem;
641
+ padding: 0;
642
+ }
643
+
644
+ .input-area {
645
+ padding: 0.75rem;
646
+ }
647
+
648
+ .input-form {
649
+ gap: 0.5rem;
650
+ }
651
+
652
+ .input-field {
653
+ height: 2.75rem;
654
+ padding: 0 0.875rem;
655
+ font-size: 0.9375rem;
656
+ }
657
+
658
+ .send-button {
659
+ width: 2.75rem;
660
+ height: 2.75rem;
661
+ flex-shrink: 0;
662
+ }
663
+
664
+ .send-icon {
665
+ width: 1.125rem;
666
+ height: 1.125rem;
667
+ }
668
+ }
669
+
670
+ /* Extra small screens */
671
+ @media (max-width: 480px) {
672
+ .header {
673
+ padding: 0.75rem 0.875rem;
674
+ }
675
+
676
+ .header-avatar {
677
+ width: 2rem;
678
+ height: 2rem;
679
+ }
680
+
681
+ .title {
682
+ font-size: 1rem;
683
+ }
684
+
685
+ .messages-area {
686
+ padding: 0.75rem 0.5rem;
687
+ }
688
+
689
+ .message {
690
+ gap: 0.5rem;
691
+ }
692
+
693
+ .avatar {
694
+ width: 1.75rem;
695
+ height: 1.75rem;
696
+ font-size: 0.7rem;
697
+ }
698
+
699
+ .message-content {
700
+ padding: 0.5rem 0.75rem;
701
+ font-size: 0.875rem;
702
+ border-radius: 0.75rem;
703
+ }
704
+
705
+ .empty-state {
706
+ margin-top: 2rem;
707
+ }
708
+
709
+ .empty-state p {
710
+ font-size: 1.125rem;
711
+ }
712
+
713
+ .input-area {
714
+ padding: 0.625rem;
715
+ }
716
+
717
+ .input-field {
718
+ height: 2.5rem;
719
+ padding: 0 0.75rem;
720
+ font-size: 0.875rem;
721
+ }
722
+
723
+ .send-button {
724
+ width: 2.5rem;
725
+ height: 2.5rem;
726
+ }
727
+
728
+ .version-tag {
729
+ font-size: 0.7rem;
730
+ padding: 0.375rem;
731
+ }
411
732
  }
412
733
 
413
734
  .header {
414
- border-bottom: 1px solid #e4e4e7;
415
- background: #fff;
416
- padding: 1rem;
735
+ background:#3681D3;
736
+ padding: 1rem 1.25rem;
737
+ display: flex;
738
+ align-items: center;
739
+ gap: 0.75rem;
740
+ box-shadow: 0 2px 8px rgba(65, 105, 225, 0.2);
417
741
  }
418
742
 
419
743
  :host([theme="dark"]) .header {
420
- border-bottom-color: #27272a;
421
- background: #18181b;
744
+ background: #3681D3
422
745
  }
423
746
 
424
747
  .header-content {
425
748
  max-width: 56rem;
426
749
  margin: 0 auto;
750
+ display: flex;
751
+ align-items: center;
752
+ gap: 0.75rem;
753
+ width: 100%;
754
+ }
755
+
756
+ .header-avatar {
757
+ width: 2.5rem;
758
+ height: 2.5rem;
759
+ border-radius: 50%;
760
+ background: #fff;
761
+ display: flex;
762
+ align-items: center;
763
+ justify-content: center;
764
+ overflow: hidden;
765
+ flex-shrink: 0;
766
+ }
767
+
768
+ .header-avatar-image {
769
+ width: 100%;
770
+ height: 100%;
771
+ object-fit: cover;
427
772
  }
428
773
 
429
774
  .title {
430
775
  font-size: 1.25rem;
431
776
  font-weight: 600;
432
777
  margin: 0;
778
+ color: #fff;
433
779
  }
434
780
 
435
781
  .messages-area {
@@ -437,6 +783,11 @@ exports.AIChat.styles = lit.css`
437
783
  overflow-y: auto;
438
784
  padding: 1.5rem 1rem;
439
785
  position: relative;
786
+ background: #ffffff;
787
+ }
788
+
789
+ :host([theme="dark"]) .messages-area {
790
+ background: #000;
440
791
  }
441
792
 
442
793
  .messages-area::before {
@@ -450,7 +801,7 @@ exports.AIChat.styles = lit.css`
450
801
  background-size: 200px auto 60%;
451
802
  background-position: center center;
452
803
  background-repeat: no-repeat;
453
- opacity: 0.5;
804
+ opacity: 0.03;
454
805
  pointer-events: none;
455
806
  z-index: 0;
456
807
  }
@@ -467,18 +818,74 @@ exports.AIChat.styles = lit.css`
467
818
 
468
819
  .empty-state {
469
820
  text-align: center;
470
- color: #71717a;
471
821
  margin-top: 5rem;
822
+ display: flex;
823
+ flex-direction: column;
824
+ align-items: center;
825
+ gap: 1.5rem;
472
826
  }
473
827
 
474
828
  :host([theme="dark"]) .empty-state {
475
829
  color: #a1a1aa;
476
830
  }
477
831
 
478
- .empty-state p {
479
- font-size: 1.5rem;
480
- font-weight: 500;
832
+ .empty-state-avatar {
833
+ width: 5rem;
834
+ height: 5rem;
835
+ border-radius: 50%;
836
+ background: #E5E7EB;
837
+ display: flex;
838
+ align-items: center;
839
+ justify-content: center;
840
+ overflow: hidden;
841
+ }
842
+
843
+ :host([theme="dark"]) .empty-state-avatar {
844
+ background: #3f3f46;
845
+ }
846
+
847
+ .empty-state-avatar-image {
848
+ width: 100%;
849
+ height: 100%;
850
+ object-fit: cover;
851
+ }
852
+
853
+ .empty-state-avatar svg {
854
+ width: 3rem;
855
+ height: 3rem;
856
+ color: #9ca3af;
857
+ }
858
+
859
+ :host([theme="dark"]) .empty-state-avatar svg {
860
+ color: #6b7280;
861
+ }
862
+
863
+ .empty-state-content {
864
+ display: flex;
865
+ flex-direction: column;
866
+ gap: 0.5rem;
867
+ }
868
+
869
+ .empty-state-message {
870
+ font-size: 1.25rem;
871
+ font-weight: 600;
872
+ margin: 0;
873
+ color: #374151;
874
+ }
875
+
876
+ :host([theme="dark"]) .empty-state-message {
877
+ color: #f3f4f6;
878
+ }
879
+
880
+ .empty-state-subtitle {
881
+ font-size: 0.9375rem;
481
882
  margin: 0;
883
+ color: #6b7280;
884
+ max-width: 24rem;
885
+ }
886
+
887
+ :host([theme="dark"]) .empty-state-subtitle {
888
+ color: #9ca3af;
482
889
  }
483
890
 
484
891
  .message {
@@ -494,18 +901,20 @@ exports.AIChat.styles = lit.css`
494
901
  width: 2.5rem;
495
902
  height: 2.5rem;
496
903
  border-radius: 9999px;
497
- background: #e4e4e7;
904
+ background: #E5E7EB;
498
905
  display: flex;
499
906
  align-items: center;
500
907
  justify-content: center;
501
908
  flex-shrink: 0;
502
- font-weight: 500;
909
+ font-weight: 600;
503
910
  font-size: 0.875rem;
504
911
  overflow: hidden;
912
+ color: #6B7280;
505
913
  }
506
914
 
507
915
  :host([theme="dark"]) .avatar {
508
916
  background: #3f3f46;
917
+ color: #9ca3af;
509
918
  }
510
919
 
511
920
  .avatar-image {
@@ -516,36 +925,63 @@ exports.AIChat.styles = lit.css`
516
925
 
517
926
  .message-content {
518
927
  max-width: 36rem;
519
- padding: 0.75rem 1rem;
520
- border-radius: 1rem;
928
+ padding: 0.875rem 1.125rem;
929
+ border-radius: 1.25rem;
930
+ line-height: 1.6;
521
931
  }
522
932
 
523
933
  .message.user .message-content {
524
- background: #2563eb;
525
- color: #fff;
934
+ background: var(--user-message-bg, #D6E4FF);
935
+ color: #1a1a1a;
936
+ border-radius: 1.25rem 1.25rem 0.25rem 1.25rem;
526
937
  }
527
938
 
528
939
  .message.assistant .message-content {
529
- background: #fff;
530
- border: 1px solid #e4e4e7;
531
- color: #09090b;
940
+ background: var(--bot-message-bg, #F5F5F5);
941
+ color: #1a1a1a;
942
+ border-radius: 1.25rem 1.25rem 1.25rem 0.25rem;
943
+ }
944
+
945
+ :host([theme="dark"]) .message.user .message-content {
946
+ background: #3D5A99;
947
+ color: #fff;
532
948
  }
533
949
 
534
950
  :host([theme="dark"]) .message.assistant .message-content {
535
951
  background: #27272a;
536
- border-color: #3f3f46;
537
952
  color: #fafafa;
538
953
  }
539
954
 
540
955
  .message-text {
541
956
  white-space: pre-wrap;
542
957
  margin: 0;
958
+ word-wrap: break-word;
959
+ }
960
+
961
+ .message-text ul,
962
+ .message-text ol {
963
+ margin: 0.5rem 0;
964
+ padding-left: 1.5rem;
965
+ white-space: normal;
966
+ }
967
+
968
+ .message-text li {
969
+ margin: 0.25rem 0;
970
+ white-space: normal;
971
+ }
972
+
973
+ .message-text ul {
974
+ list-style-type: disc;
975
+ }
976
+
977
+ .message-text ol {
978
+ list-style-type: decimal;
543
979
  }
544
980
 
545
981
  .faq-section {
546
- margin-top: 1rem;
547
- padding-top: 1rem;
548
- border-top: 1px solid #e4e4e7;
982
+ margin-top: 0.75rem;
983
+ padding-top: 0.75rem;
984
+ border-top: 1px solid #d1d5db;
549
985
  }
550
986
 
551
987
  :host([theme="dark"]) .faq-section {
@@ -554,13 +990,13 @@ exports.AIChat.styles = lit.css`
554
990
 
555
991
  .faq-title {
556
992
  font-size: 0.875rem;
557
- font-weight: 500;
558
- color: #3f3f46;
559
- margin: 0 0 0.5rem 0;
993
+ font-weight: 600;
994
+ color: var(--primary-color, #3681D3);
995
+ margin: 0 0 0.375rem 0;
560
996
  }
561
997
 
562
998
  :host([theme="dark"]) .faq-title {
563
- color: #d4d4d8;
999
+ color: var(--primary-color-light, #5B7FE8);
564
1000
  }
565
1001
 
566
1002
  .faq-list {
@@ -569,30 +1005,46 @@ exports.AIChat.styles = lit.css`
569
1005
  margin: 0;
570
1006
  display: flex;
571
1007
  flex-direction: column;
572
- gap: 0.5rem;
1008
+ gap: 0.375rem;
573
1009
  }
574
1010
 
575
1011
  .faq-item {
576
1012
  font-size: 0.875rem;
577
- color: #52525b;
578
- padding: 0.5rem;
579
- border-radius: 0.375rem;
1013
+ color: var(--primary-color, #3681D3);
1014
+ padding: 0;
1015
+ border-radius: 0.5rem;
580
1016
  cursor: pointer;
581
1017
  transition: background-color 0.2s, color 0.2s;
1018
+ border: 1px solid transparent;
582
1019
  }
583
1020
 
584
1021
  .faq-item:hover {
585
- background-color: #f4f4f5;
586
- color: #18181b;
1022
+ background-color: #EEF2FF;
1023
+ color: var(--primary-color-hover, #3457C7);
1024
+ border-color: #C7D2FE;
587
1025
  }
588
1026
 
589
1027
  :host([theme="dark"]) .faq-item {
590
- color: #a1a1aa;
1028
+ color: var(--primary-color-light, #5B7FE8);
591
1029
  }
592
1030
 
593
1031
  :host([theme="dark"]) .faq-item:hover {
594
- background-color: #27272a;
595
- color: #fafafa;
1032
+ background-color: #1e293b;
1033
+ color: #93C5FD;
1034
+ border-color: #3f3f46;
1035
+ }
1036
+
1037
+ .faq-item-static {
1038
+ font-size: 0.875rem;
1039
+ color: #6B7280;
1040
+ padding: 0;
1041
+ border-radius: 0.5rem;
1042
+ cursor: default;
1043
+ border: 1px solid transparent;
1044
+ }
1045
+
1046
+ :host([theme="dark"]) .faq-item-static {
1047
+ color: #9CA3AF;
596
1048
  }
597
1049
 
598
1050
  .loading {
@@ -615,14 +1067,14 @@ exports.AIChat.styles = lit.css`
615
1067
  }
616
1068
 
617
1069
  .input-area {
618
- border-top: 1px solid #e4e4e7;
1070
+ border-top: 1px solid #e5e7eb;
619
1071
  background: #fff;
620
- padding: 1rem;
1072
+ padding: 1rem 1.25rem;
621
1073
  }
622
1074
 
623
1075
  :host([theme="dark"]) .input-area {
624
1076
  border-top-color: #27272a;
625
- background: #000;
1077
+ background: #18181b;
626
1078
  }
627
1079
 
628
1080
  .input-form {
@@ -630,18 +1082,24 @@ exports.AIChat.styles = lit.css`
630
1082
  margin: 0 auto;
631
1083
  display: flex;
632
1084
  gap: 0.75rem;
1085
+ align-items: center;
633
1086
  }
634
1087
 
635
1088
  .input-field {
636
1089
  flex: 1;
637
1090
  height: 3rem;
638
1091
  padding: 0 1rem;
639
- border: 1px solid #e4e4e7;
640
- border-radius: 0.5rem;
641
- font-size: 1rem;
1092
+ border: 1px solid #d1d5db;
1093
+ border-radius: 1.5rem;
1094
+ font-size: 0.9375rem;
642
1095
  font-family: inherit;
643
1096
  background: #fff;
644
- color: #09090b;
1097
+ color: #374151;
1098
+ transition: border-color 0.2s, box-shadow 0.2s;
1099
+ }
1100
+
1101
+ .input-field::placeholder {
1102
+ color: #9ca3af;
645
1103
  }
646
1104
 
647
1105
  :host([theme="dark"]) .input-field {
@@ -651,8 +1109,9 @@ exports.AIChat.styles = lit.css`
651
1109
  }
652
1110
 
653
1111
  .input-field:focus {
654
- outline: 2px solid #2563eb;
655
- outline-offset: 2px;
1112
+ outline: none;
1113
+ border-color: var(--primary-color, #3681D3);
1114
+ box-shadow: 0 0 0 3px rgba(65, 105, 225, 0.1);
656
1115
  }
657
1116
 
658
1117
  .input-field:disabled {
@@ -665,17 +1124,23 @@ exports.AIChat.styles = lit.css`
665
1124
  height: 3rem;
666
1125
  border-radius: 9999px;
667
1126
  border: none;
668
- background: #2563eb;
1127
+ background: var(--primary-color, #3681D3);
669
1128
  color: #fff;
670
1129
  cursor: pointer;
671
1130
  display: flex;
672
1131
  align-items: center;
673
1132
  justify-content: center;
674
- transition: background 0.2s;
1133
+ transition: background 0.2s, transform 0.1s;
1134
+ flex-shrink: 0;
675
1135
  }
676
1136
 
677
1137
  .send-button:hover:not(:disabled) {
678
- background: #1d4ed8;
1138
+ background: var(--primary-color-hover, #3457C7);
1139
+ transform: scale(1.05);
1140
+ }
1141
+
1142
+ .send-button:active:not(:disabled) {
1143
+ transform: scale(0.95);
679
1144
  }
680
1145
 
681
1146
  .send-button:disabled {
@@ -692,12 +1157,12 @@ exports.AIChat.styles = lit.css`
692
1157
  text-align: center;
693
1158
  padding: 0.5rem;
694
1159
  font-size: 0.75rem;
695
- color: #71717a;
696
- border-top: 1px solid #e4e4e7;
1160
+ color: #9ca3af;
1161
+ border-top: 1px solid #e5e7eb;
697
1162
  }
698
1163
 
699
1164
  :host([theme="dark"]) .version-tag {
700
- color: #a1a1aa;
1165
+ color: #6b7280;
701
1166
  border-top-color: #27272a;
702
1167
  }
703
1168
  `;
@@ -709,7 +1174,15 @@ exports.AIChat.properties = {
709
1174
  mode: { type: String, reflect: true },
710
1175
  initialMessages: { type: Array },
711
1176
  botAvatarUrl: { type: String, attribute: "bot-avatar-url" },
712
- backgroundImageUrl: { type: String, attribute: "background-image-url" }
1177
+ backgroundImageUrl: { type: String, attribute: "background-image-url" },
1178
+ widgetWidth: { type: String, attribute: "widget-width" },
1179
+ widgetHeight: { type: String, attribute: "widget-height" },
1180
+ primaryColor: { type: String, attribute: "primary-color" },
1181
+ primaryColorHover: { type: String, attribute: "primary-color-hover" },
1182
+ userMessageBg: { type: String, attribute: "user-message-bg" },
1183
+ botMessageBg: { type: String, attribute: "bot-message-bg" },
1184
+ welcomeMessage: { type: String, attribute: "welcome-message" },
1185
+ welcomeSubtitle: { type: String, attribute: "welcome-subtitle" }
713
1186
  };
714
1187
  __decorateClass([
715
1188
  decorators_js.state()