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 +6 -1
- package/dist/react.d.ts +6 -1
- package/dist/react.js +32 -1
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +31 -1
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +60 -0
- package/package.json +5 -4
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
package/dist/react.mjs.map
CHANGED
|
@@ -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.
|
|
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": "^
|
|
35
|
-
"@langchain/groq": "^
|
|
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
|
+
}
|