mehdi-akbari-ai-assistant-free 0.7.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
 
@@ -82,6 +86,14 @@ var import_lucide_react = require("lucide-react");
82
86
  var import_jsx_runtime3 = require("react/jsx-runtime");
83
87
  var ChatInput = ({ onSendMessage, isLoading }) => {
84
88
  const [inputValue, setInputValue] = (0, import_react2.useState)("");
89
+ const textareaRef = (0, import_react2.useRef)(null);
90
+ (0, import_react2.useEffect)(() => {
91
+ const textarea = textareaRef.current;
92
+ if (textarea) {
93
+ textarea.style.height = "auto";
94
+ textarea.style.height = `${textarea.scrollHeight}px`;
95
+ }
96
+ }, [inputValue]);
85
97
  const handleSend = () => {
86
98
  if (inputValue.trim()) {
87
99
  onSendMessage(inputValue);
@@ -96,14 +108,16 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
96
108
  };
97
109
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mra-input-wrapper", children: [
98
110
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
99
- "input",
111
+ "textarea",
100
112
  {
113
+ ref: textareaRef,
101
114
  className: "mra-input-field",
102
115
  value: inputValue,
103
116
  onChange: (e) => setInputValue(e.target.value),
104
117
  onKeyDown: handleKeyDown,
105
118
  placeholder: "\u067E\u06CC\u0627\u0645 \u062E\u0648\u062F \u0631\u0627 \u0628\u0646\u0648\u06CC\u0633\u06CC\u062F...",
106
- disabled: isLoading
119
+ disabled: isLoading,
120
+ rows: 1
107
121
  }
108
122
  ),
109
123
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -128,7 +142,7 @@ var ChatWindow = ({
128
142
  }) => {
129
143
  const [messages, setMessages] = (0, import_react3.useState)([]);
130
144
  const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
131
- const version = "0.7.0";
145
+ const version = "0.9.0";
132
146
  (0, import_react3.useEffect)(() => {
133
147
  if (welcomeMessage && messages.length === 0) {
134
148
  setMessages([{ role: "assistant", content: welcomeMessage }]);
@@ -177,8 +191,35 @@ var ChatWindow = ({
177
191
  ] })
178
192
  ] });
179
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
+ };
180
220
  // Annotate the CommonJS export names for ESM import in node:
181
221
  0 && (module.exports = {
222
+ AiAssistant,
182
223
  ChatWindow
183
224
  });
184
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 } 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\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\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 <input\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 />\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,7 +1,10 @@
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
- import { useState as useState2, useEffect as useEffect2 } from "react";
7
+ import { useState as useState2, useEffect as useEffect3 } from "react";
5
8
 
6
9
  // src/components/MessageList/MessageList.tsx
7
10
  import { useRef, useEffect } from "react";
@@ -42,11 +45,19 @@ var MessageList = ({ messages, isLoading }) => {
42
45
  };
43
46
 
44
47
  // src/components/ChatInput/ChatInput.tsx
45
- import { useState } from "react";
48
+ import { useState, useRef as useRef2, useEffect as useEffect2 } from "react";
46
49
  import { Send } from "lucide-react";
47
50
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
48
51
  var ChatInput = ({ onSendMessage, isLoading }) => {
49
52
  const [inputValue, setInputValue] = useState("");
53
+ const textareaRef = useRef2(null);
54
+ useEffect2(() => {
55
+ const textarea = textareaRef.current;
56
+ if (textarea) {
57
+ textarea.style.height = "auto";
58
+ textarea.style.height = `${textarea.scrollHeight}px`;
59
+ }
60
+ }, [inputValue]);
50
61
  const handleSend = () => {
51
62
  if (inputValue.trim()) {
52
63
  onSendMessage(inputValue);
@@ -61,14 +72,16 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
61
72
  };
62
73
  return /* @__PURE__ */ jsxs2("div", { className: "mra-input-wrapper", children: [
63
74
  /* @__PURE__ */ jsx3(
64
- "input",
75
+ "textarea",
65
76
  {
77
+ ref: textareaRef,
66
78
  className: "mra-input-field",
67
79
  value: inputValue,
68
80
  onChange: (e) => setInputValue(e.target.value),
69
81
  onKeyDown: handleKeyDown,
70
82
  placeholder: "\u067E\u06CC\u0627\u0645 \u062E\u0648\u062F \u0631\u0627 \u0628\u0646\u0648\u06CC\u0633\u06CC\u062F...",
71
- disabled: isLoading
83
+ disabled: isLoading,
84
+ rows: 1
72
85
  }
73
86
  ),
74
87
  /* @__PURE__ */ jsx3(
@@ -93,8 +106,8 @@ var ChatWindow = ({
93
106
  }) => {
94
107
  const [messages, setMessages] = useState2([]);
95
108
  const [isLoading, setIsLoading] = useState2(false);
96
- const version = "0.7.0";
97
- useEffect2(() => {
109
+ const version = "0.9.0";
110
+ useEffect3(() => {
98
111
  if (welcomeMessage && messages.length === 0) {
99
112
  setMessages([{ role: "assistant", content: welcomeMessage }]);
100
113
  }
@@ -142,7 +155,34 @@ var ChatWindow = ({
142
155
  ] })
143
156
  ] });
144
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
+ };
145
184
  export {
185
+ AiAssistant,
146
186
  ChatWindow
147
187
  };
148
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 } 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\r\n const handleSend = () => {\r\n if (inputValue.trim()) {\r\n onSendMessage(inputValue);\r\n setInputValue('');\r\n }\r\n };\r\n\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 <input\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 />\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","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
@@ -29,10 +29,11 @@
29
29
  }
30
30
 
31
31
  .mra-title {
32
- font-weight: 600; /* font-semibold */
32
+ font-weight: 600;
33
+ color: #1f2937;
33
34
  }
34
35
 
35
- /* === MessageList Styles === */
36
+
36
37
  .mra-message-list {
37
38
  flex: 1 1 0%;
38
39
  overflow-y: auto;
@@ -113,19 +114,28 @@
113
114
  .mra-input-wrapper {
114
115
  display: flex;
115
116
  gap: 0.5rem;
116
- padding: 0.75rem; /* p-3 */
117
+ padding: 0.75rem;
117
118
  border-top: 1px solid var(--ai-border, #e5e7eb);
118
119
  background-color: var(--ai-bg, #ffffff);
120
+ /* این خط جدید برای تراز کردن دکمه با textarea است */
121
+ align-items: flex-end;
119
122
  }
123
+
120
124
  .mra-input-field {
121
125
  flex: 1 1 0%;
122
126
  padding: 0.5rem 0.75rem;
123
127
  border: 1px solid var(--ai-border, #e5e7eb);
124
- border-radius: 0.5rem; /* rounded-lg */
128
+ border-radius: 0.5rem;
125
129
  outline: none;
126
130
  font-family: inherit;
127
131
  color: var(--ai-text, #1f2937);
132
+ /* === تغییرات و اضافات برای textarea === */
133
+ resize: none; /* غیرفعال کردن تغییر سایز دستی */
134
+ max-height: 120px; /* حداکثر ارتفاع قبل از نمایش اسکرول‌بار (تقریباً 5 خط) */
135
+ overflow-y: auto; /* نمایش اسکرول‌بار در صورت نیاز */
136
+ line-height: 1.5; /* بهبود خوانایی متن چندخطی */
128
137
  }
138
+
129
139
  .mra-input-field::placeholder {
130
140
  color: var(--ai-text-secondary, #6b7280);
131
141
  }
@@ -147,7 +157,11 @@
147
157
  color: var(--ai-primary-fg, #ffffff);
148
158
  border: none;
149
159
  cursor: pointer;
160
+ /* این خط جدید برای تراز کردن دکمه است */
161
+ align-self: flex-end;
162
+ height: 38px; /* ارتفاع ثابت برای هم‌ترازی با اولین ردیف textarea */
150
163
  }
164
+
151
165
  .mra-send-button:hover {
152
166
  opacity: 0.9;
153
167
  }
@@ -181,4 +195,64 @@
181
195
 
182
196
  .mra-footer-link:hover {
183
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;
184
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mehdi-akbari-ai-assistant-free",
3
- "version": "0.7.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
+ }