mehdi-akbari-ai-assistant-free 0.1.0 → 0.1.1
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.js +11 -11
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +11 -11
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -51,8 +51,8 @@ var MessageBubble = ({ message }) => {
|
|
|
51
51
|
"div",
|
|
52
52
|
{
|
|
53
53
|
className: (0, import_clsx.default)(
|
|
54
|
-
"max-w-[80%] px-3 py-2 rounded-xl text-sm break-
|
|
55
|
-
isUser ? "bg-
|
|
54
|
+
"max-w-[80%] px-3 py-2 rounded-xl text-sm break-all",
|
|
55
|
+
isUser ? "bg-(--ai-user-bg) text-(--ai-user-text) rounded-br-sm" : "bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm"
|
|
56
56
|
),
|
|
57
57
|
children: message.content
|
|
58
58
|
}
|
|
@@ -68,7 +68,7 @@ var MessageList = ({ messages, isLoading }) => {
|
|
|
68
68
|
}, [messages, isLoading]);
|
|
69
69
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth", children: [
|
|
70
70
|
messages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MessageBubble, { message: msg }, index)),
|
|
71
|
-
isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[80%] px-3 py-2 rounded-xl bg-
|
|
71
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[80%] px-3 py-2 rounded-xl bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm flex gap-1 items-center", children: [
|
|
72
72
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "-0.32s" } }),
|
|
73
73
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "-0.16s" } }),
|
|
74
74
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce" })
|
|
@@ -96,14 +96,14 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
|
|
|
96
96
|
handleSend();
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex gap-2 p-3 border-t border-
|
|
99
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex gap-2 p-3 border-t border-(--ai-border) bg-(--ai-bg)", children: [
|
|
100
100
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
101
101
|
"input",
|
|
102
102
|
{
|
|
103
103
|
className: (0, import_clsx2.default)(
|
|
104
|
-
"flex-1 px-3 py-2 border border-
|
|
105
|
-
"font-inherit text-
|
|
106
|
-
"focus:border-
|
|
104
|
+
"flex-1 px-3 py-2 border border-(--ai-border) rounded-lg outline-none",
|
|
105
|
+
"font-inherit text-(--ai-text) placeholder:text-(--ai-text-secondary)",
|
|
106
|
+
"focus:border-(--ai-primary) disabled:opacity-50"
|
|
107
107
|
),
|
|
108
108
|
value: inputValue,
|
|
109
109
|
onChange: (e) => setInputValue(e.target.value),
|
|
@@ -117,7 +117,7 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
|
|
|
117
117
|
{
|
|
118
118
|
className: (0, import_clsx2.default)(
|
|
119
119
|
"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity",
|
|
120
|
-
"bg-
|
|
120
|
+
"bg-(--ai-primary) text-(--ai-primary-fg)",
|
|
121
121
|
"hover:opacity-90",
|
|
122
122
|
(isLoading || !inputValue.trim()) && "opacity-50 cursor-not-allowed"
|
|
123
123
|
),
|
|
@@ -168,11 +168,11 @@ var ChatWindow = ({
|
|
|
168
168
|
}
|
|
169
169
|
};
|
|
170
170
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: (0, import_clsx3.default)(
|
|
171
|
-
"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-
|
|
172
|
-
"bg-
|
|
171
|
+
"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-(--ai-border)",
|
|
172
|
+
"bg-(--ai-bg) overflow-hidden shadow-lg relative",
|
|
173
173
|
"font-inherit text-base leading-6 box-border"
|
|
174
174
|
), children: [
|
|
175
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 px-4 py-4 border-b border-
|
|
175
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 px-4 py-4 border-b border-(--ai-border) bg-gray-50", children: [
|
|
176
176
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Bot, { size: 20 }),
|
|
177
177
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "font-semibold", children: title })
|
|
178
178
|
] }),
|
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\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\n\r\n\r\nexport * from \"./types\";","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport clsx from 'clsx';\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\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\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={clsx(\r\n \"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-[var(--ai-border)]\",\r\n \"bg-[var(--ai-bg)] overflow-hidden shadow-lg relative\",\r\n \"font-inherit text-base leading-6 box-border\"\r\n )}>\r\n <div className=\"flex items-center gap-2 px-4 py-4 border-b border-[var(--ai-border)] bg-gray-50\">\r\n <Bot size={20} />\r\n <span className=\"font-semibold\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\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 clsx from 'clsx';\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=\"flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"flex justify-start\">\r\n <div className=\"max-w-[80%] px-3 py-2 rounded-xl bg-[var(--ai-bot-bg)] text-[var(--ai-text)] rounded-bl-sm flex gap-1 items-center\">\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\"></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(\"flex w-full\", isUser ? \"justify-end\" : \"justify-start\")}>\r\n <div\r\n className={clsx(\r\n \"max-w-[80%] px-3 py-2 rounded-xl text-sm break-words\",\r\n isUser\r\n ? \"bg-[var(--ai-user-bg)] text-[var(--ai-user-text)] rounded-br-sm\"\r\n : \"bg-[var(--ai-bot-bg)] text-[var(--ai-text)] rounded-bl-sm\"\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 clsx from 'clsx';\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=\"flex gap-2 p-3 border-t border-[var(--ai-border)] bg-[var(--ai-bg)]\">\r\n <input\r\n className={clsx(\r\n \"flex-1 px-3 py-2 border border-[var(--ai-border)] rounded-lg outline-none\",\r\n \"font-inherit text-[var(--ai-text)] placeholder:text-[var(--ai-text-secondary)]\",\r\n \"focus:border-[var(--ai-primary)] disabled:opacity-50\"\r\n )}\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={clsx(\r\n \"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity\",\r\n \"bg-[var(--ai-primary)] text-[var(--ai-primary-fg)]\",\r\n \"hover:opacity-90\",\r\n (isLoading || !inputValue.trim()) && \"opacity-50 cursor-not-allowed\"\r\n )}\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","import_clsx","clsx","import_jsx_runtime","import_react","import_clsx","import_jsx_runtime","clsx","import_lucide_react","import_jsx_runtime","clsx"]}
|
|
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\n\r\n\r\nexport { ChatWindow, type ChatWindowProps } from \"./components/ChatWindow/ChatWindow\";\r\n\r\n\r\nexport * from \"./types\";","// src/components/ChatWindow/ChatWindow.tsx\r\n\"use client\";\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport clsx from 'clsx';\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\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\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={clsx(\r\n \"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-(--ai-border)\",\r\n \"bg-(--ai-bg) overflow-hidden shadow-lg relative\",\r\n \"font-inherit text-base leading-6 box-border\"\r\n )}>\r\n <div className=\"flex items-center gap-2 px-4 py-4 border-b border-(--ai-border) bg-gray-50\">\r\n <Bot size={20} />\r\n <span className=\"font-semibold\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\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 clsx from 'clsx';\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=\"flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"flex justify-start\">\r\n <div className=\"max-w-[80%] px-3 py-2 rounded-xl bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm flex gap-1 items-center\">\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\"></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(\"flex w-full\", isUser ? \"justify-end\" : \"justify-start\")}>\r\n <div\r\n className={clsx(\r\n \"max-w-[80%] px-3 py-2 rounded-xl text-sm break-all\",\r\n isUser\r\n ? \"bg-(--ai-user-bg) text-(--ai-user-text) rounded-br-sm\"\r\n : \"bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm\"\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 clsx from 'clsx';\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=\"flex gap-2 p-3 border-t border-(--ai-border) bg-(--ai-bg)\">\r\n <input\r\n className={clsx(\r\n \"flex-1 px-3 py-2 border border-(--ai-border) rounded-lg outline-none\",\r\n \"font-inherit text-(--ai-text) placeholder:text-(--ai-text-secondary)\",\r\n \"focus:border-(--ai-primary) disabled:opacity-50\"\r\n )}\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={clsx(\r\n \"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity\",\r\n \"bg-(--ai-primary) text-(--ai-primary-fg)\",\r\n \"hover:opacity-90\",\r\n (isLoading || !inputValue.trim()) && \"opacity-50 cursor-not-allowed\"\r\n )}\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","import_clsx","clsx","import_jsx_runtime","import_react","import_clsx","import_jsx_runtime","clsx","import_lucide_react","import_jsx_runtime","clsx"]}
|
package/dist/react.mjs
CHANGED
|
@@ -16,8 +16,8 @@ var MessageBubble = ({ message }) => {
|
|
|
16
16
|
"div",
|
|
17
17
|
{
|
|
18
18
|
className: clsx(
|
|
19
|
-
"max-w-[80%] px-3 py-2 rounded-xl text-sm break-
|
|
20
|
-
isUser ? "bg-
|
|
19
|
+
"max-w-[80%] px-3 py-2 rounded-xl text-sm break-all",
|
|
20
|
+
isUser ? "bg-(--ai-user-bg) text-(--ai-user-text) rounded-br-sm" : "bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm"
|
|
21
21
|
),
|
|
22
22
|
children: message.content
|
|
23
23
|
}
|
|
@@ -33,7 +33,7 @@ var MessageList = ({ messages, isLoading }) => {
|
|
|
33
33
|
}, [messages, isLoading]);
|
|
34
34
|
return /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth", children: [
|
|
35
35
|
messages.map((msg, index) => /* @__PURE__ */ jsx2(MessageBubble, { message: msg }, index)),
|
|
36
|
-
isLoading && /* @__PURE__ */ jsx2("div", { className: "flex justify-start", children: /* @__PURE__ */ jsxs("div", { className: "max-w-[80%] px-3 py-2 rounded-xl bg-
|
|
36
|
+
isLoading && /* @__PURE__ */ jsx2("div", { className: "flex justify-start", children: /* @__PURE__ */ jsxs("div", { className: "max-w-[80%] px-3 py-2 rounded-xl bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm flex gap-1 items-center", children: [
|
|
37
37
|
/* @__PURE__ */ jsx2("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "-0.32s" } }),
|
|
38
38
|
/* @__PURE__ */ jsx2("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: "-0.16s" } }),
|
|
39
39
|
/* @__PURE__ */ jsx2("div", { className: "w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce" })
|
|
@@ -61,14 +61,14 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
|
|
|
61
61
|
handleSend();
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex gap-2 p-3 border-t border-
|
|
64
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex gap-2 p-3 border-t border-(--ai-border) bg-(--ai-bg)", children: [
|
|
65
65
|
/* @__PURE__ */ jsx3(
|
|
66
66
|
"input",
|
|
67
67
|
{
|
|
68
68
|
className: clsx2(
|
|
69
|
-
"flex-1 px-3 py-2 border border-
|
|
70
|
-
"font-inherit text-
|
|
71
|
-
"focus:border-
|
|
69
|
+
"flex-1 px-3 py-2 border border-(--ai-border) rounded-lg outline-none",
|
|
70
|
+
"font-inherit text-(--ai-text) placeholder:text-(--ai-text-secondary)",
|
|
71
|
+
"focus:border-(--ai-primary) disabled:opacity-50"
|
|
72
72
|
),
|
|
73
73
|
value: inputValue,
|
|
74
74
|
onChange: (e) => setInputValue(e.target.value),
|
|
@@ -82,7 +82,7 @@ var ChatInput = ({ onSendMessage, isLoading }) => {
|
|
|
82
82
|
{
|
|
83
83
|
className: clsx2(
|
|
84
84
|
"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity",
|
|
85
|
-
"bg-
|
|
85
|
+
"bg-(--ai-primary) text-(--ai-primary-fg)",
|
|
86
86
|
"hover:opacity-90",
|
|
87
87
|
(isLoading || !inputValue.trim()) && "opacity-50 cursor-not-allowed"
|
|
88
88
|
),
|
|
@@ -133,11 +133,11 @@ var ChatWindow = ({
|
|
|
133
133
|
}
|
|
134
134
|
};
|
|
135
135
|
return /* @__PURE__ */ jsxs3("div", { className: clsx3(
|
|
136
|
-
"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-
|
|
137
|
-
"bg-
|
|
136
|
+
"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-(--ai-border)",
|
|
137
|
+
"bg-(--ai-bg) overflow-hidden shadow-lg relative",
|
|
138
138
|
"font-inherit text-base leading-6 box-border"
|
|
139
139
|
), children: [
|
|
140
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-4 py-4 border-b border-
|
|
140
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 px-4 py-4 border-b border-(--ai-border) bg-gray-50", children: [
|
|
141
141
|
/* @__PURE__ */ jsx4(Bot, { size: 20 }),
|
|
142
142
|
/* @__PURE__ */ jsx4("span", { className: "font-semibold", children: title })
|
|
143
143
|
] }),
|
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 clsx from 'clsx';\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\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\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={clsx(\r\n \"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-[var(--ai-border)]\",\r\n \"bg-[var(--ai-bg)] overflow-hidden shadow-lg relative\",\r\n \"font-inherit text-base leading-6 box-border\"\r\n )}>\r\n <div className=\"flex items-center gap-2 px-4 py-4 border-b border-[var(--ai-border)] bg-gray-50\">\r\n <Bot size={20} />\r\n <span className=\"font-semibold\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\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 clsx from 'clsx';\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=\"flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"flex justify-start\">\r\n <div className=\"max-w-[80%] px-3 py-2 rounded-xl bg-[var(--ai-bot-bg)] text-[var(--ai-text)] rounded-bl-sm flex gap-1 items-center\">\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\"></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(\"flex w-full\", isUser ? \"justify-end\" : \"justify-start\")}>\r\n <div\r\n className={clsx(\r\n \"max-w-[80%] px-3 py-2 rounded-xl text-sm break-words\",\r\n isUser\r\n ? \"bg-[var(--ai-user-bg)] text-[var(--ai-user-text)] rounded-br-sm\"\r\n : \"bg-[var(--ai-bot-bg)] text-[var(--ai-text)] rounded-bl-sm\"\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 clsx from 'clsx';\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=\"flex gap-2 p-3 border-t border-[var(--ai-border)] bg-[var(--ai-bg)]\">\r\n <input\r\n className={clsx(\r\n \"flex-1 px-3 py-2 border border-[var(--ai-border)] rounded-lg outline-none\",\r\n \"font-inherit text-[var(--ai-text)] placeholder:text-[var(--ai-text-secondary)]\",\r\n \"focus:border-[var(--ai-primary)] disabled:opacity-50\"\r\n )}\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={clsx(\r\n \"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity\",\r\n \"bg-[var(--ai-primary)] text-[var(--ai-primary-fg)]\",\r\n \"hover:opacity-90\",\r\n (isLoading || !inputValue.trim()) && \"opacity-50 cursor-not-allowed\"\r\n )}\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","clsx","jsx","clsx","jsx","jsxs","jsx","jsxs","useState","useEffect","clsx"]}
|
|
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 clsx from 'clsx';\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\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\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={clsx(\r\n \"flex flex-col h-[500px] w-full max-w-md rounded-xl border border-(--ai-border)\",\r\n \"bg-(--ai-bg) overflow-hidden shadow-lg relative\",\r\n \"font-inherit text-base leading-6 box-border\"\r\n )}>\r\n <div className=\"flex items-center gap-2 px-4 py-4 border-b border-(--ai-border) bg-gray-50\">\r\n <Bot size={20} />\r\n <span className=\"font-semibold\">{title}</span>\r\n </div>\r\n\r\n <MessageList messages={messages} isLoading={isLoading} />\r\n <ChatInput onSendMessage={handleSendMessage} isLoading={isLoading} />\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 clsx from 'clsx';\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=\"flex-1 overflow-y-auto p-4 flex flex-col gap-3 scroll-smooth\">\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n\r\n {isLoading && (\r\n <div className=\"flex justify-start\">\r\n <div className=\"max-w-[80%] px-3 py-2 rounded-xl bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm flex gap-1 items-center\">\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.32s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\" style={{ animationDelay: '-0.16s' }}></div>\r\n <div className=\"w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce\"></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(\"flex w-full\", isUser ? \"justify-end\" : \"justify-start\")}>\r\n <div\r\n className={clsx(\r\n \"max-w-[80%] px-3 py-2 rounded-xl text-sm break-all\",\r\n isUser\r\n ? \"bg-(--ai-user-bg) text-(--ai-user-text) rounded-br-sm\"\r\n : \"bg-(--ai-bot-bg) text-(--ai-text) rounded-bl-sm\"\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 clsx from 'clsx';\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=\"flex gap-2 p-3 border-t border-(--ai-border) bg-(--ai-bg)\">\r\n <input\r\n className={clsx(\r\n \"flex-1 px-3 py-2 border border-(--ai-border) rounded-lg outline-none\",\r\n \"font-inherit text-(--ai-text) placeholder:text-(--ai-text-secondary)\",\r\n \"focus:border-(--ai-primary) disabled:opacity-50\"\r\n )}\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={clsx(\r\n \"px-3 py-2 rounded-lg flex items-center justify-center transition-opacity\",\r\n \"bg-(--ai-primary) text-(--ai-primary-fg)\",\r\n \"hover:opacity-90\",\r\n (isLoading || !inputValue.trim()) && \"opacity-50 cursor-not-allowed\"\r\n )}\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","clsx","jsx","clsx","jsx","jsxs","jsx","jsxs","useState","useEffect","clsx"]}
|