mini-chat-bot-widget 0.2.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,15 +34,17 @@ function getDefaultExportFromCjs (x) {
34
34
  var chatWidget = {exports: {}};
35
35
 
36
36
  (function (module) {
37
- // chat-widget.js - vanilla JS chat bot widget
37
+ // chat-widget.js - Modern vanilla JS chat bot widget
38
38
  var ChatWidget = /*#__PURE__*/function () {
39
39
  function ChatWidget() {
40
40
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
41
41
  _classCallCheck(this, ChatWidget);
42
- this.title = options.title || "Chat Bot";
43
- this.placeholder = options.placeholder || "Type a message...";
42
+ this.title = options.title || "Chat Assistant";
43
+ this.placeholder = options.placeholder || "Type your message...";
44
+ this.primaryColor = options.primaryColor || "#6366f1";
44
45
  this.container = null;
45
46
  this.messages = [];
47
+ this.isMinimized = false;
46
48
  this._init();
47
49
  }
48
50
  return _createClass(ChatWidget, [{
@@ -51,7 +53,7 @@ var chatWidget = {exports: {}};
51
53
  // Create container
52
54
  this.container = document.createElement("div");
53
55
  this.container.id = "chat-widget-container";
54
- this.container.innerHTML = "\n <div class=\"chat-header\">".concat(this.title, "</div>\n <div class=\"chat-messages\" id=\"chat-messages\"></div>\n <div class=\"chat-input-wrapper\">\n <input type=\"text\" id=\"chat-input\" placeholder=\"").concat(this.placeholder, "\" />\n <button id=\"chat-send\">Send</button>\n </div>\n ");
56
+ this.container.innerHTML = "\n <div class=\"chat-widget-minimized\" id=\"chat-toggle\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <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>\n </svg>\n </div>\n <div class=\"chat-widget-expanded\" id=\"chat-expanded\">\n <div class=\"chat-header\">\n <div class=\"chat-header-content\">\n <div class=\"chat-avatar\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\"></path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\n </svg>\n </div>\n <div class=\"chat-header-text\">\n <div class=\"chat-title\">".concat(this.title, "</div>\n <div class=\"chat-status\">\u25CF Online</div>\n </div>\n </div>\n <button class=\"chat-close\" id=\"chat-close\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n <div class=\"chat-messages\" id=\"chat-messages\">\n <div class=\"chat-welcome\">\n <div class=\"welcome-icon\">\uD83D\uDC4B</div>\n <div class=\"welcome-text\">Hello! How can I help you today?</div>\n </div>\n </div>\n <div class=\"chat-input-wrapper\">\n <input type=\"text\" id=\"chat-input\" placeholder=\"").concat(this.placeholder, "\" autocomplete=\"off\" />\n <button id=\"chat-send\" disabled>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n </div>\n ");
55
57
  document.body.appendChild(this.container);
56
58
  this._applyStyles();
57
59
  this._bindEvents();
@@ -60,40 +62,83 @@ var chatWidget = {exports: {}};
60
62
  key: "_applyStyles",
61
63
  value: function _applyStyles() {
62
64
  var style = document.createElement("style");
63
- style.textContent = "\n #chat-widget-container {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 300px;\n max-height: 400px;\n background: rgba(255,255,255,0.95);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n font-family: 'Inter', sans-serif;\n overflow: hidden;\n z-index: 10000;\n }\n #chat-widget-container .chat-header {\n background: linear-gradient(135deg, #6a5acd, #00bfff);\n color: white;\n padding: 8px 12px;\n font-weight: 600;\n text-align: center;\n }\n #chat-widget-container .chat-messages {\n flex: 1;\n padding: 8px 12px;\n overflow-y: auto;\n font-size: 0.9rem;\n color: #333;\n }\n #chat-widget-container .chat-input-wrapper {\n display: flex;\n border-top: 1px solid #ddd;\n }\n #chat-widget-container #chat-input {\n flex: 1;\n border: none;\n padding: 8px;\n font-size: 0.9rem;\n outline: none;\n }\n #chat-widget-container #chat-send {\n background: #6a5acd;\n color: white;\n border: none;\n padding: 0 12px;\n cursor: pointer;\n font-weight: 600;\n }\n #chat-widget-container #chat-send:hover {\n background: #5a4acb;\n }\n ";
65
+ style.textContent = "\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n #chat-widget-container {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10000;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n .chat-widget-minimized {\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, ".concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: pulse 2s infinite;\n }\n\n .chat-widget-minimized:hover {\n transform: scale(1.1);\n box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);\n }\n\n @keyframes pulse {\n 0%, 100% { box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4); }\n 50% { box-shadow: 0 8px 32px rgba(99, 102, 241, 0.6); }\n }\n\n .chat-widget-expanded {\n width: 380px;\n height: 600px;\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n display: none;\n flex-direction: column;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n .chat-widget-expanded.visible {\n display: flex;\n }\n\n .chat-header {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n padding: 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .chat-header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .chat-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(10px);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .chat-title {\n font-weight: 600;\n font-size: 16px;\n }\n\n .chat-status {\n font-size: 12px;\n opacity: 0.9;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .chat-close {\n background: transparent;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n .chat-close:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n .chat-messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background: #f9fafb;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n }\n\n .chat-welcome {\n text-align: center;\n padding: 40px 20px;\n color: #64748b;\n }\n\n .welcome-icon {\n font-size: 48px;\n margin-bottom: 12px;\n }\n\n .welcome-text {\n font-size: 15px;\n font-weight: 500;\n color: #475569;\n }\n\n .chat-message {\n display: flex;\n gap: 8px;\n animation: messageSlide 0.3s ease-out;\n }\n\n @keyframes messageSlide {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .chat-message.user {\n flex-direction: row-reverse;\n }\n\n .message-bubble {\n max-width: 75%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user .message-bubble {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.bot .message-bubble {\n background: white;\n color: #1e293b;\n border-bottom-left-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-indicator {\n display: flex;\n gap: 4px;\n padding: 12px 16px;\n background: white;\n border-radius: 16px;\n border-bottom-left-radius: 4px;\n max-width: 60px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #94a3b8;\n animation: typing 1.4s infinite;\n }\n\n .typing-dot:nth-child(2) {\n animation-delay: 0.2s;\n }\n\n .typing-dot:nth-child(3) {\n animation-delay: 0.4s;\n }\n\n @keyframes typing {\n 0%, 60%, 100% {\n transform: translateY(0);\n opacity: 0.7;\n }\n 30% {\n transform: translateY(-10px);\n opacity: 1;\n }\n }\n\n .chat-input-wrapper {\n display: flex;\n padding: 16px;\n gap: 8px;\n background: white;\n border-top: 1px solid #e2e8f0;\n }\n\n #chat-input {\n flex: 1;\n border: 2px solid #e2e8f0;\n border-radius: 12px;\n padding: 12px 16px;\n font-size: 14px;\n outline: none;\n transition: all 0.2s;\n font-family: inherit;\n }\n\n #chat-input:focus {\n border-color: ").concat(this.primaryColor, ";\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n #chat-send {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n border: none;\n border-radius: 12px;\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n #chat-send:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n #chat-send:not(:disabled):hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n }\n\n #chat-send:not(:disabled):active {\n transform: scale(0.95);\n }\n ");
64
66
  document.head.appendChild(style);
65
67
  }
66
68
  }, {
67
69
  key: "_bindEvents",
68
70
  value: function _bindEvents() {
69
71
  var _this = this;
72
+ var toggle = this.container.querySelector("#chat-toggle");
73
+ var closeBtn = this.container.querySelector("#chat-close");
74
+ var expanded = this.container.querySelector("#chat-expanded");
70
75
  var input = this.container.querySelector("#chat-input");
71
76
  var sendBtn = this.container.querySelector("#chat-send");
72
- var addMessage = function addMessage(text) {
73
- var fromUser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
74
- var msgEl = document.createElement("div");
75
- msgEl.textContent = text;
76
- msgEl.style.marginBottom = "6px";
77
- msgEl.style.textAlign = fromUser ? "right" : "left";
78
- msgEl.style.color = fromUser ? "#0066cc" : "#333";
79
- _this.container.querySelector("#chat-messages").appendChild(msgEl);
80
- _this.container.querySelector("#chat-messages").scrollTop = 9999;
81
- };
77
+ toggle.addEventListener("click", function () {
78
+ toggle.style.display = "none";
79
+ expanded.classList.add("visible");
80
+ input.focus();
81
+ });
82
+ closeBtn.addEventListener("click", function () {
83
+ expanded.classList.remove("visible");
84
+ toggle.style.display = "flex";
85
+ });
86
+ input.addEventListener("input", function () {
87
+ sendBtn.disabled = !input.value.trim();
88
+ });
82
89
  var send = function send() {
83
90
  var text = input.value.trim();
84
91
  if (!text) return;
85
- addMessage(text, true);
92
+ _this._addMessage(text, true);
86
93
  input.value = "";
87
- // Simple echo bot – replace with real logic or API call
94
+ sendBtn.disabled = true;
95
+ _this._showTypingIndicator();
88
96
  setTimeout(function () {
89
- return addMessage("You said: " + text, false);
90
- }, 500);
97
+ _this._hideTypingIndicator();
98
+ _this._addMessage("Thanks for your message! You said: \"".concat(text, "\""), false);
99
+ }, 1000 + Math.random() * 1000);
91
100
  };
92
101
  sendBtn.addEventListener("click", send);
93
102
  input.addEventListener("keypress", function (e) {
94
- if (e.key === "Enter") send();
103
+ if (e.key === "Enter" && !sendBtn.disabled) send();
95
104
  });
96
105
  }
106
+ }, {
107
+ key: "_addMessage",
108
+ value: function _addMessage(text, isUser) {
109
+ var messagesContainer = this.container.querySelector("#chat-messages");
110
+ var welcome = messagesContainer.querySelector(".chat-welcome");
111
+ if (welcome) welcome.remove();
112
+ var messageEl = document.createElement("div");
113
+ messageEl.className = "chat-message ".concat(isUser ? "user" : "bot");
114
+ messageEl.innerHTML = "<div class=\"message-bubble\">".concat(this._escapeHtml(text), "</div>");
115
+ messagesContainer.appendChild(messageEl);
116
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
117
+ }
118
+ }, {
119
+ key: "_showTypingIndicator",
120
+ value: function _showTypingIndicator() {
121
+ var messagesContainer = this.container.querySelector("#chat-messages");
122
+ var indicator = document.createElement("div");
123
+ indicator.className = "chat-message bot";
124
+ indicator.id = "typing-indicator";
125
+ indicator.innerHTML = "\n <div class=\"typing-indicator\">\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n </div>\n ";
126
+ messagesContainer.appendChild(indicator);
127
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
128
+ }
129
+ }, {
130
+ key: "_hideTypingIndicator",
131
+ value: function _hideTypingIndicator() {
132
+ var indicator = this.container.querySelector("#typing-indicator");
133
+ if (indicator) indicator.remove();
134
+ }
135
+ }, {
136
+ key: "_escapeHtml",
137
+ value: function _escapeHtml(text) {
138
+ var div = document.createElement("div");
139
+ div.textContent = text;
140
+ return div.innerHTML;
141
+ }
97
142
  }]);
98
143
  }(); // Export as UMD and ESM compatible
99
144
  {
@@ -1 +1 @@
1
- function n(n,t,i){return t&&function(n,t){for(var i=0;i<t.length;i++){var r=t[i];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,e(r.key),r)}}(n.prototype,t),Object.defineProperty(n,"prototype",{writable:!1}),n}function e(n){var e=function(n,e){if("object"!=typeof n||!n)return n;var t=n[Symbol.toPrimitive];if(void 0!==t){var i=t.call(n,e);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}(n,"string");return"symbol"==typeof e?e:e+""}function t(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var i,r,a={exports:{}};i=a,r=function(){return n(function n(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this.title=e.title||"Chat Bot",this.placeholder=e.placeholder||"Type a message...",this.container=null,this.messages=[],this._init()},[{key:"_init",value:function(){this.container=document.createElement("div"),this.container.id="chat-widget-container",this.container.innerHTML='\n <div class="chat-header">'.concat(this.title,'</div>\n <div class="chat-messages" id="chat-messages"></div>\n <div class="chat-input-wrapper">\n <input type="text" id="chat-input" placeholder="').concat(this.placeholder,'" />\n <button id="chat-send">Send</button>\n </div>\n '),document.body.appendChild(this.container),this._applyStyles(),this._bindEvents()}},{key:"_applyStyles",value:function(){var n=document.createElement("style");n.textContent="\n #chat-widget-container {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 300px;\n max-height: 400px;\n background: rgba(255,255,255,0.95);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n font-family: 'Inter', sans-serif;\n overflow: hidden;\n z-index: 10000;\n }\n #chat-widget-container .chat-header {\n background: linear-gradient(135deg, #6a5acd, #00bfff);\n color: white;\n padding: 8px 12px;\n font-weight: 600;\n text-align: center;\n }\n #chat-widget-container .chat-messages {\n flex: 1;\n padding: 8px 12px;\n overflow-y: auto;\n font-size: 0.9rem;\n color: #333;\n }\n #chat-widget-container .chat-input-wrapper {\n display: flex;\n border-top: 1px solid #ddd;\n }\n #chat-widget-container #chat-input {\n flex: 1;\n border: none;\n padding: 8px;\n font-size: 0.9rem;\n outline: none;\n }\n #chat-widget-container #chat-send {\n background: #6a5acd;\n color: white;\n border: none;\n padding: 0 12px;\n cursor: pointer;\n font-weight: 600;\n }\n #chat-widget-container #chat-send:hover {\n background: #5a4acb;\n }\n ",document.head.appendChild(n)}},{key:"_bindEvents",value:function(){var n=this,e=this.container.querySelector("#chat-input"),t=this.container.querySelector("#chat-send"),i=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=document.createElement("div");i.textContent=e,i.style.marginBottom="6px",i.style.textAlign=t?"right":"left",i.style.color=t?"#0066cc":"#333",n.container.querySelector("#chat-messages").appendChild(i),n.container.querySelector("#chat-messages").scrollTop=9999},r=function(){var n=e.value.trim();n&&(i(n,!0),e.value="",setTimeout(function(){return i("You said: "+n,!1)},500))};t.addEventListener("click",r),e.addEventListener("keypress",function(n){"Enter"===n.key&&r()})}}])}(),i.exports=r;var o=t(a.exports);export{o as default};
1
+ function n(n,t,i){return t&&function(n,t){for(var i=0;i<t.length;i++){var a=t[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(n,e(a.key),a)}}(n.prototype,t),Object.defineProperty(n,"prototype",{writable:!1}),n}function e(n){var e=function(n,e){if("object"!=typeof n||!n)return n;var t=n[Symbol.toPrimitive];if(void 0!==t){var i=t.call(n,e);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}(n,"string");return"symbol"==typeof e?e:e+""}function t(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var i,a,o={exports:{}};i=o,a=function(){return n(function n(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this.title=e.title||"Chat Assistant",this.placeholder=e.placeholder||"Type your message...",this.primaryColor=e.primaryColor||"#6366f1",this.container=null,this.messages=[],this.isMinimized=!1,this._init()},[{key:"_init",value:function(){this.container=document.createElement("div"),this.container.id="chat-widget-container",this.container.innerHTML='\n <div class="chat-widget-minimized" id="chat-toggle">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <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>\n </svg>\n </div>\n <div class="chat-widget-expanded" id="chat-expanded">\n <div class="chat-header">\n <div class="chat-header-content">\n <div class="chat-avatar">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path>\n <path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>\n </svg>\n </div>\n <div class="chat-header-text">\n <div class="chat-title">'.concat(this.title,'</div>\n <div class="chat-status">● Online</div>\n </div>\n </div>\n <button class="chat-close" id="chat-close">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="18" y1="6" x2="6" y2="18"></line>\n <line x1="6" y1="6" x2="18" y2="18"></line>\n </svg>\n </button>\n </div>\n <div class="chat-messages" id="chat-messages">\n <div class="chat-welcome">\n <div class="welcome-icon">👋</div>\n <div class="welcome-text">Hello! How can I help you today?</div>\n </div>\n </div>\n <div class="chat-input-wrapper">\n <input type="text" id="chat-input" placeholder="').concat(this.placeholder,'" autocomplete="off" />\n <button id="chat-send" disabled>\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="22" y1="2" x2="11" y2="13"></line>\n <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>\n </svg>\n </button>\n </div>\n </div>\n '),document.body.appendChild(this.container),this._applyStyles(),this._bindEvents()}},{key:"_applyStyles",value:function(){var n=document.createElement("style");n.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n #chat-widget-container {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10000;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n .chat-widget-minimized {\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, ".concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: pulse 2s infinite;\n }\n\n .chat-widget-minimized:hover {\n transform: scale(1.1);\n box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);\n }\n\n @keyframes pulse {\n 0%, 100% { box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4); }\n 50% { box-shadow: 0 8px 32px rgba(99, 102, 241, 0.6); }\n }\n\n .chat-widget-expanded {\n width: 380px;\n height: 600px;\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n display: none;\n flex-direction: column;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n .chat-widget-expanded.visible {\n display: flex;\n }\n\n .chat-header {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n padding: 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .chat-header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .chat-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(10px);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .chat-title {\n font-weight: 600;\n font-size: 16px;\n }\n\n .chat-status {\n font-size: 12px;\n opacity: 0.9;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .chat-close {\n background: transparent;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n .chat-close:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n .chat-messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background: #f9fafb;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n }\n\n .chat-welcome {\n text-align: center;\n padding: 40px 20px;\n color: #64748b;\n }\n\n .welcome-icon {\n font-size: 48px;\n margin-bottom: 12px;\n }\n\n .welcome-text {\n font-size: 15px;\n font-weight: 500;\n color: #475569;\n }\n\n .chat-message {\n display: flex;\n gap: 8px;\n animation: messageSlide 0.3s ease-out;\n }\n\n @keyframes messageSlide {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .chat-message.user {\n flex-direction: row-reverse;\n }\n\n .message-bubble {\n max-width: 75%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user .message-bubble {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.bot .message-bubble {\n background: white;\n color: #1e293b;\n border-bottom-left-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-indicator {\n display: flex;\n gap: 4px;\n padding: 12px 16px;\n background: white;\n border-radius: 16px;\n border-bottom-left-radius: 4px;\n max-width: 60px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #94a3b8;\n animation: typing 1.4s infinite;\n }\n\n .typing-dot:nth-child(2) {\n animation-delay: 0.2s;\n }\n\n .typing-dot:nth-child(3) {\n animation-delay: 0.4s;\n }\n\n @keyframes typing {\n 0%, 60%, 100% {\n transform: translateY(0);\n opacity: 0.7;\n }\n 30% {\n transform: translateY(-10px);\n opacity: 1;\n }\n }\n\n .chat-input-wrapper {\n display: flex;\n padding: 16px;\n gap: 8px;\n background: white;\n border-top: 1px solid #e2e8f0;\n }\n\n #chat-input {\n flex: 1;\n border: 2px solid #e2e8f0;\n border-radius: 12px;\n padding: 12px 16px;\n font-size: 14px;\n outline: none;\n transition: all 0.2s;\n font-family: inherit;\n }\n\n #chat-input:focus {\n border-color: ").concat(this.primaryColor,";\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n #chat-send {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n border: none;\n border-radius: 12px;\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n #chat-send:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n #chat-send:not(:disabled):hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n }\n\n #chat-send:not(:disabled):active {\n transform: scale(0.95);\n }\n "),document.head.appendChild(n)}},{key:"_bindEvents",value:function(){var n=this,e=this.container.querySelector("#chat-toggle"),t=this.container.querySelector("#chat-close"),i=this.container.querySelector("#chat-expanded"),a=this.container.querySelector("#chat-input"),o=this.container.querySelector("#chat-send");e.addEventListener("click",function(){e.style.display="none",i.classList.add("visible"),a.focus()}),t.addEventListener("click",function(){i.classList.remove("visible"),e.style.display="flex"}),a.addEventListener("input",function(){o.disabled=!a.value.trim()});var r=function(){var e=a.value.trim();e&&(n._addMessage(e,!0),a.value="",o.disabled=!0,n._showTypingIndicator(),setTimeout(function(){n._hideTypingIndicator(),n._addMessage('Thanks for your message! You said: "'.concat(e,'"'),!1)},1e3+1e3*Math.random()))};o.addEventListener("click",r),a.addEventListener("keypress",function(n){"Enter"!==n.key||o.disabled||r()})}},{key:"_addMessage",value:function(n,e){var t=this.container.querySelector("#chat-messages"),i=t.querySelector(".chat-welcome");i&&i.remove();var a=document.createElement("div");a.className="chat-message ".concat(e?"user":"bot"),a.innerHTML='<div class="message-bubble">'.concat(this._escapeHtml(n),"</div>"),t.appendChild(a),t.scrollTop=t.scrollHeight}},{key:"_showTypingIndicator",value:function(){var n=this.container.querySelector("#chat-messages"),e=document.createElement("div");e.className="chat-message bot",e.id="typing-indicator",e.innerHTML='\n <div class="typing-indicator">\n <div class="typing-dot"></div>\n <div class="typing-dot"></div>\n <div class="typing-dot"></div>\n </div>\n ',n.appendChild(e),n.scrollTop=n.scrollHeight}},{key:"_hideTypingIndicator",value:function(){var n=this.container.querySelector("#typing-indicator");n&&n.remove()}},{key:"_escapeHtml",value:function(n){var e=document.createElement("div");return e.textContent=n,e.innerHTML}}])}(),i.exports=a;var r=t(o.exports);export{r as default};
@@ -40,15 +40,17 @@
40
40
  var chatWidget = {exports: {}};
41
41
 
42
42
  (function (module) {
43
- // chat-widget.js - vanilla JS chat bot widget
43
+ // chat-widget.js - Modern vanilla JS chat bot widget
44
44
  var ChatWidget = /*#__PURE__*/function () {
45
45
  function ChatWidget() {
46
46
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
47
47
  _classCallCheck(this, ChatWidget);
48
- this.title = options.title || "Chat Bot";
49
- this.placeholder = options.placeholder || "Type a message...";
48
+ this.title = options.title || "Chat Assistant";
49
+ this.placeholder = options.placeholder || "Type your message...";
50
+ this.primaryColor = options.primaryColor || "#6366f1";
50
51
  this.container = null;
51
52
  this.messages = [];
53
+ this.isMinimized = false;
52
54
  this._init();
53
55
  }
54
56
  return _createClass(ChatWidget, [{
@@ -57,7 +59,7 @@
57
59
  // Create container
58
60
  this.container = document.createElement("div");
59
61
  this.container.id = "chat-widget-container";
60
- this.container.innerHTML = "\n <div class=\"chat-header\">".concat(this.title, "</div>\n <div class=\"chat-messages\" id=\"chat-messages\"></div>\n <div class=\"chat-input-wrapper\">\n <input type=\"text\" id=\"chat-input\" placeholder=\"").concat(this.placeholder, "\" />\n <button id=\"chat-send\">Send</button>\n </div>\n ");
62
+ this.container.innerHTML = "\n <div class=\"chat-widget-minimized\" id=\"chat-toggle\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <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>\n </svg>\n </div>\n <div class=\"chat-widget-expanded\" id=\"chat-expanded\">\n <div class=\"chat-header\">\n <div class=\"chat-header-content\">\n <div class=\"chat-avatar\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\"></path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\n </svg>\n </div>\n <div class=\"chat-header-text\">\n <div class=\"chat-title\">".concat(this.title, "</div>\n <div class=\"chat-status\">\u25CF Online</div>\n </div>\n </div>\n <button class=\"chat-close\" id=\"chat-close\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n <div class=\"chat-messages\" id=\"chat-messages\">\n <div class=\"chat-welcome\">\n <div class=\"welcome-icon\">\uD83D\uDC4B</div>\n <div class=\"welcome-text\">Hello! How can I help you today?</div>\n </div>\n </div>\n <div class=\"chat-input-wrapper\">\n <input type=\"text\" id=\"chat-input\" placeholder=\"").concat(this.placeholder, "\" autocomplete=\"off\" />\n <button id=\"chat-send\" disabled>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n </div>\n ");
61
63
  document.body.appendChild(this.container);
62
64
  this._applyStyles();
63
65
  this._bindEvents();
@@ -66,40 +68,83 @@
66
68
  key: "_applyStyles",
67
69
  value: function _applyStyles() {
68
70
  var style = document.createElement("style");
69
- style.textContent = "\n #chat-widget-container {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 300px;\n max-height: 400px;\n background: rgba(255,255,255,0.95);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n font-family: 'Inter', sans-serif;\n overflow: hidden;\n z-index: 10000;\n }\n #chat-widget-container .chat-header {\n background: linear-gradient(135deg, #6a5acd, #00bfff);\n color: white;\n padding: 8px 12px;\n font-weight: 600;\n text-align: center;\n }\n #chat-widget-container .chat-messages {\n flex: 1;\n padding: 8px 12px;\n overflow-y: auto;\n font-size: 0.9rem;\n color: #333;\n }\n #chat-widget-container .chat-input-wrapper {\n display: flex;\n border-top: 1px solid #ddd;\n }\n #chat-widget-container #chat-input {\n flex: 1;\n border: none;\n padding: 8px;\n font-size: 0.9rem;\n outline: none;\n }\n #chat-widget-container #chat-send {\n background: #6a5acd;\n color: white;\n border: none;\n padding: 0 12px;\n cursor: pointer;\n font-weight: 600;\n }\n #chat-widget-container #chat-send:hover {\n background: #5a4acb;\n }\n ";
71
+ style.textContent = "\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n #chat-widget-container {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10000;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n .chat-widget-minimized {\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, ".concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: pulse 2s infinite;\n }\n\n .chat-widget-minimized:hover {\n transform: scale(1.1);\n box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);\n }\n\n @keyframes pulse {\n 0%, 100% { box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4); }\n 50% { box-shadow: 0 8px 32px rgba(99, 102, 241, 0.6); }\n }\n\n .chat-widget-expanded {\n width: 380px;\n height: 600px;\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n display: none;\n flex-direction: column;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n .chat-widget-expanded.visible {\n display: flex;\n }\n\n .chat-header {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n padding: 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .chat-header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .chat-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(10px);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .chat-title {\n font-weight: 600;\n font-size: 16px;\n }\n\n .chat-status {\n font-size: 12px;\n opacity: 0.9;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .chat-close {\n background: transparent;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n .chat-close:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n .chat-messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background: #f9fafb;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n }\n\n .chat-welcome {\n text-align: center;\n padding: 40px 20px;\n color: #64748b;\n }\n\n .welcome-icon {\n font-size: 48px;\n margin-bottom: 12px;\n }\n\n .welcome-text {\n font-size: 15px;\n font-weight: 500;\n color: #475569;\n }\n\n .chat-message {\n display: flex;\n gap: 8px;\n animation: messageSlide 0.3s ease-out;\n }\n\n @keyframes messageSlide {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .chat-message.user {\n flex-direction: row-reverse;\n }\n\n .message-bubble {\n max-width: 75%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user .message-bubble {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.bot .message-bubble {\n background: white;\n color: #1e293b;\n border-bottom-left-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-indicator {\n display: flex;\n gap: 4px;\n padding: 12px 16px;\n background: white;\n border-radius: 16px;\n border-bottom-left-radius: 4px;\n max-width: 60px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #94a3b8;\n animation: typing 1.4s infinite;\n }\n\n .typing-dot:nth-child(2) {\n animation-delay: 0.2s;\n }\n\n .typing-dot:nth-child(3) {\n animation-delay: 0.4s;\n }\n\n @keyframes typing {\n 0%, 60%, 100% {\n transform: translateY(0);\n opacity: 0.7;\n }\n 30% {\n transform: translateY(-10px);\n opacity: 1;\n }\n }\n\n .chat-input-wrapper {\n display: flex;\n padding: 16px;\n gap: 8px;\n background: white;\n border-top: 1px solid #e2e8f0;\n }\n\n #chat-input {\n flex: 1;\n border: 2px solid #e2e8f0;\n border-radius: 12px;\n padding: 12px 16px;\n font-size: 14px;\n outline: none;\n transition: all 0.2s;\n font-family: inherit;\n }\n\n #chat-input:focus {\n border-color: ").concat(this.primaryColor, ";\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n #chat-send {\n background: linear-gradient(135deg, ").concat(this.primaryColor, " 0%, #8b5cf6 100%);\n color: white;\n border: none;\n border-radius: 12px;\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n #chat-send:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n #chat-send:not(:disabled):hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n }\n\n #chat-send:not(:disabled):active {\n transform: scale(0.95);\n }\n ");
70
72
  document.head.appendChild(style);
71
73
  }
72
74
  }, {
73
75
  key: "_bindEvents",
74
76
  value: function _bindEvents() {
75
77
  var _this = this;
78
+ var toggle = this.container.querySelector("#chat-toggle");
79
+ var closeBtn = this.container.querySelector("#chat-close");
80
+ var expanded = this.container.querySelector("#chat-expanded");
76
81
  var input = this.container.querySelector("#chat-input");
77
82
  var sendBtn = this.container.querySelector("#chat-send");
78
- var addMessage = function addMessage(text) {
79
- var fromUser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
80
- var msgEl = document.createElement("div");
81
- msgEl.textContent = text;
82
- msgEl.style.marginBottom = "6px";
83
- msgEl.style.textAlign = fromUser ? "right" : "left";
84
- msgEl.style.color = fromUser ? "#0066cc" : "#333";
85
- _this.container.querySelector("#chat-messages").appendChild(msgEl);
86
- _this.container.querySelector("#chat-messages").scrollTop = 9999;
87
- };
83
+ toggle.addEventListener("click", function () {
84
+ toggle.style.display = "none";
85
+ expanded.classList.add("visible");
86
+ input.focus();
87
+ });
88
+ closeBtn.addEventListener("click", function () {
89
+ expanded.classList.remove("visible");
90
+ toggle.style.display = "flex";
91
+ });
92
+ input.addEventListener("input", function () {
93
+ sendBtn.disabled = !input.value.trim();
94
+ });
88
95
  var send = function send() {
89
96
  var text = input.value.trim();
90
97
  if (!text) return;
91
- addMessage(text, true);
98
+ _this._addMessage(text, true);
92
99
  input.value = "";
93
- // Simple echo bot – replace with real logic or API call
100
+ sendBtn.disabled = true;
101
+ _this._showTypingIndicator();
94
102
  setTimeout(function () {
95
- return addMessage("You said: " + text, false);
96
- }, 500);
103
+ _this._hideTypingIndicator();
104
+ _this._addMessage("Thanks for your message! You said: \"".concat(text, "\""), false);
105
+ }, 1000 + Math.random() * 1000);
97
106
  };
98
107
  sendBtn.addEventListener("click", send);
99
108
  input.addEventListener("keypress", function (e) {
100
- if (e.key === "Enter") send();
109
+ if (e.key === "Enter" && !sendBtn.disabled) send();
101
110
  });
102
111
  }
112
+ }, {
113
+ key: "_addMessage",
114
+ value: function _addMessage(text, isUser) {
115
+ var messagesContainer = this.container.querySelector("#chat-messages");
116
+ var welcome = messagesContainer.querySelector(".chat-welcome");
117
+ if (welcome) welcome.remove();
118
+ var messageEl = document.createElement("div");
119
+ messageEl.className = "chat-message ".concat(isUser ? "user" : "bot");
120
+ messageEl.innerHTML = "<div class=\"message-bubble\">".concat(this._escapeHtml(text), "</div>");
121
+ messagesContainer.appendChild(messageEl);
122
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
123
+ }
124
+ }, {
125
+ key: "_showTypingIndicator",
126
+ value: function _showTypingIndicator() {
127
+ var messagesContainer = this.container.querySelector("#chat-messages");
128
+ var indicator = document.createElement("div");
129
+ indicator.className = "chat-message bot";
130
+ indicator.id = "typing-indicator";
131
+ indicator.innerHTML = "\n <div class=\"typing-indicator\">\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n </div>\n ";
132
+ messagesContainer.appendChild(indicator);
133
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
134
+ }
135
+ }, {
136
+ key: "_hideTypingIndicator",
137
+ value: function _hideTypingIndicator() {
138
+ var indicator = this.container.querySelector("#typing-indicator");
139
+ if (indicator) indicator.remove();
140
+ }
141
+ }, {
142
+ key: "_escapeHtml",
143
+ value: function _escapeHtml(text) {
144
+ var div = document.createElement("div");
145
+ div.textContent = text;
146
+ return div.innerHTML;
147
+ }
103
148
  }]);
104
149
  }(); // Export as UMD and ESM compatible
105
150
  {
@@ -1 +1 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).ChatWidget=n()}(this,function(){"use strict";function e(e,t,i){return t&&function(e,t){for(var i=0;i<t.length;i++){var o=t[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,n(o.key),o)}}(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function n(e){var n=function(e,n){if("object"!=typeof e||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var i=t.call(e,n);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof n?n:n+""}function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var i={exports:{}};return function(n){var t=function(){return e(function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.title=n.title||"Chat Bot",this.placeholder=n.placeholder||"Type a message...",this.container=null,this.messages=[],this._init()},[{key:"_init",value:function(){this.container=document.createElement("div"),this.container.id="chat-widget-container",this.container.innerHTML='\n <div class="chat-header">'.concat(this.title,'</div>\n <div class="chat-messages" id="chat-messages"></div>\n <div class="chat-input-wrapper">\n <input type="text" id="chat-input" placeholder="').concat(this.placeholder,'" />\n <button id="chat-send">Send</button>\n </div>\n '),document.body.appendChild(this.container),this._applyStyles(),this._bindEvents()}},{key:"_applyStyles",value:function(){var e=document.createElement("style");e.textContent="\n #chat-widget-container {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 300px;\n max-height: 400px;\n background: rgba(255,255,255,0.95);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 12px;\n display: flex;\n flex-direction: column;\n font-family: 'Inter', sans-serif;\n overflow: hidden;\n z-index: 10000;\n }\n #chat-widget-container .chat-header {\n background: linear-gradient(135deg, #6a5acd, #00bfff);\n color: white;\n padding: 8px 12px;\n font-weight: 600;\n text-align: center;\n }\n #chat-widget-container .chat-messages {\n flex: 1;\n padding: 8px 12px;\n overflow-y: auto;\n font-size: 0.9rem;\n color: #333;\n }\n #chat-widget-container .chat-input-wrapper {\n display: flex;\n border-top: 1px solid #ddd;\n }\n #chat-widget-container #chat-input {\n flex: 1;\n border: none;\n padding: 8px;\n font-size: 0.9rem;\n outline: none;\n }\n #chat-widget-container #chat-send {\n background: #6a5acd;\n color: white;\n border: none;\n padding: 0 12px;\n cursor: pointer;\n font-weight: 600;\n }\n #chat-widget-container #chat-send:hover {\n background: #5a4acb;\n }\n ",document.head.appendChild(e)}},{key:"_bindEvents",value:function(){var e=this,n=this.container.querySelector("#chat-input"),t=this.container.querySelector("#chat-send"),i=function(n){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=document.createElement("div");i.textContent=n,i.style.marginBottom="6px",i.style.textAlign=t?"right":"left",i.style.color=t?"#0066cc":"#333",e.container.querySelector("#chat-messages").appendChild(i),e.container.querySelector("#chat-messages").scrollTop=9999},o=function(){var e=n.value.trim();e&&(i(e,!0),n.value="",setTimeout(function(){return i("You said: "+e,!1)},500))};t.addEventListener("click",o),n.addEventListener("keypress",function(e){"Enter"===e.key&&o()})}}])}();n.exports=t}(i),t(i.exports)});
1
+ !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(n="undefined"!=typeof globalThis?globalThis:n||self).ChatWidget=e()}(this,function(){"use strict";function n(n,t,i){return t&&function(n,t){for(var i=0;i<t.length;i++){var a=t[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(n,e(a.key),a)}}(n.prototype,t),Object.defineProperty(n,"prototype",{writable:!1}),n}function e(n){var e=function(n,e){if("object"!=typeof n||!n)return n;var t=n[Symbol.toPrimitive];if(void 0!==t){var i=t.call(n,e);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(n)}(n,"string");return"symbol"==typeof e?e:e+""}function t(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var i={exports:{}};return function(e){var t=function(){return n(function n(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this.title=e.title||"Chat Assistant",this.placeholder=e.placeholder||"Type your message...",this.primaryColor=e.primaryColor||"#6366f1",this.container=null,this.messages=[],this.isMinimized=!1,this._init()},[{key:"_init",value:function(){this.container=document.createElement("div"),this.container.id="chat-widget-container",this.container.innerHTML='\n <div class="chat-widget-minimized" id="chat-toggle">\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <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>\n </svg>\n </div>\n <div class="chat-widget-expanded" id="chat-expanded">\n <div class="chat-header">\n <div class="chat-header-content">\n <div class="chat-avatar">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path>\n <path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>\n </svg>\n </div>\n <div class="chat-header-text">\n <div class="chat-title">'.concat(this.title,'</div>\n <div class="chat-status">● Online</div>\n </div>\n </div>\n <button class="chat-close" id="chat-close">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="18" y1="6" x2="6" y2="18"></line>\n <line x1="6" y1="6" x2="18" y2="18"></line>\n </svg>\n </button>\n </div>\n <div class="chat-messages" id="chat-messages">\n <div class="chat-welcome">\n <div class="welcome-icon">👋</div>\n <div class="welcome-text">Hello! How can I help you today?</div>\n </div>\n </div>\n <div class="chat-input-wrapper">\n <input type="text" id="chat-input" placeholder="').concat(this.placeholder,'" autocomplete="off" />\n <button id="chat-send" disabled>\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\n <line x1="22" y1="2" x2="11" y2="13"></line>\n <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>\n </svg>\n </button>\n </div>\n </div>\n '),document.body.appendChild(this.container),this._applyStyles(),this._bindEvents()}},{key:"_applyStyles",value:function(){var n=document.createElement("style");n.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');\n \n #chat-widget-container {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10000;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n .chat-widget-minimized {\n width: 60px;\n height: 60px;\n border-radius: 50%;\n background: linear-gradient(135deg, ".concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n animation: pulse 2s infinite;\n }\n\n .chat-widget-minimized:hover {\n transform: scale(1.1);\n box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);\n }\n\n @keyframes pulse {\n 0%, 100% { box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4); }\n 50% { box-shadow: 0 8px 32px rgba(99, 102, 241, 0.6); }\n }\n\n .chat-widget-expanded {\n width: 380px;\n height: 600px;\n background: white;\n border-radius: 16px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);\n display: none;\n flex-direction: column;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n @keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n .chat-widget-expanded.visible {\n display: flex;\n }\n\n .chat-header {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n padding: 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .chat-header-content {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .chat-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.2);\n backdrop-filter: blur(10px);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-header-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .chat-title {\n font-weight: 600;\n font-size: 16px;\n }\n\n .chat-status {\n font-size: 12px;\n opacity: 0.9;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .chat-close {\n background: transparent;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n .chat-close:hover {\n background: rgba(255, 255, 255, 0.15);\n }\n\n .chat-messages {\n flex: 1;\n padding: 20px;\n overflow-y: auto;\n background: #f9fafb;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .chat-messages::-webkit-scrollbar {\n width: 6px;\n }\n\n .chat-messages::-webkit-scrollbar-track {\n background: transparent;\n }\n\n .chat-messages::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n }\n\n .chat-welcome {\n text-align: center;\n padding: 40px 20px;\n color: #64748b;\n }\n\n .welcome-icon {\n font-size: 48px;\n margin-bottom: 12px;\n }\n\n .welcome-text {\n font-size: 15px;\n font-weight: 500;\n color: #475569;\n }\n\n .chat-message {\n display: flex;\n gap: 8px;\n animation: messageSlide 0.3s ease-out;\n }\n\n @keyframes messageSlide {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .chat-message.user {\n flex-direction: row-reverse;\n }\n\n .message-bubble {\n max-width: 75%;\n padding: 12px 16px;\n border-radius: 16px;\n font-size: 14px;\n line-height: 1.5;\n word-wrap: break-word;\n }\n\n .chat-message.user .message-bubble {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n border-bottom-right-radius: 4px;\n }\n\n .chat-message.bot .message-bubble {\n background: white;\n color: #1e293b;\n border-bottom-left-radius: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-indicator {\n display: flex;\n gap: 4px;\n padding: 12px 16px;\n background: white;\n border-radius: 16px;\n border-bottom-left-radius: 4px;\n max-width: 60px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n\n .typing-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #94a3b8;\n animation: typing 1.4s infinite;\n }\n\n .typing-dot:nth-child(2) {\n animation-delay: 0.2s;\n }\n\n .typing-dot:nth-child(3) {\n animation-delay: 0.4s;\n }\n\n @keyframes typing {\n 0%, 60%, 100% {\n transform: translateY(0);\n opacity: 0.7;\n }\n 30% {\n transform: translateY(-10px);\n opacity: 1;\n }\n }\n\n .chat-input-wrapper {\n display: flex;\n padding: 16px;\n gap: 8px;\n background: white;\n border-top: 1px solid #e2e8f0;\n }\n\n #chat-input {\n flex: 1;\n border: 2px solid #e2e8f0;\n border-radius: 12px;\n padding: 12px 16px;\n font-size: 14px;\n outline: none;\n transition: all 0.2s;\n font-family: inherit;\n }\n\n #chat-input:focus {\n border-color: ").concat(this.primaryColor,";\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);\n }\n\n #chat-send {\n background: linear-gradient(135deg, ").concat(this.primaryColor," 0%, #8b5cf6 100%);\n color: white;\n border: none;\n border-radius: 12px;\n padding: 12px 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n }\n\n #chat-send:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n #chat-send:not(:disabled):hover {\n transform: scale(1.05);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n }\n\n #chat-send:not(:disabled):active {\n transform: scale(0.95);\n }\n "),document.head.appendChild(n)}},{key:"_bindEvents",value:function(){var n=this,e=this.container.querySelector("#chat-toggle"),t=this.container.querySelector("#chat-close"),i=this.container.querySelector("#chat-expanded"),a=this.container.querySelector("#chat-input"),o=this.container.querySelector("#chat-send");e.addEventListener("click",function(){e.style.display="none",i.classList.add("visible"),a.focus()}),t.addEventListener("click",function(){i.classList.remove("visible"),e.style.display="flex"}),a.addEventListener("input",function(){o.disabled=!a.value.trim()});var r=function(){var e=a.value.trim();e&&(n._addMessage(e,!0),a.value="",o.disabled=!0,n._showTypingIndicator(),setTimeout(function(){n._hideTypingIndicator(),n._addMessage('Thanks for your message! You said: "'.concat(e,'"'),!1)},1e3+1e3*Math.random()))};o.addEventListener("click",r),a.addEventListener("keypress",function(n){"Enter"!==n.key||o.disabled||r()})}},{key:"_addMessage",value:function(n,e){var t=this.container.querySelector("#chat-messages"),i=t.querySelector(".chat-welcome");i&&i.remove();var a=document.createElement("div");a.className="chat-message ".concat(e?"user":"bot"),a.innerHTML='<div class="message-bubble">'.concat(this._escapeHtml(n),"</div>"),t.appendChild(a),t.scrollTop=t.scrollHeight}},{key:"_showTypingIndicator",value:function(){var n=this.container.querySelector("#chat-messages"),e=document.createElement("div");e.className="chat-message bot",e.id="typing-indicator",e.innerHTML='\n <div class="typing-indicator">\n <div class="typing-dot"></div>\n <div class="typing-dot"></div>\n <div class="typing-dot"></div>\n </div>\n ',n.appendChild(e),n.scrollTop=n.scrollHeight}},{key:"_hideTypingIndicator",value:function(){var n=this.container.querySelector("#typing-indicator");n&&n.remove()}},{key:"_escapeHtml",value:function(n){var e=document.createElement("div");return e.textContent=n,e.innerHTML}}])}();e.exports=t}(i),t(i.exports)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mini-chat-bot-widget",
3
- "version": "0.2.0",
3
+ "version": "0.6.0",
4
4
  "description": "A tiny chat bot widget fixed at bottom right, distributable via npm and usable with a <script> tag.",
5
5
  "main": "dist/chat-widget.umd.js",
6
6
  "module": "dist/chat-widget.esm.js",
@@ -1,119 +1,458 @@
1
- // chat-widget.js - vanilla JS chat bot widget
1
+ // chat-widget.js - Modern vanilla JS chat bot widget
2
2
 
3
3
  class ChatWidget {
4
- constructor(options = {}) {
5
- this.title = options.title || "Chat Bot";
6
- this.placeholder = options.placeholder || "Type a message...";
7
- this.container = null;
8
- this.messages = [];
9
- this._init();
10
- }
11
-
12
- _init() {
13
- // Create container
14
- this.container = document.createElement("div");
15
- this.container.id = "chat-widget-container";
16
- this.container.innerHTML = `
17
- <div class="chat-header">${this.title}</div>
18
- <div class="chat-messages" id="chat-messages"></div>
19
- <div class="chat-input-wrapper">
20
- <input type="text" id="chat-input" placeholder="${this.placeholder}" />
21
- <button id="chat-send">Send</button>
4
+ constructor(options = {}) {
5
+ this.title = options.title || "Chat Assistant";
6
+ this.placeholder = options.placeholder || "Type your message...";
7
+ this.primaryColor = options.primaryColor || "#6366f1";
8
+ this.container = null;
9
+ this.messages = [];
10
+ this.isMinimized = false;
11
+ this._init();
12
+ }
13
+
14
+ _init() {
15
+ // Create container
16
+ this.container = document.createElement("div");
17
+ this.container.id = "chat-widget-container";
18
+ this.container.innerHTML = `
19
+ <div class="chat-widget-minimized" id="chat-toggle">
20
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
21
+ <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>
22
+ </svg>
23
+ </div>
24
+ <div class="chat-widget-expanded" id="chat-expanded">
25
+ <div class="chat-header">
26
+ <div class="chat-header-content">
27
+ <div class="chat-avatar">
28
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
29
+ <path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path>
30
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>
31
+ </svg>
32
+ </div>
33
+ <div class="chat-header-text">
34
+ <div class="chat-title">${this.title}</div>
35
+ <div class="chat-status">● Online</div>
36
+ </div>
37
+ </div>
38
+ <button class="chat-close" id="chat-close">
39
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
40
+ <line x1="18" y1="6" x2="6" y2="18"></line>
41
+ <line x1="6" y1="6" x2="18" y2="18"></line>
42
+ </svg>
43
+ </button>
44
+ </div>
45
+ <div class="chat-messages" id="chat-messages">
46
+ <div class="chat-welcome">
47
+ <div class="welcome-icon">👋</div>
48
+ <div class="welcome-text">Hello! How can I help you today?</div>
49
+ </div>
50
+ </div>
51
+ <div class="chat-input-wrapper">
52
+ <input type="text" id="chat-input" placeholder="${this.placeholder}" autocomplete="off" />
53
+ <button id="chat-send" disabled>
54
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
55
+ <line x1="22" y1="2" x2="11" y2="13"></line>
56
+ <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
57
+ </svg>
58
+ </button>
59
+ </div>
22
60
  </div>
23
61
  `;
24
- document.body.appendChild(this.container);
25
- this._applyStyles();
26
- this._bindEvents();
27
- }
28
-
29
- _applyStyles() {
30
- const style = document.createElement("style");
31
- style.textContent = `
62
+ document.body.appendChild(this.container);
63
+ this._applyStyles();
64
+ this._bindEvents();
65
+ }
66
+
67
+ _applyStyles() {
68
+ const style = document.createElement("style");
69
+ style.textContent = `
70
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');
71
+
32
72
  #chat-widget-container {
33
73
  position: fixed;
34
- bottom: 20px;
35
- right: 20px;
36
- width: 300px;
37
- max-height: 400px;
38
- background: rgba(255,255,255,0.95);
39
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
40
- border-radius: 12px;
74
+ bottom: 24px;
75
+ right: 24px;
76
+ z-index: 10000;
77
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
78
+ }
79
+
80
+ .chat-widget-minimized {
81
+ width: 60px;
82
+ height: 60px;
83
+ border-radius: 50%;
84
+ background: linear-gradient(135deg, ${this.primaryColor} 0%, #8b5cf6 100%);
85
+ color: white;
41
86
  display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ cursor: pointer;
90
+ box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4);
91
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
92
+ animation: pulse 2s infinite;
93
+ }
94
+
95
+ .chat-widget-minimized:hover {
96
+ transform: scale(1.1);
97
+ box-shadow: 0 12px 32px rgba(99, 102, 241, 0.5);
98
+ }
99
+
100
+ @keyframes pulse {
101
+ 0%, 100% { box-shadow: 0 8px 24px rgba(99, 102, 241, 0.4); }
102
+ 50% { box-shadow: 0 8px 32px rgba(99, 102, 241, 0.6); }
103
+ }
104
+
105
+ .chat-widget-expanded {
106
+ width: 380px;
107
+ height: 600px;
108
+ background: white;
109
+ border-radius: 16px;
110
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
111
+ display: none;
42
112
  flex-direction: column;
43
- font-family: 'Inter', sans-serif;
44
113
  overflow: hidden;
45
- z-index: 10000;
114
+ animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
46
115
  }
47
- #chat-widget-container .chat-header {
48
- background: linear-gradient(135deg, #6a5acd, #00bfff);
116
+
117
+ @keyframes slideUp {
118
+ from {
119
+ opacity: 0;
120
+ transform: translateY(20px) scale(0.95);
121
+ }
122
+ to {
123
+ opacity: 1;
124
+ transform: translateY(0) scale(1);
125
+ }
126
+ }
127
+
128
+ .chat-widget-expanded.visible {
129
+ display: flex;
130
+ }
131
+
132
+ .chat-header {
133
+ background: linear-gradient(135deg, ${this.primaryColor} 0%, #8b5cf6 100%);
49
134
  color: white;
50
- padding: 8px 12px;
135
+ padding: 20px;
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ }
140
+
141
+ .chat-header-content {
142
+ display: flex;
143
+ align-items: center;
144
+ gap: 12px;
145
+ }
146
+
147
+ .chat-avatar {
148
+ width: 40px;
149
+ height: 40px;
150
+ border-radius: 50%;
151
+ background: rgba(255, 255, 255, 0.2);
152
+ backdrop-filter: blur(10px);
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ }
157
+
158
+ .chat-header-text {
159
+ display: flex;
160
+ flex-direction: column;
161
+ gap: 2px;
162
+ }
163
+
164
+ .chat-title {
51
165
  font-weight: 600;
52
- text-align: center;
166
+ font-size: 16px;
167
+ }
168
+
169
+ .chat-status {
170
+ font-size: 12px;
171
+ opacity: 0.9;
172
+ display: flex;
173
+ align-items: center;
174
+ gap: 4px;
175
+ }
176
+
177
+ .chat-close {
178
+ background: transparent;
179
+ border: none;
180
+ color: white;
181
+ cursor: pointer;
182
+ padding: 8px;
183
+ border-radius: 8px;
184
+ display: flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ transition: all 0.2s;
53
188
  }
54
- #chat-widget-container .chat-messages {
189
+
190
+ .chat-close:hover {
191
+ background: rgba(255, 255, 255, 0.15);
192
+ }
193
+
194
+ .chat-messages {
55
195
  flex: 1;
56
- padding: 8px 12px;
196
+ padding: 20px;
57
197
  overflow-y: auto;
58
- font-size: 0.9rem;
59
- color: #333;
198
+ background: #f9fafb;
199
+ display: flex;
200
+ flex-direction: column;
201
+ gap: 12px;
202
+ }
203
+
204
+ .chat-messages::-webkit-scrollbar {
205
+ width: 6px;
206
+ }
207
+
208
+ .chat-messages::-webkit-scrollbar-track {
209
+ background: transparent;
210
+ }
211
+
212
+ .chat-messages::-webkit-scrollbar-thumb {
213
+ background: #cbd5e1;
214
+ border-radius: 3px;
215
+ }
216
+
217
+ .chat-welcome {
218
+ text-align: center;
219
+ padding: 40px 20px;
220
+ color: #64748b;
221
+ }
222
+
223
+ .welcome-icon {
224
+ font-size: 48px;
225
+ margin-bottom: 12px;
226
+ }
227
+
228
+ .welcome-text {
229
+ font-size: 15px;
230
+ font-weight: 500;
231
+ color: #475569;
60
232
  }
61
- #chat-widget-container .chat-input-wrapper {
233
+
234
+ .chat-message {
62
235
  display: flex;
63
- border-top: 1px solid #ddd;
236
+ gap: 8px;
237
+ animation: messageSlide 0.3s ease-out;
238
+ }
239
+
240
+ @keyframes messageSlide {
241
+ from {
242
+ opacity: 0;
243
+ transform: translateY(10px);
244
+ }
245
+ to {
246
+ opacity: 1;
247
+ transform: translateY(0);
248
+ }
249
+ }
250
+
251
+ .chat-message.user {
252
+ flex-direction: row-reverse;
64
253
  }
65
- #chat-widget-container #chat-input {
254
+
255
+ .message-bubble {
256
+ max-width: 75%;
257
+ padding: 12px 16px;
258
+ border-radius: 16px;
259
+ font-size: 14px;
260
+ line-height: 1.5;
261
+ word-wrap: break-word;
262
+ }
263
+
264
+ .chat-message.user .message-bubble {
265
+ background: linear-gradient(135deg, ${this.primaryColor} 0%, #8b5cf6 100%);
266
+ color: white;
267
+ border-bottom-right-radius: 4px;
268
+ }
269
+
270
+ .chat-message.bot .message-bubble {
271
+ background: white;
272
+ color: #1e293b;
273
+ border-bottom-left-radius: 4px;
274
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
275
+ }
276
+
277
+ .typing-indicator {
278
+ display: flex;
279
+ gap: 4px;
280
+ padding: 12px 16px;
281
+ background: white;
282
+ border-radius: 16px;
283
+ border-bottom-left-radius: 4px;
284
+ max-width: 60px;
285
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
286
+ }
287
+
288
+ .typing-dot {
289
+ width: 8px;
290
+ height: 8px;
291
+ border-radius: 50%;
292
+ background: #94a3b8;
293
+ animation: typing 1.4s infinite;
294
+ }
295
+
296
+ .typing-dot:nth-child(2) {
297
+ animation-delay: 0.2s;
298
+ }
299
+
300
+ .typing-dot:nth-child(3) {
301
+ animation-delay: 0.4s;
302
+ }
303
+
304
+ @keyframes typing {
305
+ 0%, 60%, 100% {
306
+ transform: translateY(0);
307
+ opacity: 0.7;
308
+ }
309
+ 30% {
310
+ transform: translateY(-10px);
311
+ opacity: 1;
312
+ }
313
+ }
314
+
315
+ .chat-input-wrapper {
316
+ display: flex;
317
+ padding: 16px;
318
+ gap: 8px;
319
+ background: white;
320
+ border-top: 1px solid #e2e8f0;
321
+ }
322
+
323
+ #chat-input {
66
324
  flex: 1;
67
- border: none;
68
- padding: 8px;
69
- font-size: 0.9rem;
325
+ border: 2px solid #e2e8f0;
326
+ border-radius: 12px;
327
+ padding: 12px 16px;
328
+ font-size: 14px;
70
329
  outline: none;
330
+ transition: all 0.2s;
331
+ font-family: inherit;
332
+ }
333
+
334
+ #chat-input:focus {
335
+ border-color: ${this.primaryColor};
336
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
71
337
  }
72
- #chat-widget-container #chat-send {
73
- background: #6a5acd;
338
+
339
+ #chat-send {
340
+ background: linear-gradient(135deg, ${this.primaryColor} 0%, #8b5cf6 100%);
74
341
  color: white;
75
342
  border: none;
76
- padding: 0 12px;
343
+ border-radius: 12px;
344
+ padding: 12px 16px;
77
345
  cursor: pointer;
78
- font-weight: 600;
346
+ display: flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ transition: all 0.2s;
79
350
  }
80
- #chat-widget-container #chat-send:hover {
81
- background: #5a4acb;
351
+
352
+ #chat-send:disabled {
353
+ opacity: 0.5;
354
+ cursor: not-allowed;
355
+ }
356
+
357
+ #chat-send:not(:disabled):hover {
358
+ transform: scale(1.05);
359
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
82
360
  }
361
+
362
+ #chat-send:not(:disabled):active {
363
+ transform: scale(0.95);
364
+ }
365
+ `;
366
+ document.head.appendChild(style);
367
+ }
368
+
369
+ _bindEvents() {
370
+ const toggle = this.container.querySelector("#chat-toggle");
371
+ const closeBtn = this.container.querySelector("#chat-close");
372
+ const expanded = this.container.querySelector("#chat-expanded");
373
+ const input = this.container.querySelector("#chat-input");
374
+ const sendBtn = this.container.querySelector("#chat-send");
375
+
376
+ toggle.addEventListener("click", () => {
377
+ toggle.style.display = "none";
378
+ expanded.classList.add("visible");
379
+ input.focus();
380
+ });
381
+
382
+ closeBtn.addEventListener("click", () => {
383
+ expanded.classList.remove("visible");
384
+ toggle.style.display = "flex";
385
+ });
386
+
387
+ input.addEventListener("input", () => {
388
+ sendBtn.disabled = !input.value.trim();
389
+ });
390
+
391
+ const send = () => {
392
+ const text = input.value.trim();
393
+ if (!text) return;
394
+
395
+ this._addMessage(text, true);
396
+ input.value = "";
397
+ sendBtn.disabled = true;
398
+
399
+ this._showTypingIndicator();
400
+
401
+ setTimeout(() => {
402
+ this._hideTypingIndicator();
403
+ this._addMessage(`Thanks for your message! You said: "${text}"`, false);
404
+ }, 1000 + Math.random() * 1000);
405
+ };
406
+
407
+ sendBtn.addEventListener("click", send);
408
+ input.addEventListener("keypress", (e) => {
409
+ if (e.key === "Enter" && !sendBtn.disabled) send();
410
+ });
411
+ }
412
+
413
+ _addMessage(text, isUser) {
414
+ const messagesContainer = this.container.querySelector("#chat-messages");
415
+ const welcome = messagesContainer.querySelector(".chat-welcome");
416
+ if (welcome) welcome.remove();
417
+
418
+ const messageEl = document.createElement("div");
419
+ messageEl.className = `chat-message ${isUser ? "user" : "bot"}`;
420
+ messageEl.innerHTML = `<div class="message-bubble">${this._escapeHtml(text)}</div>`;
421
+ messagesContainer.appendChild(messageEl);
422
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
423
+ }
424
+
425
+ _showTypingIndicator() {
426
+ const messagesContainer = this.container.querySelector("#chat-messages");
427
+ const indicator = document.createElement("div");
428
+ indicator.className = "chat-message bot";
429
+ indicator.id = "typing-indicator";
430
+ indicator.innerHTML = `
431
+ <div class="typing-indicator">
432
+ <div class="typing-dot"></div>
433
+ <div class="typing-dot"></div>
434
+ <div class="typing-dot"></div>
435
+ </div>
83
436
  `;
84
- document.head.appendChild(style);
85
- }
86
-
87
- _bindEvents() {
88
- const input = this.container.querySelector("#chat-input");
89
- const sendBtn = this.container.querySelector("#chat-send");
90
- const addMessage = (text, fromUser = true) => {
91
- const msgEl = document.createElement("div");
92
- msgEl.textContent = text;
93
- msgEl.style.marginBottom = "6px";
94
- msgEl.style.textAlign = fromUser ? "right" : "left";
95
- msgEl.style.color = fromUser ? "#0066cc" : "#333";
96
- this.container.querySelector("#chat-messages").appendChild(msgEl);
97
- this.container.querySelector("#chat-messages").scrollTop = 9999;
98
- };
99
- const send = () => {
100
- const text = input.value.trim();
101
- if (!text) return;
102
- addMessage(text, true);
103
- input.value = "";
104
- // Simple echo bot – replace with real logic or API call
105
- setTimeout(() => addMessage("You said: " + text, false), 500);
106
- };
107
- sendBtn.addEventListener("click", send);
108
- input.addEventListener("keypress", (e) => {
109
- if (e.key === "Enter") send();
110
- });
111
- }
437
+ messagesContainer.appendChild(indicator);
438
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
439
+ }
440
+
441
+ _hideTypingIndicator() {
442
+ const indicator = this.container.querySelector("#typing-indicator");
443
+ if (indicator) indicator.remove();
444
+ }
445
+
446
+ _escapeHtml(text) {
447
+ const div = document.createElement("div");
448
+ div.textContent = text;
449
+ return div.innerHTML;
450
+ }
112
451
  }
113
452
 
114
453
  // Export as UMD and ESM compatible
115
454
  if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
116
- module.exports = ChatWidget;
455
+ module.exports = ChatWidget;
117
456
  } else {
118
- window.ChatWidget = ChatWidget;
119
- }
457
+ window.ChatWidget = ChatWidget;
458
+ }