mehdi-akbari-ai-assistant-free 0.8.0 → 0.9.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.
package/dist/react.d.mts CHANGED
@@ -8,4 +8,9 @@ interface ChatWindowProps {
8
8
  }
9
9
  declare const ChatWindow: React.FC<ChatWindowProps>;
10
10
 
11
- export { ChatWindow, type ChatWindowProps };
11
+ interface AiAssistantProps extends ChatWindowProps {
12
+ lottieUrl?: string;
13
+ }
14
+ declare const AiAssistant: React.FC<AiAssistantProps>;
15
+
16
+ export { AiAssistant, ChatWindow, type ChatWindowProps };
package/dist/react.d.ts CHANGED
@@ -8,4 +8,9 @@ interface ChatWindowProps {
8
8
  }
9
9
  declare const ChatWindow: React.FC<ChatWindowProps>;
10
10
 
11
- export { ChatWindow, type ChatWindowProps };
11
+ interface AiAssistantProps extends ChatWindowProps {
12
+ lottieUrl?: string;
13
+ }
14
+ declare const AiAssistant: React.FC<AiAssistantProps>;
15
+
16
+ export { AiAssistant, ChatWindow, type ChatWindowProps };
package/dist/react.js CHANGED
@@ -31,10 +31,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/react.ts
32
32
  var react_exports = {};
33
33
  __export(react_exports, {
34
+ AiAssistant: () => AiAssistant,
34
35
  ChatWindow: () => ChatWindow
35
36
  });
36
37
  module.exports = __toCommonJS(react_exports);
37
38
 
39
+ // src/components/AiAssistant/AiAssistant.tsx
40
+ var import_react4 = require("react");
41
+
38
42
  // src/components/ChatWindow/ChatWindow.tsx
39
43
  var import_react3 = require("react");
40
44
 
@@ -138,7 +142,7 @@ var ChatWindow = ({
138
142
  }) => {
139
143
  const [messages, setMessages] = (0, import_react3.useState)([]);
140
144
  const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
141
- const version = "0.8.0";
145
+ const version = "0.9.0";
142
146
  (0, import_react3.useEffect)(() => {
143
147
  if (welcomeMessage && messages.length === 0) {
144
148
  setMessages([{ role: "assistant", content: welcomeMessage }]);
@@ -187,8 +191,35 @@ var ChatWindow = ({
187
191
  ] })
188
192
  ] });
189
193
  };
194
+
195
+ // src/components/ChatbotFAB/ChatbotFAB.tsx
196
+ var import_lottie_react = __toESM(require("lottie-react"));
197
+ var import_jsx_runtime5 = require("react/jsx-runtime");
198
+ var ChatbotFAB = ({ onClick, lottieUrl }) => {
199
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "mra-fab", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lottie_react.default, { animationData: lottieUrl, loop: true }) });
200
+ };
201
+
202
+ // src/components/AiAssistant/AiAssistant.tsx
203
+ var import_clsx2 = __toESM(require("clsx"));
204
+ var import_jsx_runtime6 = require("react/jsx-runtime");
205
+ var DEFAULT_LOTTIE_URL = "https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json";
206
+ var AiAssistant = ({
207
+ lottieUrl = DEFAULT_LOTTIE_URL,
208
+ ...chatWindowProps
209
+ // بقیه پراپ‌ها برای ChatWindow هستند
210
+ }) => {
211
+ const [isOpen, setIsOpen] = (0, import_react4.useState)(false);
212
+ const toggleChat = () => {
213
+ setIsOpen((prev) => !prev);
214
+ };
215
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mra-container", children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: (0, import_clsx2.default)("mra-chat-window-container", isOpen && "mra-chat-window-container--open"), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatWindow, { ...chatWindowProps }) }),
217
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatbotFAB, { onClick: toggleChat, lottieUrl })
218
+ ] });
219
+ };
190
220
  // Annotate the CommonJS export names for ESM import in node:
191
221
  0 && (module.exports = {
222
+ AiAssistant,
192
223
  ChatWindow
193
224
  });
194
225
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx"],"sourcesContent":["\"use client\";\r\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\nexport * from \"./types\";","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم می‌کند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست می‌کنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم می‌کنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت می‌کند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع می‌شود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["import_react","clsx","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/react.ts","../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["\r\n\"use client\";\r\n\r\n\r\nexport { AiAssistant } from \"./components/AiAssistant/AiAssistant\";\r\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\nexport * from \"./types\";","// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\n// این کامپوننت تمام پراپ‌های ChatWindow را به علاوه‌ی پراپ lottieUrl می‌پذیرد\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieUrl?: string;\r\n}\r\n\r\n// یک انیمیشن پیش‌فرض جذاب\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({ \r\n lottieUrl = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps // بقیه پراپ‌ها برای ChatWindow هستند\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const toggleChat = () => {\r\n setIsOpen(prev => !prev);\r\n };\r\n\r\n return (\r\n <div className=\"mra-container\">\r\n \r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow {...chatWindowProps} />\r\n </div>\r\n\r\n \r\n <ChatbotFAB onClick={toggleChat} lottieUrl={lottieUrl} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم می‌کند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست می‌کنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم می‌کنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت می‌کند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع می‌شود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n lottieUrl: string; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, lottieUrl }) => {\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie animationData={lottieUrl} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":"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","names":["import_react","import_react","clsx","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","Lottie","import_clsx","import_jsx_runtime","clsx"]}
package/dist/react.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  "use client";
2
2
 
3
+ // src/components/AiAssistant/AiAssistant.tsx
4
+ import { useState as useState3 } from "react";
5
+
3
6
  // src/components/ChatWindow/ChatWindow.tsx
4
7
  import { useState as useState2, useEffect as useEffect3 } from "react";
5
8
 
@@ -103,7 +106,7 @@ var ChatWindow = ({
103
106
  }) => {
104
107
  const [messages, setMessages] = useState2([]);
105
108
  const [isLoading, setIsLoading] = useState2(false);
106
- const version = "0.8.0";
109
+ const version = "0.9.0";
107
110
  useEffect3(() => {
108
111
  if (welcomeMessage && messages.length === 0) {
109
112
  setMessages([{ role: "assistant", content: welcomeMessage }]);
@@ -152,7 +155,34 @@ var ChatWindow = ({
152
155
  ] })
153
156
  ] });
154
157
  };
158
+
159
+ // src/components/ChatbotFAB/ChatbotFAB.tsx
160
+ import Lottie from "lottie-react";
161
+ import { jsx as jsx5 } from "react/jsx-runtime";
162
+ var ChatbotFAB = ({ onClick, lottieUrl }) => {
163
+ return /* @__PURE__ */ jsx5("button", { className: "mra-fab", onClick, children: /* @__PURE__ */ jsx5(Lottie, { animationData: lottieUrl, loop: true }) });
164
+ };
165
+
166
+ // src/components/AiAssistant/AiAssistant.tsx
167
+ import clsx2 from "clsx";
168
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
169
+ var DEFAULT_LOTTIE_URL = "https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json";
170
+ var AiAssistant = ({
171
+ lottieUrl = DEFAULT_LOTTIE_URL,
172
+ ...chatWindowProps
173
+ // بقیه پراپ‌ها برای ChatWindow هستند
174
+ }) => {
175
+ const [isOpen, setIsOpen] = useState3(false);
176
+ const toggleChat = () => {
177
+ setIsOpen((prev) => !prev);
178
+ };
179
+ return /* @__PURE__ */ jsxs4("div", { className: "mra-container", children: [
180
+ /* @__PURE__ */ jsx6("div", { className: clsx2("mra-chat-window-container", isOpen && "mra-chat-window-container--open"), children: /* @__PURE__ */ jsx6(ChatWindow, { ...chatWindowProps }) }),
181
+ /* @__PURE__ */ jsx6(ChatbotFAB, { onClick: toggleChat, lottieUrl })
182
+ ] });
183
+ };
155
184
  export {
185
+ AiAssistant,
156
186
  ChatWindow
157
187
  };
158
188
  //# sourceMappingURL=react.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx"],"sourcesContent":["// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم می‌کند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست می‌کنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم می‌کنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت می‌کند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع می‌شود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["useState","useEffect","jsx","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect"]}
1
+ {"version":3,"sources":["../src/components/AiAssistant/AiAssistant.tsx","../src/components/ChatWindow/ChatWindow.tsx","../src/components/MessageList/MessageList.tsx","../src/components/MessageBubble/MessageBubble.tsx","../src/components/ChatInput/ChatInput.tsx","../src/components/ChatbotFAB/ChatbotFAB.tsx"],"sourcesContent":["// src/components/AiAssistant/AiAssistant.tsx\r\n\"use client\";\r\nimport React, { useState } from 'react';\r\nimport { ChatWindow, ChatWindowProps } from '../ChatWindow/ChatWindow';\r\nimport { ChatbotFAB } from '../ChatbotFAB/ChatbotFAB';\r\nimport clsx from 'clsx';\r\n\r\n// این کامپوننت تمام پراپ‌های ChatWindow را به علاوه‌ی پراپ lottieUrl می‌پذیرد\r\ninterface AiAssistantProps extends ChatWindowProps {\r\n lottieUrl?: string;\r\n}\r\n\r\n// یک انیمیشن پیش‌فرض جذاب\r\nconst DEFAULT_LOTTIE_URL = \"https://lottie.host/a822cf1a-1e96-4187-a220-42adb2a61d19/B5bQnC2p9K.json\";\r\n\r\nexport const AiAssistant: React.FC<AiAssistantProps> = ({ \r\n lottieUrl = DEFAULT_LOTTIE_URL,\r\n ...chatWindowProps // بقیه پراپ‌ها برای ChatWindow هستند\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n const toggleChat = () => {\r\n setIsOpen(prev => !prev);\r\n };\r\n\r\n return (\r\n <div className=\"mra-container\">\r\n \r\n <div className={clsx(\"mra-chat-window-container\", isOpen && \"mra-chat-window-container--open\")}>\r\n <ChatWindow {...chatWindowProps} />\r\n </div>\r\n\r\n \r\n <ChatbotFAB onClick={toggleChat} lottieUrl={lottieUrl} />\r\n </div>\r\n );\r\n};","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport { MessageList } from '../MessageList/MessageList';\r\nimport { ChatInput } from '../ChatInput/ChatInput';\r\nimport { Message } from '../../types';\r\nimport { Bot } from 'lucide-react';\r\n\r\nexport interface ChatWindowProps {\r\n apiEndpoint: string;\r\n title?: string;\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatWindow: React.FC<ChatWindowProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const version = process.env.PACKAGE_VERSION; \r\n\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage, messages.length]);\r\n\r\n const handleSendMessage = async (userMessage: string) => {\r\n const newUserMsg: Message = { role: 'user', content: userMessage };\r\n const currentMessages = [...messages, newUserMsg];\r\n setMessages(currentMessages);\r\n setIsLoading(true);\r\n\r\n try {\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: currentMessages }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n const data = await response.json();\r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n const errorMsg: Message = { role: 'assistant', content: \"خطایی رخ داده است.\" };\r\n setMessages(prev => [...prev, errorMsg]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-chat-window\">\r\n <div className=\"mra-header\">\r\n <Bot size={20} />\r\n <span className=\"mra-title\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\r\n\r\n {/* === فوتر جدید اضافه شده === */}\r\n <footer className=\"mra-footer\">\r\n <span>v{version}</span>\r\n <div className=\"mra-footer-links\">\r\n <span>Powered By Mehdi Akbari |</span>\r\n <a href=\"mailto:mehdiakbarideveloper@gmail.com\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail</a>\r\n <a href=\"https://t.me/MehdiAkbariDev\" className=\"mra-footer-link\" target=\"_blank\" rel=\"noopener noreferrer\">Telegram</a>\r\n </div>\r\n </footer>\r\n </div>\r\n );\r\n};","// src/components/MessageList/MessageList.tsx\r\n\"use client\";\r\n\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { MessageBubble } from '../MessageBubble/MessageBubble';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageListProps {\r\n messages: Message[];\r\n isLoading: boolean;\r\n}\r\n\r\nexport const MessageList: React.FC<MessageListProps> = ({ messages, isLoading }) => {\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages, isLoading]);\r\n\r\n return (\r\n <div className=\"mra-message-list\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"mra-loading-wrapper\">\r\n <div className=\"mra-loading-bubble\">\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"mra-loading-dot\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"mra-loading-dot\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n );\r\n};","// src/components/MessageBubble/MessageBubble.tsx\r\n\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { Message } from '../../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div className={clsx(\"mra-bubble-wrapper\", isUser ? \"mra-wrapper-user\" : \"mra-wrapper-bot\")}>\r\n <div\r\n className={clsx(\r\n \"mra-bubble\",\r\n isUser ? \"mra-bubble-user\" : \"mra-bubble-bot\"\r\n )}\r\n >\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};","// src/components/ChatInput/ChatInput.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport { Send } from 'lucide-react';\r\n\r\ninterface ChatInputProps {\r\n onSendMessage: (message: string) => void;\r\n isLoading: boolean;\r\n}\r\n\r\nexport const ChatInput: React.FC<ChatInputProps> = ({ onSendMessage, isLoading }) => {\r\n const [inputValue, setInputValue] = useState('');\r\n const textareaRef = useRef<HTMLTextAreaElement>(null); // Ref برای دسترسی به textarea\r\n\r\n // این افکت با هر بار تغییر متن، ارتفاع textarea را تنظیم می‌کند\r\n useEffect(() => {\r\n const textarea = textareaRef.current;\r\n if (textarea) {\r\n // ارتفاع را ریست می‌کنیم تا در صورت پاک کردن متن، کوچک شود\r\n textarea.style.height = 'auto';\r\n // ارتفاع جدید را بر اساس محتوای داخلی تنظیم می‌کنیم\r\n textarea.style.height = `${textarea.scrollHeight}px`;\r\n }\r\n }, [inputValue]);\r\n\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\r\n // این منطق به درستی Shift+Enter را برای ایجاد خط جدید مدیریت می‌کند\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSend();\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"mra-input-wrapper\">\r\n <textarea\r\n ref={textareaRef}\r\n className=\"mra-input-field\"\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n rows={1} // با یک ردیف شروع می‌شود\r\n />\r\n <button\r\n className=\"mra-send-button\"\r\n onClick={handleSend}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n );\r\n};","\r\n\"use client\";\r\nimport React from 'react';\r\nimport Lottie from 'lottie-react';\r\n\r\ninterface ChatbotFABProps {\r\n onClick: () => void;\r\n lottieUrl: string; \r\n}\r\n\r\nexport const ChatbotFAB: React.FC<ChatbotFABProps> = ({ onClick, lottieUrl }) => {\r\n return (\r\n <button className=\"mra-fab\" onClick={onClick}>\r\n <Lottie animationData={lottieUrl} loop={true} />\r\n </button>\r\n );\r\n};"],"mappings":"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","names":["useState","useState","useEffect","jsx","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect","jsx","clsx","jsx","jsxs","useState"]}
package/dist/styles.css CHANGED
@@ -195,4 +195,64 @@
195
195
 
196
196
  .mra-footer-link:hover {
197
197
  color: var(--ai-primary, #2563eb);
198
+ }
199
+
200
+ .mra-container {
201
+ position: fixed;
202
+ bottom: 2rem; /* 32px */
203
+ right: 2rem; /* 32px */
204
+ z-index: 1000;
205
+ }
206
+
207
+ .mra-fab {
208
+ width: 64px;
209
+ height: 64px;
210
+ border-radius: 9999px; /* rounded-full */
211
+ background-color: var(--ai-primary, #2563eb);
212
+ border: none;
213
+ cursor: pointer;
214
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.2), 0 4px 6px -4px rgb(0 0 0 / 0.2);
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ transition: transform 0.2s ease-in-out;
219
+ }
220
+ .mra-fab:hover {
221
+ transform: scale(1.1);
222
+ }
223
+
224
+ .mra-chat-window-container {
225
+ position: absolute;
226
+ bottom: calc(100% + 1rem); /* 16px فاصله بالای دکمه */
227
+ right: 0;
228
+ opacity: 0;
229
+ transform: translateY(20px);
230
+ transition: opacity 0.3s ease, transform 0.3s ease;
231
+ pointer-events: none; /* در حالت بسته قابل کلیک نیست */
232
+ }
233
+
234
+ .mra-chat-window-container--open {
235
+ opacity: 1;
236
+ transform: translateY(0);
237
+ pointer-events: auto; /* در حالت باز قابل کلیک است */
238
+ }
239
+
240
+
241
+ /* === ChatWindow Styles === */
242
+ .mra-chat-window {
243
+ display: flex;
244
+ flex-direction: column;
245
+ height: 500px;
246
+ width: 100%;
247
+ max-width: 28rem; /* max-w-md */
248
+ border-radius: 0.75rem; /* rounded-xl */
249
+ border: 1px solid var(--ai-border, #e5e7eb);
250
+ background-color: var(--ai-bg, #ffffff);
251
+ overflow: hidden;
252
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* shadow-lg */
253
+ position: relative;
254
+ font-family: inherit;
255
+ font-size: 1rem;
256
+ line-height: 1.5rem;
257
+ box-sizing: border-box;
198
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mehdi-akbari-ai-assistant-free",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Professional AI Chatbot Library with self-contained CSS styles",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -31,9 +31,10 @@
31
31
  "react-dom": ">=18"
32
32
  },
33
33
  "dependencies": {
34
- "@langchain/core": "^0.1.0",
35
- "@langchain/groq": "^0.0.14",
34
+ "@langchain/core": "^1.1.8",
35
+ "@langchain/groq": "^1.0.2",
36
36
  "clsx": "^2.1.0",
37
+ "lottie-react": "^2.4.0",
37
38
  "lucide-react": "^0.300.0"
38
39
  },
39
40
  "devDependencies": {
@@ -56,4 +57,4 @@
56
57
  ],
57
58
  "author": "Mehdi Akbari",
58
59
  "license": "MIT"
59
- }
60
+ }