react-groq-chat 1.0.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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026, Ahmed Mamdoh
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # 🤖 React Groq Chat
2
+
3
+ A modern, customizable React component for integrating a chatbot with the Groq API. Built with TypeScript, Tailwind CSS, and Radix UI for a professional chat interface.
4
+
5
+ [![npm version](https://badge.fury.io/js/react-groq-chat.svg)](https://badge.fury.io/js/react-groq-chat)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
7
+
8
+ ## ✨ Features
9
+
10
+ - 🎯 **Easy Integration** - Simple drop-in component for React applications
11
+ - 🎨 **Customizable UI** - Tailwind CSS styling with custom color themes
12
+ - 🚀 **Modern Stack** - Built with TypeScript, Radix UI, and React 19
13
+ - 📱 **Responsive Design** - Works perfectly on desktop and mobile
14
+ - ⚡ **Fast Performance** - Optimized with React best practices
15
+ - 🔒 **Type Safe** - Full TypeScript support with comprehensive types
16
+ - 🎭 **Markdown Support** - Rich message formatting with react-markdown
17
+ - 🔄 **Real-time Chat** - Smooth conversation flow with loading states
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install react-groq-chat
23
+ ```
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ ```tsx
28
+ import { ChatBot } from 'react-groq-chat';
29
+
30
+ function App() {
31
+ return (
32
+ <ChatBot
33
+ apiKey="your-groq-api-key"
34
+ triggerColor="#007bff"
35
+ />
36
+ );
37
+ }
38
+ ```
39
+
40
+ ## 🔧 Props
41
+
42
+ | Prop | Type | Default | Description |
43
+ |------|------|---------|-------------|
44
+ | `apiKey` | `string` | **Required** | Your Groq API key |
45
+ | `triggerColor` | `string` | `"#007bff"` | Color theme for the chat trigger button |
46
+ | `triggerImg` | `string` | Built-in icon | Custom image for the trigger button |
47
+
48
+ ## 🎨 Customization
49
+
50
+ ### Custom Trigger Button
51
+
52
+ ```tsx
53
+ <ChatBot
54
+ apiKey="your-api-key"
55
+ triggerColor="#ff6b6b"
56
+ triggerImg="/path/to/your/icon.png"
57
+ />
58
+ ```
59
+
60
+ ### Styling with Tailwind CSS
61
+
62
+ The component uses Tailwind CSS classes. Make sure you have Tailwind CSS installed in your project:
63
+
64
+ ```bash
65
+ npm install -D tailwindcss postcss autoprefixer
66
+ npx tailwindcss init
67
+ ```
68
+
69
+ ## 📋 Requirements
70
+
71
+ - React 19.0.0 or higher
72
+ - Tailwind CSS (for styling)
73
+ - Groq API key
74
+
75
+ ## 🛠️ Development
76
+
77
+ ```bash
78
+ # Clone the repository
79
+ git clone https://github.com/your-username/react-groq-chat.git
80
+
81
+ # Install dependencies
82
+ npm install
83
+
84
+ # Build the package
85
+ npm run build
86
+
87
+ # Watch for changes
88
+ npm run dev
89
+ ```
90
+
91
+ ## 🔗 API Integration
92
+
93
+ This component integrates with the Groq API and supports multiple models:
94
+
95
+ - `llama-3.3-70b-versatile`
96
+ - `meta-llama/llama-4-maverick-17b-128e-instruct`
97
+ - `meta-llama/llama-4-scout-17b-16e-instruct`
98
+ - `moonshotai/kimi-k2-instruct-0905`
99
+ - And more...
100
+
101
+ ## 🎯 Example Usage
102
+
103
+ ```tsx
104
+ import React, { useState } from 'react';
105
+ import { ChatBot } from 'react-groq-chat';
106
+
107
+ function ChatApp() {
108
+ const [apiKey, setApiKey] = useState('');
109
+ const [showChat, setShowChat] = useState(false);
110
+
111
+ return (
112
+ <div>
113
+ {!showChat ? (
114
+ <div>
115
+ <input
116
+ type="password"
117
+ placeholder="Enter Groq API Key"
118
+ value={apiKey}
119
+ onChange={(e) => setApiKey(e.target.value)}
120
+ />
121
+ <button onClick={() => setShowChat(true)}>
122
+ Start Chat
123
+ </button>
124
+ </div>
125
+ ) : (
126
+ <ChatBot
127
+ apiKey={apiKey}
128
+ triggerColor="#456"
129
+ />
130
+ )}
131
+ </div>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ## 🐛 Error Handling
137
+
138
+ The component includes built-in error handling for:
139
+ - Invalid API keys
140
+ - Network errors
141
+ - Rate limiting
142
+ - Model availability issues
143
+
144
+ ## 📄 License
145
+
146
+ ISC License - see [LICENSE](LICENSE) file for details.
147
+
148
+ ## 🤝 Contributing
149
+
150
+ Contributions are welcome! Please feel free to submit a Pull Request.
151
+
152
+ ## 📞 Support
153
+
154
+ For issues and questions:
155
+ - Open an issue on GitHub
156
+ - Check the [documentation](https://github.com/your-username/react-groq-chat)
157
+
158
+ ---
159
+
160
+ Made with ❤️ by Ahmed Mamdoh
package/SETUP.md ADDED
@@ -0,0 +1,199 @@
1
+ # 🚀 Setup Guide for React Groq Chat
2
+
3
+ ## Prerequisites
4
+
5
+ Before using this component, make sure you have:
6
+
7
+ 1. **Node.js** (v14 or higher)
8
+ 2. **React** (v16.8 or higher)
9
+ 3. **Tailwind CSS** installed in your project
10
+ 4. **Groq API Key** (get one at [groq.com](https://groq.com))
11
+
12
+ ## 📦 Installation
13
+
14
+ ```bash
15
+ npm install react-groq-chat
16
+ ```
17
+
18
+ ## 🎨 Tailwind CSS Setup
19
+
20
+ If you don't have Tailwind CSS installed:
21
+
22
+ ```bash
23
+ npm install -D tailwindcss postcss autoprefixer
24
+ npx tailwindcss init
25
+ ```
26
+
27
+ Configure your `tailwind.config.js`:
28
+
29
+ ```javascript
30
+ module.exports = {
31
+ content: [
32
+ "./src/**/*.{js,jsx,ts,tsx}",
33
+ "./node_modules/react-groq-chat/dist/**/*.{js,jsx,ts,tsx}"
34
+ ],
35
+ theme: {
36
+ extend: {},
37
+ },
38
+ plugins: [],
39
+ }
40
+ ```
41
+
42
+ Add to your CSS file:
43
+
44
+ ```css
45
+ @tailwind base;
46
+ @tailwind components;
47
+ @tailwind utilities;
48
+ ```
49
+
50
+ ## 🔑 Getting a Groq API Key
51
+
52
+ 1. Visit [console.groq.com](https://console.groq.com)
53
+ 2. Sign up for an account
54
+ 3. Navigate to API Keys
55
+ 4. Create a new API key
56
+ 5. Copy the key (it starts with `gsk_`)
57
+
58
+ ## 💻 Basic Usage
59
+
60
+ ```tsx
61
+ import { ChatBot } from 'react-groq-chat';
62
+
63
+ function App() {
64
+ return (
65
+ <ChatBot
66
+ apiKey="your-groq-api-key-here"
67
+ triggerColor="#007bff"
68
+ />
69
+ );
70
+ }
71
+ ```
72
+
73
+ ## 🎨 Customization Options
74
+
75
+ ### Custom Trigger Button
76
+
77
+ ```tsx
78
+ <ChatBot
79
+ apiKey="your-api-key"
80
+ triggerColor="#ff6b6b"
81
+ triggerImg="/path/to/your/icon.png"
82
+ />
83
+ ```
84
+
85
+ ### Available Props
86
+
87
+ | Prop | Type | Default | Description |
88
+ |------|------|---------|-------------|
89
+ | `apiKey` | `string` | **Required** | Your Groq API key |
90
+ | `triggerColor` | `string` | `"#007bff"` | Color theme for the chat trigger button |
91
+ | `triggerImg` | `string` | Built-in icon | Custom image for the trigger button |
92
+
93
+ ## 🛠️ Advanced Setup with State Management
94
+
95
+ ```tsx
96
+ import React, { useState } from 'react';
97
+ import { ChatBot } from 'react-groq-chat';
98
+
99
+ function App() {
100
+ const [apiKey, setApiKey] = useState('');
101
+ const [showChat, setShowChat] = useState(false);
102
+
103
+ return (
104
+ <div>
105
+ {!showChat ? (
106
+ <div>
107
+ <input
108
+ type="password"
109
+ placeholder="Enter Groq API Key"
110
+ value={apiKey}
111
+ onChange={(e) => setApiKey(e.target.value)}
112
+ />
113
+ <button onClick={() => setShowChat(true)}>
114
+ Start Chat
115
+ </button>
116
+ </div>
117
+ ) : (
118
+ <ChatBot
119
+ apiKey={apiKey}
120
+ triggerColor="#456"
121
+ />
122
+ )}
123
+ </div>
124
+ );
125
+ }
126
+ ```
127
+
128
+ ## 🔧 Environment Variables (Recommended)
129
+
130
+ For production applications, store your API key in environment variables:
131
+
132
+ ```tsx
133
+ <ChatBot
134
+ apiKey={process.env.REACT_APP_GROQ_API_KEY}
135
+ triggerColor="#007bff"
136
+ />
137
+ ```
138
+
139
+ Create a `.env` file:
140
+
141
+ ```
142
+ REACT_APP_GROQ_API_KEY=your-groq-api-key-here
143
+ ```
144
+
145
+ ## 🎯 Available Models
146
+
147
+ The component supports multiple Groq models:
148
+
149
+ - `llama-3.3-70b-versatile`
150
+ - `meta-llama/llama-4-maverick-17b-128e-instruct`
151
+ - `meta-llama/llama-4-scout-17b-16e-instruct`
152
+ - `moonshotai/kimi-k2-instruct-0905`
153
+ - `groq/compound`
154
+
155
+ ## 🐛 Troubleshooting
156
+
157
+ ### Image Not Loading
158
+
159
+ If the default chat icon doesn't load:
160
+ - Check your build configuration
161
+ - Provide a custom `triggerImg` prop
162
+ - Ensure proper asset handling in your build tool
163
+
164
+ ### Chat Not Responding
165
+
166
+ - Verify your API key is valid
167
+ - Check your internet connection
168
+ - Ensure you're not hitting rate limits
169
+ - Check browser console for errors
170
+
171
+ ### Styling Issues
172
+
173
+ - Make sure Tailwind CSS is properly configured
174
+ - Check that the component classes aren't being purged
175
+ - Verify your Tailwind config includes the component files
176
+
177
+ ## 📱 Mobile Optimization
178
+
179
+ The component is fully responsive and works great on mobile devices. The chat interface adapts to smaller screens automatically.
180
+
181
+ ## 🔒 Security Best Practices
182
+
183
+ 1. **Never commit API keys** to your repository
184
+ 2. **Use environment variables** for production
185
+ 3. **Implement proper authentication** in your application
186
+ 4. **Validate user input** before processing
187
+ 5. **Use HTTPS** in production
188
+
189
+ ## 📞 Support
190
+
191
+ If you encounter any issues:
192
+
193
+ 1. Check the [GitHub Issues](https://github.com/your-username/react-groq-chat/issues)
194
+ 2. Review the [documentation](README.md)
195
+ 3. Create a new issue with detailed information
196
+
197
+ ---
198
+
199
+ Happy coding! 🚀
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';var x=require('@radix-ui/react-popover'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),D=require('react-markdown'),fa=require('react-icons/fa');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var x__namespace=/*#__PURE__*/_interopNamespace(x);var D__default=/*#__PURE__*/_interopDefault(D);async function B({messages:o,model:t,apiKey:r}){let e="https://api.groq.com/openai/v1/chat/completions",n={method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({model:t,messages:o,temperature:.3})};try{return (await(await fetch(e,n)).json()).choices[0].message}catch(s){return console.error(s),"error"}}function K({apiKey:o,systemPrompt:t,assistantFirstMessage:r}){let e=["openai/gpt-oss-120b","llama-3.3-70b-versatile","moonshotai/kimi-k2-instruct-0905","meta-llama/llama-4-maverick-17b-128e-instruct","meta-llama/llama-4-scout-17b-16e-instruct","groq/compound","openai/gpt-oss-20b","openai/gpt-oss-safeguard-20b","llama-3.1-8b-instant","groq/compound-mini","meta-llama/llama-guard-4-12b","meta-llama/llama-prompt-guard-2-86m","meta-llama/llama-prompt-guard-2-22m"],[n,s]=react.useState([{role:"system",content:t},{role:"assistant",content:r}]),[a,d]=react.useState(""),[v,c]=react.useState(false),p=react.useRef(null),l=react.useRef(0);react.useEffect(()=>{p?.current?.scrollTo({top:p.current.scrollHeight,behavior:"smooth"});},[n]);function y(h=""){let f=typeof h=="string"?h:"";if(!a.trim()&&!f.trim())return;let C={role:"user",content:a||f},b=[...n,C];s(b),d(""),c(true),B({model:e[l.current],messages:b,apiKey:o}).then(g=>{g==="error"?(s(u=>[...u,{role:"assistant",content:"Sorry, I encountered an error. Please try again."}]),l.current++,l.current>=e.length&&(l.current=0)):s(u=>[...u,g]);}).catch(g=>{console.error(g);}).finally(()=>{c(false);});}return {messages:n,input:a,setInput:d,handleSendMessage:y,messagesRef:p,isLoading:v}}var N=K;function j({triggerColor:o="#111",triggerImg:t,triggerRightPosition:r=24,triggerBottomPosition:e=24}){return jsxRuntime.jsx(x.PopoverTrigger,{asChild:true,children:jsxRuntime.jsxs("button",{className:`fixed right-[${r}px] ${t?"":"h-14 w-14"} bottom-[${e}px] z-10 cursor-pointer rounded-full bg-[${o}] p-1 shadow-lg transition-all hover:scale-110 hover:bg-[${o}]/90 active:scale-95`,children:[t&&jsxRuntime.jsx("img",{src:t,alt:"Chat with chatbot",className:"h-14 w-14"}),!t&&jsxRuntime.jsx("p",{className:"text-white text-center text-xl",children:"C"})]})})}var _=j;function E({messages:o,messagesRef:t,isLoading:r,userMessageBgColor:e="#fff",assistantMessageBgColor:n="#007bff"}){return jsxRuntime.jsxs("div",{ref:t,style:{scrollbarWidth:"none",msOverflowStyle:"none"},className:" flex h-full flex-col gap-4 overflow-x-hidden overflow-y-auto",children:[o.map((s,a)=>{if(s.role==="user")return jsxRuntime.jsx("div",{className:"flex justify-start",children:jsxRuntime.jsx("div",{dir:"auto",style:{unicodeBidi:"isolate"},className:`max-w-[95%] rounded-2xl rounded-bl-none bg-[${e}] px-4 py-2 text-start text-sm shadow-sm`,children:s.content.replace(/\[\[.*?\]\]/g,"")})},a);if(s.role==="assistant")return jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("div",{dir:"rtl",style:{unicodeBidi:"isolate",display:"inline-block"},className:`bg-[${n}] max-w-[95%] rounded-2xl rounded-br-none px-4 py-2 text-start text-sm wrap-break-word whitespace-normal text-white shadow-md`,children:jsxRuntime.jsx(D__default.default,{children:s.content})})},a)}),r&&jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("div",{className:"bg-red/90 rounded-2xl rounded-br-none px-4 py-2 text-white shadow-md",children:jsxRuntime.jsx("span",{className:"loading loading-dots loading-xs"})})})]})}var $=E;function H({handleSendMessage:o,input:t,setInput:r}){return jsxRuntime.jsxs("div",{className:"flex h-full items-end gap-2",children:[jsxRuntime.jsx("textarea",{onKeyDown:e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),o());},value:t,onChange:e=>r(e.target.value),placeholder:"Ask me anything...",style:{fieldSizing:"content",scrollbarWidth:"none",msOverflowStyle:"none"},dir:"auto",className:"auto-expand text-yellowish-white placeholder:text-dark-yellowish-white max-h-[20vh] min-h-6 w-full resize-none overflow-auto bg-transparent py-1 ring-transparent outline-none"}),jsxRuntime.jsx("button",{onClick:()=>o(),className:"bg-red hover:bg-light-red cursor-pointer rounded-full p-2 text-white transition-colors",children:jsxRuntime.jsx(fa.FaPaperPlane,{className:"h-4 w-4"})})]})}var I=H;var U=x__namespace.Root,J=x__namespace.Content;function Q({apiKey:o,triggerColor:t,triggerImg:r,contentBgColor:e="#1a1a1a",contentHeight:n=500,contentWidth:s=350,contentBorder:a=1,contentBorderColor:d="#333333",textColor:v="#ffffff",userMessageBgColor:c="#007bff",assistantMessageBgColor:p="#2d2d2d",triggerRightPosition:l=24,triggerBottomPosition:y=24,contentRightPosition:h=24,systemPrompt:f="You are a helpful AI assistant. Provide clear, concise, and accurate responses.",assistantFirstMessage:C="Hello! I'm here to help you. What can I assist you with today?",contentBorderRoundness:b=16}){let{messages:g,input:u,setInput:L,handleSendMessage:T,messagesRef:S,isLoading:q}=N({apiKey:o,systemPrompt:f,assistantFirstMessage:C});return jsxRuntime.jsxs(U,{children:[jsxRuntime.jsx(_,{triggerColor:t,triggerImg:r,triggerRightPosition:l,triggerBottomPosition:y}),jsxRuntime.jsx(J,{className:`bg-[${e}] mr-[${h}px] h-[${n}px] max-h-[${n}px] w-[${s}px] border-[${a}px] border-[${d}] text-[${v}] shadow-2xl ring-1 ring-white/10 rounded-[${b}px]`,children:jsxRuntime.jsxs("div",{className:"flex h-full flex-col gap-4 p-2",children:[jsxRuntime.jsx("div",{className:"min-h-0 flex-1",children:jsxRuntime.jsx($,{messages:g,messagesRef:S,isLoading:q,userMessageBgColor:c,assistantMessageBgColor:p})}),jsxRuntime.jsx("div",{className:"shrink-0 rounded-xl bg-black/40 p-2",children:jsxRuntime.jsx(I,{handleSendMessage:T,input:u,setInput:L})})]})})]})}
2
+ exports.ChatBot=Q;//# sourceMappingURL=index.cjs.map
3
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/groqApi.ts","../src/ChatBot/hooks/useChat.tsx","../src/ChatBot/components/ChatTrigger.tsx","../src/ChatBot/components/MessageList.tsx","../src/ChatBot/components/ChatInput.tsx","../src/ChatBot/ChatBot.tsx"],"names":["chatWithGroq","messages","model","apiKey","url","options","error","useChat","systemPrompt","assistantFirstMessage","models","setMessages","useState","input","setInput","isLoading","setIsLoading","messagesRef","useRef","modelNumber","useEffect","handleSendMessage","text","messageContent","userMessage","newMessages","res","prev","err","useChat_default","ChatTrigger","triggerColor","triggerImg","triggerRightPosition","triggerBottomPosition","jsx","PopoverTrigger","jsxs","ChatTrigger_default","MessageList","userMessageBgColor","assistantMessageBgColor","item","index","Markdown","MessageList_default","ChatInput","FaPaperPlane","ChatInput_default","Popover","x","PopoverContent","ChatBot","contentBgColor","contentHeight","contentWidth","contentBorder","contentBorderColor","textColor","contentRightPosition","contentBorderRoundness"],"mappings":"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","file":"index.cjs","sourcesContent":["type chatWithGroqProps = {\r\n messages: {\r\n role: string;\r\n content: string;\r\n }[];\r\n model: string;\r\n apiKey: string;\r\n};\r\n\r\ntype response = {\r\n id: string;\r\n object: string;\r\n created: number;\r\n model: string;\r\n choices: {\r\n index: number;\r\n message: {\r\n role: string;\r\n content: string;\r\n reasoning?: string;\r\n };\r\n logprobs: null;\r\n finish_reason: string;\r\n }[];\r\n usage: {\r\n queue_time: number;\r\n prompt_tokens: number;\r\n prompt_time: number;\r\n completion_tokens: number;\r\n completion_time: number;\r\n total_tokens: number;\r\n total_time: number;\r\n prompt_tokens_details: {\r\n cached_tokens: number;\r\n };\r\n completion_tokens_details: {\r\n reasoning_tokens: number;\r\n };\r\n };\r\n usage_breakdown: null;\r\n system_fingerprint: string;\r\n x_groq: {\r\n id: string;\r\n seed: number;\r\n };\r\n service_tier: string;\r\n};\r\n\r\nexport async function chatWithGroq({\r\n messages,\r\n model,\r\n apiKey,\r\n}: chatWithGroqProps) {\r\n const url = \"https://api.groq.com/openai/v1/chat/completions\";\r\n const options = {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n model: model,\r\n messages,\r\n temperature: 0.3,\r\n }),\r\n };\r\n\r\n try {\r\n const response = await fetch(url, options);\r\n const result: response = await response.json();\r\n return result.choices[0].message;\r\n } catch (error) {\r\n console.error(error);\r\n return \"error\";\r\n }\r\n}\r\n","import { chatWithGroq } from \"@/api/groqApi\";\r\nimport { useEffect, useRef, useState } from \"react\";\r\n\r\nexport type UseChatProps = {\r\n apiKey: string;\r\n systemPrompt: string;\r\n assistantFirstMessage: string;\r\n};\r\n\r\nfunction useChat({\r\n apiKey,\r\n systemPrompt,\r\n assistantFirstMessage,\r\n}: UseChatProps) {\r\n const models = [\r\n \"openai/gpt-oss-120b\",\r\n \"llama-3.3-70b-versatile\",\r\n \"moonshotai/kimi-k2-instruct-0905\",\r\n \"meta-llama/llama-4-maverick-17b-128e-instruct\",\r\n \"meta-llama/llama-4-scout-17b-16e-instruct\",\r\n \"groq/compound\",\r\n \"openai/gpt-oss-20b\",\r\n \"openai/gpt-oss-safeguard-20b\",\r\n \"llama-3.1-8b-instant\",\r\n \"groq/compound-mini\",\r\n \"meta-llama/llama-guard-4-12b\",\r\n \"meta-llama/llama-prompt-guard-2-86m\",\r\n \"meta-llama/llama-prompt-guard-2-22m\",\r\n ];\r\n const [messages, setMessages] = useState([\r\n {\r\n role: \"system\",\r\n content: systemPrompt,\r\n },\r\n {\r\n role: \"assistant\",\r\n content: assistantFirstMessage,\r\n },\r\n ]);\r\n const [input, setInput] = useState(\"\");\r\n const [isLoading, setIsLoading] = useState(false);\r\n const messagesRef = useRef<HTMLDivElement>(null);\r\n const modelNumber = useRef(0);\r\n\r\n useEffect(() => {\r\n // Scroll to the bottom of the messages container\r\n messagesRef?.current?.scrollTo({\r\n top: messagesRef.current.scrollHeight,\r\n behavior: \"smooth\",\r\n });\r\n }, [messages]);\r\n\r\n function handleSendMessage(text = \"\") {\r\n const messageContent = typeof text === \"string\" ? text : \"\";\r\n if (!input.trim() && !messageContent.trim()) return;\r\n\r\n const userMessage = { role: \"user\", content: input || messageContent };\r\n const newMessages = [...messages, userMessage];\r\n\r\n setMessages(newMessages);\r\n setInput(\"\");\r\n setIsLoading(true);\r\n\r\n chatWithGroq({\r\n model: models[modelNumber.current],\r\n messages: newMessages,\r\n apiKey: apiKey,\r\n })\r\n .then((res) => {\r\n if (res === \"error\") {\r\n setMessages((prev) => [\r\n ...prev,\r\n {\r\n role: \"assistant\",\r\n content: \"Sorry, I encountered an error. Please try again.\",\r\n },\r\n ]);\r\n modelNumber.current++;\r\n if (modelNumber.current >= models.length) {\r\n modelNumber.current = 0;\r\n }\r\n } else {\r\n setMessages((prev) => [...prev, res]);\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n })\r\n .finally(() => {\r\n setIsLoading(false);\r\n });\r\n }\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n handleSendMessage,\r\n messagesRef,\r\n isLoading,\r\n };\r\n}\r\n\r\nexport default useChat;\r\n","import { PopoverTrigger } from \"@radix-ui/react-popover\";\r\n\r\ntype ChatTriggerProps = {\r\n triggerColor?: string;\r\n triggerImg?: string;\r\n triggerRightPosition?: number;\r\n triggerBottomPosition?: number;\r\n};\r\n\r\nfunction ChatTrigger({\r\n triggerColor = \"#111\",\r\n triggerImg,\r\n triggerRightPosition = 24,\r\n triggerBottomPosition = 24,\r\n}: ChatTriggerProps) {\r\n return (\r\n <PopoverTrigger asChild>\r\n <button\r\n className={`fixed right-[${triggerRightPosition}px] ${triggerImg ? \"\" : \"h-14 w-14\"} bottom-[${triggerBottomPosition}px] z-10 cursor-pointer rounded-full bg-[${triggerColor}] p-1 shadow-lg transition-all hover:scale-110 hover:bg-[${triggerColor}]/90 active:scale-95`}\r\n >\r\n {triggerImg && (\r\n <img src={triggerImg} alt=\"Chat with chatbot\" className=\"h-14 w-14\" />\r\n )}\r\n {!triggerImg && <p className=\"text-white text-center text-xl\">C</p>}\r\n </button>\r\n </PopoverTrigger>\r\n );\r\n}\r\n\r\nexport default ChatTrigger;\r\n","import type { RefObject } from \"react\";\r\nimport Markdown from \"react-markdown\";\r\n\r\ntype MessageListProps = {\r\n messages: { role: string; content: string }[];\r\n messagesRef: RefObject<HTMLDivElement | null>;\r\n isLoading: boolean;\r\n userMessageBgColor?: string;\r\n assistantMessageBgColor?: string;\r\n};\r\n\r\nfunction MessageList({\r\n messages,\r\n messagesRef,\r\n isLoading,\r\n userMessageBgColor = \"#fff\",\r\n assistantMessageBgColor = \"#007bff\",\r\n}: MessageListProps) {\r\n return (\r\n <div\r\n ref={messagesRef}\r\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\r\n className=\" flex h-full flex-col gap-4 overflow-x-hidden overflow-y-auto\"\r\n >\r\n {messages.map((item, index) => {\r\n if (item.role === \"user\")\r\n return (\r\n <div key={index} className=\"flex justify-start\">\r\n <div\r\n dir=\"auto\"\r\n style={{ unicodeBidi: \"isolate\" }}\r\n className={`max-w-[95%] rounded-2xl rounded-bl-none bg-[${userMessageBgColor}] px-4 py-2 text-start text-sm shadow-sm`}\r\n >\r\n {item.content.replace(/\\[\\[.*?\\]\\]/g, \"\")}\r\n </div>\r\n </div>\r\n );\r\n if (item.role === \"assistant\") {\r\n return (\r\n <div key={index} className=\"flex justify-end\">\r\n <div\r\n dir=\"rtl\"\r\n style={{ unicodeBidi: \"isolate\", display: \"inline-block\" }}\r\n className={`bg-[${assistantMessageBgColor}] max-w-[95%] rounded-2xl rounded-br-none px-4 py-2 text-start text-sm wrap-break-word whitespace-normal text-white shadow-md`}\r\n >\r\n <Markdown>{item.content}</Markdown>\r\n </div>\r\n </div>\r\n );\r\n }\r\n })}\r\n {isLoading && (\r\n <div className=\"flex justify-end\">\r\n <div className=\"bg-red/90 rounded-2xl rounded-br-none px-4 py-2 text-white shadow-md\">\r\n <span className=\"loading loading-dots loading-xs\"></span>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default MessageList;\r\n","import { FaPaperPlane } from \"react-icons/fa\";\r\nimport { FaQuestionCircle } from \"react-icons/fa\";\r\n\r\ntype ChatInputProps = {\r\n handleSendMessage: (text?: string) => void;\r\n input: string;\r\n setInput: (text: string) => void;\r\n};\r\n\r\nfunction ChatInput({ handleSendMessage, input, setInput }: ChatInputProps) {\r\n return (\r\n <div className=\"flex h-full items-end gap-2\">\r\n <textarea\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\" && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSendMessage();\r\n }\r\n }}\r\n value={input}\r\n onChange={(e) => setInput(e.target.value)}\r\n placeholder=\"Ask me anything...\"\r\n style={{\r\n fieldSizing: \"content\",\r\n scrollbarWidth: \"none\",\r\n msOverflowStyle: \"none\",\r\n }}\r\n dir=\"auto\"\r\n className=\"auto-expand text-yellowish-white placeholder:text-dark-yellowish-white max-h-[20vh] min-h-6 w-full resize-none overflow-auto bg-transparent py-1 ring-transparent outline-none\"\r\n />\r\n <button\r\n onClick={() => handleSendMessage()}\r\n className=\"bg-red hover:bg-light-red cursor-pointer rounded-full p-2 text-white transition-colors\"\r\n >\r\n <FaPaperPlane className=\"h-4 w-4\" />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nexport default ChatInput;\r\n","import * as PopoverPrimitive from \"@radix-ui/react-popover\";\r\nimport useChat from \"./hooks/useChat\";\r\nimport ChatTrigger from \"./components/ChatTrigger\";\r\nimport MessageList from \"./components/MessageList\";\r\nimport ChatInput from \"./components/ChatInput\";\r\n\r\n// Custom popover components to avoid shadcn dependency\r\nconst Popover = PopoverPrimitive.Root;\r\nconst PopoverContent = PopoverPrimitive.Content;\r\n\r\nexport type ChatBotProps = {\r\n apiKey: string;\r\n triggerColor?: string;\r\n triggerImg?: string;\r\n contentBgColor?: string;\r\n contentHeight?: number;\r\n contentWidth?: number;\r\n contentBorder?: number;\r\n contentBorderColor?: string;\r\n contentBorderRoundness?: number;\r\n textColor?: string;\r\n userMessageBgColor?: string;\r\n assistantMessageBgColor?: string;\r\n triggerRightPosition?: number;\r\n triggerBottomPosition?: number;\r\n contentRightPosition?: number;\r\n systemPrompt?: string;\r\n assistantFirstMessage?: string;\r\n};\r\n\r\nexport function ChatBot({\r\n apiKey,\r\n triggerColor,\r\n triggerImg,\r\n contentBgColor = \"#1a1a1a\",\r\n contentHeight = 500,\r\n contentWidth = 350,\r\n contentBorder = 1,\r\n contentBorderColor = \"#333333\",\r\n textColor = \"#ffffff\",\r\n userMessageBgColor = \"#007bff\",\r\n assistantMessageBgColor = \"#2d2d2d\",\r\n triggerRightPosition = 24,\r\n triggerBottomPosition = 24,\r\n contentRightPosition = 24,\r\n systemPrompt = `You are a helpful AI assistant. Provide clear, concise, and accurate responses.`,\r\n assistantFirstMessage = \"Hello! I'm here to help you. What can I assist you with today?\",\r\n contentBorderRoundness = 16,\r\n}: ChatBotProps) {\r\n const {\r\n messages,\r\n input,\r\n setInput,\r\n handleSendMessage,\r\n messagesRef,\r\n isLoading,\r\n } = useChat({ apiKey, systemPrompt, assistantFirstMessage });\r\n return (\r\n <Popover>\r\n <ChatTrigger\r\n triggerColor={triggerColor}\r\n triggerImg={triggerImg}\r\n triggerRightPosition={triggerRightPosition}\r\n triggerBottomPosition={triggerBottomPosition}\r\n />\r\n <PopoverContent\r\n className={`bg-[${contentBgColor}] mr-[${contentRightPosition}px] h-[${contentHeight}px] max-h-[${contentHeight}px] w-[${contentWidth}px] border-[${contentBorder}px] border-[${contentBorderColor}] text-[${textColor}] shadow-2xl ring-1 ring-white/10 rounded-[${contentBorderRoundness}px]`}\r\n >\r\n <div className=\"flex h-full flex-col gap-4 p-2\">\r\n <div className=\"min-h-0 flex-1\">\r\n <MessageList\r\n messages={messages}\r\n messagesRef={messagesRef}\r\n isLoading={isLoading}\r\n userMessageBgColor={userMessageBgColor}\r\n assistantMessageBgColor={assistantMessageBgColor}\r\n />\r\n </div>\r\n\r\n <div className=\"shrink-0 rounded-xl bg-black/40 p-2\">\r\n <ChatInput\r\n handleSendMessage={handleSendMessage}\r\n input={input}\r\n setInput={setInput}\r\n />\r\n </div>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"]}
@@ -0,0 +1,30 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type ChatBotProps = {
4
+ apiKey: string;
5
+ triggerColor?: string;
6
+ triggerImg?: string;
7
+ contentBgColor?: string;
8
+ contentHeight?: number;
9
+ contentWidth?: number;
10
+ contentBorder?: number;
11
+ contentBorderColor?: string;
12
+ contentBorderRoundness?: number;
13
+ textColor?: string;
14
+ userMessageBgColor?: string;
15
+ assistantMessageBgColor?: string;
16
+ triggerRightPosition?: number;
17
+ triggerBottomPosition?: number;
18
+ contentRightPosition?: number;
19
+ systemPrompt?: string;
20
+ assistantFirstMessage?: string;
21
+ };
22
+ declare function ChatBot({ apiKey, triggerColor, triggerImg, contentBgColor, contentHeight, contentWidth, contentBorder, contentBorderColor, textColor, userMessageBgColor, assistantMessageBgColor, triggerRightPosition, triggerBottomPosition, contentRightPosition, systemPrompt, assistantFirstMessage, contentBorderRoundness, }: ChatBotProps): react_jsx_runtime.JSX.Element;
23
+
24
+ type UseChatProps = {
25
+ apiKey: string;
26
+ systemPrompt: string;
27
+ assistantFirstMessage: string;
28
+ };
29
+
30
+ export { ChatBot, type ChatBotProps, type UseChatProps };
@@ -0,0 +1,30 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type ChatBotProps = {
4
+ apiKey: string;
5
+ triggerColor?: string;
6
+ triggerImg?: string;
7
+ contentBgColor?: string;
8
+ contentHeight?: number;
9
+ contentWidth?: number;
10
+ contentBorder?: number;
11
+ contentBorderColor?: string;
12
+ contentBorderRoundness?: number;
13
+ textColor?: string;
14
+ userMessageBgColor?: string;
15
+ assistantMessageBgColor?: string;
16
+ triggerRightPosition?: number;
17
+ triggerBottomPosition?: number;
18
+ contentRightPosition?: number;
19
+ systemPrompt?: string;
20
+ assistantFirstMessage?: string;
21
+ };
22
+ declare function ChatBot({ apiKey, triggerColor, triggerImg, contentBgColor, contentHeight, contentWidth, contentBorder, contentBorderColor, textColor, userMessageBgColor, assistantMessageBgColor, triggerRightPosition, triggerBottomPosition, contentRightPosition, systemPrompt, assistantFirstMessage, contentBorderRoundness, }: ChatBotProps): react_jsx_runtime.JSX.Element;
23
+
24
+ type UseChatProps = {
25
+ apiKey: string;
26
+ systemPrompt: string;
27
+ assistantFirstMessage: string;
28
+ };
29
+
30
+ export { ChatBot, type ChatBotProps, type UseChatProps };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import*as x from'@radix-ui/react-popover';import {PopoverTrigger}from'@radix-ui/react-popover';import {useState,useRef,useEffect}from'react';import {jsxs,jsx}from'react/jsx-runtime';import D from'react-markdown';import {FaPaperPlane}from'react-icons/fa';async function B({messages:o,model:t,apiKey:r}){let e="https://api.groq.com/openai/v1/chat/completions",n={method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({model:t,messages:o,temperature:.3})};try{return (await(await fetch(e,n)).json()).choices[0].message}catch(s){return console.error(s),"error"}}function K({apiKey:o,systemPrompt:t,assistantFirstMessage:r}){let e=["openai/gpt-oss-120b","llama-3.3-70b-versatile","moonshotai/kimi-k2-instruct-0905","meta-llama/llama-4-maverick-17b-128e-instruct","meta-llama/llama-4-scout-17b-16e-instruct","groq/compound","openai/gpt-oss-20b","openai/gpt-oss-safeguard-20b","llama-3.1-8b-instant","groq/compound-mini","meta-llama/llama-guard-4-12b","meta-llama/llama-prompt-guard-2-86m","meta-llama/llama-prompt-guard-2-22m"],[n,s]=useState([{role:"system",content:t},{role:"assistant",content:r}]),[a,d]=useState(""),[v,c]=useState(false),p=useRef(null),l=useRef(0);useEffect(()=>{p?.current?.scrollTo({top:p.current.scrollHeight,behavior:"smooth"});},[n]);function y(h=""){let f=typeof h=="string"?h:"";if(!a.trim()&&!f.trim())return;let C={role:"user",content:a||f},b=[...n,C];s(b),d(""),c(true),B({model:e[l.current],messages:b,apiKey:o}).then(g=>{g==="error"?(s(u=>[...u,{role:"assistant",content:"Sorry, I encountered an error. Please try again."}]),l.current++,l.current>=e.length&&(l.current=0)):s(u=>[...u,g]);}).catch(g=>{console.error(g);}).finally(()=>{c(false);});}return {messages:n,input:a,setInput:d,handleSendMessage:y,messagesRef:p,isLoading:v}}var N=K;function j({triggerColor:o="#111",triggerImg:t,triggerRightPosition:r=24,triggerBottomPosition:e=24}){return jsx(PopoverTrigger,{asChild:true,children:jsxs("button",{className:`fixed right-[${r}px] ${t?"":"h-14 w-14"} bottom-[${e}px] z-10 cursor-pointer rounded-full bg-[${o}] p-1 shadow-lg transition-all hover:scale-110 hover:bg-[${o}]/90 active:scale-95`,children:[t&&jsx("img",{src:t,alt:"Chat with chatbot",className:"h-14 w-14"}),!t&&jsx("p",{className:"text-white text-center text-xl",children:"C"})]})})}var _=j;function E({messages:o,messagesRef:t,isLoading:r,userMessageBgColor:e="#fff",assistantMessageBgColor:n="#007bff"}){return jsxs("div",{ref:t,style:{scrollbarWidth:"none",msOverflowStyle:"none"},className:" flex h-full flex-col gap-4 overflow-x-hidden overflow-y-auto",children:[o.map((s,a)=>{if(s.role==="user")return jsx("div",{className:"flex justify-start",children:jsx("div",{dir:"auto",style:{unicodeBidi:"isolate"},className:`max-w-[95%] rounded-2xl rounded-bl-none bg-[${e}] px-4 py-2 text-start text-sm shadow-sm`,children:s.content.replace(/\[\[.*?\]\]/g,"")})},a);if(s.role==="assistant")return jsx("div",{className:"flex justify-end",children:jsx("div",{dir:"rtl",style:{unicodeBidi:"isolate",display:"inline-block"},className:`bg-[${n}] max-w-[95%] rounded-2xl rounded-br-none px-4 py-2 text-start text-sm wrap-break-word whitespace-normal text-white shadow-md`,children:jsx(D,{children:s.content})})},a)}),r&&jsx("div",{className:"flex justify-end",children:jsx("div",{className:"bg-red/90 rounded-2xl rounded-br-none px-4 py-2 text-white shadow-md",children:jsx("span",{className:"loading loading-dots loading-xs"})})})]})}var $=E;function H({handleSendMessage:o,input:t,setInput:r}){return jsxs("div",{className:"flex h-full items-end gap-2",children:[jsx("textarea",{onKeyDown:e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),o());},value:t,onChange:e=>r(e.target.value),placeholder:"Ask me anything...",style:{fieldSizing:"content",scrollbarWidth:"none",msOverflowStyle:"none"},dir:"auto",className:"auto-expand text-yellowish-white placeholder:text-dark-yellowish-white max-h-[20vh] min-h-6 w-full resize-none overflow-auto bg-transparent py-1 ring-transparent outline-none"}),jsx("button",{onClick:()=>o(),className:"bg-red hover:bg-light-red cursor-pointer rounded-full p-2 text-white transition-colors",children:jsx(FaPaperPlane,{className:"h-4 w-4"})})]})}var I=H;var U=x.Root,J=x.Content;function Q({apiKey:o,triggerColor:t,triggerImg:r,contentBgColor:e="#1a1a1a",contentHeight:n=500,contentWidth:s=350,contentBorder:a=1,contentBorderColor:d="#333333",textColor:v="#ffffff",userMessageBgColor:c="#007bff",assistantMessageBgColor:p="#2d2d2d",triggerRightPosition:l=24,triggerBottomPosition:y=24,contentRightPosition:h=24,systemPrompt:f="You are a helpful AI assistant. Provide clear, concise, and accurate responses.",assistantFirstMessage:C="Hello! I'm here to help you. What can I assist you with today?",contentBorderRoundness:b=16}){let{messages:g,input:u,setInput:L,handleSendMessage:T,messagesRef:S,isLoading:q}=N({apiKey:o,systemPrompt:f,assistantFirstMessage:C});return jsxs(U,{children:[jsx(_,{triggerColor:t,triggerImg:r,triggerRightPosition:l,triggerBottomPosition:y}),jsx(J,{className:`bg-[${e}] mr-[${h}px] h-[${n}px] max-h-[${n}px] w-[${s}px] border-[${a}px] border-[${d}] text-[${v}] shadow-2xl ring-1 ring-white/10 rounded-[${b}px]`,children:jsxs("div",{className:"flex h-full flex-col gap-4 p-2",children:[jsx("div",{className:"min-h-0 flex-1",children:jsx($,{messages:g,messagesRef:S,isLoading:q,userMessageBgColor:c,assistantMessageBgColor:p})}),jsx("div",{className:"shrink-0 rounded-xl bg-black/40 p-2",children:jsx(I,{handleSendMessage:T,input:u,setInput:L})})]})})]})}
2
+ export{Q as ChatBot};//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/groqApi.ts","../src/ChatBot/hooks/useChat.tsx","../src/ChatBot/components/ChatTrigger.tsx","../src/ChatBot/components/MessageList.tsx","../src/ChatBot/components/ChatInput.tsx","../src/ChatBot/ChatBot.tsx"],"names":["chatWithGroq","messages","model","apiKey","url","options","error","useChat","systemPrompt","assistantFirstMessage","models","setMessages","useState","input","setInput","isLoading","setIsLoading","messagesRef","useRef","modelNumber","useEffect","handleSendMessage","text","messageContent","userMessage","newMessages","res","prev","err","useChat_default","ChatTrigger","triggerColor","triggerImg","triggerRightPosition","triggerBottomPosition","jsx","PopoverTrigger","jsxs","ChatTrigger_default","MessageList","userMessageBgColor","assistantMessageBgColor","item","index","Markdown","MessageList_default","ChatInput","FaPaperPlane","ChatInput_default","Popover","PopoverContent","ChatBot","contentBgColor","contentHeight","contentWidth","contentBorder","contentBorderColor","textColor","contentRightPosition","contentBorderRoundness"],"mappings":"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","file":"index.js","sourcesContent":["type chatWithGroqProps = {\r\n messages: {\r\n role: string;\r\n content: string;\r\n }[];\r\n model: string;\r\n apiKey: string;\r\n};\r\n\r\ntype response = {\r\n id: string;\r\n object: string;\r\n created: number;\r\n model: string;\r\n choices: {\r\n index: number;\r\n message: {\r\n role: string;\r\n content: string;\r\n reasoning?: string;\r\n };\r\n logprobs: null;\r\n finish_reason: string;\r\n }[];\r\n usage: {\r\n queue_time: number;\r\n prompt_tokens: number;\r\n prompt_time: number;\r\n completion_tokens: number;\r\n completion_time: number;\r\n total_tokens: number;\r\n total_time: number;\r\n prompt_tokens_details: {\r\n cached_tokens: number;\r\n };\r\n completion_tokens_details: {\r\n reasoning_tokens: number;\r\n };\r\n };\r\n usage_breakdown: null;\r\n system_fingerprint: string;\r\n x_groq: {\r\n id: string;\r\n seed: number;\r\n };\r\n service_tier: string;\r\n};\r\n\r\nexport async function chatWithGroq({\r\n messages,\r\n model,\r\n apiKey,\r\n}: chatWithGroqProps) {\r\n const url = \"https://api.groq.com/openai/v1/chat/completions\";\r\n const options = {\r\n method: \"POST\",\r\n headers: {\r\n Authorization: `Bearer ${apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify({\r\n model: model,\r\n messages,\r\n temperature: 0.3,\r\n }),\r\n };\r\n\r\n try {\r\n const response = await fetch(url, options);\r\n const result: response = await response.json();\r\n return result.choices[0].message;\r\n } catch (error) {\r\n console.error(error);\r\n return \"error\";\r\n }\r\n}\r\n","import { chatWithGroq } from \"@/api/groqApi\";\r\nimport { useEffect, useRef, useState } from \"react\";\r\n\r\nexport type UseChatProps = {\r\n apiKey: string;\r\n systemPrompt: string;\r\n assistantFirstMessage: string;\r\n};\r\n\r\nfunction useChat({\r\n apiKey,\r\n systemPrompt,\r\n assistantFirstMessage,\r\n}: UseChatProps) {\r\n const models = [\r\n \"openai/gpt-oss-120b\",\r\n \"llama-3.3-70b-versatile\",\r\n \"moonshotai/kimi-k2-instruct-0905\",\r\n \"meta-llama/llama-4-maverick-17b-128e-instruct\",\r\n \"meta-llama/llama-4-scout-17b-16e-instruct\",\r\n \"groq/compound\",\r\n \"openai/gpt-oss-20b\",\r\n \"openai/gpt-oss-safeguard-20b\",\r\n \"llama-3.1-8b-instant\",\r\n \"groq/compound-mini\",\r\n \"meta-llama/llama-guard-4-12b\",\r\n \"meta-llama/llama-prompt-guard-2-86m\",\r\n \"meta-llama/llama-prompt-guard-2-22m\",\r\n ];\r\n const [messages, setMessages] = useState([\r\n {\r\n role: \"system\",\r\n content: systemPrompt,\r\n },\r\n {\r\n role: \"assistant\",\r\n content: assistantFirstMessage,\r\n },\r\n ]);\r\n const [input, setInput] = useState(\"\");\r\n const [isLoading, setIsLoading] = useState(false);\r\n const messagesRef = useRef<HTMLDivElement>(null);\r\n const modelNumber = useRef(0);\r\n\r\n useEffect(() => {\r\n // Scroll to the bottom of the messages container\r\n messagesRef?.current?.scrollTo({\r\n top: messagesRef.current.scrollHeight,\r\n behavior: \"smooth\",\r\n });\r\n }, [messages]);\r\n\r\n function handleSendMessage(text = \"\") {\r\n const messageContent = typeof text === \"string\" ? text : \"\";\r\n if (!input.trim() && !messageContent.trim()) return;\r\n\r\n const userMessage = { role: \"user\", content: input || messageContent };\r\n const newMessages = [...messages, userMessage];\r\n\r\n setMessages(newMessages);\r\n setInput(\"\");\r\n setIsLoading(true);\r\n\r\n chatWithGroq({\r\n model: models[modelNumber.current],\r\n messages: newMessages,\r\n apiKey: apiKey,\r\n })\r\n .then((res) => {\r\n if (res === \"error\") {\r\n setMessages((prev) => [\r\n ...prev,\r\n {\r\n role: \"assistant\",\r\n content: \"Sorry, I encountered an error. Please try again.\",\r\n },\r\n ]);\r\n modelNumber.current++;\r\n if (modelNumber.current >= models.length) {\r\n modelNumber.current = 0;\r\n }\r\n } else {\r\n setMessages((prev) => [...prev, res]);\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(err);\r\n })\r\n .finally(() => {\r\n setIsLoading(false);\r\n });\r\n }\r\n return {\r\n messages,\r\n input,\r\n setInput,\r\n handleSendMessage,\r\n messagesRef,\r\n isLoading,\r\n };\r\n}\r\n\r\nexport default useChat;\r\n","import { PopoverTrigger } from \"@radix-ui/react-popover\";\r\n\r\ntype ChatTriggerProps = {\r\n triggerColor?: string;\r\n triggerImg?: string;\r\n triggerRightPosition?: number;\r\n triggerBottomPosition?: number;\r\n};\r\n\r\nfunction ChatTrigger({\r\n triggerColor = \"#111\",\r\n triggerImg,\r\n triggerRightPosition = 24,\r\n triggerBottomPosition = 24,\r\n}: ChatTriggerProps) {\r\n return (\r\n <PopoverTrigger asChild>\r\n <button\r\n className={`fixed right-[${triggerRightPosition}px] ${triggerImg ? \"\" : \"h-14 w-14\"} bottom-[${triggerBottomPosition}px] z-10 cursor-pointer rounded-full bg-[${triggerColor}] p-1 shadow-lg transition-all hover:scale-110 hover:bg-[${triggerColor}]/90 active:scale-95`}\r\n >\r\n {triggerImg && (\r\n <img src={triggerImg} alt=\"Chat with chatbot\" className=\"h-14 w-14\" />\r\n )}\r\n {!triggerImg && <p className=\"text-white text-center text-xl\">C</p>}\r\n </button>\r\n </PopoverTrigger>\r\n );\r\n}\r\n\r\nexport default ChatTrigger;\r\n","import type { RefObject } from \"react\";\r\nimport Markdown from \"react-markdown\";\r\n\r\ntype MessageListProps = {\r\n messages: { role: string; content: string }[];\r\n messagesRef: RefObject<HTMLDivElement | null>;\r\n isLoading: boolean;\r\n userMessageBgColor?: string;\r\n assistantMessageBgColor?: string;\r\n};\r\n\r\nfunction MessageList({\r\n messages,\r\n messagesRef,\r\n isLoading,\r\n userMessageBgColor = \"#fff\",\r\n assistantMessageBgColor = \"#007bff\",\r\n}: MessageListProps) {\r\n return (\r\n <div\r\n ref={messagesRef}\r\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\r\n className=\" flex h-full flex-col gap-4 overflow-x-hidden overflow-y-auto\"\r\n >\r\n {messages.map((item, index) => {\r\n if (item.role === \"user\")\r\n return (\r\n <div key={index} className=\"flex justify-start\">\r\n <div\r\n dir=\"auto\"\r\n style={{ unicodeBidi: \"isolate\" }}\r\n className={`max-w-[95%] rounded-2xl rounded-bl-none bg-[${userMessageBgColor}] px-4 py-2 text-start text-sm shadow-sm`}\r\n >\r\n {item.content.replace(/\\[\\[.*?\\]\\]/g, \"\")}\r\n </div>\r\n </div>\r\n );\r\n if (item.role === \"assistant\") {\r\n return (\r\n <div key={index} className=\"flex justify-end\">\r\n <div\r\n dir=\"rtl\"\r\n style={{ unicodeBidi: \"isolate\", display: \"inline-block\" }}\r\n className={`bg-[${assistantMessageBgColor}] max-w-[95%] rounded-2xl rounded-br-none px-4 py-2 text-start text-sm wrap-break-word whitespace-normal text-white shadow-md`}\r\n >\r\n <Markdown>{item.content}</Markdown>\r\n </div>\r\n </div>\r\n );\r\n }\r\n })}\r\n {isLoading && (\r\n <div className=\"flex justify-end\">\r\n <div className=\"bg-red/90 rounded-2xl rounded-br-none px-4 py-2 text-white shadow-md\">\r\n <span className=\"loading loading-dots loading-xs\"></span>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nexport default MessageList;\r\n","import { FaPaperPlane } from \"react-icons/fa\";\r\nimport { FaQuestionCircle } from \"react-icons/fa\";\r\n\r\ntype ChatInputProps = {\r\n handleSendMessage: (text?: string) => void;\r\n input: string;\r\n setInput: (text: string) => void;\r\n};\r\n\r\nfunction ChatInput({ handleSendMessage, input, setInput }: ChatInputProps) {\r\n return (\r\n <div className=\"flex h-full items-end gap-2\">\r\n <textarea\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\" && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSendMessage();\r\n }\r\n }}\r\n value={input}\r\n onChange={(e) => setInput(e.target.value)}\r\n placeholder=\"Ask me anything...\"\r\n style={{\r\n fieldSizing: \"content\",\r\n scrollbarWidth: \"none\",\r\n msOverflowStyle: \"none\",\r\n }}\r\n dir=\"auto\"\r\n className=\"auto-expand text-yellowish-white placeholder:text-dark-yellowish-white max-h-[20vh] min-h-6 w-full resize-none overflow-auto bg-transparent py-1 ring-transparent outline-none\"\r\n />\r\n <button\r\n onClick={() => handleSendMessage()}\r\n className=\"bg-red hover:bg-light-red cursor-pointer rounded-full p-2 text-white transition-colors\"\r\n >\r\n <FaPaperPlane className=\"h-4 w-4\" />\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\nexport default ChatInput;\r\n","import * as PopoverPrimitive from \"@radix-ui/react-popover\";\r\nimport useChat from \"./hooks/useChat\";\r\nimport ChatTrigger from \"./components/ChatTrigger\";\r\nimport MessageList from \"./components/MessageList\";\r\nimport ChatInput from \"./components/ChatInput\";\r\n\r\n// Custom popover components to avoid shadcn dependency\r\nconst Popover = PopoverPrimitive.Root;\r\nconst PopoverContent = PopoverPrimitive.Content;\r\n\r\nexport type ChatBotProps = {\r\n apiKey: string;\r\n triggerColor?: string;\r\n triggerImg?: string;\r\n contentBgColor?: string;\r\n contentHeight?: number;\r\n contentWidth?: number;\r\n contentBorder?: number;\r\n contentBorderColor?: string;\r\n contentBorderRoundness?: number;\r\n textColor?: string;\r\n userMessageBgColor?: string;\r\n assistantMessageBgColor?: string;\r\n triggerRightPosition?: number;\r\n triggerBottomPosition?: number;\r\n contentRightPosition?: number;\r\n systemPrompt?: string;\r\n assistantFirstMessage?: string;\r\n};\r\n\r\nexport function ChatBot({\r\n apiKey,\r\n triggerColor,\r\n triggerImg,\r\n contentBgColor = \"#1a1a1a\",\r\n contentHeight = 500,\r\n contentWidth = 350,\r\n contentBorder = 1,\r\n contentBorderColor = \"#333333\",\r\n textColor = \"#ffffff\",\r\n userMessageBgColor = \"#007bff\",\r\n assistantMessageBgColor = \"#2d2d2d\",\r\n triggerRightPosition = 24,\r\n triggerBottomPosition = 24,\r\n contentRightPosition = 24,\r\n systemPrompt = `You are a helpful AI assistant. Provide clear, concise, and accurate responses.`,\r\n assistantFirstMessage = \"Hello! I'm here to help you. What can I assist you with today?\",\r\n contentBorderRoundness = 16,\r\n}: ChatBotProps) {\r\n const {\r\n messages,\r\n input,\r\n setInput,\r\n handleSendMessage,\r\n messagesRef,\r\n isLoading,\r\n } = useChat({ apiKey, systemPrompt, assistantFirstMessage });\r\n return (\r\n <Popover>\r\n <ChatTrigger\r\n triggerColor={triggerColor}\r\n triggerImg={triggerImg}\r\n triggerRightPosition={triggerRightPosition}\r\n triggerBottomPosition={triggerBottomPosition}\r\n />\r\n <PopoverContent\r\n className={`bg-[${contentBgColor}] mr-[${contentRightPosition}px] h-[${contentHeight}px] max-h-[${contentHeight}px] w-[${contentWidth}px] border-[${contentBorder}px] border-[${contentBorderColor}] text-[${textColor}] shadow-2xl ring-1 ring-white/10 rounded-[${contentBorderRoundness}px]`}\r\n >\r\n <div className=\"flex h-full flex-col gap-4 p-2\">\r\n <div className=\"min-h-0 flex-1\">\r\n <MessageList\r\n messages={messages}\r\n messagesRef={messagesRef}\r\n isLoading={isLoading}\r\n userMessageBgColor={userMessageBgColor}\r\n assistantMessageBgColor={assistantMessageBgColor}\r\n />\r\n </div>\r\n\r\n <div className=\"shrink-0 rounded-xl bg-black/40 p-2\">\r\n <ChatInput\r\n handleSendMessage={handleSendMessage}\r\n input={input}\r\n setInput={setInput}\r\n />\r\n </div>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n"]}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "react-groq-chat",
3
+ "version": "1.0.0",
4
+ "description": "A modern, customizable React component for integrating a chatbot with the Groq API",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "SETUP.md",
12
+ "LICENSE"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.mjs",
18
+ "require": "./dist/index.js"
19
+ }
20
+ },
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "prepublishOnly": "npm run build",
25
+ "test": "echo \"Error: no test specified\" && exit 1"
26
+ },
27
+ "keywords": [
28
+ "react",
29
+ "chatbot",
30
+ "groq",
31
+ "api",
32
+ "typescript",
33
+ "tailwindcss",
34
+ "radix-ui",
35
+ "ai-chat",
36
+ "groq-api",
37
+ "react-component",
38
+ "chat-interface",
39
+ "markdown-support"
40
+ ],
41
+ "author": {
42
+ "name": "Ahmed Mamdoh",
43
+ "email": "your-email@example.com",
44
+ "url": "https://github.com/your-username"
45
+ },
46
+ "license": "ISC",
47
+ "type": "module",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/your-username/react-groq-chat.git"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/your-username/react-groq-chat/issues"
54
+ },
55
+ "homepage": "https://github.com/your-username/react-groq-chat#readme",
56
+ "peerDependencies": {
57
+ "react": ">=16.8.0",
58
+ "react-dom": ">=16.8.0"
59
+ },
60
+ "engines": {
61
+ "node": ">=14.0.0"
62
+ },
63
+ "dependencies": {
64
+ "@radix-ui/react-popover": "^1.0.7",
65
+ "clsx": "^2.1.0",
66
+ "tailwind-merge": "^2.2.0",
67
+ "react-icons": "^5.0.1",
68
+ "react-markdown": "^9.0.1"
69
+ },
70
+ "devDependencies": {
71
+ "@types/react": "^19.2.14",
72
+ "tsup": "^8.5.1",
73
+ "typescript": "^5.9.3"
74
+ }
75
+ }